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: Status management updates #155

Merged
merged 7 commits into from
Dec 19, 2023
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
2 changes: 1 addition & 1 deletion pool-factory/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ fn test_pool_factory() {
pool::PoolConfig {
oracle: oracle,
bstop_rate: backstop_rate,
status: 1
status: 3
}
);
assert_eq!(
Expand Down
31 changes: 18 additions & 13 deletions pool/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,28 +119,35 @@ pub trait Pool {
/// If the user has collateral posted
fn bad_debt(e: Env, user: Address);

/// Update the pool status based on the backstop state
/// * 0 = active - if the minimum backstop deposit has been reached
/// * 1 = on ice - if the minimum backstop deposit has not been reached
/// or 25% of backstop deposits are queued for withdrawal
/// * 2 = frozen - if 50% of backstop deposits are queued for withdrawal
/// Update the pool status based on the backstop state - backstop triggered status' are odd numbers
/// * 1 = backstop active - if the minimum backstop deposit has been reached
/// and 30% of backstop deposits are not queued for withdrawal
/// then all pool operations are permitted
/// * 3 = backstop on-ice - if the minimum backstop deposit has not been reached
/// or 30% of backstop deposits are queued for withdrawal and admin active isn't set
/// or 50% of backstop deposits are queued for withdrawal
/// then borrowing and cancelling liquidations are not permitted
/// * 5 = backstop frozen - if 60% of backstop deposits are queued for withdrawal and admin on-ice isn't set
/// or 75% of backstop deposits are queued for withdrawal
/// then all borrowing, cancelling liquidations, and supplying are not permitted
///
/// ### Panics
/// If the pool is currently of status 3, "admin-freeze", where only the admin
/// If the pool is currently on status 4, "admin-freeze", where only the admin
/// can perform a status update via `set_status`
fn update_status(e: Env) -> u32;

/// (Admin only) Pool status is changed to "pool_status"
/// * 0 = active
/// * 1 = on ice
/// * 2 = frozen
/// * 3 = admin frozen (only the admin can unfreeze)
/// * 0 = admin active - requires that the backstop threshold is met
/// and less than 50% of backstop deposits are queued for withdrawal
/// * 2 = admin on-ice - requires that less than 75% of backstop deposits are queued for withdrawal
/// * 4 = admin frozen - can always be set
///
/// ### Arguments
/// * 'pool_status' - The pool status to be set
///
/// ### Panics
/// If the caller is not the admin
/// If the specified conditions are not met for the status to be set
fn set_status(e: Env, pool_status: u32);

/********* Emission Functions **********/
Expand Down Expand Up @@ -314,9 +321,7 @@ impl Pool for PoolContract {
storage::extend_instance(&e);
let admin = storage::get_admin(&e);
admin.require_auth();

pool::set_pool_status(&e, pool_status);

pool::execute_set_pool_status(&e, pool_status);
e.events()
.publish((Symbol::new(&e, "set_status"), admin), pool_status);
}
Expand Down
1 change: 1 addition & 0 deletions pool/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub enum PoolError {
NegativeAmount = 4,
InvalidPoolInitArgs = 5,
InvalidReserveMetadata = 6,
StatusNotAllowed = 8,
// Pool State Errors (10-19)
InvalidHf = 10,
InvalidPoolStatus = 11,
Expand Down
4 changes: 2 additions & 2 deletions pool/src/pool/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub fn execute_initialize(
&PoolConfig {
oracle: oracle.clone(),
bstop_rate: *bstop_rate,
status: 1,
status: 3,
},
);
storage::set_blnd_token(e, blnd_id);
Expand Down Expand Up @@ -160,7 +160,7 @@ mod tests {
let pool_config = storage::get_pool_config(&e);
assert_eq!(pool_config.oracle, oracle);
assert_eq!(pool_config.bstop_rate, bstop_rate);
assert_eq!(pool_config.status, 1);
assert_eq!(pool_config.status, 3);
assert_eq!(storage::get_backstop(&e), backstop_address);
assert_eq!(storage::get_blnd_token(&e), blnd_id);
assert_eq!(storage::get_usdc_token(&e), usdc_id);
Expand Down
4 changes: 3 additions & 1 deletion pool/src/pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ mod user;
pub use user::{Positions, User};

mod status;
pub use status::{calc_pool_backstop_threshold, execute_update_pool_status, set_pool_status};
pub use status::{
calc_pool_backstop_threshold, execute_set_pool_status, execute_update_pool_status,
};
55 changes: 47 additions & 8 deletions pool/src/pool/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ impl Pool {
/// ### Arguments
/// * `action_type` - The type of action being performed
pub fn require_action_allowed(&self, e: &Env, action_type: u32) {
// disable borrowing for any non-active pool and disable supplying for any frozen pool
if (self.config.status > 0 && action_type == 4)
|| (self.config.status > 1 && (action_type == 2 || action_type == 0))
// disable borrowing or auction cancellation for any non-active pool and disable supplying for any frozen pool
if (self.config.status > 1 && (action_type == 4 || action_type == 9))
|| (self.config.status > 3 && (action_type == 2 || action_type == 0))
{
panic_with_error!(e, PoolError::InvalidPoolStatus);
}
Expand Down Expand Up @@ -267,7 +267,7 @@ mod tests {
let pool_config = PoolConfig {
oracle,
bstop_rate: 0_200_000_000,
status: 1,
status: 2,
};
e.as_contract(&pool, || {
storage::set_pool_config(&e, &pool_config);
Expand All @@ -286,7 +286,7 @@ mod tests {
let pool_config = PoolConfig {
oracle,
bstop_rate: 0_200_000_000,
status: 0,
status: 1,
};
e.as_contract(&pool, || {
storage::set_pool_config(&e, &pool_config);
Expand All @@ -298,7 +298,7 @@ mod tests {

#[test]
#[should_panic(expected = "Error(Contract, #11)")]
fn test_require_action_allowed_supply_while_frozen() {
fn test_require_action_allowed_cancel_liquidation_while_on_ice_panics() {
let e = Env::default();

let pool = testutils::create_pool(&e);
Expand All @@ -312,6 +312,45 @@ mod tests {
storage::set_pool_config(&e, &pool_config);
let pool = Pool::load(&e);

pool.require_action_allowed(&e, 9);
});
}

#[test]
fn test_require_action_allowed_cancel_liquidation_while_active() {
let e = Env::default();

let pool = testutils::create_pool(&e);
let oracle = Address::generate(&e);
let pool_config = PoolConfig {
oracle,
bstop_rate: 0_200_000_000,
status: 1,
};
e.as_contract(&pool, || {
storage::set_pool_config(&e, &pool_config);
let pool = Pool::load(&e);

pool.require_action_allowed(&e, 9);
});
}

#[test]
#[should_panic(expected = "Error(Contract, #11)")]
fn test_require_action_allowed_supply_while_frozen() {
let e = Env::default();

let pool = testutils::create_pool(&e);
let oracle = Address::generate(&e);
let pool_config = PoolConfig {
oracle,
bstop_rate: 0_200_000_000,
status: 4,
};
e.as_contract(&pool, || {
storage::set_pool_config(&e, &pool_config);
let pool = Pool::load(&e);

pool.require_action_allowed(&e, 0);
});
}
Expand All @@ -326,7 +365,7 @@ mod tests {
let pool_config = PoolConfig {
oracle,
bstop_rate: 0_200_000_000,
status: 2,
status: 4,
};
e.as_contract(&pool, || {
storage::set_pool_config(&e, &pool_config);
Expand All @@ -345,7 +384,7 @@ mod tests {
let pool_config = PoolConfig {
oracle,
bstop_rate: 0_200_000_000,
status: 2,
status: 4,
};
e.as_contract(&pool, || {
storage::set_pool_config(&e, &pool_config);
Expand Down
Loading