From f2f905df1f2339ea40e01510eb831c25a249cca6 Mon Sep 17 00:00:00 2001 From: markuspluna <59978114+markuspluna@users.noreply.github.com> Date: Sun, 22 Oct 2023 15:06:07 -0400 Subject: [PATCH 1/2] added delay --- emitter/src/contract.rs | 2 + emitter/src/emitter.rs | 62 +++++++++++++++++++++++++++++-- emitter/src/storage.rs | 32 ++++++++++++++++ test-suites/src/liquidity_pool.rs | 4 +- test-suites/src/test_fixture.rs | 2 +- 5 files changed, 96 insertions(+), 6 deletions(-) diff --git a/emitter/src/contract.rs b/emitter/src/contract.rs index 4d6117cb..9410de7d 100644 --- a/emitter/src/contract.rs +++ b/emitter/src/contract.rs @@ -57,6 +57,8 @@ impl Emitter for EmitterContract { storage::set_backstop(&e, &backstop); storage::set_blend_id(&e, &blnd_token_id); + storage::set_last_fork(&e, e.ledger().sequence() - 777600); // We set the block 45 days in the past to allow for an immediate initial drop + storage::set_drop_status(&e, false); // TODO: Determine if setting the last distro time here is appropriate, since it means tokens immediately start being distributed storage::set_last_distro_time(&e, &(e.ledger().timestamp() - 7 * 24 * 60 * 60)); } diff --git a/emitter/src/emitter.rs b/emitter/src/emitter.rs index ab91db0e..f770e538 100644 --- a/emitter/src/emitter.rs +++ b/emitter/src/emitter.rs @@ -32,6 +32,7 @@ pub fn execute_swap_backstop(e: &Env, new_backstop_id: Address) { if new_backstop_balance > backstop_balance { storage::set_backstop(e, &new_backstop_id); storage::set_drop_status(e, false); + storage::set_last_fork(e, e.ledger().sequence()); } else { panic_with_error!(e, EmitterError::InsufficientBackstopSize); } @@ -42,6 +43,10 @@ pub fn execute_drop(e: &Env) -> Map { if storage::get_drop_status(e) { panic_with_error!(e, EmitterError::BadDrop); } + if storage::get_last_fork(e) + 777600 > e.ledger().sequence() { + // Check that the last fork was at least 45 days ago + panic_with_error!(e, EmitterError::BadDrop); + } let backstop = storage::get_backstop(e); let backstop_client = BackstopClient::new(e, &backstop); let backstop_token = backstop_client.backstop_token(); @@ -65,6 +70,7 @@ pub fn execute_drop(e: &Env) -> Map { #[cfg(test)] mod tests { + use crate::{ storage, testutils::{create_backstop, create_emitter}, @@ -208,7 +214,7 @@ mod tests { e.ledger().set(LedgerInfo { timestamp: 12345, protocol_version: 20, - sequence_number: 50, + sequence_number: 5000000, network_id: Default::default(), base_reserve: 10, min_temp_entry_expiration: 10, @@ -242,6 +248,7 @@ mod tests { storage::set_last_distro_time(&e, &1000); storage::set_backstop(&e, &backstop); storage::set_drop_status(&e, false); + storage::set_last_fork(&e, 4000000); let list = execute_drop(&e); assert_eq!(storage::get_drop_status(&e), true); @@ -263,7 +270,7 @@ mod tests { e.ledger().set(LedgerInfo { timestamp: 12345, protocol_version: 20, - sequence_number: 50, + sequence_number: 5000000, network_id: Default::default(), base_reserve: 10, min_temp_entry_expiration: 10, @@ -296,6 +303,7 @@ mod tests { storage::set_last_distro_time(&e, &1000); storage::set_backstop(&e, &backstop); storage::set_drop_status(&e, true); + storage::set_last_fork(&e, 4000000); execute_drop(&e); assert_eq!(storage::get_drop_status(&e), true); @@ -311,7 +319,7 @@ mod tests { e.ledger().set(LedgerInfo { timestamp: 12345, protocol_version: 20, - sequence_number: 50, + sequence_number: 5000000, network_id: Default::default(), base_reserve: 10, min_temp_entry_expiration: 10, @@ -344,6 +352,7 @@ mod tests { storage::set_last_distro_time(&e, &1000); storage::set_backstop(&e, &backstop); storage::set_drop_status(&e, false); + storage::set_last_fork(&e, 4000000); execute_drop(&e); assert_eq!(storage::get_drop_status(&e), false); @@ -392,6 +401,53 @@ mod tests { storage::set_last_distro_time(&e, &1000); storage::set_backstop(&e, &backstop); + execute_drop(&e); + }); + } + #[test] + #[should_panic(expected = "Error(Contract, #40)")] + fn test_drop_bad_block() { + let e = Env::default(); + e.mock_all_auths_allowing_non_root_auth(); + + e.ledger().set(LedgerInfo { + timestamp: 12345, + protocol_version: 20, + sequence_number: 5000000, + network_id: Default::default(), + base_reserve: 10, + min_temp_entry_expiration: 10, + min_persistent_entry_expiration: 10, + max_entry_expiration: 2000000, + }); + + let bombadil = Address::random(&e); + let frodo = Address::random(&e); + let samwise = Address::random(&e); + let emitter = create_emitter(&e); + let (backstop, backstop_client) = create_backstop(&e); + + let backstop_token = e.register_stellar_asset_contract(bombadil.clone()); + let drop_list = map![ + &e, + (frodo.clone(), 20_000_000 * SCALAR_7), + (samwise.clone(), 30_000_000 * SCALAR_7) + ]; + + backstop_client.initialize( + &backstop_token, + &Address::random(&e), + &Address::random(&e), + &Address::random(&e), + &drop_list, + ); + + e.as_contract(&emitter, || { + storage::set_last_distro_time(&e, &1000); + storage::set_backstop(&e, &backstop); + storage::set_last_fork(&e, 5000000); + storage::set_drop_status(&e, false); + execute_drop(&e); }); } diff --git a/emitter/src/storage.rs b/emitter/src/storage.rs index 31e90d8f..e0e4a602 100644 --- a/emitter/src/storage.rs +++ b/emitter/src/storage.rs @@ -21,6 +21,8 @@ pub enum EmitterDataKey { LastDistro, // The drop status for the current backstop DropStatus, + // The last block emissions were forked + LastFork, } /// Bump the instance rent for the contract. Bumps for 10 days due to the 7-day cycle window of this contract @@ -142,3 +144,33 @@ pub fn set_drop_status(e: &Env, new_status: bool) { LEDGER_BUMP_SHARED, ); } + +/// Get the last block an emission fork was executed +/// +/// Returns true if the emitter has dropped +pub fn get_last_fork(e: &Env) -> u32 { + e.storage().persistent().bump( + &EmitterDataKey::DropStatus, + LEDGER_THRESHOLD_SHARED, + LEDGER_BUMP_SHARED, + ); + e.storage() + .persistent() + .get(&EmitterDataKey::LastFork) + .unwrap_optimized() +} + +/// Set whether the emitter has performed the drop distribution or not for the current backstop +/// +/// ### Arguments +/// * `new_status` - new drop status +pub fn set_last_fork(e: &Env, block: u32) { + e.storage() + .persistent() + .set::(&EmitterDataKey::LastFork, &block); + e.storage().persistent().bump( + &EmitterDataKey::LastFork, + LEDGER_THRESHOLD_SHARED, + LEDGER_BUMP_SHARED, + ); +} diff --git a/test-suites/src/liquidity_pool.rs b/test-suites/src/liquidity_pool.rs index 3943e24a..fb8b6474 100644 --- a/test-suites/src/liquidity_pool.rs +++ b/test-suites/src/liquidity_pool.rs @@ -30,8 +30,8 @@ pub(crate) fn create_lp_pool<'a>( let token_2_client = TokenClient::new(e, token_2); token_1_client.mint(&admin, &1_000_0000000); token_2_client.mint(&admin, &25_0000000); - token_1_client.approve(&admin, &contract_address, &1_000_0000000, &535670); - token_2_client.approve(&admin, &contract_address, &1_000_0000000, &535670); + token_1_client.approve(&admin, &contract_address, &1_000_0000000, &5356700); + token_2_client.approve(&admin, &contract_address, &1_000_0000000, &5356700); client.init(&Address::random(e), &admin); client.bundle_bind( diff --git a/test-suites/src/test_fixture.rs b/test-suites/src/test_fixture.rs index 0f6196dc..47e5df51 100644 --- a/test-suites/src/test_fixture.rs +++ b/test-suites/src/test_fixture.rs @@ -72,7 +72,7 @@ impl TestFixture<'_> { e.ledger().set(LedgerInfo { timestamp: 1441065600, // Sept 1st, 2015 (backstop epoch) protocol_version: 20, - sequence_number: 100, + sequence_number: 5000000, network_id: Default::default(), base_reserve: 10, min_temp_entry_expiration: 999999, From 7bb7fe68a5094f19cc74238b02956a88257a3316 Mon Sep 17 00:00:00 2001 From: markuspluna <59978114+markuspluna@users.noreply.github.com> Date: Tue, 24 Oct 2023 10:07:32 -0400 Subject: [PATCH 2/2] storage: changed fork and drop to instance | contract: initialize sets last_fork to 0 --- emitter/src/contract.rs | 2 +- emitter/src/emitter.rs | 45 ----------------------------------------- emitter/src/storage.rs | 28 ++++--------------------- 3 files changed, 5 insertions(+), 70 deletions(-) diff --git a/emitter/src/contract.rs b/emitter/src/contract.rs index 9410de7d..015daf0a 100644 --- a/emitter/src/contract.rs +++ b/emitter/src/contract.rs @@ -57,7 +57,7 @@ impl Emitter for EmitterContract { storage::set_backstop(&e, &backstop); storage::set_blend_id(&e, &blnd_token_id); - storage::set_last_fork(&e, e.ledger().sequence() - 777600); // We set the block 45 days in the past to allow for an immediate initial drop + storage::set_last_fork(&e, 0); // We set the block 45 days in the past to allow for an immediate initial drop storage::set_drop_status(&e, false); // TODO: Determine if setting the last distro time here is appropriate, since it means tokens immediately start being distributed storage::set_last_distro_time(&e, &(e.ledger().timestamp() - 7 * 24 * 60 * 60)); diff --git a/emitter/src/emitter.rs b/emitter/src/emitter.rs index f770e538..5f99cf99 100644 --- a/emitter/src/emitter.rs +++ b/emitter/src/emitter.rs @@ -359,51 +359,6 @@ mod tests { }); } - #[test] - #[should_panic(expected = "Error(Storage, MissingValue)")] - fn test_drop_no_status() { - let e = Env::default(); - e.mock_all_auths_allowing_non_root_auth(); - - e.ledger().set(LedgerInfo { - timestamp: 12345, - protocol_version: 20, - sequence_number: 50, - network_id: Default::default(), - base_reserve: 10, - min_temp_entry_expiration: 10, - min_persistent_entry_expiration: 10, - max_entry_expiration: 2000000, - }); - - let bombadil = Address::random(&e); - let frodo = Address::random(&e); - let samwise = Address::random(&e); - let emitter = create_emitter(&e); - let (backstop, backstop_client) = create_backstop(&e); - - let backstop_token = e.register_stellar_asset_contract(bombadil.clone()); - let drop_list = map![ - &e, - (frodo.clone(), 20_000_000 * SCALAR_7), - (samwise.clone(), 30_000_000 * SCALAR_7) - ]; - - backstop_client.initialize( - &backstop_token, - &Address::random(&e), - &Address::random(&e), - &Address::random(&e), - &drop_list, - ); - - e.as_contract(&emitter, || { - storage::set_last_distro_time(&e, &1000); - storage::set_backstop(&e, &backstop); - - execute_drop(&e); - }); - } #[test] #[should_panic(expected = "Error(Contract, #40)")] fn test_drop_bad_block() { diff --git a/emitter/src/storage.rs b/emitter/src/storage.rs index e0e4a602..2d42c026 100644 --- a/emitter/src/storage.rs +++ b/emitter/src/storage.rs @@ -119,13 +119,8 @@ pub fn set_last_distro_time(e: &Env, last_distro: &u64) { /// /// Returns true if the emitter has dropped pub fn get_drop_status(e: &Env) -> bool { - e.storage().persistent().bump( - &EmitterDataKey::DropStatus, - LEDGER_THRESHOLD_SHARED, - LEDGER_BUMP_SHARED, - ); e.storage() - .persistent() + .instance() .get(&EmitterDataKey::DropStatus) .unwrap_optimized() } @@ -136,26 +131,16 @@ pub fn get_drop_status(e: &Env) -> bool { /// * `new_status` - new drop status pub fn set_drop_status(e: &Env, new_status: bool) { e.storage() - .persistent() + .instance() .set::(&EmitterDataKey::DropStatus, &new_status); - e.storage().persistent().bump( - &EmitterDataKey::DropStatus, - LEDGER_THRESHOLD_SHARED, - LEDGER_BUMP_SHARED, - ); } /// Get the last block an emission fork was executed /// /// Returns true if the emitter has dropped pub fn get_last_fork(e: &Env) -> u32 { - e.storage().persistent().bump( - &EmitterDataKey::DropStatus, - LEDGER_THRESHOLD_SHARED, - LEDGER_BUMP_SHARED, - ); e.storage() - .persistent() + .instance() .get(&EmitterDataKey::LastFork) .unwrap_optimized() } @@ -166,11 +151,6 @@ pub fn get_last_fork(e: &Env) -> u32 { /// * `new_status` - new drop status pub fn set_last_fork(e: &Env, block: u32) { e.storage() - .persistent() + .instance() .set::(&EmitterDataKey::LastFork, &block); - e.storage().persistent().bump( - &EmitterDataKey::LastFork, - LEDGER_THRESHOLD_SHARED, - LEDGER_BUMP_SHARED, - ); }