Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored interest auction to use backstop token donations #188

Merged
merged 3 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 0 additions & 212 deletions backstop/src/backstop/fund_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,6 @@ pub fn execute_donate(e: &Env, from: &Address, pool_address: &Address, amount: i
storage::set_pool_balance(e, pool_address, &pool_balance);
}

/// Perform a donation of USDC to a pool's backstop
pub fn execute_donate_usdc(e: &Env, from: &Address, pool_address: &Address, amount: i128) {
require_nonnegative(e, amount);
if from == pool_address || from == &e.current_contract_address() {
panic_with_error!(e, &BackstopError::BadRequest)
}

let mut pool_usdc = storage::get_pool_usdc(e, pool_address);
require_is_from_pool_factory(e, pool_address, pool_usdc);

let usdc_token = TokenClient::new(e, &storage::get_usdc_token(e));
usdc_token.transfer(from, &e.current_contract_address(), &amount);

pool_usdc += amount;
storage::set_pool_usdc(e, pool_address, &pool_usdc);
}

/// Perform a mint of backstop LP tokens with USDC and deposit the LP tokens to the pool
pub fn execute_gulp_usdc(e: &Env, pool_address: &Address) {
let pool_usdc = storage::get_pool_usdc(e, pool_address);
if pool_usdc != 0 {
// mint LP tokens with USDC
let backstop_token = storage::get_backstop_token(e);
let usdc_token = storage::get_usdc_token(e);
let lp_tokens_minted = CometClient::new(e, &backstop_token)
.dep_tokn_amt_in_get_lp_tokns_out(
&usdc_token,
&pool_usdc,
&0,
&e.current_contract_address(),
);

// attribute shares to the pool's backstop
let mut pool_balance = storage::get_pool_balance(e, pool_address);
pool_balance.deposit(lp_tokens_minted, 0);
storage::set_pool_balance(e, pool_address, &pool_balance);
storage::set_pool_usdc(e, pool_address, &0);
}
}

/// Perform an update to the Comet LP token underlying value
pub fn execute_update_comet_token_value(
e: &Env,
Expand Down Expand Up @@ -358,178 +318,6 @@ mod tests {
});
}

#[test]
fn test_execute_donate_usdc() {
let e = Env::default();
e.mock_all_auths_allowing_non_root_auth();
e.budget().reset_unlimited();

let backstop_id = create_backstop(&e);
let pool_0_id = Address::generate(&e);
let bombadil = Address::generate(&e);
let samwise = Address::generate(&e);
let frodo = Address::generate(&e);

let (_, usdc_token_client) = create_usdc_token(&e, &backstop_id, &bombadil);
usdc_token_client.mint(&samwise, &100_0000000);
usdc_token_client.mint(&frodo, &100_0000000);

let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_id);
mock_pool_factory_client.set_pool(&pool_0_id);

e.as_contract(&backstop_id, || {
execute_donate_usdc(&e, &samwise, &pool_0_id, 30_0000000);
let new_pool_usdc = storage::get_pool_usdc(&e, &pool_0_id);
assert_eq!(new_pool_usdc, 30_0000000);
assert_eq!(usdc_token_client.balance(&samwise), 70_0000000);
assert_eq!(usdc_token_client.balance(&backstop_id), 30_0000000);

execute_donate_usdc(&e, &frodo, &pool_0_id, 10_0000000);
let new_pool_usdc = storage::get_pool_usdc(&e, &pool_0_id);
assert_eq!(new_pool_usdc, 40_0000000);
assert_eq!(usdc_token_client.balance(&frodo), 90_0000000);
assert_eq!(usdc_token_client.balance(&backstop_id), 40_0000000);
});
}

#[test]
#[should_panic(expected = "Error(Contract, #8)")]
fn test_execute_donate_usdc_negative_amount() {
let e = Env::default();
e.mock_all_auths_allowing_non_root_auth();
e.budget().reset_unlimited();

let backstop_id = create_backstop(&e);
let pool_0_id = Address::generate(&e);
let bombadil = Address::generate(&e);
let samwise = Address::generate(&e);

let (_, usdc_token_client) = create_usdc_token(&e, &backstop_id, &bombadil);
usdc_token_client.mint(&samwise, &100_0000000);

let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_id);
mock_pool_factory_client.set_pool(&pool_0_id);

e.as_contract(&backstop_id, || {
execute_donate_usdc(&e, &samwise, &pool_0_id, -30_0000000);
});
}

#[test]
#[should_panic(expected = "Error(Contract, #1000)")]
fn test_execute_donate_usdc_from_is_to() {
let e = Env::default();
e.mock_all_auths_allowing_non_root_auth();
e.budget().reset_unlimited();

let backstop_id = create_backstop(&e);
let pool_0_id = Address::generate(&e);
let bombadil = Address::generate(&e);
let samwise = Address::generate(&e);

let (_, usdc_token_client) = create_usdc_token(&e, &backstop_id, &bombadil);
usdc_token_client.mint(&samwise, &100_0000000);

let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_id);
mock_pool_factory_client.set_pool(&pool_0_id);

e.as_contract(&backstop_id, || {
execute_donate_usdc(&e, &pool_0_id, &pool_0_id, 10_0000000);
});
}

#[test]
#[should_panic(expected = "Error(Contract, #1000)")]
fn test_execute_donate_usdc_from_is_self() {
let e = Env::default();
e.mock_all_auths_allowing_non_root_auth();
e.budget().reset_unlimited();

let backstop_id = create_backstop(&e);
let pool_0_id = Address::generate(&e);
let bombadil = Address::generate(&e);
let samwise = Address::generate(&e);

let (_, usdc_token_client) = create_usdc_token(&e, &backstop_id, &bombadil);
usdc_token_client.mint(&samwise, &100_0000000);

let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_id);
mock_pool_factory_client.set_pool(&pool_0_id);

e.as_contract(&backstop_id, || {
execute_donate_usdc(&e, &backstop_id, &pool_0_id, 10_0000000);
});
}

#[test]
#[should_panic(expected = "Error(Contract, #1004)")]
fn test_execute_donate_usdc_not_pool() {
let e = Env::default();
e.mock_all_auths_allowing_non_root_auth();
e.budget().reset_unlimited();

let backstop_id = create_backstop(&e);
let pool_0_id = Address::generate(&e);
let bombadil = Address::generate(&e);
let samwise = Address::generate(&e);

let (_, usdc_token_client) = create_usdc_token(&e, &backstop_id, &bombadil);
usdc_token_client.mint(&samwise, &100_0000000);

create_mock_pool_factory(&e, &backstop_id);

e.as_contract(&backstop_id, || {
execute_donate_usdc(&e, &samwise, &pool_0_id, 30_0000000);
});
}

#[test]
fn test_execute_gulp_usdc() {
let e = Env::default();
e.mock_all_auths_allowing_non_root_auth();
e.budget().reset_unlimited();

let backstop_id = create_backstop(&e);
let pool_0_id = Address::generate(&e);
let bombadil = Address::generate(&e);
let samwise = Address::generate(&e);

let (usdc_token, usdc_token_client) = create_usdc_token(&e, &backstop_id, &bombadil);
usdc_token_client.mint(&samwise, &100_0000000);

let (blnd_token, blnd_token_client) = create_blnd_token(&e, &backstop_id, &bombadil);
blnd_token_client.mint(&samwise, &100_0000000);

let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_id);
mock_pool_factory_client.set_pool(&pool_0_id);

let (comet_id, comet_client) =
create_comet_lp_pool(&e, &bombadil, &blnd_token, &usdc_token);

// initialize pool 0 with funds and a donation
e.as_contract(&backstop_id, || {
storage::set_backstop_token(&e, &comet_id);
execute_deposit(&e, &bombadil, &pool_0_id, 10_0000000);
execute_donate_usdc(&e, &samwise, &pool_0_id, 5_0000000);
usdc_token_client.approve(&e.current_contract_address(), &comet_id, &i128::MAX, &500);
});

e.as_contract(&backstop_id, || {
execute_gulp_usdc(&e, &pool_0_id);

let new_pool_usdc = storage::get_pool_usdc(&e, &pool_0_id);
assert_eq!(new_pool_usdc, 0);
assert_eq!(usdc_token_client.balance(&backstop_id), 0);

let new_pool_balance = storage::get_pool_balance(&e, &pool_0_id);
assert_eq!(new_pool_balance.shares, 10_0000000);
assert_eq!(new_pool_balance.tokens, 13_9904000);

let comet_balance = comet_client.balance(&backstop_id);
assert_eq!(comet_balance, 13_9904000);
});
}

#[test]
fn test_execute_update_comet_token_value() {
let e = Env::default();
Expand Down
5 changes: 1 addition & 4 deletions backstop/src/backstop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ mod deposit;
pub use deposit::execute_deposit;

mod fund_management;
pub use fund_management::{
execute_donate, execute_donate_usdc, execute_draw, execute_gulp_usdc,
execute_update_comet_token_value,
};
pub use fund_management::{execute_donate, execute_draw, execute_update_comet_token_value};

mod withdrawal;
pub use withdrawal::{execute_dequeue_withdrawal, execute_queue_withdrawal, execute_withdraw};
Expand Down
39 changes: 0 additions & 39 deletions backstop/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,28 +160,6 @@ pub trait Backstop {
/// If the `pool_address` is not valid
fn donate(e: Env, from: Address, pool_address: Address, amount: i128);

/// Sends USDC from "from" to a pools backstop to be queued for donation
///
/// NOTE: This is not a deposit, and "from" will permanently lose access to the funds
///
/// ### Arguments
/// * `from` - tge
/// * `pool_address` - The address of the pool
/// * `amount` - The amount of BLND to add
///
/// ### Errors
/// If the `pool_address` is not valid
fn donate_usdc(e: Env, from: Address, pool_address: Address, amount: i128);

/// Consume donated USDC for a pool and mint LP tokens into the pool's backstop
///
/// ### Arguments
/// * `pool_address` - The address of the pool
///
/// ### Errors
/// If the `pool_address` is not valid
fn gulp_usdc(e: Env, pool_address: Address);

/// Updates the underlying value of 1 backstop token
///
/// ### Returns
Expand Down Expand Up @@ -352,23 +330,6 @@ impl Backstop for BackstopContract {
.publish((Symbol::new(&e, "donate"), pool_address, from), amount);
}

fn donate_usdc(e: Env, from: Address, pool_address: Address, amount: i128) {
storage::extend_instance(&e);
from.require_auth();

backstop::execute_donate_usdc(&e, &from, &pool_address, amount);
e.events()
.publish((Symbol::new(&e, "donate_usdc"), pool_address, from), amount);
}

fn gulp_usdc(e: Env, pool_address: Address) {
storage::extend_instance(&e);

backstop::execute_gulp_usdc(&e, &pool_address);
e.events()
.publish((Symbol::new(&e, "gulp_usdc"), pool_address), ());
}

fn update_tkn_val(e: Env) -> (i128, i128) {
storage::extend_instance(&e);

Expand Down
5 changes: 3 additions & 2 deletions backstop/src/emissions/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ pub fn gulp_emissions(e: &Env) -> i128 {
.fixed_div_floor(total_non_queued_tokens, SCALAR_7)
.unwrap_optimized();

// store pool EPS and distribute pool's emissions via allowances to pool
// store new emissions for pool
let new_pool_emissions = share
.fixed_mul_floor(total_pool_emissions, SCALAR_7)
.unwrap_optimized();
let current_emissions = storage::get_pool_emissions(e, &rz_pool);
storage::set_pool_emissions(e, &rz_pool, current_emissions + new_pool_emissions);

// distribute backstop depositor emissions
// distribute backstop depositor emissions and store backstop EPS
let new_pool_backstop_tokens = share
.fixed_mul_floor(total_backstop_emissions, SCALAR_7)
.unwrap_optimized();
Expand All @@ -128,6 +128,7 @@ pub fn gulp_pool_emissions(e: &Env, pool_id: &Address) -> i128 {
panic_with_error!(e, BackstopError::BadRequest);
}

// distribute pool emissions via allowance to pools
let blnd_token_client = TokenClient::new(e, &storage::get_blnd_token(e));
let current_allowance = blnd_token_client.allowance(&e.current_contract_address(), pool_id);
let new_tokens = current_allowance + pool_emissions;
Expand Down
24 changes: 0 additions & 24 deletions backstop/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,30 +278,6 @@ pub fn set_pool_balance(e: &Env, pool: &Address, balance: &PoolBalance) {
.extend_ttl(&key, LEDGER_THRESHOLD_SHARED, LEDGER_BUMP_SHARED);
}

/// Fetch the balances for a given pool
///
/// ### Arguments
/// * `pool` - The pool the deposit is associated with
pub fn get_pool_usdc(e: &Env, pool: &Address) -> i128 {
let key = BackstopDataKey::PoolUSDC(pool.clone());
get_persistent_default(e, &key, 0i128, LEDGER_THRESHOLD_SHARED, LEDGER_BUMP_SHARED)
}

/// Set the balances for a pool
///
/// ### Arguments
/// * `pool` - The pool the deposit is associated with
/// * `balance` - The pool balances
pub fn set_pool_usdc(e: &Env, pool: &Address, balance: &i128) {
let key = BackstopDataKey::PoolUSDC(pool.clone());
e.storage()
.persistent()
.set::<BackstopDataKey, i128>(&key, balance);
e.storage()
.persistent()
.extend_ttl(&key, LEDGER_THRESHOLD_SHARED, LEDGER_BUMP_SHARED);
}

/********** Distribution / Reward Zone **********/

/// Get the timestamp of when the next emission cycle begins
Expand Down
Loading
Loading