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::