Skip to content

Commit

Permalink
feat(interchain-token-service): add flow limit
Browse files Browse the repository at this point in the history
- improve docstring describing flow direction
- remove unneeded variables in add_flow
  • Loading branch information
AttissNgo committed Jan 14, 2025
1 parent 50a2e91 commit a90af89
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 12 deletions.
1 change: 1 addition & 0 deletions contracts/interchain-token-service/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ pub enum ContractError {
TokenAlreadyDeployed = 18,
InvalidFlowLimit = 19,
FlowLimitExceeded = 20,
FlowAmountOverflow = 21,
}
18 changes: 10 additions & 8 deletions contracts/interchain-token-service/src/flow_limit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl FlowDirection {
/// Checks that:
/// - Flow amount doesn't exceed the flow limit
/// - Adding flows won't cause overflow
/// - Total flow in one direction doesn't exceed flow in opposite direction plus limit
/// - Net flow (outgoing minus incoming flow) doesn't exceed the limit
pub fn add_flow(
&self,
env: &Env,
Expand All @@ -63,16 +63,18 @@ impl FlowDirection {
return Ok(());
};

let flow_to_add = self.flow(env, token_id.clone());
let flow_to_compare = self.reverse_flow(env, token_id.clone());

ensure!(flow_amount <= flow_limit, ContractError::FlowLimitExceeded);
let new_flow = flow_to_add

let new_flow = self
.flow(env, token_id.clone())
.checked_add(flow_amount)
.ok_or(ContractError::FlowLimitExceeded)?;
let max_allowed = flow_to_compare
.ok_or(ContractError::FlowAmountOverflow)?;
let max_allowed = self
.reverse_flow(env, token_id.clone())
.checked_add(flow_limit)
.ok_or(ContractError::FlowLimitExceeded)?;
.ok_or(ContractError::FlowAmountOverflow)?;

// Equivalent to flow_amount + flow - reverse_flow <= flow_limit
ensure!(new_flow <= max_allowed, ContractError::FlowLimitExceeded);

self.update_flow(env, token_id.clone(), new_flow);
Expand Down
5 changes: 2 additions & 3 deletions contracts/interchain-token-service/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ pub trait InterchainTokenServiceInterface: AxelarExecutableInterface {
/// Returns `None` if no limit is set.
fn flow_limit(env: &Env, token_id: BytesN<32>) -> Option<i128>;

/// Retrieves the amount that has flowed out of the contract during the current epoch
/// Retrieves the amount that has flowed out of the chain to other chains during the current epoch
/// for the token associated with the specified token ID.
fn flow_out_amount(env: &Env, token_id: BytesN<32>) -> i128;

/// Retrieves the amount that has flowed into the contract during the current epoch
/// Retrieves the amount that has flowed into the chain from other chains during the current epoch
/// for the token associated with the specified token ID.
fn flow_in_amount(env: &Env, token_id: BytesN<32>) -> i128;

Expand All @@ -53,7 +53,6 @@ pub trait InterchainTokenServiceInterface: AxelarExecutableInterface {
/// Setting the limit to 0 effectively freezes the token by preventing any flow.
///
/// # Arguments
/// - `env`: Reference to the contract environment.
/// - `token_id`: Unique identifier of the token.
/// - `flow_limit`: The new flow limit value. Must be positive if Some.
///
Expand Down
2 changes: 1 addition & 1 deletion contracts/interchain-token-service/tests/flow_limit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ fn add_flow_out_fails_exceeds_flow_limit() {
}

#[test]
#[should_panic(expected = "Error(Contract, #20)")] // ContractError::FlowLimitExceeded
#[should_panic(expected = "Error(Contract, #21)")] // ContractError::FlowAmountOverflow
fn add_flow_fails_on_flow_comparison_overflow() {
let (env, client, gateway_client, _, signers) = setup_env();
register_chains(&env, &client);
Expand Down

0 comments on commit a90af89

Please sign in to comment.