diff --git a/x/ibc-rate-limit/contracts/rate-limiter/Cargo.toml b/x/ibc-rate-limit/contracts/rate-limiter/Cargo.toml index e166d606418b04ebdf8e808502aa151a959cddb9..4c78fcf37fb16f61f76dce940b6921747377012f 100644 --- a/x/ibc-rate-limit/contracts/rate-limiter/Cargo.toml +++ b/x/ibc-rate-limit/contracts/rate-limiter/Cargo.toml @@ -15,17 +15,6 @@ exclude = [ [lib] crate-type = ["cdylib", "rlib"] -[profile.release] -opt-level = 3 -debug = false -rpath = false -lto = true -debug-assertions = false -codegen-units = 1 -panic = 'abort' -incremental = false -overflow-checks = true - [features] # for more explicit tests, cargo test --features=backtraces backtraces = ["cosmwasm-std/backtraces"] @@ -43,8 +32,9 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -cosmwasm-std = "1.0.0" -cosmwasm-storage = "1.0.0" +cosmwasm-std = "1.1.0" +cosmwasm-storage = "1.1.0" +cosmwasm-schema = "1.1.0" cw-storage-plus = "0.13.2" cw2 = "0.13.2" schemars = "0.8.8" @@ -52,5 +42,4 @@ serde = { version = "1.0.137", default-features = false, features = ["derive"] } thiserror = { version = "1.0.31" } [dev-dependencies] -cosmwasm-schema = "1.0.0" cw-multi-test = "0.13.2" diff --git a/x/ibc-rate-limit/contracts/rate-limiter/examples/schema.rs b/x/ibc-rate-limit/contracts/rate-limiter/examples/schema.rs new file mode 100644 index 0000000000000000000000000000000000000000..954edd462e1cc2783e20d7832d6856e595b25418 --- /dev/null +++ b/x/ibc-rate-limit/contracts/rate-limiter/examples/schema.rs @@ -0,0 +1,13 @@ +use cosmwasm_schema::write_api; + +use rate_limiter::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, SudoMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + sudo: SudoMsg, + migrate: MigrateMsg, + } +} diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/contract_tests.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/contract_tests.rs index 3eef38eed8b814b4276f609ca88b0df571c56180..16bc08802b072971eb1dbb887da57bb4eefbd1d4 100644 --- a/x/ibc-rate-limit/contracts/rate-limiter/src/contract_tests.rs +++ b/x/ibc-rate-limit/contracts/rate-limiter/src/contract_tests.rs @@ -2,7 +2,7 @@ use crate::{contract::*, ContractError}; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -use cosmwasm_std::{from_binary, Addr, Attribute}; +use cosmwasm_std::{from_binary, Addr, Attribute, Uint256}; use crate::helpers::tests::verify_query_response; use crate::msg::{InstantiateMsg, PathMsg, QueryMsg, QuotaMsg, SudoMsg}; @@ -52,8 +52,8 @@ fn consume_allowance() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 300, + channel_value: 3_000_u32.into(), + funds: 300_u32.into(), }; let res = sudo(deps.as_mut(), mock_env(), msg).unwrap(); @@ -64,8 +64,8 @@ fn consume_allowance() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 300, + channel_value: 3_000_u32.into(), + funds: 300_u32.into(), }; let err = sudo(deps.as_mut(), mock_env(), msg).unwrap_err(); assert!(matches!(err, ContractError::RateLimitExceded { .. })); @@ -91,14 +91,14 @@ fn symetric_flows_dont_consume_allowance() { let send_msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 300, + channel_value: 3_000_u32.into(), + funds: 300_u32.into(), }; let recv_msg = SudoMsg::RecvPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 300, + channel_value: 3_000_u32.into(), + funds: 300_u32.into(), }; let res = sudo(deps.as_mut(), mock_env(), send_msg.clone()).unwrap(); @@ -154,8 +154,8 @@ fn asymetric_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 60, + channel_value: 3_000_u32.into(), + funds: 60_u32.into(), }; let res = sudo(deps.as_mut(), mock_env(), msg).unwrap(); let Attribute { key, value } = &res.attributes[4]; @@ -166,8 +166,8 @@ fn asymetric_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 60, + channel_value: 3_000_u32.into(), + funds: 60_u32.into(), }; let res = sudo(deps.as_mut(), mock_env(), msg).unwrap(); @@ -180,8 +180,8 @@ fn asymetric_quotas() { let recv_msg = SudoMsg::RecvPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 30, + channel_value: 3_000_u32.into(), + funds: 30_u32.into(), }; let res = sudo(deps.as_mut(), mock_env(), recv_msg).unwrap(); let Attribute { key, value } = &res.attributes[3]; @@ -195,8 +195,8 @@ fn asymetric_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 60, + channel_value: 3_000_u32.into(), + funds: 60_u32.into(), }; let err = sudo(deps.as_mut(), mock_env(), msg.clone()).unwrap_err(); assert!(matches!(err, ContractError::RateLimitExceded { .. })); @@ -205,8 +205,8 @@ fn asymetric_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 30, + channel_value: 3_000_u32.into(), + funds: 30_u32.into(), }; let res = sudo(deps.as_mut(), mock_env(), msg.clone()).unwrap(); let Attribute { key, value } = &res.attributes[3]; @@ -246,8 +246,8 @@ fn query_state() { assert_eq!(value[0].quota.max_percentage_send, 10); assert_eq!(value[0].quota.max_percentage_recv, 10); assert_eq!(value[0].quota.duration, RESET_TIME_WEEKLY); - assert_eq!(value[0].flow.inflow, 0); - assert_eq!(value[0].flow.outflow, 0); + assert_eq!(value[0].flow.inflow, Uint256::from(0_u32)); + assert_eq!(value[0].flow.outflow, Uint256::from(0_u32)); assert_eq!( value[0].flow.period_end, env.block.time.plus_seconds(RESET_TIME_WEEKLY) @@ -256,16 +256,16 @@ fn query_state() { let send_msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 300, + channel_value: 3_000_u32.into(), + funds: 300_u32.into(), }; sudo(deps.as_mut(), mock_env(), send_msg.clone()).unwrap(); let recv_msg = SudoMsg::RecvPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 30, + channel_value: 3_000_u32.into(), + funds: 30_u32.into(), }; sudo(deps.as_mut(), mock_env(), recv_msg.clone()).unwrap(); @@ -277,8 +277,8 @@ fn query_state() { "weekly", (10, 10), RESET_TIME_WEEKLY, - 30, - 300, + 30_u32.into(), + 300_u32.into(), env.block.time.plus_seconds(RESET_TIME_WEEKLY), ); } @@ -317,8 +317,8 @@ fn bad_quotas() { "bad_quota", (100, 100), 200, - 0, - 0, + 0_u32.into(), + 0_u32.into(), env.block.time.plus_seconds(200), ); } @@ -343,13 +343,13 @@ fn undo_send() { let send_msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 300, + channel_value: 3_000_u32.into(), + funds: 300_u32.into(), }; let undo_msg = SudoMsg::UndoSend { channel_id: format!("channel"), denom: format!("denom"), - funds: 300, + funds: 300_u32.into(), }; sudo(deps.as_mut(), mock_env(), send_msg.clone()).unwrap(); @@ -357,7 +357,10 @@ fn undo_send() { let trackers = RATE_LIMIT_TRACKERS .load(&deps.storage, ("channel".to_string(), "denom".to_string())) .unwrap(); - assert_eq!(trackers.first().unwrap().flow.outflow, 300); + assert_eq!( + trackers.first().unwrap().flow.outflow, + Uint256::from(300_u32) + ); let period_end = trackers.first().unwrap().flow.period_end; let channel_value = trackers.first().unwrap().quota.channel_value; @@ -366,7 +369,7 @@ fn undo_send() { let trackers = RATE_LIMIT_TRACKERS .load(&deps.storage, ("channel".to_string(), "denom".to_string())) .unwrap(); - assert_eq!(trackers.first().unwrap().flow.outflow, 0); + assert_eq!(trackers.first().unwrap().flow.outflow, Uint256::from(0_u32)); assert_eq!(trackers.first().unwrap().flow.period_end, period_end); assert_eq!(trackers.first().unwrap().quota.channel_value, channel_value); } diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/execute.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/execute.rs index 4bac4c0d37ffda1eb2651afd7ed7733d2e2fc8e6..047a2179dd01b06dbcfd1a180b797ad7c56bbcbb 100644 --- a/x/ibc-rate-limit/contracts/rate-limiter/src/execute.rs +++ b/x/ibc-rate-limit/contracts/rate-limiter/src/execute.rs @@ -159,8 +159,8 @@ mod tests { "daily", (3, 5), 1600, - 0, - 0, + 0_u32.into(), + 0_u32.into(), env.block.time.plus_seconds(1600), ); @@ -208,8 +208,8 @@ mod tests { "daily", (3, 5), 1600, - 0, - 0, + 0_u32.into(), + 0_u32.into(), env.block.time.plus_seconds(1600), ); @@ -241,8 +241,8 @@ mod tests { "different", (50, 30), 5000, - 0, - 0, + 0_u32.into(), + 0_u32.into(), env.block.time.plus_seconds(5000), ); } diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/helpers.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/helpers.rs index 6cfd60a65a85fe0026db7b1e8135363092a50ae6..530d3b6cf2d392304cffe0991eb60e97229b97b4 100644 --- a/x/ibc-rate-limit/contracts/rate-limiter/src/helpers.rs +++ b/x/ibc-rate-limit/contracts/rate-limiter/src/helpers.rs @@ -37,7 +37,7 @@ impl RateLimitingContract { } pub mod tests { - use cosmwasm_std::Timestamp; + use cosmwasm_std::{Timestamp, Uint256}; use crate::state::RateLimit; @@ -46,8 +46,8 @@ pub mod tests { quota_name: &str, send_recv: (u32, u32), duration: u64, - inflow: u128, - outflow: u128, + inflow: Uint256, + outflow: Uint256, period_end: Timestamp, ) { assert_eq!(value.quota.name, quota_name); diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/integration_tests.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/integration_tests.rs index 8807028fcb9a7fb9461a0c3d7761c0f8a48157ee..66a145b397dc04d66076f8df023fce805dc1a105 100644 --- a/x/ibc-rate-limit/contracts/rate-limiter/src/integration_tests.rs +++ b/x/ibc-rate-limit/contracts/rate-limiter/src/integration_tests.rs @@ -42,7 +42,7 @@ fn mock_app() -> App { // Instantiate the contract fn proper_instantiate(paths: Vec<PathMsg>) -> (App, RateLimitingContract) { let mut app = mock_app(); - let cw_template_id = app.store_code(contract_template()); + let cw_code_id = app.store_code(contract_template()); let msg = InstantiateMsg { gov_module: Addr::unchecked(GOV_ADDR), @@ -52,7 +52,7 @@ fn proper_instantiate(paths: Vec<PathMsg>) -> (App, RateLimitingContract) { let cw_rate_limit_contract_addr = app .instantiate_contract( - cw_template_id, + cw_code_id, Addr::unchecked(GOV_ADDR), &msg, &[], @@ -82,8 +82,8 @@ fn expiration() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 300, + channel_value: 3_000_u32.into(), + funds: 300_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); let res = app.sudo(cosmos_msg).unwrap(); @@ -105,8 +105,8 @@ fn expiration() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 300, + channel_value: 3_000_u32.into(), + funds: 300_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); let _err = app.sudo(cosmos_msg).unwrap_err(); @@ -123,8 +123,8 @@ fn expiration() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 300, + channel_value: 3_000_u32.into(), + funds: 300_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); @@ -162,8 +162,8 @@ fn multiple_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100, - funds: 1, + channel_value: 100_u32.into(), + funds: 1_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); app.sudo(cosmos_msg).unwrap(); @@ -172,8 +172,8 @@ fn multiple_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100, - funds: 1, + channel_value: 100_u32.into(), + funds: 1_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); app.sudo(cosmos_msg).unwrap_err(); @@ -188,8 +188,8 @@ fn multiple_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100, - funds: 1, + channel_value: 100_u32.into(), + funds: 1_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); @@ -207,8 +207,8 @@ fn multiple_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100, - funds: 1, + channel_value: 100_u32.into(), + funds: 1_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); app.sudo(cosmos_msg).unwrap(); @@ -224,8 +224,8 @@ fn multiple_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100, - funds: 1, + channel_value: 100_u32.into(), + funds: 1_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); app.sudo(cosmos_msg).unwrap_err(); @@ -240,8 +240,8 @@ fn multiple_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100, - funds: 1, + channel_value: 100_u32.into(), + funds: 1_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); app.sudo(cosmos_msg).unwrap_err(); @@ -257,8 +257,8 @@ fn multiple_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100, - funds: 1, + channel_value: 100_u32.into(), + funds: 1_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); app.sudo(cosmos_msg).unwrap_err(); @@ -272,8 +272,8 @@ fn multiple_quotas() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100, - funds: 1, + channel_value: 100_u32.into(), + funds: 1_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); app.sudo(cosmos_msg).unwrap(); @@ -296,8 +296,8 @@ fn channel_value_cached() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100, - funds: 1, + channel_value: 100_u32.into(), + funds: 1_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); app.sudo(cosmos_msg).unwrap(); @@ -306,8 +306,8 @@ fn channel_value_cached() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100, - funds: 3, + channel_value: 100_u32.into(), + funds: 3_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); app.sudo(cosmos_msg).unwrap_err(); @@ -316,8 +316,8 @@ fn channel_value_cached() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 100000, - funds: 3, + channel_value: 100000_u32.into(), + funds: 3_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); app.sudo(cosmos_msg).unwrap_err(); @@ -336,8 +336,8 @@ fn channel_value_cached() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 10_000, - funds: 100, + channel_value: 10_000_u32.into(), + funds: 100_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); @@ -353,8 +353,8 @@ fn channel_value_cached() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 10_000, - funds: 100, + channel_value: 10_000_u32.into(), + funds: 100_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); @@ -364,8 +364,8 @@ fn channel_value_cached() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 1, - funds: 75, + channel_value: 1_u32.into(), + funds: 75_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg); @@ -380,8 +380,8 @@ fn add_paths_later() { let msg = SudoMsg::SendPacket { channel_id: format!("channel"), denom: format!("denom"), - channel_value: 3_000, - funds: 300, + channel_value: 3_000_u32.into(), + funds: 300_u32.into(), }; let cosmos_msg = cw_rate_limit_contract.sudo(msg.clone()); let res = app.sudo(cosmos_msg).unwrap(); diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/msg.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/msg.rs index 7ae027efd25f0d22b02f8ab3fec352e891094f79..0f1f0c4b0611bf619a8d15713b999df98cbf3a90 100644 --- a/x/ibc-rate-limit/contracts/rate-limiter/src/msg.rs +++ b/x/ibc-rate-limit/contracts/rate-limiter/src/msg.rs @@ -1,4 +1,5 @@ -use cosmwasm_std::Addr; +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{Addr, Uint256}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -44,7 +45,7 @@ impl QuotaMsg { /// Initialize the contract with the address of the IBC module and any existing channels. /// Only the ibc module is allowed to execute actions on this contract -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[cw_serde] pub struct InstantiateMsg { pub gov_module: Addr, pub ibc_module: Addr, @@ -53,8 +54,7 @@ pub struct InstantiateMsg { /// The caller (IBC module) is responsible for correctly calculating the funds /// being sent through the channel -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { AddPath { channel_id: String, @@ -72,34 +72,33 @@ pub enum ExecuteMsg { }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { + #[returns(Vec<crate::state::RateLimit>)] GetQuotas { channel_id: String, denom: String }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum SudoMsg { SendPacket { channel_id: String, denom: String, - channel_value: u128, - funds: u128, + channel_value: Uint256, + funds: Uint256, }, RecvPacket { channel_id: String, denom: String, - channel_value: u128, - funds: u128, + channel_value: Uint256, + funds: Uint256, }, UndoSend { channel_id: String, denom: String, - funds: u128, + funds: Uint256, }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum MigrateMsg {} diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/state.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/state.rs index 8dc5f9fa2f66e126eb79bf058e08a1467c292fc7..5237946487d0d84fd3676cf23b7f7e791f7a68c0 100644 --- a/x/ibc-rate-limit/contracts/rate-limiter/src/state.rs +++ b/x/ibc-rate-limit/contracts/rate-limiter/src/state.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{Addr, Timestamp}; +use cosmwasm_std::{Addr, Timestamp, Uint256}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::cmp; @@ -62,16 +62,15 @@ pub enum FlowType { /// This is a design decision to avoid the period calculations and thus reduce gas consumption #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, Copy)] pub struct Flow { - // Q: Do we have edge case issues with inflow/outflow being u128, e.g. what if a token has super high precision. - pub inflow: u128, - pub outflow: u128, + pub inflow: Uint256, + pub outflow: Uint256, pub period_end: Timestamp, } impl Flow { pub fn new( - inflow: impl Into<u128>, - outflow: impl Into<u128>, + inflow: impl Into<Uint256>, + outflow: impl Into<Uint256>, now: Timestamp, duration: u64, ) -> Self { @@ -87,7 +86,7 @@ impl Flow { /// (balance_in, balance_out) where balance_in in is how much has been /// transferred into the flow, and balance_out is how much value transferred /// out. - pub fn balance(&self) -> (u128, u128) { + pub fn balance(&self) -> (Uint256, Uint256) { ( self.inflow.saturating_sub(self.outflow), self.outflow.saturating_sub(self.inflow), @@ -95,7 +94,7 @@ impl Flow { } /// checks if the flow, in the current state, has exceeded a max allowance - pub fn exceeds(&self, direction: &FlowType, max_inflow: u128, max_outflow: u128) -> bool { + pub fn exceeds(&self, direction: &FlowType, max_inflow: Uint256, max_outflow: Uint256) -> bool { let (balance_in, balance_out) = self.balance(); match direction { FlowType::In => balance_in > max_inflow, @@ -113,13 +112,13 @@ impl Flow { /// Expire resets the Flow to start tracking the value transfer from the /// moment this method is called. pub fn expire(&mut self, now: Timestamp, duration: u64) { - self.inflow = 0; - self.outflow = 0; + self.inflow = Uint256::from(0_u32); + self.outflow = Uint256::from(0_u32); self.period_end = now.plus_seconds(duration); } /// Updates the current flow incrementing it by a transfer of value. - pub fn add_flow(&mut self, direction: FlowType, value: u128) { + pub fn add_flow(&mut self, direction: FlowType, value: Uint256) { match direction { FlowType::In => self.inflow = self.inflow.saturating_add(value), FlowType::Out => self.outflow = self.outflow.saturating_add(value), @@ -127,7 +126,7 @@ impl Flow { } /// Updates the current flow reducing it by a transfer of value. - pub fn undo_flow(&mut self, direction: FlowType, value: u128) { + pub fn undo_flow(&mut self, direction: FlowType, value: Uint256) { match direction { FlowType::In => self.inflow = self.inflow.saturating_sub(value), FlowType::Out => self.outflow = self.outflow.saturating_sub(value), @@ -139,7 +138,7 @@ impl Flow { fn apply_transfer( &mut self, direction: &FlowType, - funds: u128, + funds: Uint256, now: Timestamp, quota: &Quota, ) -> bool { @@ -166,7 +165,7 @@ pub struct Quota { pub max_percentage_send: u32, pub max_percentage_recv: u32, pub duration: u64, - pub channel_value: Option<u128>, + pub channel_value: Option<Uint256>, } impl Quota { @@ -174,13 +173,13 @@ impl Quota { /// total_value) in each direction based on the total value of the denom in /// the channel. The result tuple represents the max capacity when the /// transfer is in directions: (FlowType::In, FlowType::Out) - pub fn capacity(&self) -> (u128, u128) { + pub fn capacity(&self) -> (Uint256, Uint256) { match self.channel_value { Some(total_value) => ( - total_value * (self.max_percentage_recv as u128) / 100_u128, - total_value * (self.max_percentage_send as u128) / 100_u128, + total_value * Uint256::from(self.max_percentage_recv) / Uint256::from(100_u32), + total_value * Uint256::from(self.max_percentage_send) / Uint256::from(100_u32), ), - None => (0, 0), // This should never happen, but ig the channel value is not set, we disallow any transfer + None => (0_u32.into(), 0_u32.into()), // This should never happen, but ig the channel value is not set, we disallow any transfer } } } @@ -221,8 +220,8 @@ impl RateLimit { &mut self, path: &Path, direction: &FlowType, - funds: u128, - channel_value: u128, + funds: Uint256, + channel_value: Uint256, now: Timestamp, ) -> Result<Self, ContractError> { let expired = self.flow.apply_transfer(direction, funds, now, &self.quota); @@ -292,18 +291,18 @@ pub mod tests { assert!(!flow.is_expired(epoch.plus_seconds(RESET_TIME_WEEKLY))); assert!(flow.is_expired(epoch.plus_seconds(RESET_TIME_WEEKLY).plus_nanos(1))); - assert_eq!(flow.balance(), (0_u128, 0_u128)); - flow.add_flow(FlowType::In, 5); - assert_eq!(flow.balance(), (5_u128, 0_u128)); - flow.add_flow(FlowType::Out, 2); - assert_eq!(flow.balance(), (3_u128, 0_u128)); + assert_eq!(flow.balance(), (0_u32.into(), 0_u32.into())); + flow.add_flow(FlowType::In, 5_u32.into()); + assert_eq!(flow.balance(), (5_u32.into(), 0_u32.into())); + flow.add_flow(FlowType::Out, 2_u32.into()); + assert_eq!(flow.balance(), (3_u32.into(), 0_u32.into())); // Adding flow doesn't affect expiration assert!(!flow.is_expired(epoch.plus_seconds(RESET_TIME_DAILY))); flow.expire(epoch.plus_seconds(RESET_TIME_WEEKLY), RESET_TIME_WEEKLY); - assert_eq!(flow.balance(), (0_u128, 0_u128)); - assert_eq!(flow.inflow, 0_u128); - assert_eq!(flow.outflow, 0_u128); + assert_eq!(flow.balance(), (0_u32.into(), 0_u32.into())); + assert_eq!(flow.inflow, Uint256::from(0_u32)); + assert_eq!(flow.outflow, Uint256::from(0_u32)); assert_eq!(flow.period_end, epoch.plus_seconds(RESET_TIME_WEEKLY * 2)); // Expiration has moved diff --git a/x/ibc-rate-limit/contracts/rate-limiter/src/sudo.rs b/x/ibc-rate-limit/contracts/rate-limiter/src/sudo.rs index 8315a01fcf8228e0f5b3b25c38f7181641f5c64a..0a8ae8e5161a48ed2327495d59092b75909ef09c 100644 --- a/x/ibc-rate-limit/contracts/rate-limiter/src/sudo.rs +++ b/x/ibc-rate-limit/contracts/rate-limiter/src/sudo.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{DepsMut, Response, Timestamp}; +use cosmwasm_std::{DepsMut, Response, Timestamp, Uint256}; use crate::{ state::{FlowType, Path, RateLimit, RATE_LIMIT_TRACKERS}, @@ -14,8 +14,8 @@ use crate::{ pub fn try_transfer( deps: DepsMut, path: &Path, - channel_value: u128, - funds: u128, + channel_value: Uint256, + funds: Uint256, direction: FlowType, now: Timestamp, ) -> Result<Response, ContractError> { @@ -96,7 +96,7 @@ fn add_rate_limit_attributes(response: Response, result: &RateLimit) -> Response // This function manually injects an inflow. This is used when reverting a // packet that failed ack or timed-out. -pub fn undo_send(deps: DepsMut, path: &Path, funds: u128) -> Result<Response, ContractError> { +pub fn undo_send(deps: DepsMut, path: &Path, funds: Uint256) -> Result<Response, ContractError> { // Sudo call. Only go modules should be allowed to access this let trackers = RATE_LIMIT_TRACKERS.may_load(deps.storage, path.into())?; diff --git a/x/ibc-rate-limit/testdata/rate_limiter.wasm b/x/ibc-rate-limit/testdata/rate_limiter.wasm index 0341a5b1c9aad1703778a5214a1d15336ad611bf..caf63c41459ca8361691cf27ae6c738682946e40 100644 Binary files a/x/ibc-rate-limit/testdata/rate_limiter.wasm and b/x/ibc-rate-limit/testdata/rate_limiter.wasm differ