From bab2ce0e0ffa2fed69c7c2bda2485c45994b3225 Mon Sep 17 00:00:00 2001 From: mootz12 Date: Tue, 17 Dec 2024 10:13:54 -0500 Subject: [PATCH] chore: use strongly typed events and improve auction events --- backstop/src/contract.rs | 40 +--- backstop/src/emissions/claim.rs | 8 +- backstop/src/events.rs | 143 +++++++++++ backstop/src/lib.rs | 1 + emitter/src/contract.rs | 19 +- emitter/src/events.rs | 69 ++++++ emitter/src/lib.rs | 1 + pool-factory/src/events.rs | 18 ++ pool-factory/src/lib.rs | 1 + pool-factory/src/pool_factory.rs | 4 +- pool/src/auctions/auction.rs | 4 +- pool/src/auctions/bad_debt_auction.rs | 8 +- pool/src/contract.rs | 46 ++-- pool/src/emissions/manager.rs | 8 +- pool/src/events.rs | 326 ++++++++++++++++++++++++++ pool/src/lib.rs | 2 + pool/src/pool/actions.rs | 147 ++++++------ pool/src/pool/bad_debt.rs | 8 +- test-suites/tests/test_liquidation.rs | 244 ++++++++----------- 19 files changed, 778 insertions(+), 319 deletions(-) create mode 100644 backstop/src/events.rs create mode 100644 emitter/src/events.rs create mode 100644 pool-factory/src/events.rs create mode 100644 pool/src/events.rs diff --git a/backstop/src/contract.rs b/backstop/src/contract.rs index e14db72..bdd1cfa 100644 --- a/backstop/src/contract.rs +++ b/backstop/src/contract.rs @@ -3,11 +3,10 @@ use crate::{ dependencies::EmitterClient, emissions, errors::BackstopError, + events::BackstopEvents, storage, }; -use soroban_sdk::{ - contract, contractclient, contractimpl, panic_with_error, Address, Env, Symbol, Vec, -}; +use soroban_sdk::{contract, contractclient, contractimpl, panic_with_error, Address, Env, Vec}; /// ### Backstop /// @@ -218,10 +217,7 @@ impl Backstop for BackstopContract { let to_mint = backstop::execute_deposit(&e, &from, &pool_address, amount); - e.events().publish( - (Symbol::new(&e, "deposit"), pool_address, from), - (amount, to_mint), - ); + BackstopEvents::deposit(&e, pool_address, from, amount, to_mint); to_mint } @@ -231,10 +227,7 @@ impl Backstop for BackstopContract { let to_queue = backstop::execute_queue_withdrawal(&e, &from, &pool_address, amount); - e.events().publish( - (Symbol::new(&e, "queue_withdrawal"), pool_address, from), - (amount, to_queue.exp), - ); + BackstopEvents::queue_withdrawal(&e, pool_address, from, amount, to_queue.exp); to_queue } @@ -244,10 +237,7 @@ impl Backstop for BackstopContract { backstop::execute_dequeue_withdrawal(&e, &from, &pool_address, amount); - e.events().publish( - (Symbol::new(&e, "dequeue_withdrawal"), pool_address, from), - amount, - ); + BackstopEvents::dequeue_withdrawal(&e, pool_address, from, amount); } fn withdraw(e: Env, from: Address, pool_address: Address, amount: i128) -> i128 { @@ -256,10 +246,7 @@ impl Backstop for BackstopContract { let to_withdraw = backstop::execute_withdraw(&e, &from, &pool_address, amount); - e.events().publish( - (Symbol::new(&e, "withdraw"), pool_address, from), - (amount, to_withdraw), - ); + BackstopEvents::withdraw(&e, pool_address, from, amount, to_withdraw); to_withdraw } @@ -281,16 +268,14 @@ impl Backstop for BackstopContract { storage::extend_instance(&e); let new_tokens_emitted = emissions::gulp_emissions(&e); - e.events() - .publish((Symbol::new(&e, "gulp_emissions"),), new_tokens_emitted); + BackstopEvents::gulp_emissions(&e, new_tokens_emitted); } fn add_reward(e: Env, to_add: Address, to_remove: Address) { storage::extend_instance(&e); emissions::add_to_reward_zone(&e, to_add.clone(), to_remove.clone()); - e.events() - .publish((Symbol::new(&e, "rw_zone"),), (to_add, to_remove)); + BackstopEvents::rw_zone(&e, to_add, to_remove); } fn gulp_pool_emissions(e: Env, pool_address: Address) -> i128 { @@ -305,7 +290,7 @@ impl Backstop for BackstopContract { let amount = emissions::execute_claim(&e, &from, &pool_addresses, &to); - e.events().publish((Symbol::new(&e, "claim"), from), amount); + BackstopEvents::claim(&e, from, amount); amount } @@ -321,8 +306,7 @@ impl Backstop for BackstopContract { backstop::execute_draw(&e, &pool_address, amount, &to); - e.events() - .publish((Symbol::new(&e, "draw"), pool_address), (to, amount)); + BackstopEvents::draw(&e, pool_address, to, amount); } fn donate(e: Env, from: Address, pool_address: Address, amount: i128) { @@ -331,8 +315,8 @@ impl Backstop for BackstopContract { pool_address.require_auth(); backstop::execute_donate(&e, &from, &pool_address, amount); - e.events() - .publish((Symbol::new(&e, "donate"), pool_address, from), amount); + + BackstopEvents::donate(&e, pool_address, from, amount); } fn update_tkn_val(e: Env) -> (i128, i128) { diff --git a/backstop/src/emissions/claim.rs b/backstop/src/emissions/claim.rs index 4625e96..33211eb 100644 --- a/backstop/src/emissions/claim.rs +++ b/backstop/src/emissions/claim.rs @@ -1,4 +1,4 @@ -use crate::{dependencies::CometClient, errors::BackstopError, storage}; +use crate::{dependencies::CometClient, errors::BackstopError, events::BackstopEvents, storage}; use soroban_fixed_point_math::FixedPoint; use soroban_sdk::{ auth::{ContractContext, InvokerContractAuthEntry, SubContractInvocation}, @@ -67,10 +67,8 @@ pub fn execute_claim(e: &Env, from: &Address, pool_addresses: &Vec
, to: storage::set_pool_balance(e, &pool_id, &pool_balance); storage::set_user_balance(e, &pool_id, to, &user_balance); - e.events().publish( - (Symbol::new(&e, "deposit"), pool_id, to), - (deposit_amount, to_mint), - ); + + BackstopEvents::deposit(e, pool_id, to.clone(), deposit_amount, to_mint); } } diff --git a/backstop/src/events.rs b/backstop/src/events.rs new file mode 100644 index 0000000..fe6e2cf --- /dev/null +++ b/backstop/src/events.rs @@ -0,0 +1,143 @@ +use soroban_sdk::{Address, Env, Symbol}; + +pub struct BackstopEvents {} + +impl BackstopEvents { + /// Emitted when tokens are deposited into a backstop + /// + /// - topics - `["deposit", pool_address: Address, from: Address]` + /// - data - `[tokens_in: i128, backstop_shares_minted: i128]` + /// + /// ### Arguments + /// * `pool_address` - The address of the pool + /// * `from` - The address of the user depositing tokens + /// * `tokens_in` - The amount of tokens sent to the backstop + /// * `backstop_shares_minted` - The amount of backstop shares minted + pub fn deposit( + e: &Env, + pool_address: Address, + from: Address, + tokens_in: i128, + backstop_shares_minted: i128, + ) { + let topics = (Symbol::new(e, "deposit"), pool_address, from); + e.events() + .publish(topics, (tokens_in, backstop_shares_minted)); + } + + /// Emitted when a withdrawal is queued + /// + /// - topics - `["queue_withdrawal", pool_address: Address, from: Address]` + /// - data - `[amount: i128, expiration: u64]` + /// + /// ### Arguments + /// * `pool_address` - The address of the pool + /// * `from` - The address of the user queuing the withdrawal + /// * `amount` - The amount of shares being queued for withdrawal + /// * `expiration` - The expiration timestamp of the withdrawal request + pub fn queue_withdrawal( + e: &Env, + pool_address: Address, + from: Address, + amount: i128, + expiration: u64, + ) { + let topics = (Symbol::new(e, "queue_withdrawal"), pool_address, from); + e.events().publish(topics, (amount, expiration)); + } + + /// Emitted when a withdrawal is dequeued + /// + /// - topics - `["dequeue_withdrawal", pool_address: Address, from: Address]` + /// - data - `[amount: i128]` + /// + /// ### Arguments + /// * `pool_address` - The address of the pool + /// * `from` - The address of the user dequeuing the withdrawal + /// * `amount` - The amount of shares being dequeued + pub fn dequeue_withdrawal(e: &Env, pool_address: Address, from: Address, amount: i128) { + let topics = (Symbol::new(e, "dequeue_withdrawal"), pool_address, from); + e.events().publish(topics, amount); + } + + /// Emitted when tokens are withdrawn from the backstop + /// + /// - topics - `["withdraw", pool_address: Address, from: Address]` + /// - data - `[amount: i128, tokens_out: i128]` + /// + /// ### Arguments + /// * `pool_address` - The address of the pool + /// * `from` - The address of the user withdrawing tokens + /// * `amount` - The amount of backstop shares being burned + /// * `tokens_out` - The amount of tokens being withdrawn + pub fn withdraw(e: &Env, pool_address: Address, from: Address, amount: i128, tokens_out: i128) { + let topics = (Symbol::new(e, "withdraw"), pool_address, from); + e.events().publish(topics, (amount, tokens_out)); + } + + /// Emitted when new emissions are gulped + /// + /// - topics - `["gulp_emissions"]` + /// - data - `[new_tokens_emitted: i128]` + /// + /// ### Arguments + /// * `new_tokens_emitted` - The amount of new tokens emitted + pub fn gulp_emissions(e: &Env, new_tokens_emitted: i128) { + let topics = (Symbol::new(e, "gulp_emissions"),); + e.events().publish(topics, new_tokens_emitted); + } + + /// Emitted when the reward zone is updated + /// + /// - topics - `["rw_zone"]` + /// - data - `[to_add: Address, to_remove: Address]` + /// + /// ### Arguments + /// * `to_add` - The address to add to the reward zone + /// * `to_remove` - The address to remove from the reward zone + pub fn rw_zone(e: &Env, to_add: Address, to_remove: Address) { + let topics = (Symbol::new(e, "rw_zone"),); + e.events().publish(topics, (to_add, to_remove)); + } + + /// Emitted when emissions are claimed + /// + /// - topics - `["claim", from: Address]` + /// - data - `[amount: i128]` + /// + /// ### Arguments + /// * `from` - The address of the user claiming emissions + /// * `amount` - The amount of emissions claimed + pub fn claim(e: &Env, from: Address, amount: i128) { + let topics = (Symbol::new(e, "claim"), from); + e.events().publish(topics, amount); + } + + /// Emitted when tokens are drawn from the backstop + /// + /// - topics - `["draw", pool_address: Address]` + /// - data - `[to: Address, amount: i128]` + /// + /// ### Arguments + /// * `pool_address` - The address of the pool + /// * `to` - The address receiving the drawn tokens + /// * `amount` - The amount of tokens drawn + pub fn draw(e: &Env, pool_address: Address, to: Address, amount: i128) { + let topics = (Symbol::new(e, "draw"), pool_address); + e.events().publish(topics, (to, amount)); + } + + /// Emitted when tokens are donated to the backstop + /// + /// - topics - `["donate", pool_address: Address, from: Address]` + /// - data - `[amount: i128]` + /// + /// ### Arguments + /// * `pool_address` - The address of the pool + /// * `from` - The address of the donor + /// * `amount` - The amount of tokens donated + pub fn donate(e: &Env, pool_address: Address, from: Address, amount: i128) { + let topics = (Symbol::new(e, "donate"), pool_address, from); + e.events().publish(topics, amount); + } +} diff --git a/backstop/src/lib.rs b/backstop/src/lib.rs index 2ad3204..2712c66 100644 --- a/backstop/src/lib.rs +++ b/backstop/src/lib.rs @@ -9,6 +9,7 @@ mod contract; mod dependencies; mod emissions; mod errors; +mod events; mod storage; mod testutils; diff --git a/emitter/src/contract.rs b/emitter/src/contract.rs index 16021ff..1a31bc9 100644 --- a/emitter/src/contract.rs +++ b/emitter/src/contract.rs @@ -1,7 +1,5 @@ -use crate::{backstop_manager, emitter, errors::EmitterError, storage}; -use soroban_sdk::{ - contract, contractclient, contractimpl, panic_with_error, Address, Env, Symbol, Vec, -}; +use crate::{backstop_manager, emitter, errors::EmitterError, events::EmitterEvents, storage}; +use soroban_sdk::{contract, contractclient, contractimpl, panic_with_error, Address, Env, Vec}; /// ### Emitter /// @@ -94,10 +92,7 @@ impl Emitter for EmitterContract { let distribution_amount = emitter::execute_distribute(&e, &backstop_address); - e.events().publish( - (Symbol::new(&e, "distribute"),), - (backstop_address, distribution_amount), - ); + EmitterEvents::distribute(&e, backstop_address, distribution_amount); distribution_amount } @@ -114,7 +109,7 @@ impl Emitter for EmitterContract { let swap = backstop_manager::execute_queue_swap_backstop(&e, &new_backstop, &new_backstop_token); - e.events().publish((Symbol::new(&e, "q_swap"),), swap); + EmitterEvents::q_swap(&e, swap); } fn get_queued_swap(e: Env) -> Option { @@ -125,20 +120,20 @@ impl Emitter for EmitterContract { storage::extend_instance(&e); let swap = backstop_manager::execute_cancel_swap_backstop(&e); - e.events().publish((Symbol::new(&e, "del_swap"),), swap); + EmitterEvents::del_swap(&e, swap); } fn swap_backstop(e: Env) { storage::extend_instance(&e); let swap = backstop_manager::execute_swap_backstop(&e); - e.events().publish((Symbol::new(&e, "swap"),), swap); + EmitterEvents::swap(&e, swap); } fn drop(e: Env, list: Vec<(Address, i128)>) { storage::extend_instance(&e); emitter::execute_drop(&e, &list); - e.events().publish((Symbol::new(&e, "drop"),), list); + EmitterEvents::drop(&e, list); } } diff --git a/emitter/src/events.rs b/emitter/src/events.rs new file mode 100644 index 0000000..e2161d1 --- /dev/null +++ b/emitter/src/events.rs @@ -0,0 +1,69 @@ +use soroban_sdk::{Address, Env, Symbol, Vec}; + +use crate::Swap; + +pub struct EmitterEvents {} + +impl EmitterEvents { + /// Emitted when tokens are distributed to the backstop + /// + /// - topics - `["distribute"]` + /// - data - `[backstop_address: Address, distribution_amount: i128]` + /// + /// ### Arguments + /// * `backstop_address` - The address of the backstop + /// * `distribution_amount` - The amount of tokens distributed + pub fn distribute(e: &Env, backstop_address: Address, distribution_amount: i128) { + let topics = (Symbol::new(e, "distribute"),); + e.events() + .publish(topics, (backstop_address, distribution_amount)); + } + + /// Emitted when a backstop swap is queued + /// + /// - topics - `["q_swap"]` + /// - data - `swap: Swap` + /// + /// ### Arguments + /// * `swap` - The backstop swap details + pub fn q_swap(e: &Env, swap: Swap) { + let topics = (Symbol::new(e, "q_swap"),); + e.events().publish(topics, swap); + } + + /// Emitted when a backstop swap is cancelled + /// + /// - topics - `["del_swap"]` + /// - data - `swap: Swap` + /// + /// ### Arguments + /// * `swap` - The backstop swap details + pub fn del_swap(e: &Env, swap: Swap) { + let topics = (Symbol::new(e, "del_swap"),); + e.events().publish(topics, swap); + } + + /// Emitted when a backstop swap is executed + /// + /// - topics - `["swap"]` + /// - data - `swap: Swap` + /// + /// ### Arguments + /// * `swap` - The backstop swap details + pub fn swap(e: &Env, swap: Swap) { + let topics = (Symbol::new(e, "swap"),); + e.events().publish(topics, swap); + } + + /// Emitted when tokens are dropped from the backstop + /// + /// - topics - `["drop"]` + /// - data - `list: Vec<(Address, i128)>` + /// + /// ### Arguments + /// * `list` - The list of tokens dropped + pub fn drop(e: &Env, list: Vec<(Address, i128)>) { + let topics = (Symbol::new(e, "drop"),); + e.events().publish(topics, list); + } +} diff --git a/emitter/src/lib.rs b/emitter/src/lib.rs index c35f5de..3951a08 100644 --- a/emitter/src/lib.rs +++ b/emitter/src/lib.rs @@ -8,6 +8,7 @@ mod constants; mod contract; mod emitter; mod errors; +mod events; mod storage; mod testutils; diff --git a/pool-factory/src/events.rs b/pool-factory/src/events.rs new file mode 100644 index 0000000..2163827 --- /dev/null +++ b/pool-factory/src/events.rs @@ -0,0 +1,18 @@ +use soroban_sdk::{Address, Env, Symbol}; + +pub struct PoolFactoryEvents {} + +impl PoolFactoryEvents { + /// Emitted when a pool is deployed by the factory + /// + /// - topics - `["distribute"]` + /// - data - `pool_: Address, distribution_amount: i128` + /// + /// ### Arguments + /// * `pool_address` - The address of the pool + /// * `distribution_amount` - The amount of tokens distributed + pub fn deploy(e: &Env, pool_address: Address) { + let topics = (Symbol::new(e, "deploy"),); + e.events().publish(topics, pool_address); + } +} diff --git a/pool-factory/src/lib.rs b/pool-factory/src/lib.rs index 746e096..d16c6fa 100644 --- a/pool-factory/src/lib.rs +++ b/pool-factory/src/lib.rs @@ -4,6 +4,7 @@ extern crate std; mod errors; +mod events; mod pool_factory; mod storage; mod test; diff --git a/pool-factory/src/pool_factory.rs b/pool-factory/src/pool_factory.rs index 885e4bb..e5edd6f 100644 --- a/pool-factory/src/pool_factory.rs +++ b/pool-factory/src/pool_factory.rs @@ -1,5 +1,6 @@ use crate::{ errors::PoolFactoryError, + events::PoolFactoryEvents, storage::{self, PoolInitMeta}, }; use soroban_sdk::{ @@ -106,8 +107,7 @@ impl PoolFactory for PoolFactoryContract { storage::set_deployed(&e, &pool_address); - e.events() - .publish((Symbol::new(&e, "deploy"),), pool_address.clone()); + PoolFactoryEvents::deploy(&e, pool_address.clone()); pool_address } diff --git a/pool/src/auctions/auction.rs b/pool/src/auctions/auction.rs index 9dbacc7..0fc3ba0 100644 --- a/pool/src/auctions/auction.rs +++ b/pool/src/auctions/auction.rs @@ -149,7 +149,7 @@ pub fn fill( user: &Address, filler_state: &mut User, percent_filled: u64, -) { +) -> AuctionData { if user.clone() == filler_state.address { panic_with_error!(e, PoolError::InvalidLiquidation); } @@ -172,6 +172,8 @@ pub fn fill( } else { storage::del_auction(e, &auction_type, user); } + + to_fill_auction } /// Scale the auction based on the percent being filled and the amount of blocks that have passed diff --git a/pool/src/auctions/bad_debt_auction.rs b/pool/src/auctions/bad_debt_auction.rs index ca145d5..c6943dc 100644 --- a/pool/src/auctions/bad_debt_auction.rs +++ b/pool/src/auctions/bad_debt_auction.rs @@ -2,12 +2,13 @@ use crate::{ constants::SCALAR_7, dependencies::BackstopClient, errors::PoolError, + events::PoolEvents, pool::{calc_pool_backstop_threshold, Pool, User}, storage, }; use cast::i128; use soroban_fixed_point_math::FixedPoint; -use soroban_sdk::{map, panic_with_error, unwrap::UnwrapOptimized, Address, Env, Symbol}; +use soroban_sdk::{map, panic_with_error, unwrap::UnwrapOptimized, Address, Env}; use super::{AuctionData, AuctionType}; @@ -107,10 +108,7 @@ pub fn fill_bad_debt_auction( backstop_state.default_liabilities(e, &mut reserve, liability_balance); pool.cache_reserve(reserve); - e.events().publish( - (Symbol::new(e, "bad_debt"), backstop_address.clone()), - (res_asset_address, liability_balance), - ); + PoolEvents::defaulted_debt(e, res_asset_address, liability_balance); } } } diff --git a/pool/src/contract.rs b/pool/src/contract.rs index 1e3410a..38d64c6 100644 --- a/pool/src/contract.rs +++ b/pool/src/contract.rs @@ -1,12 +1,13 @@ use crate::{ auctions::{self, AuctionData}, emissions::{self, ReserveEmissionMetadata}, + events::PoolEvents, pool::{self, Positions, Request, Reserve}, storage::{self, ReserveConfig}, PoolConfig, PoolError, ReserveEmissionsData, UserEmissionData, }; use soroban_sdk::{ - contract, contractclient, contractimpl, panic_with_error, Address, Env, String, Symbol, Vec, + contract, contractclient, contractimpl, panic_with_error, Address, Env, String, Vec, }; /// ### Pool @@ -287,8 +288,7 @@ impl Pool for PoolContract { storage::set_admin(&e, &new_admin); - e.events() - .publish((Symbol::new(&e, "set_admin"), admin), new_admin); + PoolEvents::set_admin(&e, admin, new_admin); } fn update_pool(e: Env, backstop_take_rate: u32, max_positions: u32) { @@ -298,10 +298,7 @@ impl Pool for PoolContract { pool::execute_update_pool(&e, backstop_take_rate, max_positions); - e.events().publish( - (Symbol::new(&e, "update_pool"), admin), - (backstop_take_rate, max_positions), - ); + PoolEvents::update_pool(&e, admin, backstop_take_rate, max_positions); } fn queue_set_reserve(e: Env, asset: Address, metadata: ReserveConfig) { @@ -311,10 +308,7 @@ impl Pool for PoolContract { pool::execute_queue_set_reserve(&e, &asset, &metadata); - e.events().publish( - (Symbol::new(&e, "queue_set_reserve"), admin), - (asset, metadata), - ); + PoolEvents::queue_set_reserve(&e, admin, asset, metadata); } fn cancel_set_reserve(e: Env, asset: Address) { @@ -324,15 +318,13 @@ impl Pool for PoolContract { pool::execute_cancel_queued_set_reserve(&e, &asset); - e.events() - .publish((Symbol::new(&e, "cancel_set_reserve"), admin), asset); + PoolEvents::cancel_set_reserve(&e, admin, asset); } fn set_reserve(e: Env, asset: Address) -> u32 { let index = pool::execute_set_reserve(&e, &asset); - e.events() - .publish((Symbol::new(&e, "set_reserve"),), (asset, index)); + PoolEvents::set_reserve(&e, asset, index); index } @@ -377,8 +369,7 @@ impl Pool for PoolContract { storage::extend_instance(&e); let new_status = pool::execute_update_pool_status(&e); - e.events() - .publish((Symbol::new(&e, "set_status"),), new_status); + PoolEvents::set_status(&e, new_status); new_status } @@ -387,19 +378,18 @@ impl Pool for PoolContract { let admin = storage::get_admin(&e); admin.require_auth(); pool::execute_set_pool_status(&e, pool_status); - e.events() - .publish((Symbol::new(&e, "set_status"), admin), pool_status); + + PoolEvents::set_status_admin(&e, admin, pool_status); } /********* Emission Functions **********/ fn gulp_emissions(e: Env) -> i128 { storage::extend_instance(&e); - let next_expiration = emissions::gulp_emissions(&e); + let emissions = emissions::gulp_emissions(&e); - e.events() - .publish((Symbol::new(&e, "update_emissions"),), next_expiration); - next_expiration + PoolEvents::gulp_emissions(&e, emissions); + emissions } fn set_emissions_config(e: Env, res_emission_metadata: Vec) { @@ -415,10 +405,7 @@ impl Pool for PoolContract { let amount_claimed = emissions::execute_claim(&e, &from, &reserve_token_ids, &to); - e.events().publish( - (Symbol::new(&e, "claim"), from), - (reserve_token_ids, amount_claimed), - ); + PoolEvents::claim(&e, from, reserve_token_ids, amount_claimed); amount_claimed } @@ -456,10 +443,7 @@ impl Pool for PoolContract { _ => panic_with_error!(&e, PoolError::BadRequest), }; - e.events().publish( - (Symbol::new(&e, "new_auction"), auction_type, user), - auction_data.clone(), - ); + PoolEvents::new_auction(&e, user, auction_type, auction_data.clone()); auction_data } diff --git a/pool/src/emissions/manager.rs b/pool/src/emissions/manager.rs index 144437d..ae7257f 100644 --- a/pool/src/emissions/manager.rs +++ b/pool/src/emissions/manager.rs @@ -2,12 +2,13 @@ use crate::{ constants::SCALAR_7, dependencies::BackstopClient, errors::PoolError, + events::PoolEvents, storage::{self, ReserveEmissionsConfig, ReserveEmissionsData}, }; use cast::{i128, u64}; use soroban_fixed_point_math::FixedPoint; use soroban_sdk::{ - contracttype, map, panic_with_error, unwrap::UnwrapOptimized, Address, Env, Map, Symbol, Vec, + contracttype, map, panic_with_error, unwrap::UnwrapOptimized, Address, Env, Map, Vec, }; use super::distributor; @@ -134,10 +135,7 @@ fn update_reserve_emission_config( let new_reserve_emis_config = ReserveEmissionsConfig { expiration, eps }; storage::set_res_emis_config(e, &res_token_id, &new_reserve_emis_config); - e.events().publish( - (Symbol::new(e, "reserve_emission_update"),), - (res_token_id, eps, expiration), - ) + PoolEvents::reserve_emission_update(e, res_token_id, eps, expiration); } #[cfg(test)] diff --git a/pool/src/events.rs b/pool/src/events.rs new file mode 100644 index 0000000..164c39f --- /dev/null +++ b/pool/src/events.rs @@ -0,0 +1,326 @@ +use soroban_sdk::{Address, Env, Symbol, Vec}; + +use crate::{AuctionData, ReserveConfig}; + +pub struct PoolEvents {} + +impl PoolEvents { + /// Emitted when a new admin is set for a pool + /// + /// - topics - `["set_admin", admin: Address]` + /// - data - `new_admin: Address` + /// + /// ### Arguments + /// * admin - The current admin of the pool + /// * new_admin - The new admin of the pool + pub fn set_admin(e: &Env, admin: Address, new_admin: Address) { + let topics = (Symbol::new(&e, "set_admin"), admin); + e.events().publish(topics, new_admin); + } + + /// Emitted when pool parameters are updated + /// + /// - topics - `["update_pool", admin: Address]` + /// - data - `[backstop_take_rate: u32, max_positions: u32]` + /// + /// ### Arguments + /// * admin - The current admin of the pool + /// * backstop_take_rate - The new backstop take rate + /// * max_positions - The new maximum number of positions + pub fn update_pool(e: &Env, admin: Address, backstop_take_rate: u32, max_positions: u32) { + let topics = (Symbol::new(&e, "update_pool"), admin); + e.events() + .publish(topics, (backstop_take_rate, max_positions)); + } + + /// Emitted when a new reserve configuration change is queued + /// + /// - topics - `["queue_set_reserve", admin: Address]` + /// - data - `[asset: Address, metadata: ReserveMetadata]` + /// + /// ### Arguments + /// * admin - The current admin of the pool + /// * asset - The asset to change the reserve configuration of + /// * metadata - The new reserve configuration + pub fn queue_set_reserve(e: &Env, admin: Address, asset: Address, metadata: ReserveConfig) { + let topics = (Symbol::new(&e, "queue_set_reserve"), admin); + e.events().publish(topics, (asset, metadata)); + } + + /// Emitted when a queued reserve configuration change is cancelled + /// + /// - topics - `["cancel_set_reserve", admin: Address]` + /// - data - `asset: Address` + /// + /// ### Arguments + /// * admin - The current admin of the pool + /// * asset - The asset to cancel the reserve configuration change of + pub fn cancel_set_reserve(e: &Env, admin: Address, asset: Address) { + let topics = (Symbol::new(&e, "cancel_set_reserve"), admin); + e.events().publish(topics, asset); + } + + /// Emitted when a reserve configuration change is set + /// + /// - topics - `["set_reserve"]` + /// - data - `[asset: Address, index: u32]` + /// + /// ### Arguments + /// * asset - The asset to change the reserve configuration of + /// * index - The reserve index + pub fn set_reserve(e: &Env, asset: Address, index: u32) { + let topics = (Symbol::new(&e, "set_reserve"),); + e.events().publish(topics, (asset, index)); + } + + /// Emitted when pool status is updated (non-admin) + /// + /// - topics - `["set_status"]` + /// - data - `new_status: PoolStatus` + /// + /// ### Arguments + /// * new_status - The new pool status + pub fn set_status(e: &Env, new_status: u32) { + let topics = (Symbol::new(&e, "set_status"),); + e.events().publish(topics, new_status); + } + + /// Emitted when pool status is updated by admin + /// + /// - topics - `["set_status", admin: Address]` + /// - data - `pool_status: PoolStatus` + /// + /// ### Arguments + /// * admin - The admin setting the pool status + /// * pool_status - The new pool status + pub fn set_status_admin(e: &Env, admin: Address, pool_status: u32) { + let topics = (Symbol::new(&e, "set_status"), admin); + e.events().publish(topics, pool_status); + } + + /// Emitted when reserve emissions are updated + /// + /// - topics - `["reserve_emission_update"]` + /// - data - `[res_token_id: u32, eps: u64, expiration: u64]` + /// + /// ### Arguments + /// * res_token_id - The reserve token ID + /// * eps - The new emissions per second + /// * expiration - The new expiration time + pub fn reserve_emission_update(e: &Env, res_token_id: u32, eps: u64, expiration: u64) { + let topics = (Symbol::new(e, "reserve_emission_update"),); + e.events().publish(topics, (res_token_id, eps, expiration)); + } + + /// Emitted when emissions are gulped + /// + /// - topics - `["update_emissions"]` + /// - data - `emissions: i128` + /// + /// ### Arguments + /// * emissions - The amount of emissions gulped + pub fn gulp_emissions(e: &Env, emissions: i128) { + let topics = (Symbol::new(&e, "gulp_emissions"),); + e.events().publish(topics, emissions); + } + + /// Emitted when emissions are claimed + /// + /// - topics - `["claim", from: Address]` + /// - data - `[reserve_token_ids: Vec, amount_claimed: i128]` + /// + /// ### Arguments + /// * from - The address claiming the emissions + /// * reserve_token_ids - The reserve token IDs claimed + /// * amount_claimed - The amount claimed + pub fn claim(e: &Env, from: Address, reserve_token_ids: Vec, amount_claimed: i128) { + let topics = (Symbol::new(&e, "claim"), from); + e.events() + .publish(topics, (reserve_token_ids, amount_claimed)); + } + + /// Emitted when bad debt is recorded + /// + /// - topics - `["bad_debt", user: Address, asset: Address]` + /// - data - `[d_tokens: i128]` + /// + /// ### Arguments + /// * user - The user with bad debt + /// * asset - The asset with bad debt + /// * d_tokens - The amount of bad debt + pub fn bad_debt(e: &Env, user: Address, asset: Address, d_tokens: i128) { + let topics = (Symbol::new(e, "bad_debt"), user, asset); + e.events().publish(topics, d_tokens); + } + + /// Emitted when bad debt is defaulted + /// + /// - topics - `["defaulted_debt", asset: Address]` + /// - data - `[d_tokens_burnt: i128]` + /// + /// ### Arguments + /// * asset - The asset with defaulted debt + /// * d_tokens_burnt - The amount of defaulted d_tokens + pub fn defaulted_debt(e: &Env, asset: Address, d_tokens_burnt: i128) { + let topics = (Symbol::new(e, "defaulted_debt"), asset); + e.events().publish(topics, d_tokens_burnt); + } + + /// Emitted when tokens are supplied + /// + /// - topics - `["supply", asset: Address, from: Address]` + /// - data - `[tokens_in: i128, b_tokens_minted: i128]` + /// + /// ### Arguments + /// * asset - The asset + /// * from - The address whose position is being modified + /// * tokens_in - The amount of tokens sent to the pool + /// * b_tokens_minted - The amount of b_tokens minted + pub fn supply(e: &Env, asset: Address, from: Address, tokens_in: i128, b_tokens_minted: i128) { + let topics = (Symbol::new(e, "supply"), asset, from); + e.events().publish(topics, (tokens_in, b_tokens_minted)); + } + + /// Emitted when tokens are withdrawn + /// + /// - topics - `["withdraw", asset: Address, from: Address]` + /// - data - `[tokens_out: i128, b_tokens_burnt: i128]` + /// + /// ### Arguments + /// * asset - The asset + /// * from - The address whose position is being modified + /// * tokens_out - The amount of tokens withdrawn from the pool + /// * b_tokens_burnt - The amount of b_tokens burnt + pub fn withdraw( + e: &Env, + asset: Address, + from: Address, + tokens_out: i128, + b_tokens_burnt: i128, + ) { + let topics = (Symbol::new(e, "withdraw"), asset, from); + e.events().publish(topics, (tokens_out, b_tokens_burnt)); + } + + /// Emitted when collateral is supplied + /// + /// - topics - `["supply_collateral", asset: Address, from: Address]` + /// - data - `[tokens_in: i128, b_tokens_minted: i128]` + /// + /// ### Arguments + /// * asset - The asset + /// * from - The address whose position is being modified + /// * tokens_in - The amount of tokens sent to the pool + /// * b_tokens_minted - The amount of b_tokens minted + pub fn supply_collateral( + e: &Env, + asset: Address, + from: Address, + tokens_in: i128, + b_tokens_minted: i128, + ) { + let topics = (Symbol::new(e, "supply_collateral"), asset, from); + e.events().publish(topics, (tokens_in, b_tokens_minted)); + } + + /// Emitted when collateral is withdrawn + /// + /// - topics - `["withdraw_collateral", asset: Address, from: Address]` + /// - data - `[tokens_out: i128, b_tokens_burnt: i128]` + /// + /// ### Arguments + /// * asset - The asset + /// * from - The address whose position is being modified + /// * tokens_out - The amount of tokens withdrawn from the pool + /// * b_tokens_burnt - The amount of b_tokens burnt + pub fn withdraw_collateral( + e: &Env, + asset: Address, + from: Address, + tokens_out: i128, + b_tokens_burnt: i128, + ) { + let topics = (Symbol::new(e, "withdraw_collateral"), asset, from); + e.events().publish(topics, (tokens_out, b_tokens_burnt)); + } + + /// Emitted when tokens are borrowed + /// + /// - topics - `["borrow", asset: Address, from: Address]` + /// - data - `[tokens_out: i128, d_tokens_minted: i128]` + /// + /// ### Arguments + /// * asset - The asset + /// * from - The address whose position is being modified + /// * tokens_out - The amount of tokens sent from the pool + /// * d_tokens_burnt - The amount of d_tokens burnt + pub fn borrow(e: &Env, asset: Address, from: Address, tokens_out: i128, d_tokens_minted: i128) { + let topics = (Symbol::new(e, "borrow"), asset, from); + e.events().publish(topics, (tokens_out, d_tokens_minted)); + } + + /// Emitted when a loan is repaid + /// + /// - topics - `["repay", asset: Address, from: Address]` + /// - data - `[tokens_in: i128, d_tokens_burnt: i128]` + /// + /// ### Arguments + /// * asset - The asset + /// * from - The address whose position is being modified + /// * tokens_in - The amount of tokens sent to the pool + /// * d_tokens_burnt - The amount of d_tokens burnt + pub fn repay(e: &Env, asset: Address, from: Address, tokens_in: i128, d_tokens_burnt: i128) { + let topics = (Symbol::new(e, "repay"), asset, from); + e.events().publish(topics, (tokens_in, d_tokens_burnt)); + } + + /// Emitted when a new auction is created + /// + /// - topics - `["new_auction", user: Address, auction_type: u32]` + /// - data - `auction_data: AuctionData` + /// + /// ### Arguments + /// * user - The auction user + /// * auction_type - The type of auction + /// * auction_data - The auction data + pub fn new_auction(e: &Env, user: Address, auction_type: u32, auction_data: AuctionData) { + let topics = (Symbol::new(e, "new_auction"), user, auction_type); + e.events().publish(topics, auction_data); + } + + /// Emitted when an auction is filled + /// + /// - topics - `["fill_auction", user: Address, auction_type: u32]` + /// - data - `[filler: Address, fill_percent: i128, filled_auction_data: AuctionData]` + /// + /// ### Arguments + /// * user - The auction user + /// * auction_type - The type of auction + /// * filler - The address of the filler + /// * fill_percent - The percentage of the auction filled + /// * filled_auction_data - The filled auction data + pub fn fill_auction( + e: &Env, + user: Address, + auction_type: u32, + filler: Address, + fill_percent: i128, + filled_auction_data: AuctionData, + ) { + let topics = (Symbol::new(e, "fill_auction"), user, auction_type); + e.events() + .publish(topics, (filler, fill_percent, filled_auction_data)); + } + + /// Emitted when a liquidation auction is deleted + /// + /// - topics - `["delete_liquidation_auction", from: Address]` + /// - data - `()` + /// + /// ### Arguments + /// * from - The address of the liquidated user + pub fn delete_liquidation_auction(e: &Env, from: Address) { + let topics = (Symbol::new(&e, "delete_liquidation_auction"), from); + e.events().publish(topics, ()); + } +} diff --git a/pool/src/lib.rs b/pool/src/lib.rs index 03b857d..bd1b3c6 100644 --- a/pool/src/lib.rs +++ b/pool/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] + #[cfg(any(test, feature = "testutils"))] extern crate std; @@ -11,6 +12,7 @@ mod contract; mod dependencies; mod emissions; mod errors; +mod events; mod pool; mod storage; mod testutils; diff --git a/pool/src/pool/actions.rs b/pool/src/pool/actions.rs index f55ebe4..7403b01 100644 --- a/pool/src/pool/actions.rs +++ b/pool/src/pool/actions.rs @@ -1,6 +1,7 @@ use soroban_sdk::Map; -use soroban_sdk::{contracttype, panic_with_error, Address, Env, Symbol, Vec}; +use soroban_sdk::{contracttype, panic_with_error, Address, Env, Vec}; +use crate::events::PoolEvents; use crate::{auctions, errors::PoolError, validator::require_nonnegative}; use super::pool::Pool; @@ -122,13 +123,12 @@ pub fn build_actions_from_request( from_state.add_supply(e, &mut reserve, b_tokens_minted); actions.add_for_spender_transfer(&reserve.asset, request.amount); pool.cache_reserve(reserve); - e.events().publish( - ( - Symbol::new(e, "supply"), - request.address.clone(), - from.clone(), - ), - (request.amount, b_tokens_minted), + PoolEvents::supply( + e, + request.address.clone(), + from.clone(), + request.amount, + b_tokens_minted, ); } RequestType::Withdraw => { @@ -143,13 +143,12 @@ pub fn build_actions_from_request( from_state.remove_supply(e, &mut reserve, to_burn); actions.add_for_pool_transfer(&reserve.asset, tokens_out); pool.cache_reserve(reserve); - e.events().publish( - ( - Symbol::new(e, "withdraw"), - request.address.clone(), - from.clone(), - ), - (tokens_out, to_burn), + PoolEvents::withdraw( + e, + request.address.clone(), + from.clone(), + request.amount, + to_burn, ); } RequestType::SupplyCollateral => { @@ -158,13 +157,12 @@ pub fn build_actions_from_request( from_state.add_collateral(e, &mut reserve, b_tokens_minted); actions.add_for_spender_transfer(&reserve.asset, request.amount); pool.cache_reserve(reserve); - e.events().publish( - ( - Symbol::new(e, "supply_collateral"), - request.address.clone(), - from.clone(), - ), - (request.amount, b_tokens_minted), + PoolEvents::supply_collateral( + e, + request.address.clone(), + from.clone(), + request.amount, + b_tokens_minted, ); } RequestType::WithdrawCollateral => { @@ -180,13 +178,12 @@ pub fn build_actions_from_request( actions.add_for_pool_transfer(&reserve.asset, tokens_out); check_health = true; pool.cache_reserve(reserve); - e.events().publish( - ( - Symbol::new(e, "withdraw_collateral"), - request.address.clone(), - from.clone(), - ), - (tokens_out, to_burn), + PoolEvents::withdraw_collateral( + e, + request.address.clone(), + from.clone(), + tokens_out, + to_burn, ); } RequestType::Borrow => { @@ -197,13 +194,12 @@ pub fn build_actions_from_request( actions.add_for_pool_transfer(&reserve.asset, request.amount); check_health = true; pool.cache_reserve(reserve); - e.events().publish( - ( - Symbol::new(e, "borrow"), - request.address.clone(), - from.clone(), - ), - (request.amount, d_tokens_minted), + PoolEvents::borrow( + e, + request.address.clone(), + from.clone(), + request.amount, + d_tokens_minted, ); } RequestType::Repay => { @@ -217,29 +213,27 @@ pub fn build_actions_from_request( require_nonnegative(e, &amount_to_refund); from_state.remove_liabilities(e, &mut reserve, cur_d_tokens); actions.add_for_pool_transfer(&reserve.asset, amount_to_refund); - e.events().publish( - ( - Symbol::new(e, "repay"), - request.address.clone().clone(), - from.clone(), - ), - (request.amount - amount_to_refund, cur_d_tokens), + PoolEvents::repay( + e, + request.address.clone(), + from.clone(), + request.amount - amount_to_refund, + cur_d_tokens, ); } else { from_state.remove_liabilities(e, &mut reserve, d_tokens_burnt); - e.events().publish( - ( - Symbol::new(e, "repay"), - request.address.clone().clone(), - from.clone(), - ), - (request.amount, d_tokens_burnt), + PoolEvents::repay( + e, + request.address.clone(), + from.clone(), + request.amount, + d_tokens_burnt, ); } pool.cache_reserve(reserve); } RequestType::FillUserLiquidationAuction => { - auctions::fill( + let filled_auction = auctions::fill( e, pool, 0, @@ -249,18 +243,18 @@ pub fn build_actions_from_request( ); check_health = true; - e.events().publish( - ( - Symbol::new(e, "fill_auction"), - request.address.clone().clone(), - 0_u32, - ), - (from.clone(), request.amount), + PoolEvents::fill_auction( + e, + request.address.clone(), + 0u32, + from.clone(), + request.amount, + filled_auction, ); } RequestType::FillBadDebtAuction => { // Note: will fail if input address is not the backstop since there cannot be a bad debt auction for a different address in storage - auctions::fill( + let filled_auction = auctions::fill( e, pool, 1, @@ -270,18 +264,18 @@ pub fn build_actions_from_request( ); check_health = true; - e.events().publish( - ( - Symbol::new(e, "fill_auction"), - request.address.clone().clone(), - 1_u32, - ), - (from.clone(), request.amount), + PoolEvents::fill_auction( + e, + request.address.clone(), + 1u32, + from.clone(), + request.amount, + filled_auction, ); } RequestType::FillInterestAuction => { // Note: will fail if input address is not the backstop since there cannot be an interest auction for a different address in storage - auctions::fill( + let filled_auction = auctions::fill( e, pool, 2, @@ -289,23 +283,20 @@ pub fn build_actions_from_request( &mut from_state, request.amount as u64, ); - e.events().publish( - ( - Symbol::new(e, "fill_auction"), - request.address.clone().clone(), - 2_u32, - ), - (from.clone(), request.amount), + PoolEvents::fill_auction( + e, + request.address.clone(), + 2u32, + from.clone(), + request.amount, + filled_auction, ); } RequestType::DeleteLiquidationAuction => { // Note: request object is ignored besides type auctions::delete_liquidation(e, &from); check_health = true; - e.events().publish( - (Symbol::new(&e, "delete_liquidation_auction"), from.clone()), - (), - ); + PoolEvents::delete_liquidation_auction(e, from.clone()); } } } diff --git a/pool/src/pool/bad_debt.rs b/pool/src/pool/bad_debt.rs index d6231ef..f35168a 100644 --- a/pool/src/pool/bad_debt.rs +++ b/pool/src/pool/bad_debt.rs @@ -1,7 +1,8 @@ -use soroban_sdk::{panic_with_error, Address, Env, Symbol}; +use soroban_sdk::{panic_with_error, Address, Env}; use crate::{ errors::PoolError, + events::PoolEvents, storage::{self}, }; @@ -40,10 +41,7 @@ pub fn transfer_bad_debt_to_backstop(e: &Env, user: &Address) { new_user_state.remove_liabilities(e, &mut reserve, liability_balance); pool.cache_reserve(reserve); - e.events().publish( - (Symbol::new(e, "bad_debt"), user), - (asset, liability_balance), - ); + PoolEvents::bad_debt(e, user.clone(), asset, liability_balance); } pool.store_cached_reserves(e); diff --git a/test-suites/tests/test_liquidation.rs b/test-suites/tests/test_liquidation.rs index b5ea312..c072313 100644 --- a/test-suites/tests/test_liquidation.rs +++ b/test-suites/tests/test_liquidation.rs @@ -1,10 +1,10 @@ #![cfg(test)] use cast::i128; -use pool::{PoolDataKey, Positions, Request, RequestType, ReserveConfig, ReserveData}; +use pool::{AuctionData, PoolDataKey, Positions, Request, RequestType, ReserveConfig, ReserveData}; use soroban_fixed_point_math::FixedPoint; use soroban_sdk::{ testutils::{Address as AddressTestTrait, Events}, - vec, Address, Error, IntoVal, Symbol, Val, Vec, + vec, Address, Env, Error, FromVal, IntoVal, Symbol, TryFromVal, Val, Vec, }; use test_suites::{ assertions::assert_approx_eq_abs, @@ -12,6 +12,39 @@ use test_suites::{ test_fixture::{TokenIndex, SCALAR_7}, }; +fn assert_fill_auction_event_no_data( + env: &Env, + event: (Address, Vec, Val), + pool_address: &Address, + auction_user: &Address, + auction_type: u32, + filler: &Address, + fill_pct: i128, +) { + let (event_pool_address, topics, data) = event; + assert_eq!(event_pool_address, pool_address.clone()); + + assert_eq!(topics.len(), 3); + assert_eq!( + Symbol::from_val(env, &topics.get_unchecked(0)), + Symbol::new(env, "fill_auction") + ); + assert_eq!( + Address::from_val(env, &topics.get_unchecked(1)), + auction_user.clone() + ); + assert_eq!(u32::from_val(env, &topics.get_unchecked(2)), auction_type); + + let event_data = Vec::::from_val(env, &data); + assert_eq!(event_data.len(), 3); + assert_eq!( + Address::from_val(env, &event_data.get_unchecked(0)), + filler.clone() + ); + assert_eq!(i128::from_val(env, &event_data.get_unchecked(1)), fill_pct); + assert!(AuctionData::try_from_val(env, &event_data.get_unchecked(2)).is_ok()); +} + #[test] fn test_liquidations() { let fixture = create_fixture_with_data(false); @@ -191,8 +224,8 @@ fn test_liquidations() { pool_fixture.pool.address.clone(), ( Symbol::new(&fixture.env, "new_auction"), - 2 as u32, - fixture.backstop.address.clone() + fixture.backstop.address.clone(), + 2 as u32 ) .into_val(&fixture.env), auction_data.into_val(&fixture.env) @@ -248,8 +281,8 @@ fn test_liquidations() { pool_fixture.pool.address.clone(), ( Symbol::new(&fixture.env, "new_auction"), - 0 as u32, - samwise.clone() + samwise.clone(), + 0 as u32 ) .into_val(&fixture.env), auction_data.into_val(&fixture.env) @@ -345,91 +378,41 @@ fn test_liquidations() { 10i128.pow(9), ); let events = fixture.env.events().all(); - let event = vec![&fixture.env, events.get_unchecked(events.len() - 16)]; - let fill_pct_1: i128 = 25; - let fill_pct_2: i128 = 100; - let fill_pct_3: i128 = 99; - let event_data_1: Vec = vec![ - &fixture.env, - frodo.into_val(&fixture.env), - fill_pct_1.into_val(&fixture.env), - ]; - let event_data_2: Vec = vec![ - &fixture.env, - frodo.into_val(&fixture.env), - fill_pct_2.into_val(&fixture.env), - ]; - let event_data_3: Vec = vec![ + assert_fill_auction_event_no_data( &fixture.env, - frodo.into_val(&fixture.env), - fill_pct_3.into_val(&fixture.env), - ]; - assert_eq!( - event, - vec![ - &fixture.env, - ( - pool_fixture.pool.address.clone(), - ( - Symbol::new(&fixture.env, "fill_auction"), - samwise.clone(), - auct_type_1 - ) - .into_val(&fixture.env), - event_data_1.into_val(&fixture.env) - ) - ] + events.get_unchecked(events.len() - 16), + &pool_fixture.pool.address, + &samwise, + auct_type_1, + &frodo, + 25, ); - let event = vec![&fixture.env, events.get_unchecked(events.len() - 15)]; - assert_eq!( - event, - vec![ - &fixture.env, - ( - pool_fixture.pool.address.clone(), - ( - Symbol::new(&fixture.env, "fill_auction"), - samwise.clone(), - auct_type_1 - ) - .into_val(&fixture.env), - event_data_2.into_val(&fixture.env) - ) - ] + assert_fill_auction_event_no_data( + &fixture.env, + events.get_unchecked(events.len() - 15), + &pool_fixture.pool.address, + &samwise, + auct_type_1, + &frodo, + 100, ); - let event = vec![&fixture.env, events.get_unchecked(events.len() - 9)]; - assert_eq!( - event, - vec![ - &fixture.env, - ( - pool_fixture.pool.address.clone(), - ( - Symbol::new(&fixture.env, "fill_auction"), - fixture.backstop.address.clone(), - auct_type_2 - ) - .into_val(&fixture.env), - event_data_3.into_val(&fixture.env) - ) - ] + assert_fill_auction_event_no_data( + &fixture.env, + events.get_unchecked(events.len() - 9), + &pool_fixture.pool.address, + &fixture.backstop.address, + auct_type_2, + &frodo, + 99, ); - let event = vec![&fixture.env, events.get_unchecked(events.len() - 3)]; - assert_eq!( - event, - vec![ - &fixture.env, - ( - pool_fixture.pool.address.clone(), - ( - Symbol::new(&fixture.env, "fill_auction"), - fixture.backstop.address.clone(), - auct_type_2 - ) - .into_val(&fixture.env), - event_data_2.into_val(&fixture.env) - ) - ] + assert_fill_auction_event_no_data( + &fixture.env, + events.get_unchecked(events.len() - 3), + &pool_fixture.pool.address, + &fixture.backstop.address, + auct_type_2, + &frodo, + 100, ); //tank eth price @@ -602,8 +585,8 @@ fn test_liquidations() { pool_fixture.pool.address.clone(), ( Symbol::new(&fixture.env, "new_auction"), - auction_type, - fixture.backstop.address.clone() + fixture.backstop.address.clone(), + auction_type ) .into_val(&fixture.env), bad_debt_auction_data.into_val(&fixture.env) @@ -696,28 +679,14 @@ fn test_liquidations() { ); assert_eq!(new_auction.block, bad_debt_auction_data.block); let events = fixture.env.events().all(); - let event = vec![&fixture.env, events.get_unchecked(events.len() - 1)]; - let fill_pct: i128 = 20; - let event_data: Vec = vec![ + assert_fill_auction_event_no_data( &fixture.env, - frodo.into_val(&fixture.env), - fill_pct.into_val(&fixture.env), - ]; - assert_eq!( - event, - vec![ - &fixture.env, - ( - pool_fixture.pool.address.clone(), - ( - Symbol::new(&fixture.env, "fill_auction"), - fixture.backstop.address.clone(), - auction_type - ) - .into_val(&fixture.env), - event_data.into_val(&fixture.env) - ) - ] + events.get_unchecked(events.len() - 1), + &pool_fixture.pool.address, + &fixture.backstop.address, + auction_type, + &frodo, + 20, ); // allow another 50 blocks to pass (150 total) fixture.jump_with_sequence(50 * 5); @@ -759,28 +728,14 @@ fn test_liquidations() { SCALAR_7, ); let events = fixture.env.events().all(); - let event = vec![&fixture.env, events.get_unchecked(events.len() - 1)]; - let fill_pct: i128 = 100; - let event_data: Vec = vec![ + assert_fill_auction_event_no_data( &fixture.env, - frodo.into_val(&fixture.env), - fill_pct.into_val(&fixture.env), - ]; - assert_eq!( - event, - vec![ - &fixture.env, - ( - pool_fixture.pool.address.clone(), - ( - Symbol::new(&fixture.env, "fill_auction"), - fixture.backstop.address.clone(), - auction_type - ) - .into_val(&fixture.env), - event_data.into_val(&fixture.env) - ) - ] + events.get_unchecked(events.len() - 1), + &pool_fixture.pool.address, + &fixture.backstop.address, + auction_type, + &frodo, + 100, ); //check that frodo was correctly slashed @@ -861,8 +816,8 @@ fn test_liquidations() { pool_fixture.pool.address.clone(), ( Symbol::new(&fixture.env, "new_auction"), + samwise.clone(), 0 as u32, - samwise.clone() ) .into_val(&fixture.env), auction_data.into_val(&fixture.env) @@ -901,13 +856,13 @@ fn test_liquidations() { &fixture.env, ( pool_fixture.pool.address.clone(), - (Symbol::new(&fixture.env, "bad_debt"), samwise.clone()).into_val(&fixture.env), - vec![ - &fixture.env, - fixture.tokens[TokenIndex::STABLE].address.clone().to_val(), - bad_debt.into_val(&fixture.env), - ] - .into_val(&fixture.env) + ( + Symbol::new(&fixture.env, "bad_debt"), + samwise.clone(), + fixture.tokens[TokenIndex::STABLE].address.clone() + ) + .into_val(&fixture.env), + bad_debt.into_val(&fixture.env) ) ] ); @@ -998,16 +953,11 @@ fn test_liquidations() { ( pool_fixture.pool.address.clone(), ( - Symbol::new(&fixture.env, "bad_debt"), - fixture.backstop.address.clone() + Symbol::new(&fixture.env, "defaulted_debt"), + fixture.tokens[TokenIndex::STABLE].address.clone() ) .into_val(&fixture.env), - vec![ - &fixture.env, - fixture.tokens[TokenIndex::STABLE].address.clone().to_val(), - bad_debt.into_val(&fixture.env), - ] - .into_val(&fixture.env) + bad_debt.into_val(&fixture.env) ) ] );