From 10573215203731ba3f2f9d8c87cad870a60188c9 Mon Sep 17 00:00:00 2001 From: 0xh3rman <119309671+0xh3rman@users.noreply.github.com> Date: Wed, 18 Mar 2026 21:40:36 +0900 Subject: [PATCH 1/4] consolidate fees logic into one mod --- crates/swapper/src/across/provider.rs | 2 +- crates/swapper/src/chainflip/provider.rs | 5 +- crates/swapper/src/config.rs | 108 +----------------- crates/swapper/src/fees/mod.rs | 13 +++ crates/swapper/src/fees/referral.rs | 67 +++++++++++ .../swapper/src/{fees.rs => fees/reserve.rs} | 7 +- crates/swapper/src/{ => fees}/slippage.rs | 14 +-- crates/swapper/src/lib.rs | 4 +- crates/swapper/src/models.rs | 2 +- crates/swapper/src/near_intents/provider.rs | 2 +- crates/swapper/src/proxy/provider.rs | 3 +- crates/swapper/src/referrer.rs | 1 - crates/swapper/src/relay/provider.rs | 2 +- crates/swapper/src/swapper.rs | 4 +- crates/swapper/src/uniswap/v3/commands.rs | 4 +- crates/swapper/src/uniswap/v3/provider.rs | 2 +- crates/swapper/src/uniswap/v4/commands.rs | 2 +- crates/swapper/src/uniswap/v4/provider.rs | 2 +- gemstone/src/config/swap_config.rs | 6 +- 19 files changed, 113 insertions(+), 137 deletions(-) create mode 100644 crates/swapper/src/fees/mod.rs create mode 100644 crates/swapper/src/fees/referral.rs rename crates/swapper/src/{fees.rs => fees/reserve.rs} (88%) rename crates/swapper/src/{ => fees}/slippage.rs (75%) delete mode 100644 crates/swapper/src/referrer.rs diff --git a/crates/swapper/src/across/provider.rs b/crates/swapper/src/across/provider.rs index 85b6240d6..62dbb59ce 100644 --- a/crates/swapper/src/across/provider.rs +++ b/crates/swapper/src/across/provider.rs @@ -11,7 +11,7 @@ use crate::{ approval::check_approval_erc20, chainlink::ChainlinkPriceFeed, client_factory::create_eth_client, - config::ReferralFee, + fees::ReferralFee, cross_chain::VaultAddresses, eth_address, models::*, diff --git a/crates/swapper/src/chainflip/provider.rs b/crates/swapper/src/chainflip/provider.rs index 871371369..0386e42cd 100644 --- a/crates/swapper/src/chainflip/provider.rs +++ b/crates/swapper/src/chainflip/provider.rs @@ -16,7 +16,8 @@ use super::{ }; use crate::{ FetchQuoteData, ProviderData, ProviderType, Quote, QuoteRequest, Route, SwapResult, Swapper, SwapperChainAsset, SwapperError, SwapperProvider, SwapperQuoteData, - alien::RpcProvider, amount_to_value, approval::check_approval_erc20, config::DEFAULT_CHAINFLIP_FEE_BPS, cross_chain::VaultAddresses, slippage, + alien::RpcProvider, amount_to_value, approval::check_approval_erc20, cross_chain::VaultAddresses, + fees::{DEFAULT_CHAINFLIP_FEE_BPS, apply_slippage_in_bp} }; use primitives::{ChainType, chain::Chain, swap::QuoteAsset}; @@ -218,7 +219,7 @@ where }) } else if from_asset.chain.chain_type() == ChainType::Bitcoin { let output_amount: U256 = quote.to_value.parse()?; - let min_output_amount = slippage::apply_slippage_in_bp(&output_amount, quote.data.slippage_bps); + let min_output_amount = apply_slippage_in_bp(&output_amount, quote.data.slippage_bps); VaultSwapExtras::Bitcoin(VaultSwapBtcExtras { chain, min_output_amount: BigUint::from_bytes_le(&min_output_amount.to_le_bytes::<32>()), diff --git a/crates/swapper/src/config.rs b/crates/swapper/src/config.rs index a30390d44..d31d478ae 100644 --- a/crates/swapper/src/config.rs +++ b/crates/swapper/src/config.rs @@ -1,4 +1,4 @@ -use crate::{SwapperSlippage, SwapperSlippageMode}; +use crate::{SwapperSlippage, SwapperSlippageMode, fees::{ReferralFees, default_referral_fees}}; use primitives::Chain; pub const DEFAULT_SLIPPAGE_BPS: u32 = 100; @@ -7,7 +7,6 @@ pub const DEFAULT_CHAINFLIP_FEE_BPS: u32 = 45; pub const DEFAULT_STABLE_SWAP_REFERRAL_BPS: u32 = 25; pub const API_BASE_URL: &str = "https://api.gemwallet.com/proxy/swap"; -pub const EVM_REFERRAL_ADDRESS: &str = "0x0D9DAB1A248f63B0a48965bA8435e4de7497a3dC"; pub fn get_swap_api_url(path: &str) -> String { format!("{API_BASE_URL}/{path}") @@ -22,114 +21,15 @@ pub struct Config { pub high_price_impact_percent: u32, } -#[derive(Default, Debug, Clone, PartialEq)] -pub struct ReferralFees { - pub evm: ReferralFee, - pub evm_bridge: ReferralFee, - pub solana: ReferralFee, - pub thorchain: ReferralFee, - pub sui: ReferralFee, - pub ton: ReferralFee, - pub tron: ReferralFee, - pub near: ReferralFee, - pub aptos: ReferralFee, -} - -#[derive(Default, Debug, Clone, PartialEq)] -pub struct ReferralFee { - pub address: String, - pub bps: u32, -} - -impl ReferralFees { - pub fn evm(evm: ReferralFee) -> ReferralFees { - ReferralFees { - evm, - evm_bridge: ReferralFee::default(), - solana: ReferralFee::default(), - thorchain: ReferralFee::default(), - sui: ReferralFee::default(), - ton: ReferralFee::default(), - tron: ReferralFee::default(), - near: ReferralFee::default(), - aptos: ReferralFee::default(), - } - } - - pub fn update_all_bps(&mut self, bps: u32) { - self.iter_mut().for_each(|fee| fee.update_bps(bps)); - } - - fn iter_mut(&mut self) -> impl Iterator { - [ - &mut self.evm, - &mut self.evm_bridge, - &mut self.solana, - &mut self.thorchain, - &mut self.sui, - &mut self.ton, - &mut self.tron, - &mut self.near, - &mut self.aptos, - ] - .into_iter() - } -} - -impl ReferralFee { - pub fn update_bps(&mut self, bps: u32) { - if !self.address.is_empty() || self.bps > 0 { - self.bps = bps; - } - } -} - pub fn get_swap_config() -> Config { Config { default_slippage: SwapperSlippage { bps: DEFAULT_SLIPPAGE_BPS, mode: SwapperSlippageMode::Exact, }, - permit2_expiration: 60 * 60 * 24 * 30, // 30 days - permit2_sig_deadline: 60 * 30, // 30 minutes - referral_fee: ReferralFees { - evm: ReferralFee { - address: EVM_REFERRAL_ADDRESS.into(), - bps: DEFAULT_SWAP_FEE_BPS, - }, - evm_bridge: ReferralFee { - address: EVM_REFERRAL_ADDRESS.into(), - bps: DEFAULT_STABLE_SWAP_REFERRAL_BPS, - }, - solana: ReferralFee { - address: "5fmLrs2GuhfDP1B51ziV5Kd1xtAr9rw1jf3aQ4ihZ2gy".into(), - bps: DEFAULT_SWAP_FEE_BPS, - }, - thorchain: ReferralFee { - address: "g1".into(), - bps: DEFAULT_SWAP_FEE_BPS, - }, - sui: ReferralFee { - address: "0x9d6b98b18fd26b5efeec68d020dcf1be7a94c2c315353779bc6b3aed44188ddf".into(), - bps: DEFAULT_SWAP_FEE_BPS, - }, - ton: ReferralFee { - address: "UQDxJKarPSp0bCta9DFgp81Mpt5hpGbuVcSxwfeza0Bin201".into(), - bps: DEFAULT_SWAP_FEE_BPS, - }, - tron: ReferralFee { - address: "TYeyZXywpA921LEtw2PF3obK4B8Jjgpp32".into(), - bps: DEFAULT_SWAP_FEE_BPS, - }, - near: ReferralFee { - address: "0x0d9dab1a248f63b0a48965ba8435e4de7497a3dc".into(), - bps: DEFAULT_SWAP_FEE_BPS, - }, - aptos: ReferralFee { - address: "0xc09d385527743bb03ed7847bb9180b5ff2263d38d5a93f1c9b3068f8505f6488".into(), - bps: DEFAULT_SWAP_FEE_BPS, - }, - }, + permit2_expiration: 2_592_000, // 30 days + permit2_sig_deadline: 1800, // 30 minutes + referral_fee: default_referral_fees(), high_price_impact_percent: 10, } } diff --git a/crates/swapper/src/fees/mod.rs b/crates/swapper/src/fees/mod.rs new file mode 100644 index 000000000..50dbade47 --- /dev/null +++ b/crates/swapper/src/fees/mod.rs @@ -0,0 +1,13 @@ +mod referral; +mod reserve; +mod slippage; + +pub use referral::{ReferralFee, ReferralFees, default_referral_fees}; +pub use reserve::{RESERVED_NATIVE_FEES, reserved_tx_fees, resolve_max_quote_value}; +pub use slippage::{BasisPointConvert, apply_slippage_in_bp}; + +pub const DEFAULT_SWAP_FEE_BPS: u32 = 50; +pub const DEFAULT_CHAINFLIP_FEE_BPS: u32 = 45; +pub const DEFAULT_STABLE_SWAP_REFERRAL_BPS: u32 = 25; +pub const DEFAULT_REFERRER: &str = "gemwallet"; +pub const EVM_REFERRAL_ADDRESS: &str = "0x0D9DAB1A248f63B0a48965bA8435e4de7497a3dC"; diff --git a/crates/swapper/src/fees/referral.rs b/crates/swapper/src/fees/referral.rs new file mode 100644 index 000000000..c0649e903 --- /dev/null +++ b/crates/swapper/src/fees/referral.rs @@ -0,0 +1,67 @@ +use super::{DEFAULT_STABLE_SWAP_REFERRAL_BPS, DEFAULT_SWAP_FEE_BPS, EVM_REFERRAL_ADDRESS}; + +#[derive(Default, Debug, Clone, PartialEq)] +pub struct ReferralFees { + pub evm: ReferralFee, + pub evm_bridge: ReferralFee, + pub solana: ReferralFee, + pub thorchain: ReferralFee, + pub sui: ReferralFee, + pub ton: ReferralFee, + pub tron: ReferralFee, + pub near: ReferralFee, + pub aptos: ReferralFee, +} + +#[derive(Default, Debug, Clone, PartialEq)] +pub struct ReferralFee { + pub address: String, + pub bps: u32, +} + +impl ReferralFees { + pub fn evm(evm: ReferralFee) -> Self { + Self { evm, ..Default::default() } + } + + pub fn update_all_bps(&mut self, bps: u32) { + self.iter_mut().for_each(|fee| fee.update_bps(bps)); + } + + fn iter_mut(&mut self) -> impl Iterator { + [ + &mut self.evm, + &mut self.evm_bridge, + &mut self.solana, + &mut self.thorchain, + &mut self.sui, + &mut self.ton, + &mut self.tron, + &mut self.near, + &mut self.aptos, + ] + .into_iter() + } +} + +impl ReferralFee { + pub fn update_bps(&mut self, bps: u32) { + if !self.address.is_empty() || self.bps > 0 { + self.bps = bps; + } + } +} + +pub fn default_referral_fees() -> ReferralFees { + ReferralFees { + evm: ReferralFee { address: EVM_REFERRAL_ADDRESS.into(), bps: DEFAULT_SWAP_FEE_BPS }, + evm_bridge: ReferralFee { address: EVM_REFERRAL_ADDRESS.into(), bps: DEFAULT_STABLE_SWAP_REFERRAL_BPS }, + solana: ReferralFee { address: "5fmLrs2GuhfDP1B51ziV5Kd1xtAr9rw1jf3aQ4ihZ2gy".into(), bps: DEFAULT_SWAP_FEE_BPS }, + thorchain: ReferralFee { address: "g1".into(), bps: DEFAULT_SWAP_FEE_BPS }, + sui: ReferralFee { address: "0x9d6b98b18fd26b5efeec68d020dcf1be7a94c2c315353779bc6b3aed44188ddf".into(), bps: DEFAULT_SWAP_FEE_BPS }, + ton: ReferralFee { address: "UQDxJKarPSp0bCta9DFgp81Mpt5hpGbuVcSxwfeza0Bin201".into(), bps: DEFAULT_SWAP_FEE_BPS }, + tron: ReferralFee { address: "TYeyZXywpA921LEtw2PF3obK4B8Jjgpp32".into(), bps: DEFAULT_SWAP_FEE_BPS }, + near: ReferralFee { address: "0x0d9dab1a248f63b0a48965ba8435e4de7497a3dc".into(), bps: DEFAULT_SWAP_FEE_BPS }, + aptos: ReferralFee { address: "0xc09d385527743bb03ed7847bb9180b5ff2263d38d5a93f1c9b3068f8505f6488".into(), bps: DEFAULT_SWAP_FEE_BPS }, + } +} diff --git a/crates/swapper/src/fees.rs b/crates/swapper/src/fees/reserve.rs similarity index 88% rename from crates/swapper/src/fees.rs rename to crates/swapper/src/fees/reserve.rs index d1fac3016..dba49eab6 100644 --- a/crates/swapper/src/fees.rs +++ b/crates/swapper/src/fees/reserve.rs @@ -4,7 +4,6 @@ use std::{collections::HashMap, str::FromStr, sync::LazyLock}; use crate::{QuoteRequest, SwapperError}; -// Reserved fees represent approximately two simple native transfers per chain, in base units. pub static RESERVED_NATIVE_FEES: LazyLock> = LazyLock::new(|| { HashMap::from([ (Chain::Near, "50000000000000000000000"), // 0.05 NEAR @@ -33,6 +32,12 @@ pub static RESERVED_NATIVE_FEES: LazyLock> = LazyLo (Chain::Monad, "5000000000000000"), // 0.005 MON (Chain::XLayer, "5000000000000000"), // 0.005 OKB (Chain::Plasma, "5000000000000000"), // 0.005 XPL + (Chain::Cosmos, "39000"), // 0.039 ATOM + (Chain::Osmosis, "130000"), // 0.13 OSMO + (Chain::Celestia, "39000"), // 0.039 TIA + (Chain::Injective, "1300000000000000"), // 0.0013 INJ + (Chain::Sei, "1300000"), // 1.3 SEI + (Chain::Noble, "25000"), // 0.025 USDC ]) }); diff --git a/crates/swapper/src/slippage.rs b/crates/swapper/src/fees/slippage.rs similarity index 75% rename from crates/swapper/src/slippage.rs rename to crates/swapper/src/fees/slippage.rs index 03a4de4df..2d79e023b 100644 --- a/crates/swapper/src/slippage.rs +++ b/crates/swapper/src/fees/slippage.rs @@ -8,21 +8,15 @@ pub trait BasisPointConvert: Sized + Copy { } impl BasisPointConvert for U256 { - fn from_u32(value: u32) -> Self { - Self::from(value) - } + fn from_u32(value: u32) -> Self { Self::from(value) } } impl BasisPointConvert for u128 { - fn from_u32(value: u32) -> Self { - value as u128 - } + fn from_u32(value: u32) -> Self { value as u128 } } impl BasisPointConvert for u64 { - fn from_u32(value: u32) -> Self { - value as u64 - } + fn from_u32(value: u32) -> Self { value as u64 } } pub fn apply_slippage_in_bp(amount: &T, bps: u32) -> T @@ -45,7 +39,5 @@ mod tests { assert_eq!(apply_slippage_in_bp(&1000_u64, 500), 950_u64); assert_eq!(apply_slippage_in_bp(&U256::from(1000), 0), U256::from(1000)); assert_eq!(apply_slippage_in_bp(&U256::from(1000), HUNDRED_PERCENT_IN_BPS), U256::ZERO); - assert_eq!(apply_slippage_in_bp(&U256::from(1000), 12000), U256::ZERO); - assert_eq!(apply_slippage_in_bp(&U256::from(1000), 300 + 9800), U256::ZERO); } } diff --git a/crates/swapper/src/lib.rs b/crates/swapper/src/lib.rs index b16890c85..e07da2a8b 100644 --- a/crates/swapper/src/lib.rs +++ b/crates/swapper/src/lib.rs @@ -3,7 +3,7 @@ mod approval; mod chainlink; pub mod cross_chain; mod eth_address; -pub(crate) mod fees; +pub mod fees; mod swapper_trait; #[cfg(test)] @@ -20,9 +20,7 @@ pub mod models; pub mod near_intents; pub mod permit2_data; pub mod proxy; -pub mod referrer; pub mod relay; -pub mod slippage; pub mod swapper; pub mod thorchain; pub mod uniswap; diff --git a/crates/swapper/src/models.rs b/crates/swapper/src/models.rs index f8712bda6..d8d2046d7 100644 --- a/crates/swapper/src/models.rs +++ b/crates/swapper/src/models.rs @@ -1,7 +1,7 @@ use super::permit2_data::Permit2Data; use crate::{ SwapperMode, SwapperProvider, SwapperQuoteAsset, SwapperSlippage, - config::{DEFAULT_SLIPPAGE_BPS, ReferralFees}, + config::DEFAULT_SLIPPAGE_BPS, fees::ReferralFees, }; pub use primitives::swap::SwapResult; use primitives::{ diff --git a/crates/swapper/src/near_intents/provider.rs b/crates/swapper/src/near_intents/provider.rs index 9858aae9c..dee7741d1 100644 --- a/crates/swapper/src/near_intents/provider.rs +++ b/crates/swapper/src/near_intents/provider.rs @@ -11,7 +11,7 @@ use crate::{ cross_chain::VaultAddresses, fees::resolve_max_quote_value, near_intents::client::{base_url, explorer_url}, - referrer::DEFAULT_REFERRER, + fees::DEFAULT_REFERRER, }; use async_trait::async_trait; use chrono::{Duration, Utc}; diff --git a/crates/swapper/src/proxy/provider.rs b/crates/swapper/src/proxy/provider.rs index f0a998279..3b966b289 100644 --- a/crates/swapper/src/proxy/provider.rs +++ b/crates/swapper/src/proxy/provider.rs @@ -10,7 +10,8 @@ use crate::{ FetchQuoteData, ProviderData, ProviderType, Quote, QuoteRequest, Route, SwapResult, Swapper, SwapperError, SwapperProvider, SwapperProviderMode, SwapperQuoteData, alien::{RpcClient, RpcProvider}, approval::evm::check_approval_erc20, - config::{DEFAULT_SWAP_FEE_BPS, get_swap_api_url}, + config::get_swap_api_url, +fees::DEFAULT_SWAP_FEE_BPS, cross_chain::VaultAddresses, models::{ApprovalType, SwapperChainAsset}, }; diff --git a/crates/swapper/src/referrer.rs b/crates/swapper/src/referrer.rs deleted file mode 100644 index c71f7ab5d..000000000 --- a/crates/swapper/src/referrer.rs +++ /dev/null @@ -1 +0,0 @@ -pub const DEFAULT_REFERRER: &str = "gemwallet"; diff --git a/crates/swapper/src/relay/provider.rs b/crates/swapper/src/relay/provider.rs index 4ff65ba8a..36797578c 100644 --- a/crates/swapper/src/relay/provider.rs +++ b/crates/swapper/src/relay/provider.rs @@ -14,7 +14,7 @@ use super::{ }; use crate::{ FetchQuoteData, ProviderData, ProviderType, Quote, QuoteRequest, Route, RpcClient, RpcProvider, SwapResult, Swapper, SwapperChainAsset, SwapperError, SwapperProvider, - SwapperQuoteData, approval::check_approval_erc20, config::get_swap_api_url, cross_chain::VaultAddresses, fees::resolve_max_quote_value, referrer::DEFAULT_REFERRER, + SwapperQuoteData, approval::check_approval_erc20, config::get_swap_api_url, cross_chain::VaultAddresses, fees::resolve_max_quote_value, fees::DEFAULT_REFERRER, }; #[derive(Debug)] diff --git a/crates/swapper/src/swapper.rs b/crates/swapper/src/swapper.rs index bcd3a4ae5..c1b28856d 100644 --- a/crates/swapper/src/swapper.rs +++ b/crates/swapper/src/swapper.rs @@ -1,6 +1,6 @@ use crate::{ AssetList, FetchQuoteData, Permit2ApprovalData, ProviderType, Quote, QuoteRequest, SwapResult, Swapper, SwapperChainAsset, SwapperError, SwapperProvider, SwapperProviderMode, - SwapperQuoteData, across, alien::RpcProvider, chainflip, config::DEFAULT_STABLE_SWAP_REFERRAL_BPS, cross_chain::VaultAddresses, hyperliquid, jupiter, near_intents, + SwapperQuoteData, across, alien::RpcProvider, chainflip, fees::DEFAULT_STABLE_SWAP_REFERRAL_BPS, cross_chain::VaultAddresses, hyperliquid, jupiter, near_intents, proxy::provider_factory, relay, thorchain, uniswap, }; use num_bigint::BigInt; @@ -271,7 +271,7 @@ mod tests { use crate::{ Options, SwapperChainAsset, SwapperMode, SwapperProvider, SwapperQuoteAsset, SwapperSlippage, SwapperSlippageMode, alien::reqwest_provider::NativeProvider, - config::{DEFAULT_STABLE_SWAP_REFERRAL_BPS, DEFAULT_SWAP_FEE_BPS, ReferralFees}, + fees::{DEFAULT_STABLE_SWAP_REFERRAL_BPS, DEFAULT_SWAP_FEE_BPS, ReferralFees}, testkit::{MockSwapper, mock_quote}, uniswap::default::{new_pancakeswap, new_uniswap_v3}, }; diff --git a/crates/swapper/src/uniswap/v3/commands.rs b/crates/swapper/src/uniswap/v3/commands.rs index b3dbf7ee2..70b2150ed 100644 --- a/crates/swapper/src/uniswap/v3/commands.rs +++ b/crates/swapper/src/uniswap/v3/commands.rs @@ -1,4 +1,4 @@ -use crate::{SwapperError, SwapperMode, eth_address, models::*, slippage::apply_slippage_in_bp}; +use crate::{SwapperError, SwapperMode, eth_address, models::*, fees::apply_slippage_in_bp}; use gem_evm::uniswap::command::{ADDRESS_THIS, PayPortion, Permit2Permit, Sweep, Transfer, UniversalRouterCommand, UnwrapWeth, V3SwapExactIn, WrapEth}; use alloy_primitives::{Address, Bytes, U256}; @@ -126,7 +126,7 @@ pub fn build_commands( mod tests { use super::*; use crate::{ - config::{ReferralFee, ReferralFees}, + fees::{ReferralFee, ReferralFees}, permit2_data::*, }; use alloy_primitives::aliases::U256; diff --git a/crates/swapper/src/uniswap/v3/provider.rs b/crates/swapper/src/uniswap/v3/provider.rs index e8abe3e83..02b974f5d 100644 --- a/crates/swapper/src/uniswap/v3/provider.rs +++ b/crates/swapper/src/uniswap/v3/provider.rs @@ -4,7 +4,7 @@ use crate::{ approval::{check_approval_erc20_with_client, check_approval_permit2_with_client}, eth_address, models::*, - slippage::apply_slippage_in_bp, + fees::apply_slippage_in_bp, uniswap::{ deadline::get_sig_deadline, fee_token::get_fee_token, diff --git a/crates/swapper/src/uniswap/v4/commands.rs b/crates/swapper/src/uniswap/v4/commands.rs index fa0ecd51e..13a596b7a 100644 --- a/crates/swapper/src/uniswap/v4/commands.rs +++ b/crates/swapper/src/uniswap/v4/commands.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use crate::{QuoteRequest, Route, SwapperError, SwapperMode, eth_address, slippage::apply_slippage_in_bp}; +use crate::{QuoteRequest, Route, SwapperError, SwapperMode, eth_address, fees::apply_slippage_in_bp}; use alloy_primitives::{Address, U256}; use gem_evm::uniswap::{ actions::V4Action::{SETTLE, SWAP_EXACT_IN, TAKE}, diff --git a/crates/swapper/src/uniswap/v4/provider.rs b/crates/swapper/src/uniswap/v4/provider.rs index 756d8c42d..7d200535c 100644 --- a/crates/swapper/src/uniswap/v4/provider.rs +++ b/crates/swapper/src/uniswap/v4/provider.rs @@ -7,7 +7,7 @@ use crate::{ alien::{RpcClient, RpcProvider}, approval::evm::{check_approval_erc20_with_client, check_approval_permit2_with_client}, eth_address, - slippage::apply_slippage_in_bp, + fees::apply_slippage_in_bp, uniswap::{ deadline::get_sig_deadline, fee_token::get_fee_token, diff --git a/gemstone/src/config/swap_config.rs b/gemstone/src/config/swap_config.rs index 2b657eab5..a22afe010 100644 --- a/gemstone/src/config/swap_config.rs +++ b/gemstone/src/config/swap_config.rs @@ -1,8 +1,8 @@ use primitives::Chain; -use swapper::{SwapperSlippage, config as swap_config}; +use swapper::{SwapperSlippage, config as swap_config, fees as swap_fees}; -pub use swap_config::get_swap_config; -pub use swap_config::{Config as SwapConfig, ReferralFee as SwapReferralFee, ReferralFees as SwapReferralFees}; +pub use swap_config::{Config as SwapConfig, get_swap_config}; +pub use swap_fees::{ReferralFee as SwapReferralFee, ReferralFees as SwapReferralFees}; #[uniffi::remote(Record)] pub struct SwapConfig { From 7260de1ba0da64c725a1f14e25281d1486d51dd4 Mon Sep 17 00:00:00 2001 From: 0xh3rman <119309671+0xh3rman@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:42:29 +0900 Subject: [PATCH 2/4] format files --- crates/swapper/src/across/provider.rs | 2 +- crates/swapper/src/chainflip/provider.rs | 7 +++- crates/swapper/src/config.rs | 7 +++- crates/swapper/src/fees/referral.rs | 45 ++++++++++++++++----- crates/swapper/src/fees/slippage.rs | 12 ++++-- crates/swapper/src/models.rs | 5 +-- crates/swapper/src/near_intents/provider.rs | 2 +- crates/swapper/src/proxy/provider.rs | 2 +- crates/swapper/src/relay/provider.rs | 2 +- crates/swapper/src/swapper.rs | 2 +- crates/swapper/src/uniswap/v3/commands.rs | 2 +- crates/swapper/src/uniswap/v3/provider.rs | 2 +- 12 files changed, 63 insertions(+), 27 deletions(-) diff --git a/crates/swapper/src/across/provider.rs b/crates/swapper/src/across/provider.rs index 62dbb59ce..8f820a4bc 100644 --- a/crates/swapper/src/across/provider.rs +++ b/crates/swapper/src/across/provider.rs @@ -11,9 +11,9 @@ use crate::{ approval::check_approval_erc20, chainlink::ChainlinkPriceFeed, client_factory::create_eth_client, - fees::ReferralFee, cross_chain::VaultAddresses, eth_address, + fees::ReferralFee, models::*, }; use alloy_primitives::{ diff --git a/crates/swapper/src/chainflip/provider.rs b/crates/swapper/src/chainflip/provider.rs index 0386e42cd..6265973df 100644 --- a/crates/swapper/src/chainflip/provider.rs +++ b/crates/swapper/src/chainflip/provider.rs @@ -16,8 +16,11 @@ use super::{ }; use crate::{ FetchQuoteData, ProviderData, ProviderType, Quote, QuoteRequest, Route, SwapResult, Swapper, SwapperChainAsset, SwapperError, SwapperProvider, SwapperQuoteData, - alien::RpcProvider, amount_to_value, approval::check_approval_erc20, cross_chain::VaultAddresses, - fees::{DEFAULT_CHAINFLIP_FEE_BPS, apply_slippage_in_bp} + alien::RpcProvider, + amount_to_value, + approval::check_approval_erc20, + cross_chain::VaultAddresses, + fees::{DEFAULT_CHAINFLIP_FEE_BPS, apply_slippage_in_bp}, }; use primitives::{ChainType, chain::Chain, swap::QuoteAsset}; diff --git a/crates/swapper/src/config.rs b/crates/swapper/src/config.rs index d31d478ae..16e08406d 100644 --- a/crates/swapper/src/config.rs +++ b/crates/swapper/src/config.rs @@ -1,4 +1,7 @@ -use crate::{SwapperSlippage, SwapperSlippageMode, fees::{ReferralFees, default_referral_fees}}; +use crate::{ + SwapperSlippage, SwapperSlippageMode, + fees::{ReferralFees, default_referral_fees}, +}; use primitives::Chain; pub const DEFAULT_SLIPPAGE_BPS: u32 = 100; @@ -28,7 +31,7 @@ pub fn get_swap_config() -> Config { mode: SwapperSlippageMode::Exact, }, permit2_expiration: 2_592_000, // 30 days - permit2_sig_deadline: 1800, // 30 minutes + permit2_sig_deadline: 1800, // 30 minutes referral_fee: default_referral_fees(), high_price_impact_percent: 10, } diff --git a/crates/swapper/src/fees/referral.rs b/crates/swapper/src/fees/referral.rs index c0649e903..f145ed4b8 100644 --- a/crates/swapper/src/fees/referral.rs +++ b/crates/swapper/src/fees/referral.rs @@ -54,14 +54,41 @@ impl ReferralFee { pub fn default_referral_fees() -> ReferralFees { ReferralFees { - evm: ReferralFee { address: EVM_REFERRAL_ADDRESS.into(), bps: DEFAULT_SWAP_FEE_BPS }, - evm_bridge: ReferralFee { address: EVM_REFERRAL_ADDRESS.into(), bps: DEFAULT_STABLE_SWAP_REFERRAL_BPS }, - solana: ReferralFee { address: "5fmLrs2GuhfDP1B51ziV5Kd1xtAr9rw1jf3aQ4ihZ2gy".into(), bps: DEFAULT_SWAP_FEE_BPS }, - thorchain: ReferralFee { address: "g1".into(), bps: DEFAULT_SWAP_FEE_BPS }, - sui: ReferralFee { address: "0x9d6b98b18fd26b5efeec68d020dcf1be7a94c2c315353779bc6b3aed44188ddf".into(), bps: DEFAULT_SWAP_FEE_BPS }, - ton: ReferralFee { address: "UQDxJKarPSp0bCta9DFgp81Mpt5hpGbuVcSxwfeza0Bin201".into(), bps: DEFAULT_SWAP_FEE_BPS }, - tron: ReferralFee { address: "TYeyZXywpA921LEtw2PF3obK4B8Jjgpp32".into(), bps: DEFAULT_SWAP_FEE_BPS }, - near: ReferralFee { address: "0x0d9dab1a248f63b0a48965ba8435e4de7497a3dc".into(), bps: DEFAULT_SWAP_FEE_BPS }, - aptos: ReferralFee { address: "0xc09d385527743bb03ed7847bb9180b5ff2263d38d5a93f1c9b3068f8505f6488".into(), bps: DEFAULT_SWAP_FEE_BPS }, + evm: ReferralFee { + address: EVM_REFERRAL_ADDRESS.into(), + bps: DEFAULT_SWAP_FEE_BPS, + }, + evm_bridge: ReferralFee { + address: EVM_REFERRAL_ADDRESS.into(), + bps: DEFAULT_STABLE_SWAP_REFERRAL_BPS, + }, + solana: ReferralFee { + address: "5fmLrs2GuhfDP1B51ziV5Kd1xtAr9rw1jf3aQ4ihZ2gy".into(), + bps: DEFAULT_SWAP_FEE_BPS, + }, + thorchain: ReferralFee { + address: "g1".into(), + bps: DEFAULT_SWAP_FEE_BPS, + }, + sui: ReferralFee { + address: "0x9d6b98b18fd26b5efeec68d020dcf1be7a94c2c315353779bc6b3aed44188ddf".into(), + bps: DEFAULT_SWAP_FEE_BPS, + }, + ton: ReferralFee { + address: "UQDxJKarPSp0bCta9DFgp81Mpt5hpGbuVcSxwfeza0Bin201".into(), + bps: DEFAULT_SWAP_FEE_BPS, + }, + tron: ReferralFee { + address: "TYeyZXywpA921LEtw2PF3obK4B8Jjgpp32".into(), + bps: DEFAULT_SWAP_FEE_BPS, + }, + near: ReferralFee { + address: "0x0d9dab1a248f63b0a48965ba8435e4de7497a3dc".into(), + bps: DEFAULT_SWAP_FEE_BPS, + }, + aptos: ReferralFee { + address: "0xc09d385527743bb03ed7847bb9180b5ff2263d38d5a93f1c9b3068f8505f6488".into(), + bps: DEFAULT_SWAP_FEE_BPS, + }, } } diff --git a/crates/swapper/src/fees/slippage.rs b/crates/swapper/src/fees/slippage.rs index 2d79e023b..3736ea9d5 100644 --- a/crates/swapper/src/fees/slippage.rs +++ b/crates/swapper/src/fees/slippage.rs @@ -8,15 +8,21 @@ pub trait BasisPointConvert: Sized + Copy { } impl BasisPointConvert for U256 { - fn from_u32(value: u32) -> Self { Self::from(value) } + fn from_u32(value: u32) -> Self { + Self::from(value) + } } impl BasisPointConvert for u128 { - fn from_u32(value: u32) -> Self { value as u128 } + fn from_u32(value: u32) -> Self { + value as u128 + } } impl BasisPointConvert for u64 { - fn from_u32(value: u32) -> Self { value as u64 } + fn from_u32(value: u32) -> Self { + value as u64 + } } pub fn apply_slippage_in_bp(amount: &T, bps: u32) -> T diff --git a/crates/swapper/src/models.rs b/crates/swapper/src/models.rs index d8d2046d7..d83498757 100644 --- a/crates/swapper/src/models.rs +++ b/crates/swapper/src/models.rs @@ -1,8 +1,5 @@ use super::permit2_data::Permit2Data; -use crate::{ - SwapperMode, SwapperProvider, SwapperQuoteAsset, SwapperSlippage, - config::DEFAULT_SLIPPAGE_BPS, fees::ReferralFees, -}; +use crate::{SwapperMode, SwapperProvider, SwapperQuoteAsset, SwapperSlippage, config::DEFAULT_SLIPPAGE_BPS, fees::ReferralFees}; pub use primitives::swap::SwapResult; use primitives::{ AssetId, Chain, diff --git a/crates/swapper/src/near_intents/provider.rs b/crates/swapper/src/near_intents/provider.rs index dee7741d1..9f07f716c 100644 --- a/crates/swapper/src/near_intents/provider.rs +++ b/crates/swapper/src/near_intents/provider.rs @@ -9,9 +9,9 @@ use crate::{ SwapperProvider, SwapperQuoteAsset, SwapperQuoteData, amount_to_value, client_factory::create_client_with_chain, cross_chain::VaultAddresses, + fees::DEFAULT_REFERRER, fees::resolve_max_quote_value, near_intents::client::{base_url, explorer_url}, - fees::DEFAULT_REFERRER, }; use async_trait::async_trait; use chrono::{Duration, Utc}; diff --git a/crates/swapper/src/proxy/provider.rs b/crates/swapper/src/proxy/provider.rs index 3b966b289..2a82258ad 100644 --- a/crates/swapper/src/proxy/provider.rs +++ b/crates/swapper/src/proxy/provider.rs @@ -11,8 +11,8 @@ use crate::{ alien::{RpcClient, RpcProvider}, approval::evm::check_approval_erc20, config::get_swap_api_url, -fees::DEFAULT_SWAP_FEE_BPS, cross_chain::VaultAddresses, + fees::DEFAULT_SWAP_FEE_BPS, models::{ApprovalType, SwapperChainAsset}, }; use gem_client::Client; diff --git a/crates/swapper/src/relay/provider.rs b/crates/swapper/src/relay/provider.rs index 36797578c..8e059642f 100644 --- a/crates/swapper/src/relay/provider.rs +++ b/crates/swapper/src/relay/provider.rs @@ -14,7 +14,7 @@ use super::{ }; use crate::{ FetchQuoteData, ProviderData, ProviderType, Quote, QuoteRequest, Route, RpcClient, RpcProvider, SwapResult, Swapper, SwapperChainAsset, SwapperError, SwapperProvider, - SwapperQuoteData, approval::check_approval_erc20, config::get_swap_api_url, cross_chain::VaultAddresses, fees::resolve_max_quote_value, fees::DEFAULT_REFERRER, + SwapperQuoteData, approval::check_approval_erc20, config::get_swap_api_url, cross_chain::VaultAddresses, fees::DEFAULT_REFERRER, fees::resolve_max_quote_value, }; #[derive(Debug)] diff --git a/crates/swapper/src/swapper.rs b/crates/swapper/src/swapper.rs index c1b28856d..2af75edea 100644 --- a/crates/swapper/src/swapper.rs +++ b/crates/swapper/src/swapper.rs @@ -1,6 +1,6 @@ use crate::{ AssetList, FetchQuoteData, Permit2ApprovalData, ProviderType, Quote, QuoteRequest, SwapResult, Swapper, SwapperChainAsset, SwapperError, SwapperProvider, SwapperProviderMode, - SwapperQuoteData, across, alien::RpcProvider, chainflip, fees::DEFAULT_STABLE_SWAP_REFERRAL_BPS, cross_chain::VaultAddresses, hyperliquid, jupiter, near_intents, + SwapperQuoteData, across, alien::RpcProvider, chainflip, cross_chain::VaultAddresses, fees::DEFAULT_STABLE_SWAP_REFERRAL_BPS, hyperliquid, jupiter, near_intents, proxy::provider_factory, relay, thorchain, uniswap, }; use num_bigint::BigInt; diff --git a/crates/swapper/src/uniswap/v3/commands.rs b/crates/swapper/src/uniswap/v3/commands.rs index 70b2150ed..d852dac5c 100644 --- a/crates/swapper/src/uniswap/v3/commands.rs +++ b/crates/swapper/src/uniswap/v3/commands.rs @@ -1,4 +1,4 @@ -use crate::{SwapperError, SwapperMode, eth_address, models::*, fees::apply_slippage_in_bp}; +use crate::{SwapperError, SwapperMode, eth_address, fees::apply_slippage_in_bp, models::*}; use gem_evm::uniswap::command::{ADDRESS_THIS, PayPortion, Permit2Permit, Sweep, Transfer, UniversalRouterCommand, UnwrapWeth, V3SwapExactIn, WrapEth}; use alloy_primitives::{Address, Bytes, U256}; diff --git a/crates/swapper/src/uniswap/v3/provider.rs b/crates/swapper/src/uniswap/v3/provider.rs index 02b974f5d..21faaf7e6 100644 --- a/crates/swapper/src/uniswap/v3/provider.rs +++ b/crates/swapper/src/uniswap/v3/provider.rs @@ -3,8 +3,8 @@ use crate::{ alien::{RpcClient, RpcProvider}, approval::{check_approval_erc20_with_client, check_approval_permit2_with_client}, eth_address, - models::*, fees::apply_slippage_in_bp, + models::*, uniswap::{ deadline::get_sig_deadline, fee_token::get_fee_token, From 1600e3a00d0c6ef48c5abde6bee0e26b0bdcbf4b Mon Sep 17 00:00:00 2001 From: 0xh3rman <119309671+0xh3rman@users.noreply.github.com> Date: Thu, 19 Mar 2026 15:03:15 +0900 Subject: [PATCH 3/4] remove evm_bridge --- crates/swapper/src/across/provider.rs | 11 ++++------- crates/swapper/src/fees/mod.rs | 2 +- crates/swapper/src/fees/referral.rs | 10 ++-------- crates/swapper/src/swapper.rs | 1 - gemstone/src/config/swap_config.rs | 1 - 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/crates/swapper/src/across/provider.rs b/crates/swapper/src/across/provider.rs index 8f820a4bc..2da52c072 100644 --- a/crates/swapper/src/across/provider.rs +++ b/crates/swapper/src/across/provider.rs @@ -442,7 +442,7 @@ impl Swapper for Across { let relayer_fee_percent = relayer_calc.capital_fee_percent(&BigInt::from_str(&request.value).unwrap(), cost_config); let relayer_fee = fees::multiply(from_amount, relayer_fee_percent, cost_config.decimals); - let referral_config = request.options.fee.clone().unwrap_or_default().evm_bridge; + let referral_config = request.options.fee.clone().unwrap_or_default().evm; // Calculate gas limit / price for relayer let remain_amount = from_amount - lpfee - relayer_fee; @@ -800,6 +800,7 @@ mod tests { use crate::{ FetchQuoteData, NativeProvider, Options, QuoteRequest, SwapperError, SwapperMode, config::{ReferralFee, ReferralFees}, + fees::DEFAULT_STABLE_SWAP_REFERRAL_BPS, }; use primitives::{AssetId, Chain, swap::SwapStatus}; use std::{sync::Arc, time::SystemTime}; @@ -808,19 +809,15 @@ mod tests { async fn test_across_quote() -> Result<(), SwapperError> { let network_provider = Arc::new(NativeProvider::default()); let swap_provider = Across::boxed(network_provider.clone()); - let mut options = Options { + let options = Options { slippage: 100.into(), fee: Some(ReferralFees::evm(ReferralFee { - bps: 25, + bps: DEFAULT_STABLE_SWAP_REFERRAL_BPS, address: "0x0D9DAB1A248f63B0a48965bA8435e4de7497a3dC".into(), })), preferred_providers: vec![], use_max_amount: false, }; - options.fee.as_mut().unwrap().evm_bridge = ReferralFee { - bps: 25, - address: "0x0D9DAB1A248f63B0a48965bA8435e4de7497a3dC".into(), - }; let request = QuoteRequest { from_asset: AssetId::from_chain(Chain::Optimism).into(), diff --git a/crates/swapper/src/fees/mod.rs b/crates/swapper/src/fees/mod.rs index 50dbade47..a29ba9146 100644 --- a/crates/swapper/src/fees/mod.rs +++ b/crates/swapper/src/fees/mod.rs @@ -10,4 +10,4 @@ pub const DEFAULT_SWAP_FEE_BPS: u32 = 50; pub const DEFAULT_CHAINFLIP_FEE_BPS: u32 = 45; pub const DEFAULT_STABLE_SWAP_REFERRAL_BPS: u32 = 25; pub const DEFAULT_REFERRER: &str = "gemwallet"; -pub const EVM_REFERRAL_ADDRESS: &str = "0x0D9DAB1A248f63B0a48965bA8435e4de7497a3dC"; + diff --git a/crates/swapper/src/fees/referral.rs b/crates/swapper/src/fees/referral.rs index f145ed4b8..2e026adba 100644 --- a/crates/swapper/src/fees/referral.rs +++ b/crates/swapper/src/fees/referral.rs @@ -1,9 +1,8 @@ -use super::{DEFAULT_STABLE_SWAP_REFERRAL_BPS, DEFAULT_SWAP_FEE_BPS, EVM_REFERRAL_ADDRESS}; +use super::DEFAULT_SWAP_FEE_BPS; #[derive(Default, Debug, Clone, PartialEq)] pub struct ReferralFees { pub evm: ReferralFee, - pub evm_bridge: ReferralFee, pub solana: ReferralFee, pub thorchain: ReferralFee, pub sui: ReferralFee, @@ -31,7 +30,6 @@ impl ReferralFees { fn iter_mut(&mut self) -> impl Iterator { [ &mut self.evm, - &mut self.evm_bridge, &mut self.solana, &mut self.thorchain, &mut self.sui, @@ -55,13 +53,9 @@ impl ReferralFee { pub fn default_referral_fees() -> ReferralFees { ReferralFees { evm: ReferralFee { - address: EVM_REFERRAL_ADDRESS.into(), + address: "0x0D9DAB1A248f63B0a48965bA8435e4de7497a3dC".into(), bps: DEFAULT_SWAP_FEE_BPS, }, - evm_bridge: ReferralFee { - address: EVM_REFERRAL_ADDRESS.into(), - bps: DEFAULT_STABLE_SWAP_REFERRAL_BPS, - }, solana: ReferralFee { address: "5fmLrs2GuhfDP1B51ziV5Kd1xtAr9rw1jf3aQ4ihZ2gy".into(), bps: DEFAULT_SWAP_FEE_BPS, diff --git a/crates/swapper/src/swapper.rs b/crates/swapper/src/swapper.rs index 2af75edea..122907aaf 100644 --- a/crates/swapper/src/swapper.rs +++ b/crates/swapper/src/swapper.rs @@ -422,7 +422,6 @@ mod tests { let adjusted_fees = adjusted_request.options.fee.unwrap(); assert_eq!(adjusted_fees.evm.bps, DEFAULT_STABLE_SWAP_REFERRAL_BPS); - assert_eq!(adjusted_fees.evm_bridge.bps, DEFAULT_STABLE_SWAP_REFERRAL_BPS); assert_eq!(adjusted_fees.solana.bps, DEFAULT_STABLE_SWAP_REFERRAL_BPS); assert_eq!(adjusted_fees.thorchain.bps, DEFAULT_STABLE_SWAP_REFERRAL_BPS); assert_eq!(adjusted_fees.sui.bps, DEFAULT_STABLE_SWAP_REFERRAL_BPS); diff --git a/gemstone/src/config/swap_config.rs b/gemstone/src/config/swap_config.rs index a22afe010..e1d4c7cd5 100644 --- a/gemstone/src/config/swap_config.rs +++ b/gemstone/src/config/swap_config.rs @@ -16,7 +16,6 @@ pub struct SwapConfig { #[uniffi::remote(Record)] pub struct SwapReferralFees { pub evm: SwapReferralFee, - pub evm_bridge: SwapReferralFee, pub solana: SwapReferralFee, pub thorchain: SwapReferralFee, pub sui: SwapReferralFee, From c3b8f94a78763578dbda447e90613c1161e71746 Mon Sep 17 00:00:00 2001 From: 0xh3rman <119309671+0xh3rman@users.noreply.github.com> Date: Thu, 19 Mar 2026 16:07:35 +0900 Subject: [PATCH 4/4] fix tests --- crates/gem_evm/src/rpc/mapper.rs | 4 ++-- crates/swapper/src/near_intents/assets.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/gem_evm/src/rpc/mapper.rs b/crates/gem_evm/src/rpc/mapper.rs index 347f3d98e..78e5ba497 100644 --- a/crates/gem_evm/src/rpc/mapper.rs +++ b/crates/gem_evm/src/rpc/mapper.rs @@ -566,7 +566,7 @@ mod tests { assert_eq!(tx.transaction_type, TransactionType::EarnDeposit); assert_eq!(tx.asset_id, ETHEREUM_USDT_ASSET_ID.clone()); assert_eq!(tx.from, "0x8d7460E51bCf4eD26877cb77E56f3ce7E9f5EB8F"); - assert_eq!(tx.to, YO_PROTOCOL_CONTRACT); + assert_eq!(tx.to, ETHEREUM_YO_PROTOCOL_CONTRACT); assert_eq!(tx.value, "1466009"); } @@ -580,7 +580,7 @@ mod tests { assert_eq!(tx.transaction_type, TransactionType::EarnWithdraw); assert_eq!(tx.asset_id, ETHEREUM_USDT_ASSET_ID.clone()); assert_eq!(tx.from, "0x8d7460E51bCf4eD26877cb77E56f3ce7E9f5EB8F"); - assert_eq!(tx.to, YO_PROTOCOL_CONTRACT); + assert_eq!(tx.to, ETHEREUM_YO_PROTOCOL_CONTRACT); assert_eq!(tx.value, "1466126"); } } diff --git a/crates/swapper/src/near_intents/assets.rs b/crates/swapper/src/near_intents/assets.rs index c1d5c50af..26bb01f06 100644 --- a/crates/swapper/src/near_intents/assets.rs +++ b/crates/swapper/src/near_intents/assets.rs @@ -269,7 +269,7 @@ mod tests { #[test] fn test_get_asset_id() { let asset = SwapperQuoteAsset { - id: "ethereum_0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48".into(), + id: "ethereum_0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48".into(), symbol: "USDC".into(), decimals: 6, };