Skip to content

Commit

Permalink
Merge pull request #153 from blend-capital/emission_cycle_fix
Browse files Browse the repository at this point in the history
Emission cycle fix
  • Loading branch information
mootz12 authored Dec 5, 2023
2 parents a35e981 + 7b13e80 commit f6991ff
Show file tree
Hide file tree
Showing 43 changed files with 2,076 additions and 1,020 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ test: build
cargo test --all --tests

build:
cargo rustc --manifest-path=emitter/Cargo.toml --crate-type=cdylib --target=wasm32-unknown-unknown --release
cargo rustc --manifest-path=pool-factory/Cargo.toml --crate-type=cdylib --target=wasm32-unknown-unknown --release
cargo rustc --manifest-path=backstop/Cargo.toml --crate-type=cdylib --target=wasm32-unknown-unknown --release
cargo rustc --manifest-path=emitter/Cargo.toml --crate-type=cdylib --target=wasm32-unknown-unknown --release
cargo rustc --manifest-path=pool/Cargo.toml --crate-type=cdylib --target=wasm32-unknown-unknown --release
mkdir -p target/wasm32-unknown-unknown/optimized
soroban contract optimize \
Expand Down
1 change: 1 addition & 0 deletions backstop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ sep-41-token = { workspace = true }
[dev_dependencies]
soroban-sdk = { workspace = true, features = ["testutils"] }
mock-pool-factory = { path = "../mocks/mock-pool-factory", features = ["testutils"] }
emitter = { path = "../emitter", features = ["testutils"] }
sep-41-token = { workspace = true, features = ["testutils"] }
36 changes: 35 additions & 1 deletion backstop/src/backstop/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ use crate::{contract::require_nonnegative, emissions, storage};
use sep_41_token::TokenClient;
use soroban_sdk::{Address, Env};

use super::require_is_from_pool_factory;

/// Perform a deposit into the backstop module
pub fn execute_deposit(e: &Env, from: &Address, pool_address: &Address, amount: i128) -> i128 {
require_nonnegative(e, amount);
let mut pool_balance = storage::get_pool_balance(e, pool_address);
require_is_from_pool_factory(e, pool_address, pool_balance.shares);
let mut user_balance = storage::get_user_balance(e, pool_address, from);

emissions::update_emissions(e, pool_address, &pool_balance, from, &user_balance, false);
Expand All @@ -29,7 +32,7 @@ mod tests {

use crate::{
backstop::execute_donate,
testutils::{create_backstop, create_backstop_token},
testutils::{create_backstop, create_backstop_token, create_mock_pool_factory},
};

use super::*;
Expand All @@ -51,6 +54,10 @@ mod tests {
backstop_token_client.mint(&samwise, &100_0000000);
backstop_token_client.mint(&frodo, &100_0000000);

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

// initialize pool 0 with funds + some profit
e.as_contract(&backstop_address, || {
execute_deposit(&e, &frodo, &pool_0_id, 25_0000000);
Expand Down Expand Up @@ -101,6 +108,9 @@ mod tests {
let (_, backstop_token_client) = create_backstop_token(&e, &backstop_address, &bombadil);
backstop_token_client.mint(&samwise, &100_0000000);

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

e.as_contract(&backstop_address, || {
execute_deposit(&e, &samwise, &pool_0_id, 100_0000001);

Expand All @@ -123,8 +133,32 @@ mod tests {
let (_, backstop_token_client) = create_backstop_token(&e, &backstop_address, &bombadil);
backstop_token_client.mint(&samwise, &100_0000000);

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

e.as_contract(&backstop_address, || {
execute_deposit(&e, &samwise, &pool_0_id, -100);
});
}

#[test]
#[should_panic(expected = "Error(Contract, #10)")]
fn text_execute_deposit_not_pool() {
let e = Env::default();
e.mock_all_auths_allowing_non_root_auth();

let backstop_address = create_backstop(&e);
let pool_0_id = Address::random(&e);
let bombadil = Address::random(&e);
let samwise = Address::random(&e);

let (_, backstop_token_client) = create_backstop_token(&e, &backstop_address, &bombadil);
backstop_token_client.mint(&samwise, &100_0000000);

create_mock_pool_factory(&e, &backstop_address);

e.as_contract(&backstop_address, || {
execute_deposit(&e, &samwise, &pool_0_id, 100);
});
}
}
95 changes: 65 additions & 30 deletions backstop/src/backstop/fund_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use super::require_is_from_pool_factory;
/// Perform a draw from a pool's backstop
pub fn execute_draw(e: &Env, pool_address: &Address, amount: i128, to: &Address) {
require_nonnegative(e, amount);
require_is_from_pool_factory(e, pool_address);

let mut pool_balance = storage::get_pool_balance(e, pool_address);

Expand All @@ -25,10 +24,12 @@ pub fn execute_draw(e: &Env, pool_address: &Address, amount: i128, to: &Address)
pub fn execute_donate(e: &Env, from: &Address, pool_address: &Address, amount: i128) {
require_nonnegative(e, amount);

let mut pool_balance = storage::get_pool_balance(e, pool_address);
require_is_from_pool_factory(e, pool_address, pool_balance.shares);

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

let mut pool_balance = storage::get_pool_balance(e, pool_address);
pool_balance.deposit(amount, 0);
storage::set_pool_balance(e, pool_address, &pool_balance);
}
Expand All @@ -37,10 +38,12 @@ pub fn execute_donate(e: &Env, from: &Address, pool_address: &Address, amount: i
pub fn execute_donate_usdc(e: &Env, from: &Address, pool_address: &Address, amount: i128) {
require_nonnegative(e, amount);

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);

let mut pool_usdc = storage::get_pool_usdc(e, pool_address);
pool_usdc += amount;
storage::set_pool_usdc(e, pool_address, &pool_usdc);
}
Expand Down Expand Up @@ -122,6 +125,9 @@ mod tests {
backstop_token_client.mint(&samwise, &100_0000000);
backstop_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);

// initialize pool 0 with funds
e.as_contract(&backstop_id, || {
execute_deposit(&e, &frodo, &pool_0_id, 25_0000000);
Expand Down Expand Up @@ -153,6 +159,9 @@ mod tests {
backstop_token_client.mint(&samwise, &100_0000000);
backstop_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);

// initialize pool 0 with funds
e.as_contract(&backstop_id, || {
execute_deposit(&e, &frodo, &pool_0_id, 25_0000000);
Expand All @@ -164,66 +173,60 @@ mod tests {
}

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

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

let (_, backstop_token_client) = create_backstop_token(&e, &backstop_address, &bombadil);
let (_, backstop_token_client) = create_backstop_token(&e, &backstop_id, &bombadil);
backstop_token_client.mint(&samwise, &100_0000000);
backstop_token_client.mint(&frodo, &100_0000000);

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

// initialize pool 0 with funds
e.as_contract(&backstop_address, || {
execute_deposit(&e, &frodo, &pool_0_id, 50_0000000);
});
create_mock_pool_factory(&e, &backstop_id);

e.as_contract(&backstop_address, || {
execute_draw(&e, &pool_0_id, 30_0000000, &samwise);

let new_pool_balance = storage::get_pool_balance(&e, &pool_0_id);
assert_eq!(new_pool_balance.shares, 50_0000000);
assert_eq!(new_pool_balance.tokens, 20_0000000);
assert_eq!(backstop_token_client.balance(&backstop_address), 20_0000000);
assert_eq!(backstop_token_client.balance(&samwise), 30_0000000);
e.as_contract(&backstop_id, || {
execute_donate(&e, &samwise, &pool_0_id, 30_0000000);
});
}

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

let backstop_id = create_backstop(&e);
let backstop_address = create_backstop(&e);
let pool_0_id = Address::random(&e);
let pool_bad_id = Address::random(&e);
let bombadil = Address::random(&e);
let samwise = Address::random(&e);
let frodo = Address::random(&e);

let (_, backstop_token_client) = create_backstop_token(&e, &backstop_id, &bombadil);
let (_, backstop_token_client) = create_backstop_token(&e, &backstop_address, &bombadil);
backstop_token_client.mint(&frodo, &100_0000000);

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

// initialize pool 0 with funds
e.as_contract(&backstop_id, || {
e.as_contract(&backstop_address, || {
execute_deposit(&e, &frodo, &pool_0_id, 50_0000000);
});

e.as_contract(&backstop_id, || {
execute_draw(&e, &pool_bad_id, 30_0000000, &samwise);
e.as_contract(&backstop_address, || {
execute_draw(&e, &pool_0_id, 30_0000000, &samwise);

let new_pool_balance = storage::get_pool_balance(&e, &pool_0_id);
assert_eq!(new_pool_balance.shares, 50_0000000);
assert_eq!(new_pool_balance.tokens, 20_0000000);
assert_eq!(backstop_token_client.balance(&backstop_address), 20_0000000);
assert_eq!(backstop_token_client.balance(&samwise), 30_0000000);
});
}

Expand All @@ -246,6 +249,7 @@ mod tests {

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

// initialize pool 0 with funds
e.as_contract(&backstop_id, || {
Expand Down Expand Up @@ -303,6 +307,9 @@ mod tests {
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);
Expand Down Expand Up @@ -333,11 +340,36 @@ mod tests {
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, #10)")]
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::random(&e);
let bombadil = Address::random(&e);
let samwise = Address::random(&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();
Expand All @@ -355,6 +387,9 @@ mod tests {
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);

Expand Down
3 changes: 2 additions & 1 deletion backstop/src/backstop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ pub use withdrawal::{execute_dequeue_withdrawal, execute_queue_withdrawal, execu

mod pool;
pub use pool::{
load_pool_backstop_data, require_is_from_pool_factory, PoolBackstopData, PoolBalance,
load_pool_backstop_data, require_is_from_pool_factory, require_pool_above_threshold,
PoolBackstopData, PoolBalance,
};

mod user;
Expand Down
Loading

0 comments on commit f6991ff

Please sign in to comment.