diff --git a/.env.bak b/.env.bak new file mode 100644 index 0000000..09d987a --- /dev/null +++ b/.env.bak @@ -0,0 +1,14 @@ +# INFRA +MONGO_URL=mongodb://127.0.0.1:27017 +REDIS_URL=redis://localhost:6379 + +# API_KEYS +BUNGEE_API_KEY= +COVALENT_API_KEY= +COINGECKO_API_KEY= + +# RPC_URLS +ETHEREUM_RPC_URL=https://rpc.ankr.com/eth +ARBITRUM_RPC_URL=https://arbitrum.llamarpc.com +OPTIMISM_RPC_URL=https://mainnet.optimism.io +BASE_RPC_URL=https://mainnet.base.org diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index b09365e..79b0c3b 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -34,13 +34,13 @@ jobs: ETHEREUM_RPC_URL: ${{ secrets.ETHEREUM_RPC_URL }} ARBITRUM_RPC_URL: ${{ secrets.ARBITRUM_RPC_URL }} OPTIMISM_RPC_URL: ${{ secrets.OPTIMISM_RPC_URL }} - BAE_RPC_URL: ${{ secrets.BASE_RPC_URL }} + BASE_RPC_URL: ${{ secrets.BASE_RPC_URL }} MONGO_URL: ${{ secrets.MONGO_URL }} REDIS_URL: ${{ secrets.REDIS_URL }} environment: Testing - + container_img_build_push_gar: - needs: [test] + needs: [ test ] # Allow the job to fetch a GitHub ID token permissions: id-token: write @@ -49,7 +49,7 @@ jobs: strategy: matrix: image: - - us-docker.pkg.dev/biconomy-prod/biconomy-prod/reflux + - us-docker.pkg.dev/biconomy-prod/biconomy-prod/reflux # LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE # {owner}/{repo}/.github/workflows/{filename}@{ref} uses: bcnmy/devops/.github/workflows/container_img_build_push_gar.yaml@master diff --git a/.gitignore b/.gitignore index 1a55d9c..b88f808 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,4 @@ target/ *.env *.swp -# *.yaml +*.log diff --git a/Cargo.lock b/Cargo.lock index 6f77b40..a6eba82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1252,6 +1252,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crunchy" version = "0.2.2" @@ -1699,6 +1705,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.30" @@ -1759,6 +1771,26 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand", + "smallvec", + "spinning_top", +] + [[package]] name = "group" version = "0.13.0" @@ -2512,6 +2544,18 @@ dependencies = [ "tempfile", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "num-bigint" version = "0.4.5" @@ -2804,6 +2848,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + [[package]] name = "powerfmt" version = "0.2.0" @@ -2978,6 +3028,21 @@ dependencies = [ "prost", ] +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -3038,6 +3103,15 @@ dependencies = [ "rand_core", ] +[[package]] +name = "raw-cpuid" +version = "11.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "recvmsg" version = "1.0.0" @@ -3218,6 +3292,7 @@ dependencies = [ "config", "derive_more 1.0.0-beta.6", "futures", + "governor", "linreg", "log", "mockall", @@ -3225,6 +3300,7 @@ dependencies = [ "ruint", "serde", "serde_json", + "serial_test", "storage", "thiserror", "tokio", @@ -3841,6 +3917,15 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.7.3" diff --git a/bin/reflux/src/main.rs b/bin/reflux/src/main.rs index 90b004f..4668fc2 100644 --- a/bin/reflux/src/main.rs +++ b/bin/reflux/src/main.rs @@ -6,6 +6,7 @@ use axum::http::Method; use clap::Parser; use dotenv::dotenv; use log::{debug, error, info}; +use tokio::sync::Mutex; use tower_http::cors::{Any, CorsLayer}; use account_aggregation::service::AccountAggregationService; @@ -35,7 +36,9 @@ struct Args { #[tokio::main] async fn main() { - dotenv().expect("Failed to read .env"); + if let Err(e) = dotenv() { + error!("Failed to load .env file: {}", e); + } simple_logger::SimpleLogger::new().env().init().unwrap(); let mut args = Args::parse(); @@ -119,16 +122,16 @@ async fn run_solver(config: Arc) { let erc20_instance_map = generate_erc20_instance_map(&config).unwrap(); let bungee_client = BungeeClient::new(&config.bungee.base_url, &config.bungee.api_key) .expect("Failed to Instantiate Bungee Client"); - let token_price_provider = CoingeckoClient::new( + let token_price_provider = Arc::new(Mutex::new(CoingeckoClient::new( config.coingecko.base_url.clone(), config.coingecko.api_key.clone(), redis_client.clone(), Duration::from_secs(config.coingecko.expiry_sec), - ); + ))); let settlement_engine = Arc::new(SettlementEngine::new( Arc::clone(&config), bungee_client, - token_price_provider, + Arc::clone(&token_price_provider), erc20_instance_map, )); @@ -205,12 +208,12 @@ async fn run_indexer(config: Arc) { let bungee_client = BungeeClient::new(&config.bungee.base_url, &config.bungee.api_key) .expect("Failed to Instantiate Bungee Client"); - let token_price_provider = CoingeckoClient::new( + let token_price_provider = Arc::new(Mutex::new(CoingeckoClient::new( config.coingecko.base_url.clone(), config.coingecko.api_key.clone(), redis_provider.clone(), Duration::from_secs(config.coingecko.expiry_sec), - ); + ))); let indexer: Indexer> = Indexer::new( diff --git a/config.yaml b/config.yaml index 2d4e397..29f6524 100644 --- a/config.yaml +++ b/config.yaml @@ -32,6 +32,14 @@ tokens: is_enabled: true decimals: 6 address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831" + "10": + is_enabled: true + decimals: 6 + address: "0x7F5c764cBc14f9669B88837ca1490cCa17c31607" + "8453": + is_enabled: true + decimals: 6 + address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" - symbol: USDT is_enabled: true coingecko_symbol: tether @@ -43,43 +51,1923 @@ tokens: "42161": is_enabled: true decimals: 6 - address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831' + address: "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9" + "10": + is_enabled: true + decimals: 6 + address: "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58" + "8453": + is_enabled: true + decimals: 6 + address: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2" + - symbol: ETH + is_enabled: true + coingecko_symbol: ethereum + by_chain: + "42161": + is_enabled: true + decimals: 18 + address: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + "10": + is_enabled: true + decimals: 18 + address: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + "8453": + is_enabled: true + decimals: 18 + address: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" buckets: - - from_chain_id: 1 - to_chain_id: 42161 + - from_chain_id: 42161 + to_chain_id: 10 from_token: USDC to_token: USDC is_smart_contract_deposit_supported: false token_amount_from_usd: 1 token_amount_to_usd: 10 - - from_chain_id: 1 - to_chain_id: 42161 + - from_chain_id: 42161 + to_chain_id: 10 from_token: USDC to_token: USDC is_smart_contract_deposit_supported: false token_amount_from_usd: 10 token_amount_to_usd: 100 - - from_chain_id: 1 - to_chain_id: 42161 + - from_chain_id: 42161 + to_chain_id: 10 from_token: USDC to_token: USDC is_smart_contract_deposit_supported: false token_amount_from_usd: 100 token_amount_to_usd: 1000 - - from_chain_id: 1 - to_chain_id: 42161 + - from_chain_id: 42161 + to_chain_id: 10 from_token: USDC to_token: USDC is_smart_contract_deposit_supported: false token_amount_from_usd: 1000 token_amount_to_usd: 10000 - - from_chain_id: 1 - to_chain_id: 42161 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 10 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 8453 from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT to_token: USDC is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 42161 + to_chain_id: 8453 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 42161 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 10 + to_chain_id: 8453 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 42161 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDC + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: USDT + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: USDC + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: USDT + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10000 + token_amount_to_usd: 100000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1 + token_amount_to_usd: 10 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 10 + token_amount_to_usd: 100 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 100 + token_amount_to_usd: 1000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false + token_amount_from_usd: 1000 + token_amount_to_usd: 10000 + - from_chain_id: 8453 + to_chain_id: 10 + from_token: ETH + to_token: ETH + is_smart_contract_deposit_supported: false token_amount_from_usd: 10000 token_amount_to_usd: 100000 + bungee: base_url: https://api.socket.tech/v2 covalent: @@ -93,7 +1981,7 @@ server: indexer_config: indexer_update_topic: indexer_update indexer_update_message: message - points_per_bucket: 10 + points_per_bucket: 8 solver_config: x_value: 2.0 y_value: 1.0 diff --git a/crates/account-aggregation/src/types.rs b/crates/account-aggregation/src/types.rs index 08d4e6a..81adbba 100644 --- a/crates/account-aggregation/src/types.rs +++ b/crates/account-aggregation/src/types.rs @@ -70,7 +70,7 @@ pub struct RegisterAccountPayload { #[derive(Deserialize, Serialize, Debug)] pub struct AddAccountPayload { pub user_id: Option, - pub account: Vec + pub account: Vec, } // Path Query Model diff --git a/crates/routing-engine/Cargo.toml b/crates/routing-engine/Cargo.toml index 67dbf6b..e3bf5dc 100644 --- a/crates/routing-engine/Cargo.toml +++ b/crates/routing-engine/Cargo.toml @@ -15,6 +15,7 @@ ruint = "1.12.3" linreg = "0.2.0" thiserror = "1.0.61" log = "0.4.21" +governor = "0.6.3" # workspace dependencies account-aggregation = { workspace = true } @@ -24,6 +25,7 @@ alloy = { version = "0.1.4", features = ["full"] } [dev-dependencies] mockall = "0.12.1" +serial_test = "3.1.1" [lib] doctest = false diff --git a/crates/routing-engine/src/indexer.rs b/crates/routing-engine/src/indexer.rs index 2666828..1362cf1 100644 --- a/crates/routing-engine/src/indexer.rs +++ b/crates/routing-engine/src/indexer.rs @@ -5,12 +5,13 @@ use std::sync::Arc; use futures::stream::StreamExt; use log::{error, info}; use thiserror::Error; +use tokio::sync::Mutex; use config::config::BucketConfig; -use crate::{estimator, source, token_price, CostType, Route, RouteError}; +use crate::{CostType, estimator, Route, RouteError, source, token_price}; -const SOURCE_FETCH_PER_BUCKET_RATE_LIMIT: usize = 10; +const SOURCE_FETCH_PER_BUCKET_RATE_LIMIT: usize = 5; const BUCKET_PROCESSING_RATE_LIMIT: usize = 5; pub struct Indexer< @@ -23,7 +24,7 @@ pub struct Indexer< source: Source, model_store: ModelStore, message_producer: Producer, - token_price_provider: TokenPriceProvider, + token_price_provider: Arc>, } impl< @@ -38,7 +39,7 @@ impl< source: RouteSource, model_store: ModelStore, message_producer: Producer, - token_price_provider: TokenPriceProvider, + token_price_provider: Arc>, ) -> Self { Indexer { config, source, model_store, message_producer, token_price_provider } } @@ -84,7 +85,7 @@ impl< let from_token_amount_in_wei = token_price::utils::get_token_amount_from_value_in_usd( &self.config, - &self.token_price_provider, + &self.token_price_provider.lock().await, &bucket.from_token, bucket.from_chain_id, &input_value_in_usd, @@ -161,13 +162,13 @@ impl< if data_points.is_empty() { error!("BucketID-{}: No data points were built", bucket_id); - return Err(BuildEstimatorError::NoDataPoints(bucket.clone())); + return Err(BuildEstimatorError::NoDataPoints(bucket_id)); } // Build the Estimator info!("BucketID-{}:All data points fetched, building estimator...", bucket_id); let estimator = Estimator::build(data_points) - .map_err(|e| BuildEstimatorError::EstimatorBuildError(bucket.clone(), e))?; + .map_err(|e| BuildEstimatorError::EstimatorBuildError(bucket_id, e))?; Ok(estimator) } @@ -294,10 +295,10 @@ pub enum IndexerErrors< #[derive(Debug, Error)] pub enum BuildEstimatorError<'est_de, Estimator: estimator::Estimator<'est_de, f64, f64>> { #[error("No data points found while building estimator for {:?}", _0)] - NoDataPoints(Arc), + NoDataPoints(u64), #[error("Estimator build error: {} for bucket {:?}", _1, _0)] - EstimatorBuildError(Arc, Estimator::Error), + EstimatorBuildError(u64, Estimator::Error), } #[cfg(test)] @@ -311,14 +312,15 @@ mod tests { use async_trait::async_trait; use derive_more::Display; use thiserror::Error; + use tokio::sync::Mutex; - use config::{get_sample_config, Config}; + use config::{Config, get_sample_config}; use storage::{ControlFlow, KeyValueStore, MessageQueue, Msg, RedisClientError}; + use crate::{BungeeClient, CostType}; use crate::estimator::{Estimator, LinearRegressionEstimator}; use crate::indexer::Indexer; use crate::token_price::TokenPriceProvider; - use crate::{BungeeClient, CostType}; #[derive(Error, Display, Debug)] struct Err; @@ -387,7 +389,9 @@ mod tests { } } - fn setup<'a>() -> (Config, BungeeClient, ModelStoreStub, ProducerStub, TokenPriceProviderStub) { + fn setup<'a>( + ) -> (Config, BungeeClient, ModelStoreStub, ProducerStub, Arc>) + { let mut config = get_sample_config(); config.buckets = vec![ Arc::new(config::BucketConfig { @@ -421,7 +425,13 @@ mod tests { let message_producer = ProducerStub; let token_price_provider = TokenPriceProviderStub; - return (config, bungee_client, model_store, message_producer, token_price_provider); + return ( + config, + bungee_client, + model_store, + message_producer, + Arc::new(Mutex::new(token_price_provider)), + ); } #[tokio::test] diff --git a/crates/routing-engine/src/settlement_engine.rs b/crates/routing-engine/src/settlement_engine.rs index 88eb17f..ce98cc2 100644 --- a/crates/routing-engine/src/settlement_engine.rs +++ b/crates/routing-engine/src/settlement_engine.rs @@ -10,6 +10,7 @@ use reqwest::{Client, Url}; use ruint::Uint; use serde::Serialize; use thiserror::Error; +use tokio::sync::Mutex; use config::Config; @@ -22,7 +23,7 @@ use crate::token_price::utils::{Errors, get_token_amount_from_value_in_usd}; pub struct SettlementEngine { source: Source, config: Arc, - price_provider: PriceProvider, + price_provider: Arc>, // (chain_id, token_address) -> contract erc20_instance_map: HashMap<(u32, String), blockchain::ERC20Contract>, } @@ -47,7 +48,7 @@ impl pub fn new( config: Arc, source: Source, - price_provider: PriceProvider, + price_provider: Arc>, erc20_instance_map: HashMap<(u32, String), blockchain::ERC20Contract>, ) -> Self { SettlementEngine { source, config, price_provider, erc20_instance_map } @@ -73,7 +74,7 @@ impl let token_amount = get_token_amount_from_value_in_usd( &self.config, - &self.price_provider, + &self.price_provider.lock().await, &route.route.from_token.symbol, route.route.from_chain.id, &route.source_amount_in_usd, @@ -384,13 +385,14 @@ pub enum GenerateERC20InstanceMapErrors { mod tests { use std::collections::HashMap; use std::env; - use std::sync::{Arc, Mutex}; + use std::sync::Arc; use std::time::Duration; use alloy::primitives::U256; use async_trait::async_trait; use derive_more::Display; use thiserror::Error; + use tokio::sync::Mutex; use config::{Config, get_sample_config}; use storage::{KeyValueStore, RedisClientError}; @@ -414,7 +416,7 @@ mod tests { type Error = Err; async fn get(&self, k: &String) -> Result { - match self.map.lock().unwrap().get(k) { + match self.map.lock().await.get(k) { Some(v) => Ok(v.clone()), None => Result::Err(Err), } @@ -427,7 +429,7 @@ mod tests { async fn set(&self, k: &String, v: &String, _: Duration) -> Result<(), Self::Error> { self.map .lock() - .unwrap() + .await .insert((*k.clone()).parse().unwrap(), (*v.clone()).parse().unwrap()); Ok(()) } @@ -456,12 +458,12 @@ mod tests { ) .unwrap(); - let client = CoingeckoClient::new( + let client = Arc::new(Mutex::new(CoingeckoClient::new( config.coingecko.base_url.clone(), env::var("COINGECKO_API_KEY").unwrap(), KVStore::default(), Duration::from_secs(config.coingecko.expiry_sec), - ); + ))); let erc20_instance_map = generate_erc20_instance_map(&config).unwrap(); diff --git a/crates/routing-engine/src/source/bungee/mod.rs b/crates/routing-engine/src/source/bungee/mod.rs index 0b73a20..2328123 100644 --- a/crates/routing-engine/src/source/bungee/mod.rs +++ b/crates/routing-engine/src/source/bungee/mod.rs @@ -1,6 +1,10 @@ +use std::num::NonZeroU32; use std::str::FromStr; use async_trait::async_trait; +use governor::{Quota, RateLimiter}; +use governor::clock::DefaultClock; +use governor::state::{InMemoryState, NotKeyed}; use log::{error, info}; use reqwest; use reqwest::header; @@ -15,19 +19,26 @@ use crate::source::{EthereumTransaction, RequiredApprovalDetails, RouteSource}; mod types; +const BUNGEE_API_RATE_LIMIT: u32 = 2; + #[derive(Debug)] pub struct BungeeClient { client: reqwest::Client, + rate_limiter: RateLimiter, base_url: String, } impl BungeeClient { pub fn new(base_url: &String, api_key: &String) -> Result { let mut headers = header::HeaderMap::new(); + let rate_limiter = RateLimiter::direct(Quota::per_second( + NonZeroU32::new(BUNGEE_API_RATE_LIMIT).expect("Invalid Bungee Rate Limit"), + )); headers.insert("API-KEY", header::HeaderValue::from_str(api_key)?); Ok(BungeeClient { client: reqwest::Client::builder().default_headers(headers).build().unwrap(), + rate_limiter, base_url: base_url.clone(), }) } @@ -38,6 +49,10 @@ impl BungeeClient { ) -> Result, BungeeClientError> { info!("Fetching quote from bungee for {:?}", params); + info!("Waiting for rate limiter to be ready"); + self.rate_limiter.until_ready().await; + info!("Rate limiter is ready"); + let response = self.client.get(self.base_url.to_owned() + "/quote").query(¶ms).send().await?; let raw_text = response.text().await?; @@ -50,6 +65,12 @@ impl BungeeClient { &self, params: BuildTxRequest, ) -> Result, BungeeClientError> { + info!("Building transaction from bungee for {:?}", params); + + info!("Waiting for rate limiter to be ready"); + self.rate_limiter.until_ready().await; + info!("Rate limiter is ready"); + let response = self.client.post(self.base_url.to_owned() + "/build-tx").json(¶ms).send().await?; let raw_text = response.text().await?; diff --git a/crates/routing-engine/src/token_price/coingecko.rs b/crates/routing-engine/src/token_price/coingecko.rs index 896c93b..321f127 100644 --- a/crates/routing-engine/src/token_price/coingecko.rs +++ b/crates/routing-engine/src/token_price/coingecko.rs @@ -147,6 +147,7 @@ mod tests { use thiserror::Error; use config::{Config, get_sample_config}; + use serial_test::serial; use storage::{KeyValueStore, RedisClientError}; use crate::CoingeckoClient; @@ -201,6 +202,7 @@ mod tests { } #[tokio::test] + #[serial] async fn test_should_fetch_fresh_api_price() { let config = setup_config(); @@ -220,6 +222,7 @@ mod tests { } #[tokio::test] + #[serial] async fn test_should_cache_api_prices() { let config = setup_config(); diff --git a/crates/routing-engine/src/token_price/utils.rs b/crates/routing-engine/src/token_price/utils.rs index 03e9131..ca2bca8 100644 --- a/crates/routing-engine/src/token_price/utils.rs +++ b/crates/routing-engine/src/token_price/utils.rs @@ -1,4 +1,5 @@ use std::fmt::Debug; +use std::ops::Deref; use ruint; use ruint::aliases::U256; @@ -7,9 +8,9 @@ use thiserror::Error; use crate::token_price::TokenPriceProvider; -pub async fn get_token_amount_from_value_in_usd( +pub async fn get_token_amount_from_value_in_usd>( config: &config::Config, - token_price_provider: &T, + token_price_provider: &U, token_symbol: &String, chain_id: u32, value_in_usd: &f64, @@ -36,9 +37,9 @@ pub async fn get_token_amount_from_value_in_usd( Ok(token_amount_in_wei) } -pub async fn get_token_price( +pub async fn get_token_price>( config: &config::Config, - token_price_provider: &T, + token_price_provider: &U, token_symbol: &String, ) -> Result> { let token_config = config.tokens.get(token_symbol); @@ -70,9 +71,11 @@ pub enum Errors { #[cfg(test)] mod tests { use std::fmt::Error; + use std::sync::Arc; use async_trait::async_trait; use ruint::Uint; + use tokio::sync::Mutex; use config::{Config, get_sample_config}; @@ -97,7 +100,7 @@ mod tests { #[tokio::test] async fn test_get_token_amount_from_value_in_usd() { let config = setup(); - let mut token_price_provider = TokenPriceProviderStub; + let token_price_provider = Arc::new(Mutex::new(TokenPriceProviderStub {})); let token_symbol = String::from("USDC"); let chain_id = 1; @@ -105,7 +108,7 @@ mod tests { let result = super::get_token_amount_from_value_in_usd( &config, - &mut token_price_provider, + &token_price_provider.lock().await, &token_symbol, chain_id, &value_in_usd,