diff --git a/lib/dex-invariant/src/internal/accounts.rs b/lib/dex-invariant/src/internal/accounts.rs index 3976f4d..fe763ed 100644 --- a/lib/dex-invariant/src/internal/accounts.rs +++ b/lib/dex-invariant/src/internal/accounts.rs @@ -1,7 +1,8 @@ use anchor_lang::prelude::*; -use anchor_spl::token::spl_token; use anyhow::Error; use invariant_types::{SEED, STATE_SEED}; +use router_lib::dex::AccountProviderView; +use solana_sdk::account::ReadableAccount; use super::swap::InvariantSwapResult; use crate::{invariant_edge::InvariantEdge, InvariantDex}; @@ -22,19 +23,23 @@ pub struct InvariantSwapAccounts { state: Pubkey, pool: Pubkey, tickmap: Pubkey, + token_x: Pubkey, + token_y: Pubkey, account_x: Pubkey, account_y: Pubkey, reserve_x: Pubkey, reserve_y: Pubkey, owner: Pubkey, program_authority: Pubkey, - token_program: Pubkey, + token_x_program: Pubkey, + token_y_program: Pubkey, ticks_accounts: Vec, referral_fee: Option, } impl InvariantSwapAccounts { pub fn from_pubkeys( + chain_data: &AccountProviderView, invariant_edge: &InvariantEdge, pool_pk: Pubkey, invariant_swap_params: &InvariantSwapParams, @@ -63,17 +68,29 @@ impl InvariantSwapAccounts { let ticks_accounts = InvariantDex::tick_indexes_to_addresses(pool_pk, &invariant_swap_result.used_ticks); + let token_x_program = *chain_data + .account(&invariant_edge.pool.token_x)? + .account + .owner(); + let token_y_program = *chain_data + .account(&invariant_edge.pool.token_y)? + .account + .owner(); + let invariant_swap_accounts = Self { state: Self::get_state_address(crate::ID), pool: pool_pk, tickmap: invariant_edge.pool.tickmap, + token_x: invariant_edge.pool.token_x, + token_y: invariant_edge.pool.token_y, account_x, account_y, reserve_x: invariant_edge.pool.token_x_reserve, reserve_y: invariant_edge.pool.token_y_reserve, owner: *owner, program_authority: Self::get_program_authority(crate::ID), - token_program: spl_token::id(), + token_x_program, + token_y_program, ticks_accounts, referral_fee: *referral_fee, }; @@ -86,13 +103,16 @@ impl InvariantSwapAccounts { AccountMeta::new_readonly(self.state, false), AccountMeta::new(self.pool, false), AccountMeta::new(self.tickmap, false), + AccountMeta::new(self.token_x, false), + AccountMeta::new(self.token_y, false), AccountMeta::new(self.account_x, false), AccountMeta::new(self.account_y, false), AccountMeta::new(self.reserve_x, false), AccountMeta::new(self.reserve_y, false), AccountMeta::new(self.owner, true), AccountMeta::new_readonly(self.program_authority, false), - AccountMeta::new_readonly(self.token_program, false), + AccountMeta::new_readonly(self.token_x_program, false), + AccountMeta::new_readonly(self.token_y_program, false), ]; let ticks_metas: Vec = self diff --git a/lib/dex-invariant/src/invariant_dex.rs b/lib/dex-invariant/src/invariant_dex.rs index 59146e3..a1d6a81 100644 --- a/lib/dex-invariant/src/invariant_dex.rs +++ b/lib/dex-invariant/src/invariant_dex.rs @@ -3,7 +3,11 @@ use std::{ sync::Arc, }; -use anchor_lang::AnchorDeserialize; +use anchor_lang::{AnchorDeserialize, Id}; +use anchor_spl::{ + token::spl_token::{self, state::AccountState}, + token_2022::Token2022, +}; use anyhow::{Context, Ok}; use async_trait::async_trait; use invariant_types::{ @@ -21,7 +25,7 @@ use solana_client::{ rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, rpc_filter::RpcFilterType, }; -use solana_sdk::{account::ReadableAccount, pubkey::Pubkey}; +use solana_sdk::{account::ReadableAccount, program_pack::Pack, pubkey::Pubkey}; use tracing::info; use crate::{ @@ -231,7 +235,30 @@ impl DexInterface for InvariantDex { where Self: Sized, { - let pools = fetch_invariant_accounts(rpc, crate::id()).await?; + let mut pools = fetch_invariant_accounts(rpc, crate::id()).await?; + + let reserves = pools + .iter() + .flat_map(|x| [x.1.token_x_reserve, x.1.token_y_reserve]) + .collect::>(); + + let vaults = rpc.get_multiple_accounts(&reserves).await?; + let banned_reserves = vaults + .iter() + .filter(|(_, reserve)| { + reserve.owner == Token2022::id() + || spl_token::state::Account::unpack(reserve.data()) + .unwrap() + .state + == AccountState::Frozen + }) + .map(|(pk, _)| pk) + .collect::>(); + + pools.retain(|p| { + !(banned_reserves.contains(&p.1.token_x_reserve) + || banned_reserves.contains(&p.1.token_y_reserve)) + }); info!("Number of Invariant Pools: {:?}", pools.len()); diff --git a/lib/dex-invariant/src/invariant_edge.rs b/lib/dex-invariant/src/invariant_edge.rs index 93fc5bd..0f19c56 100644 --- a/lib/dex-invariant/src/invariant_edge.rs +++ b/lib/dex-invariant/src/invariant_edge.rs @@ -48,7 +48,7 @@ impl DexEdgeIdentifier for InvariantEdgeIdentifier { } fn accounts_needed(&self) -> usize { - 10 // total accounts without ticks + 13 // total accounts without ticks - 2 // user output ATA + user wallet address + TICK_CROSSES_PER_IX + TICKS_BACK_COUNT } diff --git a/lib/dex-invariant/src/invariant_ix_builder.rs b/lib/dex-invariant/src/invariant_ix_builder.rs index 2132673..a8b887b 100644 --- a/lib/dex-invariant/src/invariant_ix_builder.rs +++ b/lib/dex-invariant/src/invariant_ix_builder.rs @@ -11,7 +11,7 @@ use solana_program::pubkey::Pubkey; pub fn build_swap_ix( id: &InvariantEdgeIdentifier, edge: &InvariantEdge, - _chain_data: &AccountProviderView, + chain_data: &AccountProviderView, wallet_pk: &Pubkey, in_amount: u64, _out_amount: u64, @@ -53,7 +53,7 @@ pub fn build_swap_ix( }; let (swap_accounts, _x_to_y) = - InvariantSwapAccounts::from_pubkeys(edge, id.pool, &swap_params)?; + InvariantSwapAccounts::from_pubkeys(chain_data, edge, id.pool, &swap_params)?; let metas = swap_accounts.to_account_metas(); let discriminator = &Sha256::digest(b"global:swap")[0..8]; diff --git a/lib/dex-invariant/src/lib.rs b/lib/dex-invariant/src/lib.rs index 1c883bf..ecb5e70 100644 --- a/lib/dex-invariant/src/lib.rs +++ b/lib/dex-invariant/src/lib.rs @@ -7,4 +7,7 @@ pub use invariant_dex::InvariantDex; use solana_sdk::declare_id; -declare_id!("HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt"); +// SOL +// declare_id!("HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt"); +// eclipse +declare_id!("iNvTyprs4TX8m6UeUEkeqDFjAL9zRCRWcexK9Sd4WEU"); diff --git a/programs/simulator/tests/fixtures/iNvTyprs4TX8m6UeUEkeqDFjAL9zRCRWcexK9Sd4WEU.so b/programs/simulator/tests/fixtures/iNvTyprs4TX8m6UeUEkeqDFjAL9zRCRWcexK9Sd4WEU.so new file mode 100644 index 0000000..2f271ac Binary files /dev/null and b/programs/simulator/tests/fixtures/iNvTyprs4TX8m6UeUEkeqDFjAL9zRCRWcexK9Sd4WEU.so differ