mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-07-03 05:29:50 +00:00
fix(stablecoin): bound redemption controller price
This commit is contained in:
parent
1679d5a4b8
commit
35c4eb3373
@ -118,9 +118,9 @@
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"name": "controller",
|
"name": "controller",
|
||||||
"writable": false,
|
"writable": true,
|
||||||
"signer": false,
|
"signer": false,
|
||||||
"init": false
|
"init": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "stablecoin_definition",
|
"name": "stablecoin_definition",
|
||||||
@ -175,7 +175,7 @@
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"name": "controller",
|
"name": "controller",
|
||||||
"writable": false,
|
"writable": true,
|
||||||
"signer": false,
|
"signer": false,
|
||||||
"init": false
|
"init": false
|
||||||
},
|
},
|
||||||
|
|||||||
@ -128,6 +128,7 @@ mod stablecoin {
|
|||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn initialize_redemption_controller(
|
pub fn initialize_redemption_controller(
|
||||||
ctx: ProgramContext,
|
ctx: ProgramContext,
|
||||||
|
#[account(init)]
|
||||||
controller: AccountWithMetadata,
|
controller: AccountWithMetadata,
|
||||||
stablecoin_definition: AccountWithMetadata,
|
stablecoin_definition: AccountWithMetadata,
|
||||||
price_feed: AccountWithMetadata,
|
price_feed: AccountWithMetadata,
|
||||||
@ -172,6 +173,7 @@ mod stablecoin {
|
|||||||
#[instruction]
|
#[instruction]
|
||||||
pub fn update_redemption_controller(
|
pub fn update_redemption_controller(
|
||||||
ctx: ProgramContext,
|
ctx: ProgramContext,
|
||||||
|
#[account(mut)]
|
||||||
controller: AccountWithMetadata,
|
controller: AccountWithMetadata,
|
||||||
price_feed: AccountWithMetadata,
|
price_feed: AccountWithMetadata,
|
||||||
current_timestamp: u64,
|
current_timestamp: u64,
|
||||||
|
|||||||
@ -276,12 +276,13 @@ fn compute_next_controller_state(
|
|||||||
|
|
||||||
fn apply_redemption_rate(redemption_price: u128, redemption_rate: i128, elapsed: u64) -> u128 {
|
fn apply_redemption_rate(redemption_price: u128, redemption_rate: i128, elapsed: u64) -> u128 {
|
||||||
let drift = redemption_rate.saturating_mul(i128::from(elapsed));
|
let drift = redemption_rate.saturating_mul(i128::from(elapsed));
|
||||||
if drift >= 0 {
|
let next_price = if drift >= 0 {
|
||||||
redemption_price.saturating_add(u128::try_from(drift).unwrap_or(u128::MAX))
|
redemption_price.saturating_add(u128::try_from(drift).unwrap_or(u128::MAX))
|
||||||
} else {
|
} else {
|
||||||
let decrease = u128::try_from(drift.saturating_neg()).unwrap_or(u128::MAX);
|
let decrease = u128::try_from(drift.saturating_neg()).unwrap_or(u128::MAX);
|
||||||
redemption_price.saturating_sub(decrease).max(1)
|
redemption_price.saturating_sub(decrease).max(1)
|
||||||
}
|
};
|
||||||
|
next_price.min(i128_max_as_u128())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn price_error(redemption_price: u128, market_price: u128) -> i128 {
|
fn price_error(redemption_price: u128, market_price: u128) -> i128 {
|
||||||
@ -582,6 +583,31 @@ mod tests {
|
|||||||
assert_eq!(updated.last_update_timestamp, 105);
|
assert_eq!(updated.last_update_timestamp, 105);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn controller_clamps_redemption_price_to_i128_max() {
|
||||||
|
let mut controller = controller_state();
|
||||||
|
controller.redemption_price = i128_max_as_u128() - 5;
|
||||||
|
controller.redemption_rate = 10;
|
||||||
|
controller.proportional_gain = 0;
|
||||||
|
|
||||||
|
let updated = compute_next_controller_state(&controller, i128_max_as_u128(), 101);
|
||||||
|
|
||||||
|
assert_eq!(updated.redemption_price, i128_max_as_u128());
|
||||||
|
assert_eq!(updated.redemption_rate, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn controller_clamps_existing_redemption_price_above_i128_max() {
|
||||||
|
let mut controller = controller_state();
|
||||||
|
controller.redemption_price = i128_max_as_u128() + 5;
|
||||||
|
controller.redemption_rate = -1;
|
||||||
|
controller.proportional_gain = 0;
|
||||||
|
|
||||||
|
let updated = compute_next_controller_state(&controller, 1, 101);
|
||||||
|
|
||||||
|
assert_eq!(updated.redemption_price, i128_max_as_u128());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn controller_clamps_accumulated_error_and_redemption_rate() {
|
fn controller_clamps_accumulated_error_and_redemption_rate() {
|
||||||
let mut controller = controller_state();
|
let mut controller = controller_state();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user