Skip to content

Commit

Permalink
updated emission math
Browse files Browse the repository at this point in the history
  • Loading branch information
markuspluna committed Oct 23, 2023
1 parent f2f905d commit bb7ced7
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 67 deletions.
42 changes: 19 additions & 23 deletions backstop/src/backstop/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -240,7 +236,7 @@ mod tests {
},
];
let mut user = UserBalance {
shares: 1000,
shares: 800,
q4w: cur_q4w.clone(),
};

Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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,
Expand All @@ -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]
Expand Down Expand Up @@ -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,
Expand All @@ -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]
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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,
Expand All @@ -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]
Expand Down Expand Up @@ -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![
Expand Down Expand Up @@ -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);
}
}
23 changes: 16 additions & 7 deletions backstop/src/backstop/withdrawal.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);

Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
42 changes: 21 additions & 21 deletions backstop/src/emissions/claim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,30 +145,30 @@ 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 =
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);
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);
});
}

Expand Down Expand Up @@ -276,30 +276,30 @@ 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 =
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);
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 {
Expand All @@ -318,33 +318,33 @@ 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 =
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, 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);
});
}

Expand Down
Loading

0 comments on commit bb7ced7

Please sign in to comment.