diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..d880042b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,44 @@ +name: Stellar Expert WASM Release +on: + push: + tags: + - 'v*' # triggered whenever a new tag (previxed with "v") is pushed to the repository +jobs: + release-contract-backstop: + uses: stellar-expert/soroban-build-workflow/.github/workflows/release.yml@main + with: + release_name: ${{ github.ref_name }} + release_description: 'Blend Backstop Release' + package: 'backstop' + make_target: 'build' + secrets: + release_token: ${{ secrets.GITHUB_TOKEN }} + + release-contract-pool: + uses: stellar-expert/soroban-build-workflow/.github/workflows/release.yml@main + with: + release_name: ${{ github.ref_name }} + release_description: 'Blend Pool Release' + package: 'pool' + make_target: 'build' + secrets: + release_token: ${{ secrets.GITHUB_TOKEN }} + + release-contract-emitter: + uses: stellar-expert/soroban-build-workflow/.github/workflows/release.yml@main + with: + release_name: ${{ github.ref_name }} + release_description: 'Blend Emitter Release' + package: 'emitter' + secrets: + release_token: ${{ secrets.GITHUB_TOKEN }} + + release-contract-pool-factory: + uses: stellar-expert/soroban-build-workflow/.github/workflows/release.yml@main + with: + release_name: ${{ github.ref_name }} + release_description: 'Blend Pool Factory Release' + package: 'pool-factory' + make_target: 'build' + secrets: + release_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Cargo.lock b/Cargo.lock index 3d3bff95..5eaed891 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,7 +106,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "blend-contract-sdk" -version = "0.2.0" +version = "1.0.0" dependencies = [ "soroban-sdk", ] diff --git a/backstop/src/backstop/pool.rs b/backstop/src/backstop/pool.rs index 6f5b1e6a..4ec3364c 100644 --- a/backstop/src/backstop/pool.rs +++ b/backstop/src/backstop/pool.rs @@ -15,10 +15,14 @@ pub struct PoolBackstopData { pub fn load_pool_backstop_data(e: &Env, address: &Address) -> PoolBackstopData { let pool_balance = storage::get_pool_balance(e, address); - let q4w_pct = pool_balance - .q4w - .fixed_div_ceil(pool_balance.shares, SCALAR_7) - .unwrap_optimized(); + let q4w_pct = if pool_balance.shares > 0 { + pool_balance + .q4w + .fixed_div_ceil(pool_balance.shares, SCALAR_7) + .unwrap_optimized() + } else { + 0 + }; let (blnd_per_tkn, usdc_per_tkn) = storage::get_lp_token_val(e); let blnd = pool_balance @@ -202,6 +206,34 @@ mod tests { }); } + #[test] + fn test_load_pool_data_no_shares() { + let e = Env::default(); + + let backstop_address = create_backstop(&e); + let pool = Address::generate(&e); + + e.as_contract(&backstop_address, || { + storage::set_pool_balance( + &e, + &pool, + &PoolBalance { + shares: 0, + tokens: 250_0000000, + q4w: 0, + }, + ); + storage::set_lp_token_val(&e, &(5_0000000, 0_0500000)); + + let pool_data = load_pool_backstop_data(&e, &pool); + + assert_eq!(pool_data.tokens, 250_0000000); + assert_eq!(pool_data.q4w_pct, 0); + assert_eq!(pool_data.blnd, 1_250_0000000); + assert_eq!(pool_data.usdc, 12_5000000); + }); + } + /********** require_is_from_pool_factory **********/ #[test] diff --git a/backstop/src/contract.rs b/backstop/src/contract.rs index 72f6ecf7..e14db729 100644 --- a/backstop/src/contract.rs +++ b/backstop/src/contract.rs @@ -6,7 +6,7 @@ use crate::{ storage, }; use soroban_sdk::{ - contract, contractclient, contractimpl, panic_with_error, Address, Env, Map, Symbol, Vec, + contract, contractclient, contractimpl, panic_with_error, Address, Env, Symbol, Vec, }; /// ### Backstop @@ -38,7 +38,7 @@ pub trait Backstop { blnd_token: Address, usdc_token: Address, pool_factory: Address, - drop_list: Map, + drop_list: Vec<(Address, i128)>, ); /********** Core **********/ @@ -184,7 +184,7 @@ impl Backstop for BackstopContract { usdc_token: Address, blnd_token: Address, pool_factory: Address, - drop_list: Map, + drop_list: Vec<(Address, i128)>, ) { storage::extend_instance(&e); if storage::get_is_init(&e) { diff --git a/backstop/src/dependencies/mod.rs b/backstop/src/dependencies/mod.rs index 89463a25..0057d802 100644 --- a/backstop/src/dependencies/mod.rs +++ b/backstop/src/dependencies/mod.rs @@ -3,7 +3,8 @@ pub use pool_factory::Client as PoolFactoryClient; mod comet; pub use comet::Client as CometClient; -#[cfg(any(test, feature = "testutils"))] + +#[cfg(test)] pub use comet::WASM as COMET_WASM; mod emitter; diff --git a/backstop/src/emissions/claim.rs b/backstop/src/emissions/claim.rs index d8f8c665..32186556 100644 --- a/backstop/src/emissions/claim.rs +++ b/backstop/src/emissions/claim.rs @@ -212,7 +212,7 @@ mod tests { assert_eq!(result, 75_3145677 + 6_2904190); assert_eq!( lp_client.balance(&backstop_address), - backstop_lp_balance + 6_5244800 + backstop_lp_balance + 6_4729326 ); assert_eq!( blnd_token_client.balance(&backstop_address), @@ -221,18 +221,18 @@ mod tests { let sam_balance_1 = storage::get_user_balance(&e, &pool_1_id, &samwise); assert_eq!(sam_balance_1.shares, 9_0000000); let frodo_balance_1 = storage::get_user_balance(&e, &pool_1_id, &frodo); - assert_eq!(frodo_balance_1.shares, pre_frodo_balance_1 + 4_5761820); + assert_eq!(frodo_balance_1.shares, pre_frodo_balance_1 + 4_5400274); let sam_balance_2 = storage::get_user_balance(&e, &pool_2_id, &samwise); assert_eq!(sam_balance_2.shares, 7_5000000); let frodo_balance_2 = storage::get_user_balance(&e, &pool_2_id, &frodo); - assert_eq!(frodo_balance_2.shares, pre_frodo_balance_2 + 0_3947102); + assert_eq!(frodo_balance_2.shares, pre_frodo_balance_2 + 0_3915917); let pool_balance_1 = storage::get_pool_balance(&e, &pool_1_id); - assert_eq!(pool_balance_1.tokens, pre_pool_tokens_1 + 6_1015761); - assert_eq!(pool_balance_1.shares, pre_pool_shares_1 + 4_5761820); + assert_eq!(pool_balance_1.tokens, pre_pool_tokens_1 + 6_0533699); + assert_eq!(pool_balance_1.shares, pre_pool_shares_1 + 4_5400274); let pool_balance_2 = storage::get_pool_balance(&e, &pool_2_id); - assert_eq!(pool_balance_2.tokens, pre_pool_tokens_2 + 0_4229038); - assert_eq!(pool_balance_2.shares, pre_pool_shares_2 + 0_3947102); + assert_eq!(pool_balance_2.tokens, pre_pool_tokens_2 + 0_4195626); + assert_eq!(pool_balance_2.shares, pre_pool_shares_2 + 0_3915917); let new_backstop_1_data = storage::get_backstop_emis_data(&e, &pool_1_id).unwrap_optimized(); @@ -371,7 +371,7 @@ mod tests { assert_eq!(result, 75_3145677 + 6_2904190); assert_eq!( lp_client.balance(&backstop_address), - backstop_lp_balance + 6_5244800 + backstop_lp_balance + 6_4729326 ); assert_eq!( blnd_token_client.balance(&backstop_address), @@ -380,18 +380,18 @@ mod tests { let sam_balance_1 = storage::get_user_balance(&e, &pool_1_id, &samwise); assert_eq!(sam_balance_1.shares, 9_0000000); let frodo_balance_1 = storage::get_user_balance(&e, &pool_1_id, &frodo); - assert_eq!(frodo_balance_1.shares, pre_frodo_balance_1 + 4_5761820); + assert_eq!(frodo_balance_1.shares, pre_frodo_balance_1 + 4_5400274); let sam_balance_2 = storage::get_user_balance(&e, &pool_2_id, &samwise); assert_eq!(sam_balance_2.shares, 7_5000000); let frodo_balance_2 = storage::get_user_balance(&e, &pool_2_id, &frodo); - assert_eq!(frodo_balance_2.shares, pre_frodo_balance_2 + 0_3947102); + assert_eq!(frodo_balance_2.shares, pre_frodo_balance_2 + 0_3915917); let pool_balance_1 = storage::get_pool_balance(&e, &pool_1_id); - assert_eq!(pool_balance_1.tokens, pre_pool_tokens_1 + 6_1015761); - assert_eq!(pool_balance_1.shares, pre_pool_shares_1 + 4_5761820); + assert_eq!(pool_balance_1.tokens, pre_pool_tokens_1 + 6_0533699); + assert_eq!(pool_balance_1.shares, pre_pool_shares_1 + 4_5400274); let pool_balance_2 = storage::get_pool_balance(&e, &pool_2_id); - assert_eq!(pool_balance_2.tokens, pre_pool_tokens_2 + 0_4229038); - assert_eq!(pool_balance_2.shares, pre_pool_shares_2 + 0_3947102); + assert_eq!(pool_balance_2.tokens, pre_pool_tokens_2 + 0_4195626); + assert_eq!(pool_balance_2.shares, pre_pool_shares_2 + 0_3915917); let new_backstop_1_data = storage::get_backstop_emis_data(&e, &pool_1_id).unwrap_optimized(); @@ -435,47 +435,47 @@ mod tests { &vec![&e, pool_1_id.clone(), pool_2_id.clone()], &frodo, ); - assert_eq!(result_1, 1005009202); + assert_eq!(result_1, 1005194703); assert_eq!( blnd_token_client.balance(&backstop_address), - 200_0000000 - (75_3145677 + 6_2904190) - (1005009202) + 200_0000000 - (75_3145677 + 6_2904190) - (1005194703) ); assert_eq!( lp_client.balance(&backstop_address), - backstop_lp_balance + 7_9137036 + backstop_lp_balance + 7_7889107 ); let sam_balance_1 = storage::get_user_balance(&e, &pool_1_id, &samwise); assert_eq!(sam_balance_1.shares, 9_0000000); let frodo_balance_1 = storage::get_user_balance(&e, &pool_1_id, &frodo); - assert_eq!(frodo_balance_1.shares, pre_frodo_balance_1 + 4_3004891); + assert_eq!(frodo_balance_1.shares, pre_frodo_balance_1 + 4_2609092); let sam_balance_2 = storage::get_user_balance(&e, &pool_2_id, &samwise); assert_eq!(sam_balance_2.shares, 7_5000000); let frodo_balance_2 = storage::get_user_balance(&e, &pool_2_id, &frodo); - assert_eq!(frodo_balance_2.shares, pre_frodo_balance_2 + 2_0344033); + assert_eq!(frodo_balance_2.shares, pre_frodo_balance_2 + 2_0152958); let pool_balance_1 = storage::get_pool_balance(&e, &pool_1_id); - assert_eq!(pool_balance_1.tokens, pre_pool_tokens_1 + 5_7339856); - assert_eq!(pool_balance_1.shares, pre_pool_shares_1 + 4_3004891); + assert_eq!(pool_balance_1.tokens, pre_pool_tokens_1 + 5_6812124); + assert_eq!(pool_balance_1.shares, pre_pool_shares_1 + 4_2609092); let pool_balance_2 = storage::get_pool_balance(&e, &pool_2_id); - assert_eq!(pool_balance_2.tokens, pre_pool_tokens_2 + 2_1797179); - assert_eq!(pool_balance_2.shares, pre_pool_shares_2 + 2_0344033); + assert_eq!(pool_balance_2.tokens, pre_pool_tokens_2 + 2_1592456); + assert_eq!(pool_balance_2.shares, pre_pool_shares_2 + 2_0152958); let new_backstop_1_data = storage::get_backstop_emis_data(&e, &pool_1_id).unwrap_optimized(); let new_user_1_data = storage::get_user_emis_data(&e, &pool_1_id, &samwise).unwrap_optimized(); assert_eq!(new_backstop_1_data.last_time, block_timestamp_1); - assert_eq!(new_backstop_1_data.index, 164344784); + assert_eq!(new_backstop_1_data.index, 164363961); assert_eq!(new_user_1_data.accrued, 0); - assert_eq!(new_user_1_data.index, 164344784); + assert_eq!(new_user_1_data.index, 164363961); let new_backstop_2_data = storage::get_backstop_emis_data(&e, &pool_2_id).unwrap_optimized(); let new_user_2_data = storage::get_user_emis_data(&e, &pool_2_id, &samwise).unwrap_optimized(); assert_eq!(new_backstop_2_data.last_time, block_timestamp_1); - assert_eq!(new_backstop_2_data.index, 43961378); + assert_eq!(new_backstop_2_data.index, 43963099); assert_eq!(new_user_2_data.accrued, 0); - assert_eq!(new_user_2_data.index, 43961378); + assert_eq!(new_user_2_data.index, 43963099); }); } diff --git a/backstop/src/storage.rs b/backstop/src/storage.rs index 112c75db..187f251f 100644 --- a/backstop/src/storage.rs +++ b/backstop/src/storage.rs @@ -1,6 +1,5 @@ use soroban_sdk::{ - contracttype, unwrap::UnwrapOptimized, vec, Address, Env, IntoVal, Map, Symbol, TryFromVal, - Val, Vec, + contracttype, unwrap::UnwrapOptimized, vec, Address, Env, IntoVal, Symbol, TryFromVal, Val, Vec, }; use crate::backstop::{PoolBalance, UserBalance}; @@ -466,10 +465,10 @@ pub fn set_user_emis_data( /********** Drop Emissions **********/ /// Get the current pool addresses that are in the drop list and the amount of the initial distribution they receive -pub fn get_drop_list(e: &Env) -> Map { +pub fn get_drop_list(e: &Env) -> Vec<(Address, i128)> { e.storage() .temporary() - .get::>(&Symbol::new(&e, DROP_LIST_KEY)) + .get::>(&Symbol::new(&e, DROP_LIST_KEY)) .unwrap_optimized() } @@ -477,10 +476,10 @@ pub fn get_drop_list(e: &Env) -> Map { /// /// ### Arguments /// * `drop_list` - The map of pool addresses to the amount of the initial distribution they receive -pub fn set_drop_list(e: &Env, drop_list: &Map) { +pub fn set_drop_list(e: &Env, drop_list: &Vec<(Address, i128)>) { e.storage() .temporary() - .set::>(&Symbol::new(&e, DROP_LIST_KEY), drop_list); + .set::>(&Symbol::new(&e, DROP_LIST_KEY), drop_list); e.storage().temporary().extend_ttl( &Symbol::new(&e, DROP_LIST_KEY), LEDGER_THRESHOLD_USER, diff --git a/backstop/src/testutils.rs b/backstop/src/testutils.rs index 8fb8d027..f9ca72a7 100644 --- a/backstop/src/testutils.rs +++ b/backstop/src/testutils.rs @@ -142,21 +142,15 @@ pub(crate) fn create_comet_lp_pool<'a>( let usdc_client = MockTokenClient::new(e, usdc_token); blnd_client.mint(&admin, &1_000_0000000); usdc_client.mint(&admin, &25_0000000); - let exp_ledger = e.ledger().sequence() + 100; - blnd_client.approve(&admin, &contract_address, &2_000_0000000, &exp_ledger); - usdc_client.approve(&admin, &contract_address, &2_000_0000000, &exp_ledger); - client.init(&Address::generate(e), &admin); - client.bundle_bind( + client.init( + admin, &vec![e, blnd_token.clone(), usdc_token.clone()], + &vec![e, 0_8000000, 0_2000000], &vec![e, 1_000_0000000, 25_0000000], - &vec![e, 8_0000000, 2_0000000], + &0_0030000, ); - client.set_swap_fee(&0_0030000, &admin); - client.set_public_swap(&admin, &true); - client.finalize(); - (contract_address, client) } diff --git a/blend-contract-sdk/Cargo.toml b/blend-contract-sdk/Cargo.toml index 79e65847..4e803dbb 100644 --- a/blend-contract-sdk/Cargo.toml +++ b/blend-contract-sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "blend-contract-sdk" -version = "0.2.0" +version = "1.0.0" description = "Traits, clients, types, and WASMs for the Blend Protocol for use in Soroban contract development." homepage = "https://github.com/blend-capital/blend-contracts" repository = "https://github.com/blend-capital/blend-contracts" diff --git a/blend-contract-sdk/README.md b/blend-contract-sdk/README.md index 94389111..280abcb7 100644 --- a/blend-contract-sdk/README.md +++ b/blend-contract-sdk/README.md @@ -66,21 +66,12 @@ pool_client.mock_all_auths().update_status(); // update status based on backstop ## WASM Verification -The WASM files included will align with the GitHub release the SDK was published with (the version numbers will match). The WASM files were generated with the Makefile. +The WASM files included will align with the GitHub release the SDK was published with (the version numbers will match). -Since WASM builds can vary based on factors like OS, here are the details of the machine that built the WASMs included in this package: - -* Ubuntu 22.04.4 LTS -* stable-x86_64-unknown-linux-gnu (default) -* rustc 1.77.1 (7cf61ebde 2024-03-27) -* soroban 20.3.1 (ae5446f63ca8a275e61912019199254d598f3bd5) -* soroban-env 20.2.1 (18a10592853d9edf4e341b565b0b1638f95f0393) -* soroban-env interface version 85899345920 -* stellar-xdr 20.1.0 (8b9d623ef40423a8462442b86997155f2c04d3a1) -* xdr curr (b96148cd4acc372cc9af17b909ffe4b12c43ecb6) +The WASMs are generated with the [Stellar Expert WASM Release Action](https://github.com/stellar-expert/soroban-build-workflow) The SHA256 Checksums: -* backstop - `8dfbc6ba300cde6ebe747cf985cf9221bf3594981595b9c26bbd108ff19a5598` -* emitter - `b1555702a4cca7c44e02beb5aa82b0271c0367471c68f2ec9246c31b202e38ee` -* pool_factory - `8bc7894d8a4e46b085d0579e233e3c436bb34e18f9a2a83d4bde8526cde18cb6` -* pool - `76ebcea354d5959c5b0d38818ddf1524c5af16970231b532f5caa63121930861` \ No newline at end of file +* backstop - `62f61b32fff99f7eec052a8e573c367759f161c481a5caf0e76a10ae4617c3b4` +* emitter - `438a5528cff17ede6fe515f095c43c5f15727af17d006971485e52462e7e7b89` +* pool_factory - `0287f4ad7350935b83d94e046c0bcabc960b233dbce1531008c021b71d406a1d` +* pool - `46b4c2d5fcac623d9668b19d0ce68f9da5a18029f3dffa8afded436ab16e8883` \ No newline at end of file diff --git a/blend-contract-sdk/src/testutils.rs b/blend-contract-sdk/src/testutils.rs index 1554491d..756d8b94 100644 --- a/blend-contract-sdk/src/testutils.rs +++ b/blend-contract-sdk/src/testutils.rs @@ -1,4 +1,4 @@ -use soroban_sdk::{testutils::Address as _, token::StellarAssetClient, vec, Address, Env, Map}; +use soroban_sdk::{token::StellarAssetClient, vec, Address, Env, Vec}; use crate::{backstop, emitter, pool, pool_factory}; @@ -6,10 +6,6 @@ pub mod comet { soroban_sdk::contractimport!(file = "./wasm/comet.wasm"); } -pub mod comet_factory { - soroban_sdk::contractimport!(file = "./wasm/comet_factory.wasm"); -} - /// Create a "good enough" ReserveConfig for most testing usecases /// /// Can be used when creating reserves for a pool. @@ -70,22 +66,13 @@ impl<'a> BlendFixture<'a> { .mint(deployer, &(25_0000000 * 2001)); let comet_client: comet::Client<'a> = comet::Client::new(env, &comet); - comet_client - .mock_all_auths() - .init(&Address::generate(env), deployer); - - comet_client.mock_all_auths().bundle_bind( + comet_client.mock_all_auths().init( + &deployer, &vec![env, blnd.clone(), usdc.clone()], + &vec![env, 0_8000000, 0_2000000], &vec![env, 1_000_0000000, 25_0000000], - &vec![env, 8_0000000, 2_0000000], + &0_0030000, ); - comet_client - .mock_all_auths() - .set_swap_fee(&30000_i128, deployer); - comet_client - .mock_all_auths() - .set_public_swap(deployer, &true); - comet_client.mock_all_auths().finalize(); comet_client.mock_all_auths().join_pool( &199_900_0000000, // finalize mints 100 @@ -106,7 +93,7 @@ impl<'a> BlendFixture<'a> { &usdc, &blnd, &pool_factory, - &Map::new(env), + &Vec::new(env), ); let pool_hash = env.deployer().upload_contract_wasm(pool::WASM); diff --git a/blend-contract-sdk/wasm/backstop.wasm b/blend-contract-sdk/wasm/backstop.wasm old mode 100644 new mode 100755 index 8b0bd59f..acf4b9e0 Binary files a/blend-contract-sdk/wasm/backstop.wasm and b/blend-contract-sdk/wasm/backstop.wasm differ diff --git a/blend-contract-sdk/wasm/comet.wasm b/blend-contract-sdk/wasm/comet.wasm old mode 100644 new mode 100755 index 82118f99..e9493fd7 Binary files a/blend-contract-sdk/wasm/comet.wasm and b/blend-contract-sdk/wasm/comet.wasm differ diff --git a/blend-contract-sdk/wasm/comet_factory.wasm b/blend-contract-sdk/wasm/comet_factory.wasm old mode 100644 new mode 100755 index 3a73646b..9db8020a Binary files a/blend-contract-sdk/wasm/comet_factory.wasm and b/blend-contract-sdk/wasm/comet_factory.wasm differ diff --git a/blend-contract-sdk/wasm/emitter.wasm b/blend-contract-sdk/wasm/emitter.wasm old mode 100644 new mode 100755 index 68bed722..c6f00d0e Binary files a/blend-contract-sdk/wasm/emitter.wasm and b/blend-contract-sdk/wasm/emitter.wasm differ diff --git a/blend-contract-sdk/wasm/pool.wasm b/blend-contract-sdk/wasm/pool.wasm old mode 100644 new mode 100755 index c10913a8..d0d28ea8 Binary files a/blend-contract-sdk/wasm/pool.wasm and b/blend-contract-sdk/wasm/pool.wasm differ diff --git a/blend-contract-sdk/wasm/pool_factory.wasm b/blend-contract-sdk/wasm/pool_factory.wasm old mode 100644 new mode 100755 index 553a632c..cc662d3d Binary files a/blend-contract-sdk/wasm/pool_factory.wasm and b/blend-contract-sdk/wasm/pool_factory.wasm differ diff --git a/comet.wasm b/comet.wasm old mode 100644 new mode 100755 index 82118f99..e9493fd7 Binary files a/comet.wasm and b/comet.wasm differ diff --git a/emitter/src/contract.rs b/emitter/src/contract.rs index 91d2476c..16021ff4 100644 --- a/emitter/src/contract.rs +++ b/emitter/src/contract.rs @@ -1,6 +1,6 @@ use crate::{backstop_manager, emitter, errors::EmitterError, storage}; use soroban_sdk::{ - contract, contractclient, contractimpl, panic_with_error, Address, Env, Map, Symbol, + contract, contractclient, contractimpl, panic_with_error, Address, Env, Symbol, Vec, }; /// ### Emitter @@ -61,7 +61,7 @@ pub trait Emitter { /// or if the queued swap has not been unlocked. fn swap_backstop(e: Env); - /// Distributes initial BLND after a new backstop is set + /// (Backstop only) Distributes initial BLND after a new backstop is set /// /// ### Arguments /// * `list` - The list of address and amounts to distribute too @@ -69,7 +69,7 @@ pub trait Emitter { /// ### Errors /// If drop has already been called for the backstop, the backstop is not the caller, /// or the list exceeds the drop amount maximum. - fn drop(e: Env, list: Map); + fn drop(e: Env, list: Vec<(Address, i128)>); } #[contractimpl] @@ -135,7 +135,7 @@ impl Emitter for EmitterContract { e.events().publish((Symbol::new(&e, "swap"),), swap); } - fn drop(e: Env, list: Map) { + fn drop(e: Env, list: Vec<(Address, i128)>) { storage::extend_instance(&e); emitter::execute_drop(&e, &list); diff --git a/emitter/src/emitter.rs b/emitter/src/emitter.rs index 898ec74d..51de3744 100644 --- a/emitter/src/emitter.rs +++ b/emitter/src/emitter.rs @@ -1,6 +1,6 @@ use crate::{constants::SCALAR_7, errors::EmitterError, storage}; use sep_41_token::StellarAssetClient; -use soroban_sdk::{panic_with_error, Address, Env, Map}; +use soroban_sdk::{panic_with_error, Address, Env, Vec}; /// Perform a distribution pub fn execute_distribute(e: &Env, backstop: &Address) -> i128 { @@ -18,7 +18,7 @@ pub fn execute_distribute(e: &Env, backstop: &Address) -> i128 { } /// Perform drop BLND distribution -pub fn execute_drop(e: &Env, list: &Map) { +pub fn execute_drop(e: &Env, list: &Vec<(Address, i128)>) { let backstop = storage::get_backstop(e); backstop.require_auth(); @@ -51,8 +51,8 @@ mod tests { use super::*; use sep_41_token::testutils::MockTokenClient; use soroban_sdk::{ - map, testutils::{Address as _, Ledger, LedgerInfo}, + vec, }; #[test] @@ -112,10 +112,10 @@ mod tests { let blnd_id = e.register_stellar_asset_contract(emitter.clone()); let blnd_client = MockTokenClient::new(&e, &blnd_id); - let drop_list = map![ + let drop_list = vec![ &e, (frodo.clone(), 20_000_000 * SCALAR_7), - (samwise.clone(), 30_000_000 * SCALAR_7) + (samwise.clone(), 30_000_000 * SCALAR_7), ]; e.as_contract(&emitter, || { @@ -153,10 +153,10 @@ mod tests { let backstop = Address::generate(&e); let blnd_id = e.register_stellar_asset_contract(emitter.clone()); - let drop_list = map![ + let drop_list = vec![ &e, (frodo.clone(), 20_000_000 * SCALAR_7), - (samwise.clone(), 30_000_000 * SCALAR_7) + (samwise.clone(), 30_000_000 * SCALAR_7), ]; e.as_contract(&emitter, || { @@ -193,10 +193,10 @@ mod tests { let backstop = Address::generate(&e); let blnd_id = e.register_stellar_asset_contract(emitter.clone()); - let drop_list = map![ + let drop_list = vec![ &e, (frodo.clone(), 20_000_000 * SCALAR_7), - (samwise.clone(), 30_000_001 * SCALAR_7) + (samwise.clone(), 30_000_001 * SCALAR_7), ]; e.as_contract(&emitter, || { diff --git a/pool/src/dependencies/mod.rs b/pool/src/dependencies/mod.rs index 6c9f6d80..74dbbb86 100644 --- a/pool/src/dependencies/mod.rs +++ b/pool/src/dependencies/mod.rs @@ -1,4 +1,2 @@ mod backstop; -#[cfg(any(test, feature = "testutils"))] -pub use backstop::{BackstopDataKey, WASM as BACKSTOP_WASM}; pub use backstop::{Client as BackstopClient, PoolBackstopData}; diff --git a/pool/src/testutils.rs b/pool/src/testutils.rs index 86d4e63f..b887323f 100644 --- a/pool/src/testutils.rs +++ b/pool/src/testutils.rs @@ -10,9 +10,7 @@ use emitter::{EmitterClient, EmitterContract}; use sep_40_oracle::testutils::{MockPriceOracleClient, MockPriceOracleWASM}; use sep_41_token::testutils::{MockTokenClient, MockTokenWASM}; use soroban_fixed_point_math::FixedPoint; -use soroban_sdk::{ - map, testutils::Address as _, unwrap::UnwrapOptimized, vec, Address, Env, IntoVal, -}; +use soroban_sdk::{testutils::Address as _, unwrap::UnwrapOptimized, vec, Address, Env, IntoVal}; use backstop::{BackstopClient, BackstopContract}; use mock_pool_factory::{MockPoolFactory, MockPoolFactoryClient}; @@ -117,7 +115,7 @@ pub(crate) fn setup_backstop( usdc_token, blnd_token, &pool_factory, - &map![e, (pool_address.clone(), 50_000_000 * SCALAR_7)], + &vec![e, (pool_address.clone(), 50_000_000 * SCALAR_7)], ); e.as_contract(pool_address, || { storage::set_backstop(e, backstop_id); @@ -145,21 +143,15 @@ pub(crate) fn create_comet_lp_pool<'a>( let usdc_client = MockTokenClient::new(e, usdc_token); blnd_client.mint(&admin, &1_000_0000000); usdc_client.mint(&admin, &25_0000000); - let exp_ledger = e.ledger().sequence() + 100; - blnd_client.approve(&admin, &contract_address, &2_000_0000000, &exp_ledger); - usdc_client.approve(&admin, &contract_address, &2_000_0000000, &exp_ledger); - client.init(&Address::generate(e), &admin); - client.bundle_bind( + client.init( + admin, &vec![e, blnd_token.clone(), usdc_token.clone()], + &vec![e, 0_8000000, 0_2000000], &vec![e, 1_000_0000000, 25_0000000], - &vec![e, 8_0000000, 2_0000000], + &0_0030000, ); - client.set_swap_fee(&0_0030000, &admin); - client.set_public_swap(&admin, &true); - client.finalize(); - (contract_address, client) } diff --git a/test-suites/src/liquidity_pool.rs b/test-suites/src/liquidity_pool.rs index 0afa5c88..3a0df37e 100644 --- a/test-suites/src/liquidity_pool.rs +++ b/test-suites/src/liquidity_pool.rs @@ -30,19 +30,14 @@ pub(crate) fn create_lp_pool<'a>( let token_2_client = MockTokenClient::new(e, token_2); token_1_client.mint(&admin, &1_000_0000000); token_2_client.mint(&admin, &25_0000000); - token_1_client.approve(&admin, &contract_address, &1_000_0000000, &5356700); - token_2_client.approve(&admin, &contract_address, &1_000_0000000, &5356700); - client.init(&Address::generate(e), &admin); - client.bundle_bind( + client.init( + admin, &vec![e, token_1.clone(), token_2.clone()], + &vec![e, 0_8000000, 0_2000000], &vec![e, 1_000_0000000, 25_0000000], - &vec![e, 8_0000000, 2_0000000], + &0_0030000, ); - client.set_swap_fee(&0_0030000, &admin); - client.set_public_swap(&admin, &true); - client.finalize(); - (contract_address, client) } diff --git a/test-suites/src/setup.rs b/test-suites/src/setup.rs index 6c62b0fb..c69d2c45 100644 --- a/test-suites/src/setup.rs +++ b/test-suites/src/setup.rs @@ -11,24 +11,18 @@ pub fn create_fixture_with_data<'a>(wasm: bool) -> TestFixture<'a> { let mut fixture = TestFixture::create(wasm); // mint whale tokens - let frodo = Address::generate(&fixture.env); - fixture.users.push(frodo.clone()); + let frodo = fixture.users[0].clone(); fixture.tokens[TokenIndex::STABLE].mint(&frodo, &(100_000 * 10i128.pow(6))); fixture.tokens[TokenIndex::XLM].mint(&frodo, &(1_000_000 * SCALAR_7)); fixture.tokens[TokenIndex::WETH].mint(&frodo, &(100 * 10i128.pow(9))); // mint LP tokens with whale - fixture.tokens[TokenIndex::BLND].mint(&frodo, &(500_0010_000_0000_0000 * SCALAR_7)); - // fixture.tokens[TokenIndex::BLND].approve(&frodo, &fixture.lp.address, &i128::MAX, &99999); - fixture.tokens[TokenIndex::USDC].mint(&frodo, &(12_5010_000_0000_0000 * SCALAR_7)); - // fixture.tokens[TokenIndex::USDC].approve(&frodo, &fixture.lp.address, &i128::MAX, &99999); + // frodo has 40m BLND from drop + fixture.tokens[TokenIndex::BLND].mint(&frodo, &(70_000_000 * SCALAR_7)); + fixture.tokens[TokenIndex::USDC].mint(&frodo, &(2_600_000 * SCALAR_7)); fixture.lp.join_pool( - &(500_000_0000 * SCALAR_7), - &svec![ - &fixture.env, - 500_0010_000_0000_0000 * SCALAR_7, - 12_5010_000_0000_0000 * SCALAR_7, - ], + &(10_000_000 * SCALAR_7), + &svec![&fixture.env, 110_000_000 * SCALAR_7, 2_600_000 * SCALAR_7,], &frodo, ); @@ -91,20 +85,6 @@ pub fn create_fixture_with_data<'a>(wasm: bool) -> TestFixture<'a> { fixture.jump(60); - // fixture.tokens[TokenIndex::STABLE].approve( - // &frodo, - // &pool_fixture.pool.address, - // &i128::MAX, - // &(fixture.env.ledger().sequence() + 100), - // ); - // fixture.tokens[TokenIndex::WETH].approve( - // &frodo, - // &pool_fixture.pool.address, - // &i128::MAX, - // &(fixture.env.ledger().sequence() + 100), - // ); - // fixture.tokens[TokenIndex::XLM].approve(&frodo, &pool_fixture.pool.address, &i128::MAX, &50000); - // supply and borrow STABLE for 80% utilization (close to target) let requests: SVec = svec![ &fixture.env, @@ -172,11 +152,15 @@ mod tests { let frodo = fixture.users.get(0).unwrap(); let pool_fixture: &PoolFixture = fixture.pools.get(0).unwrap(); - // validate backstop deposit + // validate backstop deposit and drop assert_eq!( 50_000 * SCALAR_7, fixture.lp.balance(&fixture.backstop.address) ); + assert_eq!( + 10_000_000 * SCALAR_7, + fixture.tokens[TokenIndex::BLND].balance(&fixture.bombadil) + ); // validate pool actions assert_eq!( @@ -224,11 +208,16 @@ mod tests { let fixture = create_fixture_with_data(false); let frodo = fixture.users.get(0).unwrap(); let pool_fixture: &PoolFixture = fixture.pools.get(0).unwrap(); + // validate backstop deposit assert_eq!( 50_000 * SCALAR_7, fixture.lp.balance(&fixture.backstop.address) ); + assert_eq!( + 10_000_000 * SCALAR_7, + fixture.tokens[TokenIndex::BLND].balance(&fixture.bombadil) + ); // validate pool actions assert_eq!( diff --git a/test-suites/src/test_fixture.rs b/test-suites/src/test_fixture.rs index 59b9104f..030f71c9 100644 --- a/test-suites/src/test_fixture.rs +++ b/test-suites/src/test_fixture.rs @@ -69,6 +69,7 @@ impl TestFixture<'_> { e.budget().reset_unlimited(); let bombadil = Address::generate(&e); + let frodo = Address::generate(&e); e.ledger().set(LedgerInfo { timestamp: 1441065600, // Sept 1st, 2015 (backstop epoch) @@ -97,7 +98,6 @@ impl TestFixture<'_> { let (lp, lp_client) = create_lp_pool(&e, &bombadil, &blnd_id, &usdc_id); // initialize emitter - blnd_client.mint(&bombadil, &(10_000_000 * SCALAR_7)); blnd_client.set_admin(&emitter_id); emitter_client.initialize(&blnd_id, &backstop_id, &lp); @@ -108,7 +108,11 @@ impl TestFixture<'_> { &usdc_id, &blnd_id, &pool_factory_id, - &Map::new(&e), + &svec![ + &e, + (bombadil.clone(), 10_000_000 * SCALAR_7), + (frodo.clone(), 40_000_000 * SCALAR_7) + ], ); // initialize pool factory @@ -121,6 +125,9 @@ impl TestFixture<'_> { let pool_factory_client = PoolFactoryClient::new(&e, &pool_factory_id); pool_factory_client.initialize(&pool_init_meta); + // drop tokens to bombadil + backstop_client.drop(); + // initialize oracle let (_, mock_oracle_client) = create_mock_oracle(&e); mock_oracle_client.set_data( @@ -147,7 +154,7 @@ impl TestFixture<'_> { let fixture = TestFixture { env: e, bombadil, - users: vec![], + users: vec![frodo], emitter: emitter_client, backstop: backstop_client, pool_factory: pool_factory_client, diff --git a/test-suites/tests/test_backstop.rs b/test-suites/tests/test_backstop.rs index aa465327..a6645396 100644 --- a/test-suites/tests/test_backstop.rs +++ b/test-suites/tests/test_backstop.rs @@ -3,7 +3,7 @@ use soroban_fixed_point_math::FixedPoint; use soroban_sdk::{ testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation, Events}, - vec, Address, IntoVal, Map, Symbol, Val, Vec, + vec, Address, IntoVal, Symbol, Val, Vec, }; use test_suites::{ assertions::assert_approx_eq_abs, @@ -29,7 +29,7 @@ fn test_backstop() { &Address::generate(&fixture.env), &Address::generate(&fixture.env), &Address::generate(&fixture.env), - &Map::new(&fixture.env), + &vec![&fixture.env], ); assert!(result.is_err()); assert_eq!( diff --git a/test-suites/tests/test_emitter.rs b/test-suites/tests/test_emitter.rs index 7b3e8cd4..5ddb90ee 100644 --- a/test-suites/tests/test_emitter.rs +++ b/test-suites/tests/test_emitter.rs @@ -18,24 +18,18 @@ use test_suites::{ fn test_emitter_no_reward_zone() { let mut fixture = TestFixture::create(false); // mint whale tokens - let frodo = Address::generate(&fixture.env); - fixture.users.push(frodo.clone()); + let frodo = fixture.users[0].clone(); fixture.tokens[TokenIndex::STABLE].mint(&frodo, &(100_000 * 10i128.pow(6))); fixture.tokens[TokenIndex::XLM].mint(&frodo, &(1_000_000 * SCALAR_7)); fixture.tokens[TokenIndex::WETH].mint(&frodo, &(100 * 10i128.pow(9))); // mint LP tokens with whale - fixture.tokens[TokenIndex::BLND].mint(&frodo, &(500_0010_000_0000_0000 * SCALAR_7)); - // fixture.tokens[TokenIndex::BLND].approve(&frodo, &fixture.lp.address, &i128::MAX, &99999); - fixture.tokens[TokenIndex::USDC].mint(&frodo, &(12_5010_000_0000_0000 * SCALAR_7)); - // fixture.tokens[TokenIndex::USDC].approve(&frodo, &fixture.lp.address, &i128::MAX, &99999); + // frodo has 40m BLND from drop + fixture.tokens[TokenIndex::BLND].mint(&frodo, &(70_000_000 * SCALAR_7)); + fixture.tokens[TokenIndex::USDC].mint(&frodo, &(2_600_000 * SCALAR_7)); fixture.lp.join_pool( - &(500_000_0000 * SCALAR_7), - &svec![ - &fixture.env, - 500_0010_000_0000_0000 * SCALAR_7, - 12_5010_000_0000_0000 * SCALAR_7, - ], + &(10_000_000 * SCALAR_7), + &svec![&fixture.env, 110_000_000 * SCALAR_7, 2_600_000 * SCALAR_7,], &frodo, ); diff --git a/test-suites/tests/test_wasm_happy_path.rs b/test-suites/tests/test_wasm_happy_path.rs index ad9fc1bc..f1d21203 100644 --- a/test-suites/tests/test_wasm_happy_path.rs +++ b/test-suites/tests/test_wasm_happy_path.rs @@ -391,7 +391,7 @@ fn test_wasm_happy_path() { &vec![&fixture.env, pool_fixture.pool.address.clone()], &frodo, ); - assert_eq!(claim_amount, 420798_0000000); + assert_eq!(claim_amount, 420797_9972539); backstop_blnd_balance -= claim_amount; assert_eq!( fixture.tokens[TokenIndex::BLND].balance(&fixture.backstop.address), @@ -433,8 +433,8 @@ fn test_wasm_happy_path() { &vec![&fixture.env, pool_fixture.pool.address.clone()], &frodo, ); - assert_eq!(claim_amount, 22014719_9998450); //actual amount is 22014720_0000000 but get's rounded down // 22014719_9998450 - backstop_blnd_balance -= 22014719_9998450; + assert_eq!(claim_amount, 22014719_9950114); //actual amount is 22014720_0000000 but get's rounded down + backstop_blnd_balance -= 22014719_9950114; assert_eq!( fixture.tokens[TokenIndex::BLND].balance(&fixture.backstop.address), backstop_blnd_balance