Skip to content

Commit

Permalink
[FIX-7] Missing Invaraint Check
Browse files Browse the repository at this point in the history
  • Loading branch information
iboss-ptk committed Sep 21, 2023
1 parent c9ca823 commit c5249a4
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
12 changes: 10 additions & 2 deletions contracts/transmuter/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cosmwasm_std::{
CheckedFromRatioError, Coin, Decimal, DivideByZeroError, OverflowError, StdError, Uint128,
Uint64,
CheckedFromRatioError, Coin, Decimal, DivideByZeroError, OverflowError, StdError, Timestamp,
Uint128, Uint64,
};
use thiserror::Error;

Expand Down Expand Up @@ -122,9 +122,17 @@ pub enum ContractError {
#[error("Moving average is undefined due to zero elapsed time since limiter started tracking")]
UndefinedMovingAverage {},

/// Time invariant error, this should never happen
#[error("Time must be monotonically increasing")]
NonMonotonicTime {},

/// Time invariant error, this should never happen
#[error("Division's update should occur before division ended: updated_at: {updated_at}, ended_at: {ended_at}")]
UpdateAfterDivisionEnded {
updated_at: Timestamp,
ended_at: Timestamp,
},

#[error("Limiter does not exist for denom: {denom}, label: {label}")]
LimiterDoesNotExist { denom: String, label: String },

Expand Down
5 changes: 5 additions & 0 deletions contracts/transmuter/src/limiter/division.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ impl Division {
}

pub fn update(&self, updated_at: Timestamp, value: Decimal) -> Result<Self, ContractError> {
ensure!(
updated_at >= self.started_at,
ContractError::NonMonotonicTime {}
);

let prev_updated_at = self.updated_at.nanos();
let elapsed_time = elapsed_time(prev_updated_at, updated_at.nanos())?;
Ok(Self {
Expand Down
32 changes: 30 additions & 2 deletions contracts/transmuter/src/limiter/limiters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ impl ChangeLimiter {
updated_limiter.latest_value = value;

updated_limiter.divisions = if updated_limiter.divisions.is_empty() {
// no need to ensure time invariant since
// started_at = updated_at so
// `updated_at <= started_at + division_size` is always true
vec![Division::new(block_time, block_time, value, value)?]
} else {
// If the division is over, create a new division
Expand All @@ -173,14 +176,39 @@ impl ChangeLimiter {

if latest_division.elapsed_time(block_time)? >= division_size {
let started_at = latest_division.next_started_at(division_size, block_time)?;
let updated_at = block_time;
let ended_at = started_at.plus_nanos(division_size.u64());

let new_division = Division::new(started_at, block_time, value, prev_value)?;
// ensure time invariant
ensure!(
updated_at <= ended_at,
ContractError::UpdateAfterDivisionEnded {
updated_at,
ended_at
}
);

let new_division = Division::new(started_at, updated_at, value, prev_value)?;
divisions.push(new_division);
}
// else update the current division
else {
let last_index = divisions.len() - 1;
divisions[last_index] = latest_division.update(block_time, value)?;

let updated_at = block_time;
let ended_at =
Timestamp::from_nanos(latest_division.ended_at(division_size)?.u64());

// ensure time invariant
ensure!(
updated_at <= ended_at,
ContractError::UpdateAfterDivisionEnded {
updated_at,
ended_at
}
);

divisions[last_index] = latest_division.update(updated_at, value)?;
}

divisions
Expand Down

0 comments on commit c5249a4

Please sign in to comment.