diff --git a/amm/contracts/stable_pool/amp_coef.rs b/amm/contracts/stable_pool/amp_coef.rs index 6301007..487ed87 100644 --- a/amm/contracts/stable_pool/amp_coef.rs +++ b/amm/contracts/stable_pool/amp_coef.rs @@ -14,11 +14,11 @@ pub struct AmpCoef { /// Initial amplification coefficient. init_amp_coef: u128, /// Target for ramping up amplification coefficient. - target_amp_coef: u128, + future_amp_coef: u128, /// Initial amplification time. - init_amp_time: u64, + init_time: u64, /// Stop ramp up amplification time. - stop_amp_time: u64, + future_time: u64, } impl AmpCoef { @@ -27,31 +27,31 @@ impl AmpCoef { ensure!(init_amp_coef <= MAX_AMP, StablePoolError::AmpCoefTooHigh); Ok(Self { init_amp_coef, - target_amp_coef: init_amp_coef, - init_amp_time: 0, - stop_amp_time: 0, + future_amp_coef: init_amp_coef, + init_time: 0, + future_time: 0, }) } pub fn compute_amp_coef(&self) -> Result { let current_time = ink::env::block_timestamp::(); - if current_time < self.stop_amp_time { + if current_time < self.future_time { let time_range = self - .stop_amp_time - .checked_sub(self.init_amp_time) + .future_time + .checked_sub(self.init_time) .ok_or(MathError::SubUnderflow(51))?; let time_delta = current_time - .checked_sub(self.init_amp_time) + .checked_sub(self.init_time) .ok_or(MathError::SubUnderflow(52))?; // Compute amp factor based on ramp time - let amp_range = self.target_amp_coef.abs_diff(self.init_amp_coef); + let amp_range = self.future_amp_coef.abs_diff(self.init_amp_coef); let amp_delta = amp_range .checked_mul(time_delta as u128) .ok_or(MathError::MulOverflow(51))? .checked_div(time_range as u128) .ok_or(MathError::DivByZero(51))?; - if self.target_amp_coef >= self.init_amp_coef { + if self.future_amp_coef >= self.init_amp_coef { // Ramp up self.init_amp_coef .checked_add(amp_delta) @@ -63,19 +63,19 @@ impl AmpCoef { .ok_or(MathError::SubUnderflow(55)) } } else { - Ok(self.target_amp_coef) + Ok(self.future_amp_coef) } } pub fn ramp_amp_coef( &mut self, future_amp_coef: u128, - future_time_ts: u64, + future_time: u64, ) -> Result<(), StablePoolError> { ensure!(future_amp_coef >= MIN_AMP, StablePoolError::AmpCoefTooLow); ensure!(future_amp_coef <= MAX_AMP, StablePoolError::AmpCoefTooHigh); let current_time = ink::env::block_timestamp::(); - let ramp_duration = future_time_ts.checked_sub(current_time); + let ramp_duration = future_time.checked_sub(current_time); ensure!( ramp_duration.is_some() && ramp_duration.unwrap() >= MIN_RAMP_DURATION, StablePoolError::AmpCoefRampDurationTooShort @@ -89,9 +89,9 @@ impl AmpCoef { StablePoolError::AmpCoefChangeTooLarge ); self.init_amp_coef = current_amp_coef; - self.init_amp_time = current_time; - self.target_amp_coef = future_amp_coef; - self.stop_amp_time = future_time_ts; + self.init_time = current_time; + self.future_amp_coef = future_amp_coef; + self.future_time = future_time; Ok(()) } @@ -100,11 +100,22 @@ impl AmpCoef { let current_amp_coef = self.compute_amp_coef()?; let current_time = ink::env::block_timestamp::(); self.init_amp_coef = current_amp_coef; - self.target_amp_coef = current_amp_coef; - self.init_amp_time = current_time; - self.stop_amp_time = current_time; + self.future_amp_coef = current_amp_coef; + self.init_time = current_time; + self.future_time = current_time; Ok(()) } + + /// Returns a tuple of the future amplification coefficient and the ramping end time. + /// Returns `None` if the amplification coefficient is not in ramping period. + pub fn future_amp_coef(&self) -> Option<(u128, u64)> { + let current_time = ink::env::block_timestamp::(); + if current_time < self.future_time { + Some((self.future_amp_coef, self.future_time)) + } else { + None + } + } } #[cfg(test)] @@ -119,9 +130,9 @@ mod tests { fn amp_coef_up() { let amp_coef = AmpCoef { init_amp_coef: 100, - target_amp_coef: 1000, - init_amp_time: 100, - stop_amp_time: 1600, + future_amp_coef: 1000, + init_time: 100, + future_time: 1600, }; set_block_timestamp(100); assert_eq!(amp_coef.compute_amp_coef(), Ok(100)); @@ -135,9 +146,9 @@ mod tests { fn amp_coef_down() { let amp_coef = AmpCoef { init_amp_coef: 1000, - target_amp_coef: 100, - init_amp_time: 100, - stop_amp_time: 1600, + future_amp_coef: 100, + init_time: 100, + future_time: 1600, }; set_block_timestamp(100); assert_eq!(amp_coef.compute_amp_coef(), Ok(1000)); @@ -152,9 +163,9 @@ mod tests { set_block_timestamp(1000); let mut amp_coef = AmpCoef { init_amp_coef: 1000, - target_amp_coef: 100, - init_amp_time: 100, - stop_amp_time: 1600, + future_amp_coef: 100, + init_time: 100, + future_time: 1600, }; assert_eq!( amp_coef.ramp_amp_coef(1000, 999), @@ -175,9 +186,9 @@ mod tests { set_block_timestamp(100); let mut amp_coef = AmpCoef { init_amp_coef: 100, - target_amp_coef: 100, - init_amp_time: 100, - stop_amp_time: 1600, + future_amp_coef: 100, + init_time: 100, + future_time: 1600, }; assert_eq!( amp_coef.ramp_amp_coef(1001, 100 + MIN_RAMP_DURATION), @@ -194,9 +205,9 @@ mod tests { set_block_timestamp(100); let mut amp_coef = AmpCoef { init_amp_coef: 100, - target_amp_coef: 100, - init_amp_time: 100, - stop_amp_time: 1600, + future_amp_coef: 100, + init_time: 100, + future_time: 1600, }; assert_eq!(amp_coef.compute_amp_coef(), Ok(100)); assert_eq!( @@ -213,9 +224,9 @@ mod tests { set_block_timestamp(100); let mut amp_coef = AmpCoef { init_amp_coef: 100, - target_amp_coef: 100, - init_amp_time: 100, - stop_amp_time: 1600, + future_amp_coef: 100, + init_time: 100, + future_time: 1600, }; assert_eq!(amp_coef.compute_amp_coef(), Ok(100)); assert_eq!( diff --git a/amm/contracts/stable_pool/lib.rs b/amm/contracts/stable_pool/lib.rs index 71c04b0..4ff627c 100644 --- a/amm/contracts/stable_pool/lib.rs +++ b/amm/contracts/stable_pool/lib.rs @@ -114,8 +114,17 @@ pub mod stable_pool { } #[ink(event)] - pub struct AmpCoefChanged { - pub new_amp_coef: u128, + pub struct AmpCoefChange { + pub init_amp_coef: u128, + pub future_amp_coef: u128, + pub init_time: u64, + pub future_time: u64, + } + + #[ink(event)] + pub struct AmpCoefChangeStop { + pub amp_coef: u128, + pub time: u64, } #[ink(event)] @@ -805,13 +814,19 @@ pub mod stable_pool { fn ramp_amp_coef( &mut self, future_amp_coef: u128, - future_time_ts: u64, + future_time: u64, ) -> Result<(), StablePoolError> { self.ensure_owner()?; + let init_amp_coef = self.amp_coef()?; self.pool .amp_coef - .ramp_amp_coef(future_amp_coef, future_time_ts)?; - + .ramp_amp_coef(future_amp_coef, future_time)?; + self.env().emit_event(AmpCoefChange { + init_amp_coef, + future_amp_coef, + init_time: self.env().block_timestamp(), + future_time, + }); Ok(()) } @@ -819,6 +834,10 @@ pub mod stable_pool { fn stop_ramp_amp_coef(&mut self) -> Result<(), StablePoolError> { self.ensure_owner()?; self.pool.amp_coef.stop_ramp_amp_coef()?; + self.env().emit_event(AmpCoefChangeStop { + amp_coef: self.amp_coef()?, + time: self.env().block_timestamp(), + }); Ok(()) } @@ -837,6 +856,11 @@ pub mod stable_pool { Ok(self.pool.amp_coef.compute_amp_coef()?) } + #[ink(message)] + fn future_amp_coef(&self) -> Option<(u128, u64)> { + self.pool.amp_coef.future_amp_coef() + } + #[ink(message)] fn fees(&self) -> (u32, u32) { (self.pool.fees.trade_fee, self.pool.fees.protocol_fee) diff --git a/amm/traits/stable_pool.rs b/amm/traits/stable_pool.rs index 765bf13..2895de2 100644 --- a/amm/traits/stable_pool.rs +++ b/amm/traits/stable_pool.rs @@ -19,6 +19,11 @@ pub trait StablePool { #[ink(message)] fn amp_coef(&self) -> Result; + /// Returns a tuple of the future amplification coefficient and the ramping end time. + /// Returns `None` if the amplification coefficient is not in ramping period. + #[ink(message)] + fn future_amp_coef(&self) -> Option<(u128, u64)>; + /// Returns current trade and protocol fees in 1e9 precision. #[ink(message)] fn fees(&self) -> (u32, u32); @@ -211,12 +216,12 @@ pub trait StablePool { #[ink(message)] fn set_fees(&mut self, trade_fee: u32, protocol_fee: u32) -> Result<(), StablePoolError>; - /// Ramp amplification coeficient to `future_amp_coef`. The ramping should finish at `future_time_ts` + /// Ramp amplification coeficient to `future_amp_coef`. The ramping should finish at `future_time` #[ink(message)] fn ramp_amp_coef( &mut self, future_amp_coef: u128, - future_time_ts: u64, + future_time: u64, ) -> Result<(), StablePoolError>; /// Stop ramping amplification coefficient.