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

pool: chore: make reserve caching system more obvious to use #180

Merged
merged 5 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
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
16 changes: 7 additions & 9 deletions pool/src/auctions/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,10 @@ mod tests {

let (underlying_0, _) = testutils::create_token_contract(&e, &bombadil);
let (mut reserve_config_0, mut reserve_data_0) = testutils::default_reserve_meta();
reserve_data_0.b_rate = 1_100_000_000;
reserve_data_0.last_time = 12345;
reserve_data_0.backstop_credit = 100_0000000;
reserve_data_0.b_supply = 1000_0000000;
reserve_data_0.d_supply = 750_0000000;
reserve_config_0.index = 0;
testutils::create_reserve(
&e,
Expand All @@ -448,8 +450,10 @@ mod tests {

let (underlying_1, _) = testutils::create_token_contract(&e, &bombadil);
let (mut reserve_config_1, mut reserve_data_1) = testutils::default_reserve_meta();
reserve_data_1.b_rate = 1_100_000_000;
reserve_data_1.last_time = 12345;
reserve_data_1.backstop_credit = 25_0000000;
reserve_data_1.b_supply = 250_0000000;
reserve_data_1.d_supply = 187_5000000;
reserve_config_1.index = 1;
testutils::create_reserve(
&e,
Expand Down Expand Up @@ -495,13 +499,7 @@ mod tests {
};
e.as_contract(&pool_address, || {
storage::set_pool_config(&e, &pool_config);
let pool = Pool::load(&e);
let mut reserve_0 = pool.load_reserve(&e, &underlying_0);
reserve_0.backstop_credit += 100_0000000;
reserve_0.store(&e);
let mut reserve_1 = pool.load_reserve(&e, &underlying_1);
reserve_1.backstop_credit += 25_0000000;
reserve_1.store(&e);

create(&e, 2);
assert!(storage::has_auction(&e, &2, &backstop_address));
});
Expand Down
60 changes: 23 additions & 37 deletions pool/src/auctions/backstop_interest_auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn create_interest_auction_data(e: &Env, backstop: &Address) -> AuctionData
for i in 0..reserve_list.len() {
let res_asset_address = reserve_list.get_unchecked(i);
// don't store updated reserve data back to ledger. This will occur on the the auction's fill.
let reserve = pool.load_reserve(e, &res_asset_address);
let reserve = pool.load_reserve(e, &res_asset_address, false);
if reserve.backstop_credit > 0 {
let asset_to_base = pool.load_price(e, &res_asset_address);
interest_value += i128(asset_to_base)
Expand Down Expand Up @@ -78,9 +78,9 @@ pub fn fill_interest_auction(

// lot contains underlying tokens, but the backstop credit must be updated on the reserve
for (res_asset_address, lot_amount) in auction_data.lot.iter() {
let mut reserve = pool.load_reserve(e, &res_asset_address);
let mut reserve = pool.load_reserve(e, &res_asset_address, true);
reserve.backstop_credit -= lot_amount;
pool.cache_reserve(reserve, true);
pool.cache_reserve(reserve);
TokenClient::new(e, &res_asset_address).transfer(
&e.current_contract_address(),
filler,
Expand Down Expand Up @@ -178,6 +178,7 @@ mod tests {
let (mut reserve_config_0, mut reserve_data_0) = testutils::default_reserve_meta();
reserve_data_0.b_rate = 1_100_000_000;
reserve_data_0.last_time = 12345;
reserve_data_0.backstop_credit = 10_0000000;
reserve_config_0.index = 0;
testutils::create_reserve(
&e,
Expand All @@ -191,6 +192,7 @@ mod tests {
let (mut reserve_config_1, mut reserve_data_1) = testutils::default_reserve_meta();
reserve_data_1.b_rate = 1_100_000_000;
reserve_data_1.last_time = 12345;
reserve_data_1.backstop_credit = 2_5000000;
reserve_config_1.index = 1;
testutils::create_reserve(
&e,
Expand Down Expand Up @@ -236,15 +238,8 @@ mod tests {
};
e.as_contract(&pool_address, || {
storage::set_pool_config(&e, &pool_config);
let pool = Pool::load(&e);
let mut reserve_0 = pool.load_reserve(&e, &underlying_0);
reserve_0.backstop_credit += 10_0000000;
reserve_0.store(&e);
let mut reserve_1 = pool.load_reserve(&e, &underlying_1);
reserve_1.backstop_credit += 2_5000000;
reserve_1.store(&e);
let result = create_interest_auction_data(&e, &backstop_address);

let result = create_interest_auction_data(&e, &backstop_address);
assert_eq!(result.block, 51);
assert_eq!(result.bid.get_unchecked(usdc_id), 42_0000000);
assert_eq!(result.bid.len(), 1);
Expand Down Expand Up @@ -288,8 +283,10 @@ mod tests {

let (underlying_0, _) = testutils::create_token_contract(&e, &bombadil);
let (mut reserve_config_0, mut reserve_data_0) = testutils::default_reserve_meta();
reserve_data_0.b_rate = 1_100_000_000;
reserve_data_0.last_time = 12345;
reserve_data_0.backstop_credit = 100_0000000;
reserve_data_0.b_supply = 1000_0000000;
reserve_data_0.d_supply = 750_0000000;
reserve_config_0.index = 0;
testutils::create_reserve(
&e,
Expand All @@ -301,8 +298,10 @@ mod tests {

let (underlying_1, _) = testutils::create_token_contract(&e, &bombadil);
let (mut reserve_config_1, mut reserve_data_1) = testutils::default_reserve_meta();
reserve_data_1.b_rate = 1_100_000_000;
reserve_data_1.last_time = 12345;
reserve_data_1.backstop_credit = 25_0000000;
reserve_data_1.b_supply = 250_0000000;
reserve_data_1.d_supply = 187_5000000;
reserve_config_1.index = 1;
testutils::create_reserve(
&e,
Expand All @@ -314,7 +313,6 @@ mod tests {

let (underlying_2, _) = testutils::create_token_contract(&e, &bombadil);
let (mut reserve_config_2, mut reserve_data_2) = testutils::default_reserve_meta();
reserve_data_2.b_rate = 1_100_000_000;
reserve_data_2.last_time = 12345;
reserve_config_2.index = 1;
testutils::create_reserve(
Expand Down Expand Up @@ -348,15 +346,8 @@ mod tests {
};
e.as_contract(&pool_address, || {
storage::set_pool_config(&e, &pool_config);
let pool = Pool::load(&e);
let mut reserve_0 = pool.load_reserve(&e, &underlying_0);
reserve_0.backstop_credit += 100_0000000;
reserve_0.store(&e);
let mut reserve_1 = pool.load_reserve(&e, &underlying_1);
reserve_1.backstop_credit += 25_0000000;
reserve_1.store(&e);
let result = create_interest_auction_data(&e, &backstop_address);

let result = create_interest_auction_data(&e, &backstop_address);
assert_eq!(result.block, 51);
assert_eq!(result.bid.get_unchecked(usdc_id), 420_0000000);
assert_eq!(result.bid.len(), 1);
Expand Down Expand Up @@ -400,8 +391,10 @@ mod tests {

let (underlying_0, _) = testutils::create_token_contract(&e, &bombadil);
let (mut reserve_config_0, mut reserve_data_0) = testutils::default_reserve_meta();
reserve_data_0.b_rate = 1_100_000_000;
reserve_data_0.last_time = 11845;
reserve_data_0.backstop_credit = 100_0000000;
reserve_data_0.b_supply = 1000_0000000;
reserve_data_0.d_supply = 750_0000000;
reserve_config_0.index = 0;
testutils::create_reserve(
&e,
Expand All @@ -413,8 +406,10 @@ mod tests {

let (underlying_1, _) = testutils::create_token_contract(&e, &bombadil);
let (mut reserve_config_1, mut reserve_data_1) = testutils::default_reserve_meta();
reserve_data_1.b_rate = 1_100_000_000;
reserve_data_1.last_time = 11845;
reserve_data_1.backstop_credit = 25_0000000;
reserve_data_1.b_supply = 250_0000000;
reserve_data_1.d_supply = 187_5000000;
reserve_config_1.index = 1;
testutils::create_reserve(
&e,
Expand All @@ -426,7 +421,6 @@ mod tests {

let (underlying_2, _) = testutils::create_token_contract(&e, &bombadil);
let (mut reserve_config_2, mut reserve_data_2) = testutils::default_reserve_meta();
reserve_data_2.b_rate = 1_100_000_000;
reserve_data_2.last_time = 11845;
reserve_config_2.index = 2;
testutils::create_reserve(
Expand Down Expand Up @@ -461,21 +455,13 @@ mod tests {
e.as_contract(&pool_address, || {
storage::set_pool_config(&e, &pool_config);

let pool = Pool::load(&e);
let mut reserve_0 = pool.load_reserve(&e, &underlying_0);
reserve_0.backstop_credit += 100_0000000;
reserve_0.store(&e);
let mut reserve_1 = pool.load_reserve(&e, &underlying_1);
reserve_1.backstop_credit += 25_0000000;
reserve_1.store(&e);

let result = create_interest_auction_data(&e, &backstop_address);
assert_eq!(result.block, 151);
assert_eq!(result.bid.get_unchecked(usdc_id), 420_0009794);
assert_eq!(result.bid.get_unchecked(usdc_id), 420_0012936);
assert_eq!(result.bid.len(), 1);
assert_eq!(result.lot.get_unchecked(underlying_0), 100_0000066);
assert_eq!(result.lot.get_unchecked(underlying_1), 25_0000066);
assert_eq!(result.lot.get_unchecked(underlying_2), 66);
assert_eq!(result.lot.get_unchecked(underlying_0), 100_0000714);
assert_eq!(result.lot.get_unchecked(underlying_1), 25_0000178);
assert_eq!(result.lot.get_unchecked(underlying_2), 71);
assert_eq!(result.lot.len(), 3);
});
}
Expand Down
2 changes: 1 addition & 1 deletion pool/src/auctions/bad_debt_auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn create_bad_debt_auction_data(e: &Env, backstop: &Address) -> AuctionData
for (reserve_index, liability_balance) in backstop_positions.liabilities.iter() {
let res_asset_address = reserve_list.get_unchecked(reserve_index);
if liability_balance > 0 {
let reserve = pool.load_reserve(e, &res_asset_address);
let reserve = pool.load_reserve(e, &res_asset_address, false);
let asset_to_base = pool.load_price(e, &res_asset_address);
let asset_balance = reserve.to_asset_from_d_token(liability_balance);
debt_value += i128(asset_to_base)
Expand Down
1 change: 1 addition & 0 deletions pool/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub enum PoolError {
InvalidPoolStatus = 11,
InvalidUtilRate = 12,
MaxPositionsExceeded = 13,
InternalReserveNotFound = 14,
// Emission Errors (20-29)
EmissionFailure = 20,
// Oracle Errors (30-39)
Expand Down
Loading