diff --git a/contracts/market/Forc.toml b/contracts/market/Forc.toml index 6177db25..8adc217b 100644 --- a/contracts/market/Forc.toml +++ b/contracts/market/Forc.toml @@ -6,7 +6,7 @@ name = "market" # address will be the addres of the proxy contract [proxy] enabled = true -address = "0x44daa228d84335bf2e17b1af1cf7f9de73266977affe6c3445f08bd07a2b0d5d" +address = "0x657ab45a6eb98a4893a99fd104347179151e8b3828fd8f2a108cc09770d1ebae" [dependencies] market_abi = { path = "../../abis/market_abi" } diff --git a/contracts/market/src/main.sw b/contracts/market/src/main.sw index bd316f8e..4e07e044 100644 --- a/contracts/market/src/main.sw +++ b/contracts/market/src/main.sw @@ -33,10 +33,10 @@ use sway_libs::ownership::*; use sway_libs::signed_integers::i256::I256; // version of the smart contract -const VERSION: u8 = 1_u8; +const VERSION: u8 = 2_u8; // pyth oracle configuration params -const ORACLE_MAX_STALENESS: u64 = 30; // 30 seconds +const ORACLE_MAX_STALENESS: u64 = 60; // 60 seconds const ORACLE_MAX_AHEADNESS: u64 = 60; // 60 seconds const ORACLE_MAX_CONF_WIDTH: u256 = 100; // 100 / 10000 = 1.0 % @@ -1524,7 +1524,7 @@ pub fn present_value_supply(base_supply_index: u256, principal: u256) -> u256 { /// let present_value = present_value_borrow(base_borrow_index, principal); /// ``` pub fn present_value_borrow(base_borrow_index: u256, principal: u256) -> u256 { - principal * base_borrow_index / BASE_INDEX_SCALE_15 + (principal * base_borrow_index + BASE_INDEX_SCALE_15 - 1) / BASE_INDEX_SCALE_15 } /// Calculates the principal value based on the given base supply index and present value. diff --git a/contracts/market/tests/local_tests/main_test_uni.rs b/contracts/market/tests/local_tests/main_test_uni.rs index ee8eeb35..57e564f3 100644 --- a/contracts/market/tests/local_tests/main_test_uni.rs +++ b/contracts/market/tests/local_tests/main_test_uni.rs @@ -262,7 +262,7 @@ async fn main_test() { .await .unwrap(); - assert!(res == u128::from(parse_units(1, usdc.decimals))); + assert!(res == u128::from(parse_units(1, usdc.decimals)) - 1); // Withdrawing more than available should fail (2 USDC) let res = market @@ -296,7 +296,7 @@ async fn main_test() { // ==================== Step #6 ==================== // πŸ‘› Wallet: Admin πŸ—Ώ // πŸ€™ Drop of collateral price - // πŸ’° Amount: -10% + // πŸ’° Amount: -30% print_case_title(6, "Admin", "Drop of collateral price", "-10%"); let res = oracle.price(uni.price_feed_id).await.unwrap().value; diff --git a/contracts/market/tests/local_tests/main_test_usdt.rs b/contracts/market/tests/local_tests/main_test_usdt.rs new file mode 100644 index 00000000..eb886158 --- /dev/null +++ b/contracts/market/tests/local_tests/main_test_usdt.rs @@ -0,0 +1,459 @@ +use crate::utils::{print_case_title, setup, TestData}; +use chrono::Utc; +use fuels::{ + prelude::ViewOnlyAccount, + programs::{ + calls::{CallHandler, CallParameters}, + responses::CallResponse, + }, + types::{transaction::TxPolicies, transaction_builders::VariableOutputPolicy}, +}; +use market::PriceDataUpdate; +use market_sdk::{convert_i256_to_u64, is_i256_negative, parse_units}; + +// Multiplies all values by this number +// It is necessary in order to test how the protocol works with large amounts +const AMOUNT_COEFFICIENT: u64 = 10u64.pow(0); + +#[tokio::test] +async fn main_test() { + let scale_6 = 10u64.pow(6) as f64; + let scale_9 = 10u64.pow(9) as f64; + + let TestData { + wallets, + alice, + alice_account, + bob, + bob_account, + chad, + chad_account, + usdc_contract, + usdc, + market, + usdt, + usdt_contract, + oracle, + price_feed_ids, + assets, + publish_time, + prices, + .. + } = setup(None).await; + + let price_data_update = PriceDataUpdate { + update_fee: 1, + price_feed_ids, + publish_times: vec![publish_time; assets.len()], + update_data: oracle.create_update_data(&prices).await.unwrap(), + }; + + // ================================================= + // ==================== Step #0 ==================== + // πŸ‘› Wallet: Bob πŸ§› + // πŸ€™ Call: supply_base + // πŸ’° Amount: 1000.00 USDC + + let amount = parse_units(100 * AMOUNT_COEFFICIENT, usdc.decimals); + let log_amount = format!("{} USDC", amount as f64 / scale_6); + print_case_title(0, "Bob", "supply_base", log_amount.as_str()); + println!("πŸ’Έ Bob + {log_amount}"); + + // Transfer of 100 USDC to the Bob's wallet + usdc_contract.mint(bob_account, amount).await.unwrap(); + + let balance = bob.get_asset_balance(&usdc.asset_id).await.unwrap(); + assert!(balance == amount); + + // Bob calls supply_base + market + .with_account(&bob) + .await + .unwrap() + .supply_base(usdc.asset_id, amount) + .await + .unwrap(); + + // Π‘heck supply balance equal to 1000 USDC + let (supply_balance, _) = market.get_user_supply_borrow(bob_account).await.unwrap(); + assert!(supply_balance == amount as u128); + + market + .print_debug_state(&wallets, &usdc, &usdt) + .await + .unwrap(); + market.debug_increment_timestamp().await.unwrap(); + + // ================================================= + // ==================== Step #1 ==================== + // πŸ‘› Wallet: Alice 🦹 + // πŸ€™ Call: supply_collateral + // πŸ’° Amount: 200.00 USDT ~ $200.00 + + let amount = parse_units(200 * AMOUNT_COEFFICIENT, usdt.decimals); + let log_amount = format!("{} USDT", amount as f64 / scale_6); + print_case_title(1, "Alice", "supply_collateral", log_amount.as_str()); + println!("πŸ’Έ Alice + {log_amount}"); + + // Transfer of 200 USDT to the Alice's wallet + usdt_contract.mint(alice_account, amount).await.unwrap(); + + let balance = alice.get_asset_balance(&usdt.asset_id).await.unwrap(); + assert!(balance == amount); + + // Alice calls supply_collateral + market + .with_account(&alice) + .await + .unwrap() + .supply_collateral(usdt.asset_id, amount) + .await + .unwrap(); + + // Π‘heck supply balance equal to 200 USDT + let res = market + .get_user_collateral(alice_account, usdt.asset_id) + .await + .unwrap() + .value; + assert!(res == amount); + + market + .print_debug_state(&wallets, &usdc, &usdt) + .await + .unwrap(); + market.debug_increment_timestamp().await.unwrap(); + + // ================================================= + // ==================== Step #2 ==================== + // πŸ‘› Wallet: Alice 🦹 + // πŸ€™ Call: withdraw_base + // πŸ’° Amount: 80.00 USDC + + let amount = parse_units(80 * AMOUNT_COEFFICIENT, usdc.decimals); + let log_amount = format!("{} USDC", amount as f64 / scale_6); + print_case_title(2, "Alice", "withdraw_base", log_amount.as_str()); + + // Alice calls withdraw_base + market + .with_account(&alice) + .await + .unwrap() + .withdraw_base(&[&oracle.instance], amount, &price_data_update) + .await + .unwrap(); + + // USDC balance check + let balance = alice.get_asset_balance(&usdc.asset_id).await.unwrap(); + assert!(balance == amount); + + market + .print_debug_state(&wallets, &usdc, &usdt) + .await + .unwrap(); + market.debug_increment_timestamp().await.unwrap(); + + // ================================================= + // ==================== Step #4 ==================== + // πŸ‘› Wallet: Chad 🀡 + // πŸ€™ Call: supply_base + // πŸ’° Amount: 90.00 USDC + + let amount = parse_units(90 * AMOUNT_COEFFICIENT, usdc.decimals); + let log_amount = format!("{} USDC", amount as f64 / scale_6); + print_case_title(4, "Chad", "supply_base", log_amount.as_str()); + println!("πŸ’Έ Chad + {log_amount}"); + + // Transfer of 20 USDC to the Chad's wallet + usdc_contract.mint(chad_account, amount).await.unwrap(); + + let balance = chad.get_asset_balance(&usdc.asset_id).await.unwrap(); + assert!(balance == amount); + + // Chad calls supply_base + market + .with_account(&chad) + .await + .unwrap() + .supply_base(usdc.asset_id, amount) + .await + .unwrap(); + + // Π‘heck supply balance equal to 90 USDC + let (supply_balance, _) = market.get_user_supply_borrow(chad_account).await.unwrap(); + assert!((amount as u128) - 5 < supply_balance); + + market + .print_debug_state(&wallets, &usdc, &usdt) + .await + .unwrap(); + market.debug_increment_timestamp().await.unwrap(); + + // ================================================= + // ==================== Step #5 ==================== + // πŸ‘› Wallet: Alice 🦹 + // πŸ€™ Call: withdraw_base + // πŸ’° Amount: ~99.96 USDC (available_to_borrow) + let amount = market + .available_to_borrow(&[&oracle.instance], alice_account) + .await + .unwrap(); + let log_amount = format!("{} USDC", amount as f64 / scale_6); + print_case_title(5, "Alice", "withdraw_base", log_amount.as_str()); + + // Alice calls withdraw_base + market + .with_account(&alice) + .await + .unwrap() + .withdraw_base( + &[&oracle.instance], + (amount - u128::from(parse_units(1, usdc.decimals))) + .try_into() + .unwrap(), + &price_data_update, + ) + .await + .unwrap(); + + // available_to_borrow should be 1 USDC + let res = market + .available_to_borrow(&[&oracle.instance], alice_account) + .await + .unwrap(); + + assert!(res == u128::from(parse_units(1, usdc.decimals)) - 1); + + // Withdrawing more than available should fail (2 USDC) + let res = market + .with_account(&alice) + .await + .unwrap() + .withdraw_base( + &[&oracle.instance], + parse_units(2, usdc.decimals), + &price_data_update, + ) + .await + .is_err(); + assert!(res); + + // USDC balance should be amount - 1 USDC + 1000 USDC from case #2 + let balance = alice.get_asset_balance(&usdc.asset_id).await.unwrap(); + assert!( + balance + == (amount as u64) - parse_units(1, usdc.decimals) + + parse_units(80 * AMOUNT_COEFFICIENT, usdc.decimals) + ); + + market + .print_debug_state(&wallets, &usdc, &usdt) + .await + .unwrap(); + market.debug_increment_timestamp().await.unwrap(); + + // ================================================= + // ==================== Step #6 ==================== + // πŸ‘› Wallet: Admin πŸ—Ώ + // πŸ€™ Drop of collateral price + // πŸ’° Amount: -30% + + print_case_title(6, "Admin", "Drop of collateral price", "-10%"); + let res = oracle.price(usdt.price_feed_id).await.unwrap().value; + let new_price = (res.price as f64 * 0.94) as u64; + let prices = Vec::from([( + usdt.price_feed_id, + ( + new_price, + usdt.price_feed_decimals, + res.publish_time, + res.confidence, + ), + )]); + + let price_data_update_old = price_data_update.clone(); + oracle.update_prices(&prices).await.unwrap(); + + // New `price_data_update` that will be used in the next steps + let price_data_update = PriceDataUpdate { + update_fee: 1, + price_feed_ids: vec![usdt.price_feed_id], + publish_times: vec![tai64::Tai64::from_unix(Utc::now().timestamp().try_into().unwrap()).0], + update_data: oracle.create_update_data(&prices).await.unwrap(), + }; + + println!( + "πŸ”» USDT price drops: ${} -> ${}", + res.price as f64 / 10_u64.pow(usdt.price_feed_decimals) as f64, + new_price as f64 / 10_u64.pow(usdt.price_feed_decimals) as f64 + ); + let res = oracle.price(usdt.price_feed_id).await.unwrap().value; + assert!(new_price == res.price); + + market + .print_debug_state(&wallets, &usdc, &usdt) + .await + .unwrap(); + market.debug_increment_timestamp().await.unwrap(); + + // ================================================= + // ==================== Step #7 ==================== + // πŸ‘› Wallet: Bob 🦹 + // πŸ€™ Call: absorb + // πŸ”₯ Target: Alice + + print_case_title(7, "Bob", "absorb", "Alice"); + + assert!( + market + .is_liquidatable(&[&oracle.instance], alice_account) + .await + .unwrap() + .value + ); + + market + .with_account(&bob) + .await + .unwrap() + .absorb(&[&oracle.instance], vec![alice_account], &price_data_update) + .await + .unwrap(); + + // Check if absorb was ok + let (_, borrow) = market.get_user_supply_borrow(alice_account).await.unwrap(); + assert!(borrow == 0); + + let amount = market + .get_user_collateral(alice_account, usdt.asset_id) + .await + .unwrap() + .value; + assert!(amount == 0); + + market + .print_debug_state(&wallets, &usdc, &usdt) + .await + .unwrap(); + market.debug_increment_timestamp().await.unwrap(); + + // ================================================= + // ==================== Step #8 ==================== + // πŸ‘› Wallet: Bob 🀡 + // πŸ€™ Call: buy_collateral + // πŸ’° Amount: 172.44 USDC + + let reserves = market + .with_account(&bob) + .await + .unwrap() + .get_collateral_reserves(usdt.asset_id) + .await + .unwrap() + .value; + assert!(!is_i256_negative(&reserves)); + + let amount = market + .collateral_value_to_sell( + &[&oracle.instance], + usdt.asset_id, + convert_i256_to_u64(&reserves), + ) + .await + .unwrap() + .value; + + let log_amount = format!("{} USDC", amount as f64 / scale_6); + print_case_title(8, "Bob", "buy_collateral", log_amount.as_str()); + + // Transfer of amount to the wallet + usdc_contract.mint(bob_account, amount).await.unwrap(); + + // Π‘heck balance + let balance = bob.get_asset_balance(&usdc.asset_id).await.unwrap(); + assert!(balance == (amount as u64)); + + // Reset prices back to old values + // This is used to test that multi_call_handler works correctly + market + .update_price_feeds_if_necessary(&[&oracle.instance], &price_data_update_old) + .await + .unwrap(); + + // Prepare calls for multi_call_handler + let tx_policies = TxPolicies::default().with_script_gas_limit(1_000_000); + + // Params for update_price_feeds_if_necessary + let call_params_update_price = + CallParameters::default().with_amount(price_data_update.update_fee); + + // Update price feeds if necessary + let update_balance_call = market + .instance + .methods() + .update_price_feeds_if_necessary(price_data_update.clone()) + .with_contracts(&[&oracle.instance]) + .with_tx_policies(tx_policies) + .call_params(call_params_update_price) + .unwrap(); + + // Params for buy_collateral + let call_params_base_asset = CallParameters::default() + .with_amount(amount as u64) + .with_asset_id(usdc.asset_id); + + // Buy collateral with base asset + let buy_collateral_call = market + .instance + .methods() + .buy_collateral(usdt.asset_id, 1u64.into(), bob_account) + .with_contracts(&[&oracle.instance]) + .with_tx_policies(tx_policies) + .call_params(call_params_base_asset) + .unwrap(); + + let mutli_call_handler = CallHandler::new_multi_call(bob.clone()) + .add_call(update_balance_call) + .add_call(buy_collateral_call) + .with_variable_output_policy(VariableOutputPolicy::Exactly(2)); + + // Sumbit tx + let submitted_tx = mutli_call_handler.submit().await.unwrap(); + + // Wait for response + let _: CallResponse<((), ())> = submitted_tx.response().await.unwrap(); + + // Check + let balance = bob.get_asset_balance(&usdt.asset_id).await.unwrap(); + println!("{}", balance); + assert!(balance == parse_units(200, usdt.decimals) * AMOUNT_COEFFICIENT); + + market + .print_debug_state(&wallets, &usdc, &usdt) + .await + .unwrap(); + market.debug_increment_timestamp().await.unwrap(); + + // ================================================= + // ==================== Step #12 ==================== + // πŸ‘› Wallet: Chad 🀡 + // πŸ€™ Call: withdraw_collateral + // πŸ’° Amount: 270 USDT + + let amount = market + .get_user_collateral(chad_account, usdt.asset_id) + .await + .unwrap() + .value; + let log_amount = format!("{} USDT", amount as f64 / scale_9); + print_case_title(12, "Chad", "withdraw_collateral", log_amount.as_str()); + + // USDT balance check + let balance = chad.get_asset_balance(&usdt.asset_id).await.unwrap(); + assert!(balance == amount); + + market + .print_debug_state(&wallets, &usdc, &usdt) + .await + .unwrap(); +} diff --git a/contracts/market/tests/local_tests/mod.rs b/contracts/market/tests/local_tests/mod.rs index a629c649..53880125 100644 --- a/contracts/market/tests/local_tests/mod.rs +++ b/contracts/market/tests/local_tests/mod.rs @@ -1,3 +1,4 @@ mod main_test_uni; mod main_test_uni_no_debug_mode; +mod main_test_usdt; mod scenarios; diff --git a/contracts/market/tests/local_tests/scenarios/reserves.rs b/contracts/market/tests/local_tests/scenarios/reserves.rs index c3df6a8b..fb3b277a 100644 --- a/contracts/market/tests/local_tests/scenarios/reserves.rs +++ b/contracts/market/tests/local_tests/scenarios/reserves.rs @@ -115,7 +115,7 @@ async fn reserves_test() { // Check reserves let reserves = market.get_reserves().await.unwrap().value; let normalized_reserves: u64 = convert_i256_to_i128(&reserves).try_into().unwrap(); - assert!(normalized_reserves == 62641); + assert!(normalized_reserves == 62644); // Governor withdraws reserves; let res = market diff --git a/contracts/market/tests/tokens.json b/contracts/market/tests/tokens.json index 1b581b07..6d294175 100644 --- a/contracts/market/tests/tokens.json +++ b/contracts/market/tests/tokens.json @@ -50,5 +50,19 @@ "liquidate_collateral_factor": 700000000000000000, "liquidation_penalty": 750000000000000000, "supply_cap": 400000000000000 + }, + { + "asset_id": "0xa0265fb5c32f6e8db3197af3c7eb05c48ae373605b8165b6f4a51c5b0ba4812e", + "price_feed_id": "0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b", + "price_feed_decimals": 7, + "name": "USDT", + "symbol": "USDT", + "default_price": 1, + "decimals": 6, + "mint_amount": 10000, + "borrow_collateral_factor": 900000000000000000, + "liquidate_collateral_factor": 950000000000000000, + "liquidation_penalty": 950000000000000000, + "supply_cap": 10000000000000 } ] diff --git a/contracts/market/tests/utils/mod.rs b/contracts/market/tests/utils/mod.rs index 2a12e6a9..a4061956 100644 --- a/contracts/market/tests/utils/mod.rs +++ b/contracts/market/tests/utils/mod.rs @@ -50,6 +50,8 @@ pub struct TestData { pub market: Market, pub usdc: Asset, pub usdc_contract: TokenAsset, + pub usdt: Asset, + pub usdt_contract: TokenAsset, pub uni: Asset, pub uni_contract: TokenAsset, pub eth: Asset, @@ -82,6 +84,13 @@ pub async fn setup(debug_step: Option) -> TestData { token_contract.contract_id().into(), &usdc.symbol, ); + let usdt = assets.get("USDT").unwrap(); + let usdt_contract = TokenAsset::new( + admin.clone(), + token_contract.contract_id().into(), + &usdt.symbol, + ); + let uni = assets.get("UNI").unwrap(); let uni_contract = TokenAsset::new( admin.clone(), @@ -157,6 +166,8 @@ pub async fn setup(debug_step: Option) -> TestData { market, usdc: usdc.clone(), usdc_contract, + usdt: usdt.clone(), + usdt_contract, uni: uni.clone(), uni_contract, eth: eth.clone(), diff --git a/contracts/pyth-mock/tests/harness.rs b/contracts/pyth-mock/tests/harness.rs index 86120b81..1131e93f 100644 --- a/contracts/pyth-mock/tests/harness.rs +++ b/contracts/pyth-mock/tests/harness.rs @@ -1,4 +1,3 @@ -mod scripts; use fuels::{ test_helpers::{launch_custom_provider_and_get_wallets, NodeConfig, Trigger, WalletsConfig}, types::{Bits256, Bytes}, diff --git a/contracts/pyth-mock/tests/scripts/deploy.rs b/contracts/pyth-mock/tests/scripts/deploy.rs deleted file mode 100644 index 5408f7d1..00000000 --- a/contracts/pyth-mock/tests/scripts/deploy.rs +++ /dev/null @@ -1,24 +0,0 @@ -use dotenv::dotenv; -use fuels::prelude::{Provider, WalletUnlocked}; -use pyth_mock_sdk::PythMockContract; - -#[tokio::test] -async fn deploy() { - //--------------- WALLET --------------- - dotenv().ok(); - let rpc = std::env::var("RPC").unwrap(); - println!("{}", rpc); - let provider = Provider::connect(rpc).await.unwrap(); - - let secret = std::env::var("SECRET").unwrap(); - - let wallet = - WalletUnlocked::new_from_private_key(secret.parse().unwrap(), Some(provider.clone())); - - let oracle = PythMockContract::deploy(&wallet).await.unwrap(); - - let block = provider.latest_block_height().await.unwrap(); - - println!("Mock oracle contract = 0x{}", oracle.contract_id().hash()); - println!("start_block: {block}",); -} diff --git a/contracts/pyth-mock/tests/scripts/mod.rs b/contracts/pyth-mock/tests/scripts/mod.rs deleted file mode 100644 index aab060ab..00000000 --- a/contracts/pyth-mock/tests/scripts/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod deploy; diff --git a/scripts/README.md b/scripts/README.md index e12ac7b3..0b2475bc 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -39,6 +39,8 @@ This script will activate the contract - setup the market configuration, owner o cargo run --bin activate_market -- --config-path ./configs/testnet_usdc_config.json ``` +**Note:** Make sure the base asset decimals is strictly smaller than collateral asset decimals (for each collateral asset). + ### Update collateral assets This script will update the collateral asset configuration (add new collateral assets, pause collateral assets, unpause collateral assets, update collateral asset configuration ...). @@ -47,6 +49,8 @@ This script will update the collateral asset configuration (add new collateral a cargo run --bin update_collateral_assets -- --config-path ./configs/testnet_usdc_config.json ``` +**Note:** Make sure the base asset decimals is strictly smaller than collateral asset decimals (for each collateral asset). + ### Upgrade market contract When you want to upgrade the market contract, make the changes to the contract, build it, and use the deploy command below. You also need to set the addres of the proxy in the `Forc.toml` in the `../contracts/market` folder. Make sure the address is written in property `address` within the `[proxy]` section. diff --git a/scripts/configs/mainnet_usdc_config.json b/scripts/configs/mainnet_usdc_config.json index 0608cb05..faab5951 100644 --- a/scripts/configs/mainnet_usdc_config.json +++ b/scripts/configs/mainnet_usdc_config.json @@ -18,7 +18,7 @@ "base_min_for_rewards": 1000000000, "base_borrow_min": 10000000, "target_reserves": 1000000000000, - "pyth_contract_id": "0x103465f1c0c901471b868b4a9e4e57c381168ac38ee5b59732943e9e004c488d", + "pyth_contract_id": "0x1c86fdd9e0e7bc0d2ae1bf6817ef4834ffa7247655701ee1b031b52a24c523da", "base_asset": { "asset_id": "0x286c479da40dc953bddc3bb4c453b608bba2e0ac483b077bd475174115395e6b", "price_feed_id": "0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a", @@ -36,7 +36,7 @@ "borrow_collateral_factor": 600000000000000000, "liquidate_collateral_factor": 800000000000000000, "liquidation_penalty": 880000000000000000, - "supply_cap": 300000000000, + "supply_cap": 2200000000000, "is_active": true }, { @@ -48,7 +48,31 @@ "borrow_collateral_factor": 600000000000000000, "liquidate_collateral_factor": 750000000000000000, "liquidation_penalty": 850000000000000000, - "supply_cap": 300000000000, + "supply_cap": 2200000000000, + "is_active": true + }, + { + "asset_id": "0xa0265fb5c32f6e8db3197af3c7eb05c48ae373605b8165b6f4a51c5b0ba4812e", + "price_feed_id": "0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b", + "name": "USDT", + "symbol": "USDT", + "decimals": 6, + "borrow_collateral_factor": 900000000000000000, + "liquidate_collateral_factor": 950000000000000000, + "liquidation_penalty": 950000000000000000, + "supply_cap": 10000000000000, + "is_active": true + }, + { + "asset_id": "0x9e46f919fbf978f3cad7cd34cca982d5613af63ff8aab6c379e4faa179552958", + "price_feed_id": "0x710659c5a68e2416ce4264ca8d50d34acc20041d91289110eea152c52ff3dc39", + "name": "sDAI", + "symbol": "sDAI", + "decimals": 9, + "borrow_collateral_factor": 900000000000000000, + "liquidate_collateral_factor": 950000000000000000, + "liquidation_penalty": 950000000000000000, + "supply_cap": 10000000000000000, "is_active": true } ] diff --git a/scripts/configs/testnet_usdc_config.json b/scripts/configs/testnet_usdc_config.json index 8e909c6a..63f4f279 100644 --- a/scripts/configs/testnet_usdc_config.json +++ b/scripts/configs/testnet_usdc_config.json @@ -18,7 +18,7 @@ "base_min_for_rewards": 1000000000, "base_borrow_min": 10000000, "target_reserves": 1000000000000, - "pyth_contract_id": "0xe31e04946c67fb41923f93d50ee7fc1c6c99d6e07c02860c6bea5f4a13919277", + "pyth_contract_id": "0x25146735b29d4216639f7f8b1d7b921ff87a1d3051de62d6cceaacabeb33b8e7", "base_asset": { "asset_id": "0x3aced3c270121c9d85e00fb14f079ecc666b733b12a0d15df1c2ecae26c1167a", "price_feed_id": "0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a", @@ -74,6 +74,18 @@ "liquidation_penalty": 930000000000000000, "supply_cap": 400000000000000, "is_active": true + }, + { + "asset_id": "0xf30eade9911f75e819deff8fa76f7cf54c477180c756f5a9c3db6fe1986fe485", + "price_feed_id": "0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b", + "name": "USDT", + "symbol": "USDT", + "decimals": 6, + "borrow_collateral_factor": 900000000000000000, + "liquidate_collateral_factor": 950000000000000000, + "liquidation_penalty": 950000000000000000, + "supply_cap": 10000000000000, + "is_active": true } ] } diff --git a/scripts/configs/testnet_usdt_config.json b/scripts/configs/testnet_usdt_config.json index ab0aef01..03d5789c 100644 --- a/scripts/configs/testnet_usdt_config.json +++ b/scripts/configs/testnet_usdt_config.json @@ -18,7 +18,7 @@ "base_min_for_rewards": 1000000000, "base_borrow_min": 10000000, "target_reserves": 1000000000000, - "pyth_contract_id": "0xe31e04946c67fb41923f93d50ee7fc1c6c99d6e07c02860c6bea5f4a13919277", + "pyth_contract_id": "0x25146735b29d4216639f7f8b1d7b921ff87a1d3051de62d6cceaacabeb33b8e7", "base_asset": { "asset_id": "0xc264acd28eaf6f33e0e13360a37741dc91221aaa8817e1b4e462d61bb08c5835", "price_feed_id": "0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b", diff --git a/scripts/src/activate_market.rs b/scripts/src/activate_market.rs index f2f49cc9..27006358 100644 --- a/scripts/src/activate_market.rs +++ b/scripts/src/activate_market.rs @@ -60,6 +60,11 @@ async fn main() -> anyhow::Result<()> { println!("Market configuration: {:#?}", market_config); + // verify explicitly assets decimals + for collateral_asset in &market_config.collateral_assets { + assert!(collateral_asset.decimals > market_config.base_asset.decimals); + } + if !get_yes_no_input("Do you want to activate market with the config above? (yes/no): ") { return Ok(()); } diff --git a/scripts/src/update_collateral_assets.rs b/scripts/src/update_collateral_assets.rs index c49215bd..ad2fb69c 100644 --- a/scripts/src/update_collateral_assets.rs +++ b/scripts/src/update_collateral_assets.rs @@ -58,6 +58,11 @@ async fn main() -> anyhow::Result<()> { let market_config = read_market_config(&args.config_path)?; + // verify explicitly assets decimals + for collateral_asset in &market_config.collateral_assets { + assert!(collateral_asset.decimals >= market_config.base_asset.decimals); + } + // get current collateral assets configurations let collateral_asset_configurations = market_instance .methods()