Skip to content

Commit

Permalink
Merge pull request #215 from blend-capital/no-rzon-bug-fix
Browse files Browse the repository at this point in the history
fixed bug updated test
  • Loading branch information
mootz12 authored Mar 27, 2024
2 parents 5b53189 + 7b6d8f6 commit 60be9d2
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 14 deletions.
8 changes: 6 additions & 2 deletions backstop/src/emissions/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ pub fn add_to_reward_zone(e: &Env, to_add: Address, to_remove: Address) {
/// Assign emissions from the Emitter to backstops and pools in the reward zone
#[allow(clippy::zero_prefixed_literal)]
pub fn gulp_emissions(e: &Env) -> i128 {
let reward_zone = storage::get_reward_zone(e);
let rz_len = reward_zone.len();
// reward zone must have at least one pool for emissions to start
if rz_len == 0 {
panic_with_error!(e, BackstopError::BadRequest);
}
let emitter = storage::get_emitter(e);
let emitter_last_distribution =
EmitterClient::new(&e, &emitter).get_last_distro(&e.current_contract_address());
Expand All @@ -81,8 +87,6 @@ pub fn gulp_emissions(e: &Env) -> i128 {
.fixed_mul_floor(0_3000000, SCALAR_7)
.unwrap_optimized();

let reward_zone = storage::get_reward_zone(e);
let rz_len = reward_zone.len();
let mut rz_balance: Vec<PoolBalance> = vec![e];

// TODO: Potential to assume optimization of backstop token balances ~= RZ tokens
Expand Down
174 changes: 162 additions & 12 deletions test-suites/tests/test_emitter.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,165 @@
#![cfg(test)]

use emitter::Swap;
use pool::{Request, RequestType, ReserveEmissionMetadata};
use soroban_sdk::{
testutils::{Address as _, Events},
vec, Address, IntoVal, Symbol,
vec as svec, Address, IntoVal, Symbol, Vec as SVec,
};
use test_suites::{
create_fixture_with_data,
test_fixture::{TokenIndex, SCALAR_7},
pool::default_reserve_metadata,
test_fixture::{TestFixture, TokenIndex, SCALAR_7},
};

/// Test user exposed functions on the emitter for basic functionality, auth, and events.
/// Does not test internal state management of the emitter, only external effects.
#[test]
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());
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);
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,
],
&frodo,
);

// create pool
fixture.create_pool(Symbol::new(&fixture.env, "Teapot"), 0_1000000, 6);

let mut stable_config = default_reserve_metadata();
stable_config.decimals = 6;
stable_config.c_factor = 0_900_0000;
stable_config.l_factor = 0_950_0000;
stable_config.util = 0_850_0000;
fixture.create_pool_reserve(0, TokenIndex::STABLE, &stable_config);

let mut xlm_config = default_reserve_metadata();
xlm_config.c_factor = 0_750_0000;
xlm_config.l_factor = 0_750_0000;
xlm_config.util = 0_500_0000;
fixture.create_pool_reserve(0, TokenIndex::XLM, &xlm_config);

let mut weth_config = default_reserve_metadata();
weth_config.decimals = 9;
weth_config.c_factor = 0_800_0000;
weth_config.l_factor = 0_800_0000;
weth_config.util = 0_700_0000;
fixture.create_pool_reserve(0, TokenIndex::WETH, &weth_config);

// enable emissions for pool
let pool_fixture = &fixture.pools[0];

let reserve_emissions: soroban_sdk::Vec<ReserveEmissionMetadata> = soroban_sdk::vec![
&fixture.env,
ReserveEmissionMetadata {
res_index: 1, // XLM
res_type: 1, // b_token
share: 1_000_0000
},
];
pool_fixture.pool.set_emissions_config(&reserve_emissions);
assert_eq!(
0,
fixture.tokens[TokenIndex::BLND].balance(&fixture.backstop.address)
);

fixture.env.budget().reset_unlimited();
let frodo = &fixture.users[0];
let pool_fixture = &fixture.pools[0];
let blnd_token = &fixture.tokens[TokenIndex::BLND];
blnd_token.balance(&fixture.emitter.address);
blnd_token.balance(&fixture.backstop.address);

// Allow 6 days to pass and call distribute
assert_eq!(blnd_token.balance(&fixture.backstop.address), 0);
fixture.jump(6 * 24 * 60 * 60);
let result = fixture.emitter.distribute();
assert_eq!(result, (13 * 24 * 60 * 60) * SCALAR_7); // 1 token per second are emitted
let result = fixture.backstop.try_gulp_emissions();
assert!(result.is_err());

assert_eq!(fixture.env.auths().len(), 0);
assert_eq!(
blnd_token.balance(&fixture.backstop.address),
(13 * 24 * 60 * 60) * SCALAR_7
); // 1 token per second are emitted
assert_eq!(fixture.env.auths().len(), 0);
// Validate Emissions can't be claimed
let result = pool_fixture.pool.claim(
&fixture.users[0],
&svec![&fixture.env, 0, 1, 2, 3],
&fixture.users[0],
);
assert!(result == 0);
let result = fixture.backstop.claim(
&fixture.users[0],
&svec![&fixture.env, pool_fixture.pool.address.clone()],
&fixture.users[0],
);
assert!(result == 0);

fixture.backstop.deposit(
&fixture.users[0],
&pool_fixture.pool.address,
&(50_000 * SCALAR_7),
);
fixture.backstop.update_tkn_val();
pool_fixture.pool.set_status(&3);
pool_fixture.pool.update_status();

let requests: SVec<Request> = svec![
&fixture.env,
Request {
request_type: RequestType::SupplyCollateral as u32,
address: fixture.tokens[TokenIndex::XLM].address.clone(),
amount: 100_000 * SCALAR_7,
},
];
pool_fixture.pool.submit(&frodo, &frodo, &frodo, &requests);

fixture
.backstop
.add_reward(&pool_fixture.pool.address, &Address::generate(&fixture.env));
fixture.backstop.gulp_emissions();

let result = pool_fixture.pool.gulp_emissions();
assert_eq!(result, (13 * 24 * 60 * 60) * 300_0000);
// Let some time go by
fixture.jump(7 * 24 * 60 * 60);
let pre_claim_balance = blnd_token.balance(&fixture.users[0]);
let result = pool_fixture.pool.claim(
&fixture.users[0],
&svec![&fixture.env, 0, 1, 2, 3,],
&fixture.users[0],
);
let post_claim_1_balance = blnd_token.balance(&fixture.users[0]);
assert_eq!(post_claim_1_balance - pre_claim_balance, result);
assert_eq!(result, (13 * 24 * 60 * 60) * 300_0000 - 400000); //pool claim is only 30% of the total emissions - subtracting 400000 for rounding
let result_1 = fixture.backstop.claim(
&fixture.users[0],
&svec![&fixture.env, pool_fixture.pool.address.clone()],
&fixture.users[0],
);
assert_eq!(result_1, (13 * 24 * 60 * 60) * 700_0000);
assert_eq!(result_1 + result, (13 * 24 * 60 * 60) * SCALAR_7 - 400000);
}

/// Test user exposed functions on the emitter for basic functionality, auth, and events.
/// Does not test internal state management of the emitter, only external effects.
#[test]
Expand Down Expand Up @@ -49,15 +199,15 @@ fn test_emitter() {
blnd_token.balance(&fixture.backstop.address),
backstop_blnd_balance
);
let event = vec![&fixture.env, fixture.env.events().all().last_unchecked()];
let event = svec![&fixture.env, fixture.env.events().all().last_unchecked()];
assert_eq!(
event,
vec![
svec![
&fixture.env,
(
fixture.emitter.address.clone(),
(Symbol::new(&fixture.env, "distribute"),).into_val(&fixture.env),
vec![
svec![
&fixture.env,
fixture.backstop.address.to_val(),
result.into_val(&fixture.env)
Expand All @@ -74,7 +224,7 @@ fn test_emitter() {
fixture.tokens[TokenIndex::USDC].mint(&new_backstop, &(20_501 * SCALAR_7));
fixture.lp.join_pool(
&(old_backstop_balance + 1),
&vec![&fixture.env, 505_001 * SCALAR_7, 13_501 * SCALAR_7],
&svec![&fixture.env, 505_001 * SCALAR_7, 13_501 * SCALAR_7],
&new_backstop,
);
fixture
Expand All @@ -86,10 +236,10 @@ fn test_emitter() {
fixture.emitter.get_backstop(),
fixture.backstop.address.clone()
);
let event = vec![&fixture.env, fixture.env.events().all().last_unchecked()];
let event = svec![&fixture.env, fixture.env.events().all().last_unchecked()];
assert_eq!(
event,
vec![
svec![
&fixture.env,
(
fixture.emitter.address.clone(),
Expand All @@ -115,10 +265,10 @@ fn test_emitter() {
fixture.emitter.get_backstop(),
fixture.backstop.address.clone()
);
let event = vec![&fixture.env, fixture.env.events().all().last_unchecked()];
let event = svec![&fixture.env, fixture.env.events().all().last_unchecked()];
assert_eq!(
event,
vec![
svec![
&fixture.env,
(
fixture.emitter.address.clone(),
Expand All @@ -141,10 +291,10 @@ fn test_emitter() {
let swap_unlock_time = fixture.env.ledger().timestamp() + 31 * 24 * 60 * 60;
fixture.jump(swap_unlock_time + 1);
fixture.emitter.swap_backstop();
let event = vec![&fixture.env, fixture.env.events().all().last_unchecked()];
let event = svec![&fixture.env, fixture.env.events().all().last_unchecked()];
assert_eq!(
event,
vec![
svec![
&fixture.env,
(
fixture.emitter.address.clone(),
Expand Down

0 comments on commit 60be9d2

Please sign in to comment.