From bb7ced751da48c33adc8a7e293c2bf745cb6120b Mon Sep 17 00:00:00 2001 From: markuspluna <59978114+markuspluna@users.noreply.github.com> Date: Mon, 23 Oct 2023 17:27:58 -0400 Subject: [PATCH 1/3] updated emission math --- backstop/src/backstop/user.rs | 42 +++++++--------- backstop/src/backstop/withdrawal.rs | 23 ++++++--- backstop/src/emissions/claim.rs | 42 ++++++++-------- backstop/src/emissions/distributor.rs | 71 +++++++++++++++++++++++++-- backstop/src/emissions/manager.rs | 8 +-- test-suites/tests/test_backstop.rs | 25 ++++++---- 6 files changed, 144 insertions(+), 67 deletions(-) diff --git a/backstop/src/backstop/user.rs b/backstop/src/backstop/user.rs index 24db4ed9..4f001fe3 100644 --- a/backstop/src/backstop/user.rs +++ b/backstop/src/backstop/user.rs @@ -48,14 +48,10 @@ impl UserBalance { /// ### Errors /// If the amount to queue is greater than the available shares pub fn queue_shares_for_withdrawal(&mut self, e: &Env, to_q: i128) { - let mut q4w_amt: i128 = 0; - for q4w in self.q4w.iter() { - q4w_amt += q4w.amount - } - - if self.shares - q4w_amt < to_q { + if self.shares < to_q { panic_with_error!(e, BackstopError::InvalidBalance); } + self.shares = self.shares - to_q; // user has enough tokens to withdrawal, add Q4W // TODO: Consider capping how many active Q4Ws a user can have @@ -117,14 +113,14 @@ impl UserBalance { /// Withdraw shares from the user /// /// ### Arguments - /// * `to_q` - The amount of new shares to queue for withdraw + /// * `to_dequeue` - The amount of shares to dequeue from withdraw /// /// ### Errors /// If the amount to queue is greater than the available shares - pub fn withdraw_shares(&mut self, e: &Env, to_withdraw: i128) { - self.dequeue_shares_for_withdrawal(e, to_withdraw, true); + pub fn dequeue_withdrawal(&mut self, e: &Env, to_dequeue: i128) { + self.dequeue_shares_for_withdrawal(e, to_dequeue, false); - self.shares -= to_withdraw; + self.shares += to_dequeue; } } @@ -240,7 +236,7 @@ mod tests { }, ]; let mut user = UserBalance { - shares: 1000, + shares: 800, q4w: cur_q4w.clone(), }; @@ -281,7 +277,7 @@ mod tests { }); let to_wd = 1; - user.withdraw_shares(&e, to_wd); + user.dequeue_shares_for_withdrawal(&e, to_wd, false); } #[test] @@ -312,10 +308,10 @@ mod tests { }); let to_wd = 200; - user.withdraw_shares(&e, to_wd); + user.dequeue_shares_for_withdrawal(&e, to_wd, true); assert_eq_vec_q4w(&user.q4w, &vec![&e]); - assert_eq!(user.shares, 800); + assert_eq!(user.shares, 1000); } #[test] @@ -346,7 +342,7 @@ mod tests { }); let to_wd = 150; - user.withdraw_shares(&e, to_wd); + user.dequeue_shares_for_withdrawal(&e, to_wd, false); let expected_q4w = vec![ &e, @@ -356,7 +352,7 @@ mod tests { }, ]; assert_eq_vec_q4w(&user.q4w, &expected_q4w); - assert_eq!(user.shares, 850); + assert_eq!(user.shares, 1000); } #[test] @@ -395,7 +391,7 @@ mod tests { }); let to_wd = 300; - user.withdraw_shares(&e, to_wd); + user.dequeue_shares_for_withdrawal(&e, to_wd, true); let expected_q4w = vec![ &e, @@ -409,7 +405,7 @@ mod tests { }, ]; assert_eq_vec_q4w(&user.q4w, &expected_q4w); - assert_eq!(user.shares, 700); + assert_eq!(user.shares, 1000); } #[test] @@ -449,7 +445,7 @@ mod tests { }); let to_wd = 300; - user.withdraw_shares(&e, to_wd); + user.dequeue_shares_for_withdrawal(&e, to_wd, true); } #[test] @@ -489,7 +485,7 @@ mod tests { let to_dequeue = 300; // verify exp is ignored if only dequeueing - user.dequeue_shares_for_withdrawal(&e, to_dequeue, false); + user.dequeue_withdrawal(&e, to_dequeue); let expected_q4w = vec![ &e, @@ -503,7 +499,7 @@ mod tests { }, ]; assert_eq_vec_q4w(&user.q4w, &expected_q4w); - assert_eq!(user.shares, 1000); + assert_eq!(user.shares, 1300); } #[test] @@ -548,7 +544,7 @@ mod tests { #[test] #[should_panic(expected = "Error(Contract, #2)")] - fn test_try_withdraw_shares_over_total() { + fn test_try_dequeue_shares_over_total() { let e = Env::default(); let cur_q4w = vec![ @@ -583,6 +579,6 @@ mod tests { }); let to_dequeue = 376; - user.dequeue_shares_for_withdrawal(&e, to_dequeue, false); + user.dequeue_withdrawal(&e, to_dequeue); } } diff --git a/backstop/src/backstop/withdrawal.rs b/backstop/src/backstop/withdrawal.rs index ceaa90a8..5bf278e3 100644 --- a/backstop/src/backstop/withdrawal.rs +++ b/backstop/src/backstop/withdrawal.rs @@ -1,4 +1,9 @@ -use crate::{contract::require_nonnegative, dependencies::TokenClient, emissions, storage}; +use crate::{ + contract::require_nonnegative, + dependencies::TokenClient, + emissions::{self}, + storage, +}; use soroban_sdk::{unwrap::UnwrapOptimized, Address, Env}; use super::Q4W; @@ -15,6 +20,9 @@ pub fn execute_queue_withdrawal( let mut pool_balance = storage::get_pool_balance(e, pool_address); let mut user_balance = storage::get_user_balance(e, pool_address, from); + // update emissions + emissions::update_emissions(e, pool_address, &pool_balance, from, &user_balance, false); + user_balance.queue_shares_for_withdrawal(e, amount); pool_balance.queue_for_withdraw(amount); @@ -31,7 +39,10 @@ pub fn execute_dequeue_withdrawal(e: &Env, from: &Address, pool_address: &Addres let mut pool_balance = storage::get_pool_balance(e, pool_address); let mut user_balance = storage::get_user_balance(e, pool_address, from); - user_balance.dequeue_shares_for_withdrawal(e, amount, false); + // update emissions + emissions::update_emissions(e, pool_address, &pool_balance, from, &user_balance, false); + + user_balance.dequeue_withdrawal(e, amount); pool_balance.dequeue_q4w(e, amount); storage::set_user_balance(e, pool_address, from, &user_balance); @@ -45,9 +56,7 @@ pub fn execute_withdraw(e: &Env, from: &Address, pool_address: &Address, amount: let mut pool_balance = storage::get_pool_balance(e, pool_address); let mut user_balance = storage::get_user_balance(e, pool_address, from); - emissions::update_emissions(e, pool_address, &pool_balance, from, &user_balance, false); - - user_balance.withdraw_shares(e, amount); + user_balance.dequeue_shares_for_withdrawal(e, amount, true); let to_return = pool_balance.convert_to_tokens(amount); pool_balance.withdraw(e, to_return, amount); @@ -108,7 +117,7 @@ mod tests { execute_queue_withdrawal(&e, &samwise, &pool_address, 42_0000000); let new_user_balance = storage::get_user_balance(&e, &pool_address, &samwise); - assert_eq!(new_user_balance.shares, 100_0000000); + assert_eq!(new_user_balance.shares, 58_0000000); let expected_q4w = vec![ &e, Q4W { @@ -213,7 +222,7 @@ mod tests { execute_dequeue_withdrawal(&e, &samwise, &pool_address, 30_0000000); let new_user_balance = storage::get_user_balance(&e, &pool_address, &samwise); - assert_eq!(new_user_balance.shares, 75_0000000); + assert_eq!(new_user_balance.shares, 40_0000000); let expected_q4w = vec![ &e, Q4W { diff --git a/backstop/src/emissions/claim.rs b/backstop/src/emissions/claim.rs index b4f940d2..37b056f2 100644 --- a/backstop/src/emissions/claim.rs +++ b/backstop/src/emissions/claim.rs @@ -145,11 +145,11 @@ mod tests { &vec![&e, pool_1_id.clone(), pool_2_id.clone()], &frodo, ); - assert_eq!(result, 75_3145677 + 5_0250000); - assert_eq!(blnd_token_client.balance(&frodo), 75_3145677 + 5_0250000); + assert_eq!(result, 75_3145677 + 6_2904190); + assert_eq!(blnd_token_client.balance(&frodo), 75_3145677 + 6_2904190); assert_eq!( blnd_token_client.balance(&backstop_address), - 100_0000000 - (75_3145677 + 5_0250000) + 100_0000000 - (75_3145677 + 6_2904190) ); let new_backstop_1_data = @@ -157,18 +157,18 @@ mod tests { 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); - assert_eq!(new_backstop_1_data.index, 82322222); + assert_eq!(new_backstop_1_data.index, 83434384); assert_eq!(new_user_1_data.accrued, 0); - assert_eq!(new_user_1_data.index, 82322222); + assert_eq!(new_user_1_data.index, 83434384); 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); - assert_eq!(new_backstop_2_data.index, 6700000); + assert_eq!(new_backstop_2_data.index, 7052631); assert_eq!(new_user_2_data.accrued, 0); - assert_eq!(new_user_2_data.index, 6700000); + assert_eq!(new_user_2_data.index, 7052631); }); } @@ -276,11 +276,11 @@ mod tests { &vec![&e, pool_1_id.clone(), pool_2_id.clone()], &frodo, ); - assert_eq!(result, 75_3145677 + 5_0250000); - assert_eq!(blnd_token_client.balance(&frodo), 75_3145677 + 5_0250000); + assert_eq!(result, 75_3145677 + 6_2904190); + assert_eq!(blnd_token_client.balance(&frodo), 75_3145677 + 6_2904190); assert_eq!( blnd_token_client.balance(&backstop_address), - 200_0000000 - (75_3145677 + 5_0250000) + 200_0000000 - (75_3145677 + 6_2904190) ); let new_backstop_1_data = @@ -288,18 +288,18 @@ mod tests { 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); - assert_eq!(new_backstop_1_data.index, 82322222); + assert_eq!(new_backstop_1_data.index, 83434384); assert_eq!(new_user_1_data.accrued, 0); - assert_eq!(new_user_1_data.index, 82322222); + assert_eq!(new_user_1_data.index, 83434384); 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); - assert_eq!(new_backstop_2_data.index, 6700000); + assert_eq!(new_backstop_2_data.index, 7052631); assert_eq!(new_user_2_data.accrued, 0); - assert_eq!(new_user_2_data.index, 6700000); + assert_eq!(new_user_2_data.index, 7052631); let block_timestamp_1 = 1500000000 + 12345 + 12345; e.ledger().set(LedgerInfo { @@ -318,14 +318,14 @@ mod tests { &vec![&e, pool_1_id.clone(), pool_2_id.clone()], &frodo, ); - assert_eq!(result_1, 1005235710); + assert_eq!(result_1, 1029168100); assert_eq!( blnd_token_client.balance(&frodo), - 75_3145677 + 5_0250000 + 1005235710 + 75_3145677 + 6_2904190 + 1029168100 ); assert_eq!( blnd_token_client.balance(&backstop_address), - 200_0000000 - (75_3145677 + 5_0250000) - (1005235710) + 200_0000000 - (75_3145677 + 6_2904190) - (1029168100) ); let new_backstop_1_data = @@ -333,18 +333,18 @@ mod tests { 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, 164622222); + assert_eq!(new_backstop_1_data.index, 166846546); assert_eq!(new_user_1_data.accrued, 0); - assert_eq!(new_user_1_data.index, 164622222); + assert_eq!(new_user_1_data.index, 166846546); 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, 41971428); + assert_eq!(new_backstop_2_data.index, 44180450); assert_eq!(new_user_2_data.accrued, 0); - assert_eq!(new_user_2_data.index, 41971428); + assert_eq!(new_user_2_data.index, 44180450); }); } diff --git a/backstop/src/emissions/distributor.rs b/backstop/src/emissions/distributor.rs index a7c80f6e..a75674c5 100644 --- a/backstop/src/emissions/distributor.rs +++ b/backstop/src/emissions/distributor.rs @@ -55,7 +55,7 @@ pub fn update_emission_data( }; let additional_idx = (i128(max_timestamp - emis_data.last_time) * i128(emis_config.eps)) - .fixed_div_floor(pool_balance.shares, SCALAR_7) + .fixed_div_floor(pool_balance.shares - pool_balance.q4w, SCALAR_7) .unwrap_optimized(); let new_data = BackstopEmissionsData { index: additional_idx + emis_data.index, @@ -77,8 +77,7 @@ fn update_user_emissions( if user_data.index != emis_data.index || to_claim { let mut accrual = user_data.accrued; if user_balance.shares != 0 { - let to_accrue = user_balance - .shares + let to_accrue = (user_balance.shares) .fixed_mul_floor(emis_data.index - user_data.index, SCALAR_7) .unwrap_optimized(); accrual += to_accrue; @@ -119,7 +118,7 @@ fn set_user_emissions( #[cfg(test)] mod tests { use crate::{ - constants::BACKSTOP_EPOCH, storage::BackstopEmissionConfig, testutils::create_backstop, + constants::BACKSTOP_EPOCH, storage::BackstopEmissionConfig, testutils::create_backstop, Q4W, }; use super::*; @@ -406,4 +405,68 @@ mod tests { assert_eq!(new_user_data.index, 34566000); }); } + #[test] + fn test_update_emissions_q4w_not_counted() { + let e = Env::default(); + let block_timestamp = BACKSTOP_EPOCH + 1234; + e.ledger().set(LedgerInfo { + timestamp: block_timestamp, + protocol_version: 20, + sequence_number: 0, + network_id: Default::default(), + base_reserve: 10, + min_temp_entry_expiration: 10, + min_persistent_entry_expiration: 10, + max_entry_expiration: 2000000, + }); + + let backstop_id = create_backstop(&e); + let pool_1 = Address::random(&e); + let samwise = Address::random(&e); + + let backstop_emissions_config = BackstopEmissionConfig { + expiration: BACKSTOP_EPOCH + 7 * 24 * 60 * 60, + eps: 0_1000000, + }; + let backstop_emissions_data = BackstopEmissionsData { + index: 22222, + last_time: BACKSTOP_EPOCH, + }; + let user_emissions_data = UserEmissionData { + index: 11111, + accrued: 3, + }; + e.as_contract(&backstop_id, || { + storage::set_next_emission_cycle(&e, &(BACKSTOP_EPOCH + 7 * 24 * 60 * 60)); + storage::set_backstop_emis_config(&e, &pool_1, &backstop_emissions_config); + storage::set_backstop_emis_data(&e, &pool_1, &backstop_emissions_data); + storage::set_user_emis_data(&e, &pool_1, &samwise, &user_emissions_data); + + let pool_balance = PoolBalance { + shares: 150_0000000, + tokens: 200_0000000, + q4w: 4_5000000, + }; + let q4w: Q4W = Q4W { + amount: (4_5000000), + exp: (5000), + }; + let user_balance = UserBalance { + shares: 4_5000000, + q4w: vec![&e, q4w], + }; + + let result = + update_emissions(&e, &pool_1, &pool_balance, &samwise, &user_balance, false); + + let new_backstop_data = storage::get_backstop_emis_data(&e, &pool_1).unwrap_optimized(); + let new_user_data = + storage::get_user_emis_data(&e, &pool_1, &samwise).unwrap_optimized(); + assert_eq!(result, 0); + assert_eq!(new_backstop_data.last_time, block_timestamp); + assert_eq!(new_backstop_data.index, 8503321); + assert_eq!(new_user_data.accrued, 38214948); + assert_eq!(new_user_data.index, 8503321); + }); + } } diff --git a/backstop/src/emissions/manager.rs b/backstop/src/emissions/manager.rs index a78f5086..8e8011d4 100644 --- a/backstop/src/emissions/manager.rs +++ b/backstop/src/emissions/manager.rs @@ -75,9 +75,11 @@ pub fn update_emission_cycle(e: &Env) { let mut total_tokens: i128 = 0; for rz_pool_index in 0..rz_len { let rz_pool = reward_zone.get(rz_pool_index).unwrap_optimized(); - let pool_tokens = storage::get_pool_balance(e, &rz_pool).tokens; - rz_tokens.push_back(pool_tokens); - total_tokens += i128(pool_tokens); + let mut pool_balance = storage::get_pool_balance(e, &rz_pool); + let net_deposits = + pool_balance.tokens.clone() - pool_balance.convert_to_tokens(pool_balance.q4w.clone()); + rz_tokens.push_back(net_deposits); + total_tokens += i128(net_deposits); } let blnd_token_client = TokenClient::new(e, &storage::get_blnd_token(e)); diff --git a/test-suites/tests/test_backstop.rs b/test-suites/tests/test_backstop.rs index a6283e07..78311902 100644 --- a/test-suites/tests/test_backstop.rs +++ b/test-suites/tests/test_backstop.rs @@ -434,20 +434,27 @@ fn test_backstop() { } ) ); - let emitted_tokens = (28 * 24 * 60 * 60 - 61 * 60) * SCALAR_7; // 27d22hr59m on emissions to claim - let emission_share = 0_7000000.fixed_mul_floor(0_2000000, SCALAR_7).unwrap(); - let emitted_blnd = emission_share - .fixed_mul_floor(emitted_tokens, SCALAR_7) + //6d23hr at full + //7 days at none + //7 at 6250 + (60 * 60 * 24 * 16 + 1) + let emission_share_1 = 0_7000000.fixed_mul_floor(0_2000000, SCALAR_7).unwrap(); + let emission_share_2 = 0_7000000.fixed_mul_floor(0_1111111, SCALAR_7).unwrap(); + let emitted_blnd_1 = ((7 * 24 * 60 * 60 - 61 * 60) * SCALAR_7) + .fixed_mul_floor(emission_share_1, SCALAR_7) .unwrap(); + let emitted_blnd_2 = ((14 * 24 * 60 * 60 + 1) * SCALAR_7 + 2096022) + .fixed_mul_floor(emission_share_2, SCALAR_7) + .unwrap(); + assert_approx_eq_abs( fixture.tokens[TokenIndex::BLND].balance(&sam), - sam_blnd_balance + emitted_blnd, - 100, + sam_blnd_balance + emitted_blnd_1 + emitted_blnd_2, + SCALAR_7, ); assert_approx_eq_abs( fixture.tokens[TokenIndex::BLND].balance(&fixture.backstop.address), - bstop_blend_balance - emitted_blnd, - 100, + bstop_blend_balance - emitted_blnd_1 - emitted_blnd_2, + SCALAR_7, ); let event = vec![&fixture.env, fixture.env.events().all().last_unchecked()]; assert_eq!( @@ -457,7 +464,7 @@ fn test_backstop() { ( fixture.backstop.address.clone(), (Symbol::new(&fixture.env, "claim"), sam.clone()).into_val(&fixture.env), - emitted_blnd.into_val(&fixture.env), + (emitted_blnd_1 + emitted_blnd_2).into_val(&fixture.env), ) ] ); From 26c9ab1d145b1365e49981a5911738213afee29b Mon Sep 17 00:00:00 2001 From: markuspluna <59978114+markuspluna@users.noreply.github.com> Date: Tue, 24 Oct 2023 13:36:26 -0400 Subject: [PATCH 2/3] removed dequeue_withrawal function and unecessary casts --- backstop/src/backstop/user.rs | 107 ---------------------------- backstop/src/backstop/withdrawal.rs | 3 +- backstop/src/emissions/manager.rs | 4 +- 3 files changed, 4 insertions(+), 110 deletions(-) diff --git a/backstop/src/backstop/user.rs b/backstop/src/backstop/user.rs index 4f001fe3..123cd3ff 100644 --- a/backstop/src/backstop/user.rs +++ b/backstop/src/backstop/user.rs @@ -109,19 +109,6 @@ impl UserBalance { panic_with_error!(e, BackstopError::InvalidBalance); } } - - /// Withdraw shares from the user - /// - /// ### Arguments - /// * `to_dequeue` - The amount of shares to dequeue from withdraw - /// - /// ### Errors - /// If the amount to queue is greater than the available shares - pub fn dequeue_withdrawal(&mut self, e: &Env, to_dequeue: i128) { - self.dequeue_shares_for_withdrawal(e, to_dequeue, false); - - self.shares += to_dequeue; - } } #[cfg(test)] @@ -448,60 +435,6 @@ mod tests { user.dequeue_shares_for_withdrawal(&e, to_wd, true); } - #[test] - fn test_dequeue_shares() { - let e = Env::default(); - - let cur_q4w = vec![ - &e, - Q4W { - amount: 125, - exp: 10000000, - }, - Q4W { - amount: 200, - exp: 12592000, - }, - Q4W { - amount: 50, - exp: 19592000, - }, - ]; - let mut user = UserBalance { - shares: 1000, - q4w: cur_q4w.clone(), - }; - - e.ledger().set(LedgerInfo { - protocol_version: 20, - sequence_number: 1, - timestamp: 11192000, - network_id: Default::default(), - base_reserve: 10, - min_temp_entry_expiration: 10, - min_persistent_entry_expiration: 10, - max_entry_expiration: 2000000, - }); - let to_dequeue = 300; - - // verify exp is ignored if only dequeueing - user.dequeue_withdrawal(&e, to_dequeue); - - let expected_q4w = vec![ - &e, - Q4W { - amount: 25, - exp: 12592000, - }, - Q4W { - amount: 50, - exp: 19592000, - }, - ]; - assert_eq_vec_q4w(&user.q4w, &expected_q4w); - assert_eq!(user.shares, 1300); - } - #[test] #[should_panic(expected = "Error(Contract, #3)")] fn test_try_dequeue_shares_require_expired_expect_panic() { @@ -541,44 +474,4 @@ mod tests { // verify exp is respected when specified user.dequeue_shares_for_withdrawal(&e, to_dequeue, true); } - - #[test] - #[should_panic(expected = "Error(Contract, #2)")] - fn test_try_dequeue_shares_over_total() { - let e = Env::default(); - - let cur_q4w = vec![ - &e, - Q4W { - amount: 125, - exp: 10000000, - }, - Q4W { - amount: 200, - exp: 12592000, - }, - Q4W { - amount: 50, - exp: 19592000, - }, - ]; - let mut user = UserBalance { - shares: 1000, - q4w: cur_q4w.clone(), - }; - - e.ledger().set(LedgerInfo { - protocol_version: 20, - sequence_number: 1, - timestamp: 11192000, - network_id: Default::default(), - base_reserve: 10, - min_temp_entry_expiration: 10, - min_persistent_entry_expiration: 10, - max_entry_expiration: 2000000, - }); - - let to_dequeue = 376; - user.dequeue_withdrawal(&e, to_dequeue); - } } diff --git a/backstop/src/backstop/withdrawal.rs b/backstop/src/backstop/withdrawal.rs index 5bf278e3..bddf32f0 100644 --- a/backstop/src/backstop/withdrawal.rs +++ b/backstop/src/backstop/withdrawal.rs @@ -42,7 +42,8 @@ pub fn execute_dequeue_withdrawal(e: &Env, from: &Address, pool_address: &Addres // update emissions emissions::update_emissions(e, pool_address, &pool_balance, from, &user_balance, false); - user_balance.dequeue_withdrawal(e, amount); + user_balance.dequeue_shares_for_withdrawal(e, amount, false); + user_balance.add_shares(amount); pool_balance.dequeue_q4w(e, amount); storage::set_user_balance(e, pool_address, from, &user_balance); diff --git a/backstop/src/emissions/manager.rs b/backstop/src/emissions/manager.rs index 8e8011d4..6a58d019 100644 --- a/backstop/src/emissions/manager.rs +++ b/backstop/src/emissions/manager.rs @@ -79,14 +79,14 @@ pub fn update_emission_cycle(e: &Env) { let net_deposits = pool_balance.tokens.clone() - pool_balance.convert_to_tokens(pool_balance.q4w.clone()); rz_tokens.push_back(net_deposits); - total_tokens += i128(net_deposits); + total_tokens += net_deposits; } let blnd_token_client = TokenClient::new(e, &storage::get_blnd_token(e)); // store pools EPS and distribute emissions to backstop depositors for rz_pool_index in 0..rz_len { let rz_pool = reward_zone.get(rz_pool_index).unwrap_optimized(); - let cur_pool_tokens = i128(rz_tokens.pop_front_unchecked()); + let cur_pool_tokens = rz_tokens.pop_front_unchecked(); let share = cur_pool_tokens .fixed_div_floor(total_tokens, SCALAR_7) .unwrap_optimized(); From 4db82ff5b22fdff16716a27496500a8589ba4c1a Mon Sep 17 00:00:00 2001 From: markuspluna <59978114+markuspluna@users.noreply.github.com> Date: Wed, 25 Oct 2023 12:46:11 -0400 Subject: [PATCH 3/3] backstop: added back overwithdraw test --- backstop/src/backstop/user.rs | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/backstop/src/backstop/user.rs b/backstop/src/backstop/user.rs index 123cd3ff..28b6488b 100644 --- a/backstop/src/backstop/user.rs +++ b/backstop/src/backstop/user.rs @@ -474,4 +474,43 @@ mod tests { // verify exp is respected when specified user.dequeue_shares_for_withdrawal(&e, to_dequeue, true); } + #[test] + #[should_panic(expected = "Error(Contract, #2)")] + fn test_try_withdraw_shares_over_total() { + let e = Env::default(); + + let cur_q4w = vec![ + &e, + Q4W { + amount: 125, + exp: 10000000, + }, + Q4W { + amount: 200, + exp: 12592000, + }, + Q4W { + amount: 50, + exp: 19592000, + }, + ]; + let mut user = UserBalance { + shares: 1000, + q4w: cur_q4w.clone(), + }; + + e.ledger().set(LedgerInfo { + protocol_version: 20, + sequence_number: 1, + timestamp: 11192000, + network_id: Default::default(), + base_reserve: 10, + min_temp_entry_expiration: 10, + min_persistent_entry_expiration: 10, + max_entry_expiration: 2000000, + }); + + let to_dequeue = 376; + user.dequeue_shares_for_withdrawal(&e, to_dequeue, false); + } }