Skip to content

Commit

Permalink
Merge pull request #181 from blend-capital/reactivity-constant
Browse files Browse the repository at this point in the history
pool: fix: update reactivity constant bounds
  • Loading branch information
mootz12 authored Jan 4, 2024
2 parents b477957 + 07a1237 commit 8a454ab
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 46 deletions.
4 changes: 3 additions & 1 deletion backstop/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ impl Backstop for BackstopContract {
drop_list: Map<Address, i128>,
) {
storage::extend_instance(&e);
if storage::has_backstop_token(&e) {
if storage::get_is_init(&e) {
panic_with_error!(e, BackstopError::AlreadyInitialized);
}

Expand All @@ -224,6 +224,8 @@ impl Backstop for BackstopContract {
let last_distribution_time =
EmitterClient::new(&e, &emitter).get_last_distro(&e.current_contract_address());
storage::set_last_distribution_time(&e, &last_distribution_time);

storage::set_is_init(&e);
}

/********** Core **********/
Expand Down
22 changes: 14 additions & 8 deletions backstop/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pub struct UserEmissionData {

/********** Storage Key Types **********/

const IS_INIT_KEY: &str = "IsInit";
const EMITTER_KEY: &str = "Emitter";
const BACKSTOP_TOKEN_KEY: &str = "BToken";
const POOL_FACTORY_KEY: &str = "PoolFact";
Expand Down Expand Up @@ -97,7 +98,19 @@ fn get_persistent_default<K: IntoVal<Env, Val>, V: TryFromVal<Env, Val>>(
}
}

/********** External Contracts **********/
/********** Instance Storage **********/

/// Check if the contract has been initialized
pub fn get_is_init(e: &Env) -> bool {
e.storage().instance().has(&Symbol::new(e, IS_INIT_KEY))
}

/// Set the contract as initialized
pub fn set_is_init(e: &Env) {
e.storage()
.instance()
.set::<Symbol, bool>(&Symbol::new(e, IS_INIT_KEY), &true);
}

/// Fetch the pool factory id
pub fn get_emitter(e: &Env) -> Address {
Expand Down Expand Up @@ -179,13 +192,6 @@ pub fn get_backstop_token(e: &Env) -> Address {
.unwrap_optimized()
}

/// Checks if a backstop token is set for the backstop
pub fn has_backstop_token(e: &Env) -> bool {
e.storage()
.instance()
.has(&Symbol::new(e, BACKSTOP_TOKEN_KEY))
}

/// Set the backstop token id
///
/// ### Arguments
Expand Down
4 changes: 3 additions & 1 deletion emitter/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,16 @@ pub trait Emitter {
impl Emitter for EmitterContract {
fn initialize(e: Env, blnd_token: Address, backstop: Address, backstop_token: Address) {
storage::extend_instance(&e);
if storage::has_blnd_token(&e) {
if storage::get_is_init(&e) {
panic_with_error!(&e, EmitterError::AlreadyInitialized)
}

storage::set_blnd_token(&e, &blnd_token);
storage::set_backstop(&e, &backstop);
storage::set_backstop_token(&e, &backstop_token);
storage::set_last_distro_time(&e, &backstop, e.ledger().timestamp());

storage::set_is_init(&e);
}

fn distribute(e: Env) -> i128 {
Expand Down
22 changes: 15 additions & 7 deletions emitter/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub(crate) const LEDGER_BUMP_SHARED: u32 = 241920; // ~ 14 days

/********** Storage **********/

const IS_INIT_KEY: &str = "IsInit";
const BACKSTOP_KEY: &str = "Backstop";
const BACKSTOP_TOKEN_KEY: &str = "BToken";
const BLND_TOKEN_KEY: &str = "BLNDTkn";
Expand All @@ -30,6 +31,20 @@ pub fn extend_instance(e: &Env) {
.extend_ttl(LEDGER_THRESHOLD_SHARED, LEDGER_BUMP_SHARED);
}

/********** Init **********/

/// Check if the contract has been initialized
pub fn get_is_init(e: &Env) -> bool {
e.storage().instance().has(&Symbol::new(e, IS_INIT_KEY))
}

/// Set the contract as initialized
pub fn set_is_init(e: &Env) {
e.storage()
.instance()
.set::<Symbol, bool>(&Symbol::new(e, IS_INIT_KEY), &true);
}

/********** Backstop **********/

/// Fetch the current backstop address
Expand Down Expand Up @@ -128,13 +143,6 @@ pub fn set_blnd_token(e: &Env, blnd_token: &Address) {
.set::<Symbol, Address>(&Symbol::new(e, BLND_TOKEN_KEY), blnd_token);
}

/// Check if the BLND token has been set
///
/// Returns true if a BLND token has been set
pub fn has_blnd_token(e: &Env) -> bool {
e.storage().instance().has(&Symbol::new(e, BLND_TOKEN_KEY))
}

/********** Blend Distributions **********/

/// Fetch the last timestamp distribution was ran on
Expand Down
5 changes: 4 additions & 1 deletion pool-factory/src/pool_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,13 @@ pub trait PoolFactory {
impl PoolFactory for PoolFactoryContract {
fn initialize(e: Env, pool_init_meta: PoolInitMeta) {
storage::extend_instance(&e);
if storage::has_pool_init_meta(&e) {
if storage::get_is_init(&e) {
panic_with_error!(&e, PoolFactoryError::AlreadyInitialized);
}

storage::set_pool_init_meta(&e, &pool_init_meta);

storage::set_is_init(&e);
}

fn deploy(
Expand Down
19 changes: 14 additions & 5 deletions pool-factory/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use soroban_sdk::{contracttype, unwrap::UnwrapOptimized, Address, BytesN, Env, S
pub(crate) const LEDGER_THRESHOLD: u32 = 518400; // TODO: Check on phase 1 max ledger entry bump
pub(crate) const LEDGER_BUMP: u32 = 535670; // TODO: Check on phase 1 max ledger entry bump

const IS_INIT_KEY: &str = "IsInit";

#[derive(Clone)]
#[contracttype]
pub enum PoolFactoryDataKey {
Expand All @@ -26,6 +28,18 @@ pub fn extend_instance(e: &Env) {
.extend_ttl(LEDGER_THRESHOLD, LEDGER_BUMP);
}

/// Check if the contract has been initialized
pub fn get_is_init(e: &Env) -> bool {
e.storage().instance().has(&Symbol::new(e, IS_INIT_KEY))
}

/// Set the contract as initialized
pub fn set_is_init(e: &Env) {
e.storage()
.instance()
.set::<Symbol, bool>(&Symbol::new(e, IS_INIT_KEY), &true);
}

/// Fetch the pool initialization metadata
pub fn get_pool_init_meta(e: &Env) -> PoolInitMeta {
e.storage()
Expand All @@ -44,11 +58,6 @@ pub fn set_pool_init_meta(e: &Env, pool_init_meta: &PoolInitMeta) {
.set::<Symbol, PoolInitMeta>(&Symbol::new(e, "PoolMeta"), pool_init_meta)
}

/// Check if the factory has a WASM hash set
pub fn has_pool_init_meta(e: &Env) -> bool {
e.storage().instance().has(&Symbol::new(e, "PoolMeta"))
}

/// Check if a given contract_id was deployed by the factory
///
/// ### Arguments
Expand Down
96 changes: 91 additions & 5 deletions pool/src/pool/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub fn execute_initialize(
blnd_id: &Address,
usdc_id: &Address,
) {
if storage::has_admin(e) {
if storage::get_is_init(e) {
panic_with_error!(e, PoolError::AlreadyInitialized);
}

Expand All @@ -45,6 +45,8 @@ pub fn execute_initialize(
);
storage::set_blnd_token(e, blnd_id);
storage::set_usdc_token(e, usdc_id);

storage::set_is_init(e);
}

/// Update the pool
Expand Down Expand Up @@ -161,7 +163,7 @@ fn require_valid_reserve_metadata(e: &Env, metadata: &ReserveConfig) {
|| metadata.util > 0_9500000
|| (metadata.max_util > SCALAR_7_U32 || metadata.max_util <= metadata.util)
|| (metadata.r_one > metadata.r_two || metadata.r_two > metadata.r_three)
|| (metadata.reactivity > 0_0005000)
|| (metadata.reactivity > 0_0001000)
{
panic_with_error!(e, PoolError::InvalidReserveMetadata);
}
Expand All @@ -184,7 +186,7 @@ mod tests {
let name = Symbol::new(&e, "pool_name");
let oracle = Address::generate(&e);
let bstop_rate = 0_100_000_000u64;
let max_postions = 2;
let max_positions = 2;
let backstop_address = Address::generate(&e);
let blnd_id = Address::generate(&e);
let usdc_id = Address::generate(&e);
Expand All @@ -196,7 +198,7 @@ mod tests {
&name,
&oracle,
&bstop_rate,
&max_postions,
&max_positions,
&backstop_address,
&blnd_id,
&usdc_id,
Expand All @@ -213,6 +215,90 @@ mod tests {
});
}

#[test]
#[should_panic(expected = "Error(Contract, #3)")]
fn test_execute_initialize_already_initialized() {
let e = Env::default();
let pool = testutils::create_pool(&e);

let admin = Address::generate(&e);
let name = Symbol::new(&e, "pool_name");
let oracle = Address::generate(&e);
let bstop_rate = 0_100_000_000u64;
let max_positions = 3;
let backstop_address = Address::generate(&e);
let blnd_id = Address::generate(&e);
let usdc_id = Address::generate(&e);

e.as_contract(&pool, || {
execute_initialize(
&e,
&admin,
&name,
&oracle,
&bstop_rate,
&max_positions,
&backstop_address,
&blnd_id,
&usdc_id,
);

execute_initialize(
&e,
&Address::generate(&e),
&name,
&oracle,
&bstop_rate,
&max_positions,
&backstop_address,
&blnd_id,
&usdc_id,
);
});
}

#[test]
#[should_panic(expected = "Error(Contract, #5)")]
fn test_execute_initialize_bad_take_rate() {
let e = Env::default();
let pool = testutils::create_pool(&e);

let admin = Address::generate(&e);
let name = Symbol::new(&e, "pool_name");
let oracle = Address::generate(&e);
let bstop_rate = 1_000_000_000u64;
let max_positions = 3;
let backstop_address = Address::generate(&e);
let blnd_id = Address::generate(&e);
let usdc_id = Address::generate(&e);

e.as_contract(&pool, || {
execute_initialize(
&e,
&admin,
&name,
&oracle,
&bstop_rate,
&max_positions,
&backstop_address,
&blnd_id,
&usdc_id,
);

execute_initialize(
&e,
&Address::generate(&e),
&name,
&oracle,
&bstop_rate,
&max_positions,
&backstop_address,
&blnd_id,
&usdc_id,
);
});
}

#[test]
fn test_execute_update_pool() {
let e = Env::default();
Expand Down Expand Up @@ -887,7 +973,7 @@ mod tests {
r_one: 0_0500000,
r_two: 0_5000000,
r_three: 1_5000000,
reactivity: 5001,
reactivity: 0_0001001,
};
require_valid_reserve_metadata(&e, &metadata);
}
Expand Down
16 changes: 8 additions & 8 deletions pool/src/pool/interest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub fn calc_accrual(
.fixed_mul_floor(util_dif_scaled, SCALAR_9)
.unwrap_optimized();
let rate_dif = util_error
.fixed_mul_floor(i128(config.reactivity), SCALAR_9)
.fixed_mul_floor(i128(config.reactivity), SCALAR_7)
.unwrap_optimized();
let next_ir_mod = ir_mod + rate_dif;
let ir_mod_max = 10 * SCALAR_9;
Expand All @@ -93,7 +93,7 @@ pub fn calc_accrual(
.fixed_mul_ceil(util_dif_scaled, SCALAR_9)
.unwrap_optimized();
let rate_dif = util_error
.fixed_mul_ceil(i128(config.reactivity), SCALAR_9)
.fixed_mul_ceil(i128(config.reactivity), SCALAR_7)
.unwrap_optimized();
let next_ir_mod = ir_mod + rate_dif;
let ir_mod_min = SCALAR_9 / 10;
Expand Down Expand Up @@ -133,7 +133,7 @@ mod tests {
r_one: 0_0500000,
r_two: 0_5000000,
r_three: 1_5000000,
reactivity: 0_000_002_000,
reactivity: 0_0000020,
index: 0,
};
let ir_mod: i128 = 1_000_000_000;
Expand Down Expand Up @@ -168,7 +168,7 @@ mod tests {
r_one: 0_0500000,
r_two: 0_5000000,
r_three: 1_5000000,
reactivity: 0_000_002_000,
reactivity: 0_0000020,
index: 0,
};
let ir_mod: i128 = 1_000_000_000;
Expand Down Expand Up @@ -203,7 +203,7 @@ mod tests {
r_one: 0_0500000,
r_two: 0_5000000,
r_three: 1_5000000,
reactivity: 0_000_002_000,
reactivity: 0_0000020,
index: 0,
};
let ir_mod: i128 = 1_000_000_000;
Expand Down Expand Up @@ -238,7 +238,7 @@ mod tests {
r_one: 0_0500000,
r_two: 0_5000000,
r_three: 1_5000000,
reactivity: 0_000_002_000,
reactivity: 0_0000020,
index: 0,
};
let ir_mod: i128 = 9_997_000_000;
Expand Down Expand Up @@ -272,7 +272,7 @@ mod tests {
r_one: 0_0500000,
r_two: 0_5000000,
r_three: 1_5000000,
reactivity: 0_000_002_000,
reactivity: 0_0000020,
index: 0,
};
let ir_mod: i128 = 0_150_000_000;
Expand Down Expand Up @@ -306,7 +306,7 @@ mod tests {
r_one: 0_0500000,
r_two: 0_5000000,
r_three: 1_5000000,
reactivity: 0_000_002_000,
reactivity: 0_0000020,
index: 0,
};
let ir_mod: i128 = 0_100_000_000;
Expand Down
Loading

0 comments on commit 8a454ab

Please sign in to comment.