Skip to content

Commit

Permalink
Merge pull request #155 from blend-capital/status-management-updates
Browse files Browse the repository at this point in the history
Pool: Status management updates
  • Loading branch information
mootz12 authored Dec 19, 2023
2 parents 5a64f8b + 6556498 commit d40bc18
Show file tree
Hide file tree
Showing 8 changed files with 745 additions and 75 deletions.
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

0 comments on commit d40bc18

Please sign in to comment.