From 52c8bbbc05adf90ef6cd412942341d3cdc39ed28 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Tue, 10 Sep 2024 17:44:07 +0700 Subject: [PATCH 01/13] implement calc functions --- packages/transmuter_math/src/errors.rs | 11 +- packages/transmuter_math/src/lib.rs | 1 + .../src/rebalancing_incentive.rs | 199 ++++++++++++++++++ 3 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 packages/transmuter_math/src/rebalancing_incentive.rs diff --git a/packages/transmuter_math/src/errors.rs b/packages/transmuter_math/src/errors.rs index 33e79dd..22c358a 100644 --- a/packages/transmuter_math/src/errors.rs +++ b/packages/transmuter_math/src/errors.rs @@ -1,4 +1,7 @@ -use cosmwasm_std::{CheckedFromRatioError, DivideByZeroError, OverflowError}; +use cosmwasm_std::{ + CheckedFromRatioError, Decimal256RangeExceeded, DecimalRangeExceeded, DivideByZeroError, + OverflowError, +}; #[derive(thiserror::Error, Debug, PartialEq)] pub enum TransmuterMathError { @@ -12,6 +15,12 @@ pub enum TransmuterMathError { #[error("Missing data points to calculate moving average")] MissingDataPoints, + #[error("{0}")] + DecimalRangeExceeded(#[from] DecimalRangeExceeded), + + #[error("{0}")] + Decimal256RangeExceeded(#[from] Decimal256RangeExceeded), + #[error("{0}")] OverflowError(#[from] OverflowError), diff --git a/packages/transmuter_math/src/lib.rs b/packages/transmuter_math/src/lib.rs index 685d3d0..f405790 100644 --- a/packages/transmuter_math/src/lib.rs +++ b/packages/transmuter_math/src/lib.rs @@ -1,6 +1,7 @@ mod division; mod errors; mod helpers; +mod rebalancing_incentive; pub use cosmwasm_std::{Decimal, Timestamp, Uint64}; pub use division::Division; diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs new file mode 100644 index 0000000..76672be --- /dev/null +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -0,0 +1,199 @@ +use cosmwasm_std::{Decimal, Decimal256, SignedDecimal256, Uint128}; + +use crate::TransmuterMathError; + +/// Calculating impact factor component +/// +/// Considering change of balance of asset $i$, fee/incentive impact factor component $\gamma_i$ is +/// +/// $$ +/// \gamma_i =\left[C(b)\right]_{b_i}^{b'_i} +/// $$ +/// +/// $$ +/// \gamma_i = C(b'_i) - C(b_i) +/// $$ +/// +/// where cumulative component $C(b)$ is +/// +/// $$ +/// C(b) = +/// \begin{cases} +/// \left(\frac{b - \phi_l}{\phi_l}\right)^2 & \text{if } 0 \leq b \lt \phi_l \\ +/// 0 & \text{if } \phi_l \leq b \leq \phi_u \\ +/// \left(\frac{b - \phi_u}{\delta - \phi_u}\right)^2 & \text{if } \phi_u \lt b \leq \delta +/// \end{cases} +/// $$ +pub fn calculate_cumulative_impact_factor_component( + normalized_balance: Decimal, + ideal_balance_lower_bound: Decimal, + ideal_balance_upper_bound: Decimal, + upper_limit: Decimal, +) -> Result { + // There might a case where $\delta$ dynamically moved to lower than $\phi_u$ (due to change limiter) uses + // $min(\delta, \phi_u)$ instead of $\phi_u$ + // and $min(\delta, \phi_u, \phi_l)$ instead of $\phi_l$. + let ideal_balance_upper_bound = ideal_balance_upper_bound.min(upper_limit); + let ideal_balance_lower_bound = ideal_balance_lower_bound.min(ideal_balance_upper_bound); + + // Calculate the cumulative impact factor component + let cumulative = if normalized_balance < ideal_balance_lower_bound { + ideal_balance_lower_bound // phi_l + .checked_sub(normalized_balance)? // - b + .checked_div(ideal_balance_lower_bound)? // / phi_l + .pow(2) // ^2 + } else if normalized_balance > ideal_balance_upper_bound { + normalized_balance // b + .checked_sub(ideal_balance_upper_bound)? // - phi_u + .checked_div(upper_limit.checked_sub(ideal_balance_upper_bound)?)? // / delta - phi_u + .pow(2) // ^2 + } else { + // within ideal balance + Decimal::zero() + }; + + Ok(cumulative) +} + +pub struct ImpactFactorParamGroup { + prev_normalized_balance: Decimal, + update_normalized_balance: Decimal, + ideal_balance_lower_bound: Decimal, + ideal_balance_upper_bound: Decimal, + upper_limit: Decimal, +} + +impl ImpactFactorParamGroup { + fn has_no_change_in_balance(&self) -> bool { + self.prev_normalized_balance == self.update_normalized_balance + } + + fn calculate_impact_factor_component(&self) -> Result { + // C(b) + let c_b = SignedDecimal256::from(calculate_cumulative_impact_factor_component( + self.prev_normalized_balance, + self.ideal_balance_lower_bound, + self.ideal_balance_upper_bound, + self.upper_limit, + )?); + + // C(b') + let c_b_prime = SignedDecimal256::from(calculate_cumulative_impact_factor_component( + self.update_normalized_balance, + self.ideal_balance_lower_bound, + self.ideal_balance_upper_bound, + self.upper_limit, + )?); + + // \gamma_i = C(b') - C(b) + c_b_prime + .checked_sub(c_b) + .map_err(TransmuterMathError::OverflowError) + } +} + +pub enum Reaction { + Incentivize, + CollectFee, +} + +/// combine all the impact factor components +/// +/// $$ +/// f = \frac{\Vert\vec{\gamma}\Vert}{\sqrt{n}} +/// $$ +/// +/// That gives a normalized magnitude of the vector of $n$ dimension into $[0,1]$. +/// The reason why it needs to include all dimensions is because the case that swapping with alloyed asset, which will effect overall composition rather than just 2 assets. +pub fn calculate_impact_factor( + impact_factor_param_groups: &[ImpactFactorParamGroup], +) -> Result<(Reaction, Decimal256), TransmuterMathError> { + let mut cumulative_impact_factor_sqaure = Decimal256::zero(); + let mut impact_factor_component_sum = SignedDecimal256::zero(); + + let n = Decimal256::from_atomics(impact_factor_param_groups.len() as u64, 0)?; + + for impact_factor_params in impact_factor_param_groups { + // optimiztion: if there is no change in balance, the result will be 0 anyway, accumulating 0 has no effect + if impact_factor_params.has_no_change_in_balance() { + continue; + } + + let impact_factor_component = impact_factor_params.calculate_impact_factor_component()?; + let impact_factor_component_square = + Decimal256::try_from(impact_factor_component.checked_pow(2)?)?; + + impact_factor_component_sum = + impact_factor_component_sum.checked_add(impact_factor_component)?; + cumulative_impact_factor_sqaure = + cumulative_impact_factor_sqaure.checked_add(impact_factor_component_square)?; + } + + let reaction = if impact_factor_component_sum.is_negative() { + Reaction::Incentivize + } else { + Reaction::CollectFee + }; + + let impact_factor = cumulative_impact_factor_sqaure.checked_div(n)?.sqrt(); + + Ok((reaction, impact_factor)) +} + +/// Calculate the rebalancing fee +/// +/// The fee is calculated as λ * f * amount_in, where: +/// - λ is the fee scaler, λ ∈ (0,1] +/// - f is the impact factor, f ∈ [0,1] +/// - amount_in is the amount being swapped in, normalized by standard normalization factor +pub fn calculate_rebalancing_fee( + lambda: Decimal, + impact_factor: Decimal, + amount_in: Uint128, +) -> Result { + let amount_in_dec = Decimal::from_atomics(amount_in, 0)?; + + lambda + .checked_mul(impact_factor)? + .checked_mul(amount_in_dec) + .map_err(TransmuterMathError::OverflowError) +} + +/// Alias for calculate_rebalancing_fee, as it's used to calculate the impact used in incentive calculation +pub fn calculate_rebalancing_impact( + lambda: Decimal, + impact_factor: Decimal, + amount_in: Uint128, +) -> Result { + calculate_rebalancing_fee(lambda, impact_factor, amount_in) +} + +/// Calculates the rebalancing incentive for a given swap. +/// +/// The incentive should be distributed considering the impact factor $f$, amount $a_{in}$ and incentive pool $p$, so the naive model could be just $min(\lambda f a_{in},p)$. +/// But $\lambda$ be updated and largely impact incentive comparing to when fee has been collected. +/// +/// So this function does not try to match the fee collected with the same amount in and impact factor, but scales the incentive by only looking at the amount in and impact factor comparing to overall incentive pool. +/// +/// $$ +/// \text{Incentive} = p \cdot \frac{\lambda fa_{in}}{p + \lambda fa_{in}} +/// $$ +/// +/// ## Arguments +/// - `impact`: the impact of the swap, calculated as $\lambda f a_{in}$ +/// - `incentive_pool`: the remaining incentive pool $p$ +/// +/// ## Returns +/// - The rebalancing incentive +pub fn calculate_rebalancing_incentive( + impact: Decimal, + incentive_pool: Uint128, +) -> Result { + let incentive_pool_dec = Decimal::from_atomics(incentive_pool, 0)?; + let extended_incentive_pool = incentive_pool_dec.checked_add(impact)?; + let impact_over_extended_incentive_pool = impact.checked_div(extended_incentive_pool)?; + + impact_over_extended_incentive_pool + .checked_mul(incentive_pool_dec) + .map_err(TransmuterMathError::OverflowError) +} From ee5a1211706eb64a1e910cb4b6bf862a01f4975d Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Wed, 11 Sep 2024 14:54:10 +0700 Subject: [PATCH 02/13] add test for calculate rebalancing fee --- Cargo.lock | 82 ++++++++++++++++--- packages/transmuter_math/Cargo.toml | 1 + packages/transmuter_math/src/errors.rs | 3 + .../src/rebalancing_incentive.rs | 79 ++++++++++++++++-- 4 files changed, 145 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82c7bf3..658af7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1362,7 +1362,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.14", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit 0.22.20", ] [[package]] @@ -1602,7 +1611,19 @@ checksum = "97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199" dependencies = [ "futures", "futures-timer", - "rstest_macros", + "rstest_macros 0.18.2", + "rustc_version", +] + +[[package]] +name = "rstest" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b423f0e62bdd61734b67cd21ff50871dfaeb9cc74f869dcd6af974fbcb19936" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros 0.22.0", "rustc_version", ] @@ -1623,6 +1644,24 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "rstest_macros" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e1711e7d14f74b12a58411c542185ef7fb7f2e7f8ee6e2940a883628522b42" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn 2.0.60", + "unicode-ident", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1790,9 +1829,9 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -1835,9 +1874,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -2025,7 +2064,7 @@ checksum = "ae5e0f41752efba2c6895514fa4caae742f69a2a73b4790bb6e365400c563bc1" dependencies = [ "convert_case", "itertools 0.12.0", - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro-error", "proc-macro2", "quote", @@ -2301,9 +2340,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" @@ -2313,7 +2352,18 @@ checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap 2.0.0", "toml_datetime", - "winnow", + "winnow 0.5.15", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow 0.6.18", ] [[package]] @@ -2354,7 +2404,7 @@ dependencies = [ "itertools 0.12.0", "osmosis-std", "osmosis-test-tube", - "rstest", + "rstest 0.18.2", "schemars", "serde", "sylvia", @@ -2368,6 +2418,7 @@ version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "rstest 0.22.0", "thiserror", ] @@ -2663,6 +2714,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/packages/transmuter_math/Cargo.toml b/packages/transmuter_math/Cargo.toml index 9a20efd..57a825a 100644 --- a/packages/transmuter_math/Cargo.toml +++ b/packages/transmuter_math/Cargo.toml @@ -10,4 +10,5 @@ version = "1.0.0" [dependencies] cosmwasm-schema = {workspace = true} cosmwasm-std = {workspace = true} +rstest = "0.22.0" thiserror = "1.0.63" diff --git a/packages/transmuter_math/src/errors.rs b/packages/transmuter_math/src/errors.rs index 22c358a..edd00ee 100644 --- a/packages/transmuter_math/src/errors.rs +++ b/packages/transmuter_math/src/errors.rs @@ -15,6 +15,9 @@ pub enum TransmuterMathError { #[error("Missing data points to calculate moving average")] MissingDataPoints, + #[error("Value is not normalized: {var_name}")] + NotNormalized { var_name: String }, + #[error("{0}")] DecimalRangeExceeded(#[from] DecimalRangeExceeded), diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index 76672be..d4e158e 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -92,9 +92,9 @@ impl ImpactFactorParamGroup { } } -pub enum Reaction { - Incentivize, - CollectFee, +pub enum ReblancingResponse { + Incentive, + Fee, } /// combine all the impact factor components @@ -107,7 +107,7 @@ pub enum Reaction { /// The reason why it needs to include all dimensions is because the case that swapping with alloyed asset, which will effect overall composition rather than just 2 assets. pub fn calculate_impact_factor( impact_factor_param_groups: &[ImpactFactorParamGroup], -) -> Result<(Reaction, Decimal256), TransmuterMathError> { +) -> Result<(ReblancingResponse, Decimal256), TransmuterMathError> { let mut cumulative_impact_factor_sqaure = Decimal256::zero(); let mut impact_factor_component_sum = SignedDecimal256::zero(); @@ -130,9 +130,9 @@ pub fn calculate_impact_factor( } let reaction = if impact_factor_component_sum.is_negative() { - Reaction::Incentivize + ReblancingResponse::Incentive } else { - Reaction::CollectFee + ReblancingResponse::Fee }; let impact_factor = cumulative_impact_factor_sqaure.checked_div(n)?.sqrt(); @@ -150,8 +150,22 @@ pub fn calculate_rebalancing_fee( lambda: Decimal, impact_factor: Decimal, amount_in: Uint128, -) -> Result { - let amount_in_dec = Decimal::from_atomics(amount_in, 0)?; +) -> Result { + if lambda > Decimal::one() { + return Err(TransmuterMathError::NotNormalized { + var_name: "lambda".to_string(), + }); + } + + if impact_factor > Decimal::one() { + return Err(TransmuterMathError::NotNormalized { + var_name: "impact_factor".to_string(), + }); + } + + let lambda = Decimal256::from(lambda); + let impact_factor = Decimal256::from(impact_factor); + let amount_in_dec = Decimal256::from_atomics(amount_in, 0)?; lambda .checked_mul(impact_factor)? @@ -164,7 +178,7 @@ pub fn calculate_rebalancing_impact( lambda: Decimal, impact_factor: Decimal, amount_in: Uint128, -) -> Result { +) -> Result { calculate_rebalancing_fee(lambda, impact_factor, amount_in) } @@ -197,3 +211,50 @@ pub fn calculate_rebalancing_incentive( .checked_mul(incentive_pool_dec) .map_err(TransmuterMathError::OverflowError) } + +#[cfg(test)] +mod tests { + use super::*; + use rstest::rstest; + + #[rstest] + #[case( + Decimal::percent(100), + Decimal::percent(100), + Uint128::MAX, + Ok(Decimal256::from_atomics(u128::MAX, 0).unwrap()) + )] + #[case( + Decimal::percent(100), + Decimal::percent(100), + Uint128::zero(), + Ok(Decimal256::zero()) + )] + #[case( + Decimal::percent(50), + Decimal::percent(50), + Uint128::from(100u128), + Ok(Decimal256::from_atomics(25u128, 0).unwrap()) + )] + #[case( + Decimal::percent(101), + Decimal::percent(100), + Uint128::MAX, + Err(TransmuterMathError::NotNormalized { var_name: "lambda".to_string() }) + )] + #[case( + Decimal::percent(100), + Decimal::percent(101), + Uint128::MAX, + Err(TransmuterMathError::NotNormalized { var_name: "impact_factor".to_string() }) + )] + fn test_calculate_rebalancing_fee( + #[case] lambda: Decimal, + #[case] impact_factor: Decimal, + #[case] amount_in: Uint128, + #[case] expected: Result, + ) { + let actual = calculate_rebalancing_fee(lambda, impact_factor, amount_in); + assert_eq!(expected, actual); + } +} From f757dd0a02ddc2352222b55b426fc9851d1f8de2 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Wed, 11 Sep 2024 15:41:38 +0700 Subject: [PATCH 03/13] add prop test --- Cargo.lock | 1166 ++++++++++------- packages/transmuter_math/Cargo.toml | 5 +- .../rebalancing_incentive.txt | 7 + .../src/rebalancing_incentive.rs | 17 + 4 files changed, 737 insertions(+), 458 deletions(-) create mode 100644 packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt diff --git a/Cargo.lock b/Cargo.lock index 658af7f..2d7cfd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,24 +4,24 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -30,49 +30,49 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -83,9 +83,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -101,43 +101,58 @@ checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" [[package]] name = "bindgen" -version = "0.69.1" +version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "cexpr", "clang-sys", + "itertools 0.12.1", "lazy_static", "lazycell", "log", - "peeking_take_while", "prettyplease", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.60", + "syn 2.0.77", "which", ] [[package]] name = "bip32" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" +checksum = "aa13fae8b6255872fd86f7faf4b41168661d7d78609f7bfe6771b85c6739a15b" dependencies = [ "bs58", "hmac", "k256", "rand_core 0.6.4", "ripemd", - "sha2 0.10.7", + "sha2 0.10.8", "subtle", "zeroize", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" @@ -146,9 +161,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -176,41 +191,41 @@ checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" [[package]] name = "bs58" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" dependencies = [ "serde", ] [[package]] name = "cc" -version = "1.0.83" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" dependencies = [ - "libc", + "shlex", ] [[package]] @@ -230,18 +245,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.28" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "num-traits", ] [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -250,15 +265,15 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_panic" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" +checksum = "7782af8f90fe69a4bb41e460abe1727d493403d8b2cc43201a3a3e906b24379f" [[package]] name = "convert_case" @@ -271,9 +286,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -281,9 +296,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cosmos-sdk-proto" @@ -291,8 +306,8 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" dependencies = [ - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.12.6", + "prost-types 0.12.6", "tendermint-proto", ] @@ -319,12 +334,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.4" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b4c3f9c4616d6413d4b5fc4c270a4cc32a374b9be08671e80e1a019f805d8f" +checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" dependencies = [ "digest 0.10.7", - "ecdsa", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -333,18 +347,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.5.4" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c586ced10c3b00e809ee664a895025a024f60d65d34fe4c09daed4a4db68a3f3" +checksum = "cd85de6467cd1073688c86b39833679ae6db18cf4771471edd9809f15f1679f1" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.5.4" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8467874827d384c131955ff6f4d47d02e72a956a08eb3c0ff24f8c903a5517b4" +checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -355,9 +369,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.5.4" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6db85d98ac80922aef465e564d5b21fa9cfac5058cb62df7f116c3682337393" +checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" dependencies = [ "proc-macro2", "quote", @@ -366,9 +380,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.5.4" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712fe58f39d55c812f7b2c84e097cdede3a39d520f89b6dc3153837e31741927" +checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" dependencies = [ "base64", "bech32", @@ -381,16 +395,16 @@ dependencies = [ "schemars", "serde", "serde-json-wasm 0.5.2", - "sha2 0.10.7", + "sha2 0.10.8", "static_assertions", "thiserror", ] [[package]] name = "cosmwasm-storage" -version = "1.3.3" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b52be0d56b78f502f3acb75e40908a0d04d9f265b6beb0f86b36ec2ece048748" +checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" dependencies = [ "cosmwasm-std", "serde", @@ -398,18 +412,18 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -455,9 +469,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", "schemars", @@ -466,28 +480,38 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", + "semver", "serde", "thiserror", ] [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "derivative" version = "2.2.0" @@ -522,15 +546,15 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.13" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", "digest 0.10.7", @@ -580,9 +604,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -605,9 +629,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -618,16 +642,32 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "eyre" -version = "0.6.8" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", ] +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + [[package]] name = "ff" version = "0.13.0" @@ -656,9 +696,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -671,9 +711,9 @@ checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -686,9 +726,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -696,15 +736,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -713,44 +753,44 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -777,9 +817,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -790,9 +830,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "glob" @@ -813,9 +853,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -823,7 +863,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap", "slab", "tokio", "tokio-util", @@ -841,15 +881,15 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -866,11 +906,20 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "http" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -879,9 +928,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -890,9 +939,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -902,9 +951,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -917,7 +966,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2", "tokio", "tower-service", "tracing", @@ -940,9 +989,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -956,29 +1005,19 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.0.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.5", ] [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "itertools" @@ -991,56 +1030,47 @@ dependencies = [ [[package]] name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.7", + "sha2 0.10.8", "signature", ] [[package]] name = "konst" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030400e39b2dff8beaa55986a17e0014ad657f569ca92426aafcb5e8e71faee7" +checksum = "50a0ba6de5f7af397afff922f22c149ff605c766cd3269cf6c1cd5e466dbe3b9" dependencies = [ "const_panic", "konst_kernel", @@ -1050,9 +1080,9 @@ dependencies = [ [[package]] name = "konst_kernel" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3376133edc39f027d551eb77b077c2865a0ef252b2e7d0dd6b6dc303db95d8b5" +checksum = "be0a455a1719220fd6adf756088e1c69a85bf14b6a9e24537a5cc04f503edb2b" dependencies = [ "typewit", ] @@ -1065,9 +1095,9 @@ checksum = "4e28ab1dc35e09d60c2b8c90d12a9a8d9666c876c10a3739a3196db0103b6043" [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lazycell" @@ -1077,31 +1107,43 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "winapi", + "windows-targets 0.52.6", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" -version = "2.6.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -1117,22 +1159,23 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.8" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1145,6 +1188,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.3.3" @@ -1158,37 +1207,19 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", + "libm", ] [[package]] name = "object" -version = "0.32.0" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] @@ -1201,9 +1232,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl-probe" @@ -1220,8 +1251,8 @@ dependencies = [ "chrono", "cosmwasm-std", "osmosis-std-derive", - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.12.6", + "prost-types 0.12.6", "schemars", "serde", "serde-cw-value", @@ -1251,7 +1282,7 @@ dependencies = [ "cosmrs", "cosmwasm-std", "osmosis-std", - "prost 0.12.3", + "prost 0.12.6", "serde", "serde_json", "test-tube", @@ -1260,21 +1291,15 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "peeking_take_while" -version = "0.1.2" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "peg" -version = "0.7.0" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" +checksum = "295283b02df346d1ef66052a757869b2876ac29a6bb0ac3f5f7cd44aebe40e8f" dependencies = [ "peg-macros", "peg-runtime", @@ -1282,9 +1307,9 @@ dependencies = [ [[package]] name = "peg-macros" -version = "0.7.0" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" +checksum = "bdad6a1d9cf116a059582ce415d5f5566aabcd4008646779dab7fdc2a9a9d426" dependencies = [ "peg-runtime", "proc-macro2", @@ -1293,41 +1318,41 @@ dependencies = [ [[package]] name = "peg-runtime" -version = "0.7.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" +checksum = "e3aeb8f54c078314c2065ee649a7241f46b9d8e418e1a9581ba0546657d7aa3a" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1345,14 +1370,29 @@ dependencies = [ "spki", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", - "syn 2.0.60", + "syn 2.0.77", ] [[package]] @@ -1362,7 +1402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit 0.19.14", + "toml_edit 0.19.15", ] [[package]] @@ -1400,13 +1440,33 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.6.0", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + [[package]] name = "prost" version = "0.11.9" @@ -1419,12 +1479,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", - "prost-derive 0.12.3", + "prost-derive 0.12.6", ] [[package]] @@ -1442,15 +1502,15 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", ] [[package]] @@ -1464,22 +1524,49 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ - "prost 0.12.3", + "prost 0.12.6", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -1495,11 +1582,20 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "regex" -version = "1.9.4" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -1509,9 +1605,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.7" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -1520,21 +1616,21 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "relative-path" -version = "1.9.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c707298afce11da2efef2f600116fa93ffa7a032b5d7b628aa17711ec81383ca" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "reqwest" -version = "0.11.22" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64", "bytes", @@ -1559,6 +1655,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-rustls", @@ -1582,16 +1679,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin", "untrusted", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1640,7 +1738,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.60", + "syn 2.0.77", "unicode-ident", ] @@ -1658,15 +1756,15 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.60", + "syn 2.0.77", "unicode-ident", ] [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -1676,18 +1774,31 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring", @@ -1726,11 +1837,23 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -1743,18 +1866,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] name = "schemars" -version = "0.8.13" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763f8cd0d4c71ed8389c90cb8100cba87e763bd01a8e614d4f0af97bcd50a161" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" dependencies = [ "dyn-clone", "schemars_derive", @@ -1764,14 +1887,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.13" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0f696e21e10fa546b7ffb1c9672c6de8fbc7a81acf59524386d8639bf12737" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -1800,11 +1923,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -1813,9 +1936,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -1823,9 +1946,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" @@ -1865,9 +1988,9 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" dependencies = [ "serde", ] @@ -1880,40 +2003,41 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", ] [[package]] name = "serde_derive_internals" -version = "0.26.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", ] [[package]] @@ -1943,9 +2067,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -1954,15 +2078,15 @@ dependencies = [ [[package]] name = "shlex" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -1979,22 +2103,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.9" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" -dependencies = [ - "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2005,9 +2119,9 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -2021,9 +2135,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "subtle-encoding" @@ -2063,12 +2177,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae5e0f41752efba2c6895514fa4caae742f69a2a73b4790bb6e365400c563bc1" dependencies = [ "convert_case", - "itertools 0.12.0", + "itertools 0.12.1", "proc-macro-crate 1.3.1", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", ] [[package]] @@ -2084,15 +2198,21 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.60" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "system-configuration" version = "0.5.1" @@ -2114,11 +2234,24 @@ dependencies = [ "libc", ] +[[package]] +name = "tempfile" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "tendermint" -version = "0.34.0" +version = "0.34.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc2294fa667c8b548ee27a9ba59115472d0a09c2ba255771092a7f1dcf03a789" +checksum = "15ab8f0a25d0d2ad49ac615da054d6a76aa6603ff95f7d18bafdd34450a1a04b" dependencies = [ "bytes", "digest 0.10.7", @@ -2129,14 +2262,14 @@ dependencies = [ "k256", "num-traits", "once_cell", - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.12.6", + "prost-types 0.12.6", "ripemd", "serde", "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.7", + "sha2 0.10.8", "signature", "subtle", "subtle-encoding", @@ -2147,9 +2280,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.34.0" +version = "0.34.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a25dbe8b953e80f3d61789fbdb83bf9ad6c0ef16df5ca6546f49912542cc137" +checksum = "e1a02da769166e2052cd537b1a97c78017632c2d9e19266367b27e73910434fc" dependencies = [ "flex-error", "serde", @@ -2161,16 +2294,16 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.34.0" +version = "0.34.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc728a4f9e891d71adf66af6ecaece146f9c7a11312288a3107b3e1d6979aaf" +checksum = "b797dd3d2beaaee91d2f065e7bdf239dc8d80bba4a183a288bc1279dd5a69a1e" dependencies = [ "bytes", "flex-error", "num-derive", "num-traits", - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.12.6", + "prost-types 0.12.6", "serde", "serde_bytes", "subtle-encoding", @@ -2179,9 +2312,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.34.0" +version = "0.34.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbf0a4753b46a190f367337e0163d0b552a2674a6bac54e74f9f2cdcde2969b" +checksum = "71afae8bb5f6b14ed48d4e1316a643b6c2c3cbad114f510be77b4ed20b7b3e42" dependencies = [ "async-trait", "bytes", @@ -2190,6 +2323,7 @@ dependencies = [ "getrandom", "peg", "pin-project", + "rand", "reqwest", "semver", "serde", @@ -2219,7 +2353,7 @@ dependencies = [ "cosmrs", "cosmwasm-std", "osmosis-std", - "prost 0.12.3", + "prost 0.12.6", "serde", "serde_json", "thiserror", @@ -2242,31 +2376,44 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", ] [[package]] name = "time" -version = "0.3.11" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ - "libc", - "num_threads", + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", "time-macros", ] +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + [[package]] name = "time-macros" -version = "0.2.4" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -2279,30 +2426,29 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "pin-project-lite", - "socket2 0.5.3", + "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", ] [[package]] @@ -2317,16 +2463,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -2346,13 +2491,13 @@ checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.19.14" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.0.0", + "indexmap", "toml_datetime", - "winnow 0.5.15", + "winnow 0.5.40", ] [[package]] @@ -2361,33 +2506,32 @@ version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.0.0", + "indexmap", "toml_datetime", "winnow 0.6.18", ] [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-core", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] @@ -2401,7 +2545,7 @@ dependencies = [ "cosmwasm-storage", "cw-storage-plus", "cw2", - "itertools 0.12.0", + "itertools 0.12.1", "osmosis-std", "osmosis-test-tube", "rstest 0.18.2", @@ -2418,54 +2562,70 @@ version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", + "proptest", "rstest 0.22.0", "thiserror", ] [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typewit" -version = "1.5.0" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fb9ae6a3cafaf0a5d14c2302ca525f9ae8e07a0f0e6949de88d882c37a6e24" +dependencies = [ + "typewit_proc_macros", +] + +[[package]] +name = "typewit_proc_macros" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5cee357cc77d1e02f10a3e6c4e13b8462fafab05998b62d331b7d9485589ff" +checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "untrusted" @@ -2475,9 +2635,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -2486,21 +2646,30 @@ dependencies = [ [[package]] name = "uuid" -version = "0.8.2" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wait-timeout" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] [[package]] name = "walkdir" -version = "2.3.3" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -2523,34 +2692,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -2560,9 +2730,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2570,28 +2740,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -2599,53 +2769,50 @@ dependencies = [ [[package]] name = "which" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "libc", + "home", "once_cell", + "rustix", ] [[package]] -name = "winapi" -version = "0.3.9" +name = "winapi-util" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-sys 0.59.0", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" +name = "windows-sys" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "winapi", + "windows-targets 0.48.5", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -2654,13 +2821,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2669,47 +2852,95 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] @@ -2730,14 +2961,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -2750,5 +3002,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.77", ] diff --git a/packages/transmuter_math/Cargo.toml b/packages/transmuter_math/Cargo.toml index 57a825a..f73fd82 100644 --- a/packages/transmuter_math/Cargo.toml +++ b/packages/transmuter_math/Cargo.toml @@ -10,5 +10,8 @@ version = "1.0.0" [dependencies] cosmwasm-schema = {workspace = true} cosmwasm-std = {workspace = true} -rstest = "0.22.0" thiserror = "1.0.63" + +[dev-dependencies] +proptest = "1.5.0" +rstest = "0.22.0" diff --git a/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt b/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt new file mode 100644 index 0000000..fb54f54 --- /dev/null +++ b/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 562a32f0f5c0872580ed28523b29332acb431e7009dee0c7aba7b67a58523c3e # shrinks to lambda = 1000000000000000001, impact_factor = 0, amount_in = 0 diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index d4e158e..d6d7c86 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -215,6 +215,7 @@ pub fn calculate_rebalancing_incentive( #[cfg(test)] mod tests { use super::*; + use proptest::prelude::*; use rstest::rstest; #[rstest] @@ -257,4 +258,20 @@ mod tests { let actual = calculate_rebalancing_fee(lambda, impact_factor, amount_in); assert_eq!(expected, actual); } + + proptest! { + #[test] + fn test_rebalancing_fee_must_never_exceed_amount_in( + lambda in 0u128..=1000000000000000000, + impact_factor in 0u128..=1000000000000000000, + amount_in in 0..=u128::MAX, + ) { + let lambda = Decimal::raw(lambda); + let impact_factor = Decimal::raw(impact_factor); + let amount_in = Uint128::new(amount_in); + + let actual = calculate_rebalancing_fee(lambda, impact_factor, amount_in).unwrap(); + assert!(actual <= Decimal256::from_atomics(amount_in, 0).unwrap()); + } + } } From 1a8ca4bf43f1d56415bb7a4b03dddfd40836a293 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Wed, 11 Sep 2024 16:20:13 +0700 Subject: [PATCH 04/13] test calc incentive --- packages/transmuter_math/src/lib.rs | 3 +- .../src/rebalancing_incentive.rs | 91 +++++++++++++++++-- 2 files changed, 85 insertions(+), 9 deletions(-) diff --git a/packages/transmuter_math/src/lib.rs b/packages/transmuter_math/src/lib.rs index f405790..69cb84b 100644 --- a/packages/transmuter_math/src/lib.rs +++ b/packages/transmuter_math/src/lib.rs @@ -1,7 +1,8 @@ mod division; mod errors; mod helpers; -mod rebalancing_incentive; + +pub mod rebalancing_incentive; pub use cosmwasm_std::{Decimal, Timestamp, Uint64}; pub use division::Division; diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index d6d7c86..6048027 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -64,6 +64,22 @@ pub struct ImpactFactorParamGroup { } impl ImpactFactorParamGroup { + pub fn new( + prev_normalized_balance: Decimal, + update_normalized_balance: Decimal, + ideal_balance_lower_bound: Decimal, + ideal_balance_upper_bound: Decimal, + upper_limit: Decimal, + ) -> Self { + Self { + prev_normalized_balance, + update_normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + } + } + fn has_no_change_in_balance(&self) -> bool { self.prev_normalized_balance == self.update_normalized_balance } @@ -202,19 +218,29 @@ pub fn calculate_rebalancing_impact( pub fn calculate_rebalancing_incentive( impact: Decimal, incentive_pool: Uint128, -) -> Result { - let incentive_pool_dec = Decimal::from_atomics(incentive_pool, 0)?; +) -> Result { + if impact > Decimal::one() { + return Err(TransmuterMathError::NotNormalized { + var_name: "impact".to_string(), + }); + } + + let impact = Decimal256::from(impact); + let incentive_pool_dec = Decimal256::from_atomics(incentive_pool, 0)?; + let impact_by_incentive_pool = impact.checked_mul(incentive_pool_dec)?; let extended_incentive_pool = incentive_pool_dec.checked_add(impact)?; - let impact_over_extended_incentive_pool = impact.checked_div(extended_incentive_pool)?; - impact_over_extended_incentive_pool - .checked_mul(incentive_pool_dec) - .map_err(TransmuterMathError::OverflowError) + impact_by_incentive_pool + .checked_div(extended_incentive_pool) + .map_err(TransmuterMathError::CheckedFromRatioError) } #[cfg(test)] mod tests { + use std::str::FromStr; + use super::*; + use cosmwasm_std::Uint256; use proptest::prelude::*; use rstest::rstest; @@ -262,8 +288,8 @@ mod tests { proptest! { #[test] fn test_rebalancing_fee_must_never_exceed_amount_in( - lambda in 0u128..=1000000000000000000, - impact_factor in 0u128..=1000000000000000000, + lambda in 0u128..=1_000_000_000_000_000_000, // -> 0.0..1.0 + impact_factor in 0u128..=1_000_000_000_000_000_000, // 0.0 -> 1.0 amount_in in 0..=u128::MAX, ) { let lambda = Decimal::raw(lambda); @@ -273,5 +299,54 @@ mod tests { let actual = calculate_rebalancing_fee(lambda, impact_factor, amount_in).unwrap(); assert!(actual <= Decimal256::from_atomics(amount_in, 0).unwrap()); } + + #[test] + fn test_rebalancing_fee_must_equal_rebalancing_impact( + lambda in 0u128..=u128::MAX, + impact_factor in 0u128..=u128::MAX, + amount_in in 0..=u128::MAX, + ) { + let lambda = Decimal::raw(lambda); + let impact_factor = Decimal::raw(impact_factor); + let amount_in = Uint128::new(amount_in); + + let fee = calculate_rebalancing_fee(lambda, impact_factor, amount_in); + let impact = calculate_rebalancing_impact(lambda, impact_factor, amount_in); + + assert_eq!(fee, impact); + } + } + + #[rstest] + #[case(Decimal::one(), Uint128::MAX, Ok(Decimal256::from_ratio( + Uint256::from(u128::MAX), + Uint256::from(u128::MAX) + Uint256::from(1u128), + )))] + #[case(Decimal::zero(), Uint128::new(1000), Ok(Decimal256::zero()))] + #[case(Decimal::one(), Uint128::zero(), Ok(Decimal256::zero()))] + #[case(Decimal::percent(50), Uint128::new(1000), Ok(Decimal256::from_str("0.499750124937531234").unwrap()))] + #[case(Decimal::percent(100), Uint128::new(1000), Ok(Decimal256::from_str("0.999000999000999").unwrap()))] + #[case(Decimal::percent(101), Uint128::new(1000), Err(TransmuterMathError::NotNormalized { var_name: "impact".to_string() }))] + fn test_calculate_rebalancing_incentive( + #[case] impact: Decimal, + #[case] incentive_pool: Uint128, + #[case] expected: Result, + ) { + let actual = calculate_rebalancing_incentive(impact, incentive_pool); + assert_eq!(expected, actual); + } + + proptest! { + #[test] + fn test_rebalancing_incentive_must_less_than_or_equal_to_incentive_pool( + impact in 0u128..=1_000_000_000_000_000_000, + incentive_pool in 0u128..=u128::MAX, + ) { + let impact = Decimal::raw(impact); + let incentive_pool = Uint128::new(incentive_pool); + + let actual = calculate_rebalancing_incentive(impact, incentive_pool).unwrap(); + assert!(actual <= Decimal256::from_atomics(incentive_pool, 0).unwrap()); + } } } From 9740855627aa6a3c2479b3e3f9c38d9247f7f2c8 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Wed, 11 Sep 2024 17:06:37 +0700 Subject: [PATCH 05/13] add test for test_calculate_impact_factor_component --- .../src/rebalancing_incentive.rs | 103 ++++++++++++++++-- 1 file changed, 94 insertions(+), 9 deletions(-) diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index 6048027..d59fdaa 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -45,6 +45,9 @@ pub fn calculate_cumulative_impact_factor_component( } else if normalized_balance > ideal_balance_upper_bound { normalized_balance // b .checked_sub(ideal_balance_upper_bound)? // - phi_u + // delta - phi_u will never be 0 as this case requires b > phi_u, + // delta - phi_u = 0 then delta = phi_u + // since b > delta is restricted by limiter, and delta <= phi_u, this will never happen .checked_div(upper_limit.checked_sub(ideal_balance_upper_bound)?)? // / delta - phi_u .pow(2) // ^2 } else { @@ -108,7 +111,7 @@ impl ImpactFactorParamGroup { } } -pub enum ReblancingResponse { +pub enum PayoffType { Incentive, Fee, } @@ -123,7 +126,7 @@ pub enum ReblancingResponse { /// The reason why it needs to include all dimensions is because the case that swapping with alloyed asset, which will effect overall composition rather than just 2 assets. pub fn calculate_impact_factor( impact_factor_param_groups: &[ImpactFactorParamGroup], -) -> Result<(ReblancingResponse, Decimal256), TransmuterMathError> { +) -> Result<(PayoffType, Decimal256), TransmuterMathError> { let mut cumulative_impact_factor_sqaure = Decimal256::zero(); let mut impact_factor_component_sum = SignedDecimal256::zero(); @@ -145,15 +148,15 @@ pub fn calculate_impact_factor( cumulative_impact_factor_sqaure.checked_add(impact_factor_component_square)?; } - let reaction = if impact_factor_component_sum.is_negative() { - ReblancingResponse::Incentive + let payoff_type = if impact_factor_component_sum.is_negative() { + PayoffType::Incentive } else { - ReblancingResponse::Fee + PayoffType::Fee }; let impact_factor = cumulative_impact_factor_sqaure.checked_div(n)?.sqrt(); - Ok((reaction, impact_factor)) + Ok((payoff_type, impact_factor)) } /// Calculate the rebalancing fee @@ -244,6 +247,8 @@ mod tests { use proptest::prelude::*; use rstest::rstest; + const ONE_DEC_RAW: u128 = 1_000_000_000_000_000_000; + #[rstest] #[case( Decimal::percent(100), @@ -288,8 +293,8 @@ mod tests { proptest! { #[test] fn test_rebalancing_fee_must_never_exceed_amount_in( - lambda in 0u128..=1_000_000_000_000_000_000, // -> 0.0..1.0 - impact_factor in 0u128..=1_000_000_000_000_000_000, // 0.0 -> 1.0 + lambda in 0u128..=ONE_DEC_RAW, + impact_factor in 0u128..=ONE_DEC_RAW, amount_in in 0..=u128::MAX, ) { let lambda = Decimal::raw(lambda); @@ -339,7 +344,7 @@ mod tests { proptest! { #[test] fn test_rebalancing_incentive_must_less_than_or_equal_to_incentive_pool( - impact in 0u128..=1_000_000_000_000_000_000, + impact in 0u128..=ONE_DEC_RAW, incentive_pool in 0u128..=u128::MAX, ) { let impact = Decimal::raw(impact); @@ -349,4 +354,84 @@ mod tests { assert!(actual <= Decimal256::from_atomics(incentive_pool, 0).unwrap()); } } + + #[rstest] + #[case( + Decimal::zero(), + Decimal::percent(40), + Decimal::percent(50), + Decimal::percent(60), + Ok(Decimal::one()) + )] + #[case( + Decimal::percent(39), + Decimal::percent(40), + Decimal::percent(50), + Decimal::percent(60), + Ok(Decimal::from_str("0.000625").unwrap()) + )] + #[case( + Decimal::percent(40), + Decimal::percent(40), + Decimal::percent(50), + Decimal::percent(60), + Ok(Decimal::zero()) + )] + #[case( + Decimal::percent(50), + Decimal::percent(40), + Decimal::percent(50), + Decimal::percent(60), + Ok(Decimal::zero()) + )] + #[case( + Decimal::percent(51), + Decimal::percent(40), + Decimal::percent(50), + Decimal::percent(60), + Ok(Decimal::percent(1)) + )] + #[case( + Decimal::percent(60), + Decimal::percent(40), + Decimal::percent(50), + Decimal::percent(60), + Ok(Decimal::one()) + )] + #[case( + Decimal::percent(50), + Decimal::percent(40), + Decimal::percent(60), + Decimal::percent(50), + Ok(Decimal::zero()) + )] + #[case( + Decimal::percent(30), + Decimal::percent(40), + Decimal::percent(60), + Decimal::percent(30), + Ok(Decimal::zero()) + )] + #[case( + Decimal::percent(30), + Decimal::percent(40), + Decimal::percent(30), + Decimal::percent(50), + Ok(Decimal::zero()) + )] + fn test_calculate_impact_factor_component( + #[case] normalized_balance: Decimal, + #[case] ideal_balance_lower_bound: Decimal, + #[case] ideal_balance_upper_bound: Decimal, + #[case] upper_limit: Decimal, + #[case] expected: Result, + ) { + let actual = calculate_cumulative_impact_factor_component( + normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ); + assert_eq!(expected, actual); + } } From 42e8c47f3dfab5545e295fed0a364ba4d9d6bdd4 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Wed, 11 Sep 2024 17:15:32 +0700 Subject: [PATCH 06/13] change pow to checked_pow --- packages/transmuter_math/src/rebalancing_incentive.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index d59fdaa..63ae747 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -41,7 +41,7 @@ pub fn calculate_cumulative_impact_factor_component( ideal_balance_lower_bound // phi_l .checked_sub(normalized_balance)? // - b .checked_div(ideal_balance_lower_bound)? // / phi_l - .pow(2) // ^2 + .checked_pow(2)? // ^2 } else if normalized_balance > ideal_balance_upper_bound { normalized_balance // b .checked_sub(ideal_balance_upper_bound)? // - phi_u @@ -49,7 +49,7 @@ pub fn calculate_cumulative_impact_factor_component( // delta - phi_u = 0 then delta = phi_u // since b > delta is restricted by limiter, and delta <= phi_u, this will never happen .checked_div(upper_limit.checked_sub(ideal_balance_upper_bound)?)? // / delta - phi_u - .pow(2) // ^2 + .checked_pow(2)? // ^2 } else { // within ideal balance Decimal::zero() @@ -74,6 +74,7 @@ impl ImpactFactorParamGroup { ideal_balance_upper_bound: Decimal, upper_limit: Decimal, ) -> Self { + // TODO: restrict this Self { prev_normalized_balance, update_normalized_balance, From 375f1ae9c4eabef682b99d1e0b046184a551658e Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Wed, 11 Sep 2024 17:58:50 +0700 Subject: [PATCH 07/13] add proptest for calculate_cumulative_impact_factor_component --- .../rebalancing_incentive.txt | 5 + .../src/rebalancing_incentive.rs | 120 +++++++++++++++++- 2 files changed, 124 insertions(+), 1 deletion(-) diff --git a/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt b/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt index fb54f54..9b7f5a9 100644 --- a/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt +++ b/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt @@ -5,3 +5,8 @@ # It is recommended to check this file in to source control so that # everyone who runs the test benefits from these saved cases. cc 562a32f0f5c0872580ed28523b29332acb431e7009dee0c7aba7b67a58523c3e # shrinks to lambda = 1000000000000000001, impact_factor = 0, amount_in = 0 +cc b152caa95a33e588b05bf0c6d3c53b91808d83e0a5f6a8176d35ce59771ac8df # shrinks to normalized_balance = 269526351641570518, ideal_balance_lower_bound = 0, ideal_balance_upper_bound = 0, upper_limit = 0 +cc 05667d509ee73bc4dc7059dabfd936ca1b83e0858079419ef4ec85d3134e545d # shrinks to normalized_balance = 269724147998904283, ideal_balance_lower_bound = 296075781682198385, ideal_balance_upper_bound = 0, upper_limit = 269724147998904283 +cc b254ff7ece5fb165f9e4d53746fc7222427cff1d17afbcd15cb8e3b3a7282cfc # shrinks to normalized_balance = 0, ideal_balance_lower_bound = 1, ideal_balance_upper_bound = 0, upper_limit = 0 +cc 6bbf8d95569b53ec005ed88b282ebcb88f2a327770cf267800b744274aeaf323 # shrinks to normalized_balance = 340640889074348996, ideal_balance_lower_bound = 340640889074348997, ideal_balance_upper_bound = 340640889074348998, upper_limit = 340640889074348998 +cc 4c6ad67ab30e522b8de8314e2219263f2e0dff53070517988a192b64099320ee # shrinks to normalized_balance = 866170838754561023, ideal_balance_lower_bound = 0, ideal_balance_range = 0 diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index 63ae747..e01d273 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -241,7 +241,7 @@ pub fn calculate_rebalancing_incentive( #[cfg(test)] mod tests { - use std::str::FromStr; + use std::{cmp::min, str::FromStr}; use super::*; use cosmwasm_std::Uint256; @@ -435,4 +435,122 @@ mod tests { ); assert_eq!(expected, actual); } + + proptest! { + #[test] + fn test_calculate_impact_factor_component_must_be_within_0_and_1( + normalized_balance in 0u128..=ONE_DEC_RAW, + ideal_balance_lower_bound in 0u128..=ONE_DEC_RAW, + ideal_balance_upper_bound in 0u128..=ONE_DEC_RAW, + upper_limit in 0u128..=ONE_DEC_RAW, + ) { + prop_assume!(normalized_balance <= upper_limit); + + let normalized_balance = Decimal::raw(normalized_balance); + let ideal_balance_lower_bound = Decimal::raw(ideal_balance_lower_bound); + let ideal_balance_upper_bound = Decimal::raw(ideal_balance_upper_bound); + let upper_limit = Decimal::raw(upper_limit); + + match calculate_cumulative_impact_factor_component( + normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ) { + Ok(actual) => assert!(actual <= Decimal::one()), + Err(e) => panic!("Failed to calculate impact factor component: {:?}", e), + } + } + + #[test] + fn test_calculate_impact_factor_component_with_normalized_balance_in_ideal_balance_bound_must_be_zero( + normalized_balance in 0u128..=ONE_DEC_RAW, + ideal_balance_lower_bound_from_normalized_balance in 0u128..=ONE_DEC_RAW, + ideal_balance_upper_bound_from_normalized_balance in 0u128..=ONE_DEC_RAW, + ) { + let ideal_balance_upper_bound = Decimal::raw(min(ONE_DEC_RAW, normalized_balance + ideal_balance_upper_bound_from_normalized_balance)); + let ideal_balance_lower_bound = Decimal::raw(normalized_balance.saturating_sub(ideal_balance_lower_bound_from_normalized_balance)); + let normalized_balance = Decimal::raw(normalized_balance); + let upper_limit = ideal_balance_upper_bound; + let actual = calculate_cumulative_impact_factor_component( + normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ).unwrap(); + + assert_eq!(Decimal::zero(), actual); + } + + #[test] + fn test_calculate_impact_factor_component_with_normalized_balance_decreasing_while_less_than_ideal_balance_lower_bound_must_be_increasing( + normalized_balance in 1u128..=ONE_DEC_RAW, + ideal_balance_lower_bound in 0u128..=ONE_DEC_RAW, + ) { + prop_assume!(normalized_balance < ideal_balance_lower_bound); + + let ideal_balance_upper_bound = ideal_balance_lower_bound + 1; + let upper_limit = ideal_balance_upper_bound + 1; + + let normalized_balance = Decimal::raw(normalized_balance); + let ideal_balance_lower_bound = Decimal::raw(ideal_balance_lower_bound); + let ideal_balance_upper_bound = Decimal::raw(ideal_balance_upper_bound); + let upper_limit = Decimal::raw(upper_limit); + let epsilon = Decimal::raw(1000u128); + + let c1 = calculate_cumulative_impact_factor_component( + normalized_balance - epsilon, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ).unwrap(); + + let c2 = calculate_cumulative_impact_factor_component( + normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ).unwrap(); + + assert!(c1 > c2, "c1: {c1}, c2: {c2}"); + } + + #[test] + fn test_calculate_impact_factor_component_with_normalized_balance_increasing_while_greater_than_ideal_balance_upper_bound_must_be_increasing( + normalized_balance in 0u128..=ONE_DEC_RAW-1, + ideal_balance_upper_bound in 0u128..=ONE_DEC_RAW, + upper_limit in 0u128..=ONE_DEC_RAW, + ) { + prop_assume!(normalized_balance > ideal_balance_upper_bound); + prop_assume!(upper_limit > ideal_balance_upper_bound); + + let ideal_balance_lower_bound = ideal_balance_upper_bound - 1; + + let normalized_balance = Decimal::raw(normalized_balance); + let ideal_balance_lower_bound = Decimal::raw(ideal_balance_lower_bound); + let ideal_balance_upper_bound = Decimal::raw(ideal_balance_upper_bound); + let upper_limit = Decimal::raw(upper_limit); + let epsilon = Decimal::raw(1000u128); + + let c1 = calculate_cumulative_impact_factor_component( + normalized_balance - epsilon, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ).unwrap(); + + let c2 = calculate_cumulative_impact_factor_component( + normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ).unwrap(); + + assert!(c1 < c2, "c1: {c1}, c2: {c2}"); + } + } + + // TODO: tests + // - ImpactFactorParamGroup + // - calculate_impact_factor } From 2d7022e1426d29ee6988d3cce6a8caec8b004236 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Mon, 16 Sep 2024 10:06:18 +0700 Subject: [PATCH 08/13] rename for clarity --- packages/transmuter_math/src/errors.rs | 4 +- .../src/rebalancing_incentive.rs | 46 ++++++++++++------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/packages/transmuter_math/src/errors.rs b/packages/transmuter_math/src/errors.rs index edd00ee..1b667a1 100644 --- a/packages/transmuter_math/src/errors.rs +++ b/packages/transmuter_math/src/errors.rs @@ -15,8 +15,8 @@ pub enum TransmuterMathError { #[error("Missing data points to calculate moving average")] MissingDataPoints, - #[error("Value is not normalized: {var_name}")] - NotNormalized { var_name: String }, + #[error("`{var_name}` must be within normalized range [0, 1]")] + OutOfNormalizedRange { var_name: String }, #[error("{0}")] DecimalRangeExceeded(#[from] DecimalRangeExceeded), diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index e01d273..a970f28 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{Decimal, Decimal256, SignedDecimal256, Uint128}; +use cosmwasm_std::{ensure, Decimal, Decimal256, SignedDecimal256, Uint128}; use crate::TransmuterMathError; @@ -74,7 +74,17 @@ impl ImpactFactorParamGroup { ideal_balance_upper_bound: Decimal, upper_limit: Decimal, ) -> Self { - // TODO: restrict this + // // Check if the input parameters are within the valid range [0, 1] + // if ideal_balance_lower_bound <= Decimal::one() { + // panic!("ideal_balance_lower_bound must be between 0 and 1"); + // } + // if ideal_balance_upper_bound <= Decimal::one() { + // panic!("ideal_balance_upper_bound must be between 0 and 1"); + // } + // if upper_limit <= Decimal::one() { + // panic!("upper_limit must be between 0 and 1"); + // } + Self { prev_normalized_balance, update_normalized_balance, @@ -171,17 +181,19 @@ pub fn calculate_rebalancing_fee( impact_factor: Decimal, amount_in: Uint128, ) -> Result { - if lambda > Decimal::one() { - return Err(TransmuterMathError::NotNormalized { + ensure!( + lambda <= Decimal::one(), + TransmuterMathError::OutOfNormalizedRange { var_name: "lambda".to_string(), - }); - } + } + ); - if impact_factor > Decimal::one() { - return Err(TransmuterMathError::NotNormalized { + ensure!( + impact_factor <= Decimal::one(), + TransmuterMathError::OutOfNormalizedRange { var_name: "impact_factor".to_string(), - }); - } + } + ); let lambda = Decimal256::from(lambda); let impact_factor = Decimal256::from(impact_factor); @@ -224,7 +236,7 @@ pub fn calculate_rebalancing_incentive( incentive_pool: Uint128, ) -> Result { if impact > Decimal::one() { - return Err(TransmuterMathError::NotNormalized { + return Err(TransmuterMathError::OutOfNormalizedRange { var_name: "impact".to_string(), }); } @@ -273,13 +285,13 @@ mod tests { Decimal::percent(101), Decimal::percent(100), Uint128::MAX, - Err(TransmuterMathError::NotNormalized { var_name: "lambda".to_string() }) + Err(TransmuterMathError::OutOfNormalizedRange { var_name: "lambda".to_string() }) )] #[case( Decimal::percent(100), Decimal::percent(101), Uint128::MAX, - Err(TransmuterMathError::NotNormalized { var_name: "impact_factor".to_string() }) + Err(TransmuterMathError::OutOfNormalizedRange { var_name: "impact_factor".to_string() }) )] fn test_calculate_rebalancing_fee( #[case] lambda: Decimal, @@ -332,7 +344,7 @@ mod tests { #[case(Decimal::one(), Uint128::zero(), Ok(Decimal256::zero()))] #[case(Decimal::percent(50), Uint128::new(1000), Ok(Decimal256::from_str("0.499750124937531234").unwrap()))] #[case(Decimal::percent(100), Uint128::new(1000), Ok(Decimal256::from_str("0.999000999000999").unwrap()))] - #[case(Decimal::percent(101), Uint128::new(1000), Err(TransmuterMathError::NotNormalized { var_name: "impact".to_string() }))] + #[case(Decimal::percent(101), Uint128::new(1000), Err(TransmuterMathError::OutOfNormalizedRange { var_name: "impact".to_string() }))] fn test_calculate_rebalancing_incentive( #[case] impact: Decimal, #[case] incentive_pool: Uint128, @@ -463,7 +475,7 @@ mod tests { } #[test] - fn test_calculate_impact_factor_component_with_normalized_balance_in_ideal_balance_bound_must_be_zero( + fn test_impact_factor_zero_within_ideal_bounds( normalized_balance in 0u128..=ONE_DEC_RAW, ideal_balance_lower_bound_from_normalized_balance in 0u128..=ONE_DEC_RAW, ideal_balance_upper_bound_from_normalized_balance in 0u128..=ONE_DEC_RAW, @@ -483,7 +495,7 @@ mod tests { } #[test] - fn test_calculate_impact_factor_component_with_normalized_balance_decreasing_while_less_than_ideal_balance_lower_bound_must_be_increasing( + fn test_impact_factor_increases_as_balance_decreases_below_lower_bound( normalized_balance in 1u128..=ONE_DEC_RAW, ideal_balance_lower_bound in 0u128..=ONE_DEC_RAW, ) { @@ -516,7 +528,7 @@ mod tests { } #[test] - fn test_calculate_impact_factor_component_with_normalized_balance_increasing_while_greater_than_ideal_balance_upper_bound_must_be_increasing( + fn test_impact_factor_increases_above_upper_bound( normalized_balance in 0u128..=ONE_DEC_RAW-1, ideal_balance_upper_bound in 0u128..=ONE_DEC_RAW, upper_limit in 0u128..=ONE_DEC_RAW, From c7859fcd594def993ed6a327280b44d5a19fa472 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Mon, 16 Sep 2024 10:16:52 +0700 Subject: [PATCH 09/13] restrict new on impact factor param group --- packages/transmuter_math/src/errors.rs | 3 + .../src/rebalancing_incentive.rs | 109 +++++++++++++++--- 2 files changed, 97 insertions(+), 15 deletions(-) diff --git a/packages/transmuter_math/src/errors.rs b/packages/transmuter_math/src/errors.rs index 1b667a1..10c5d1d 100644 --- a/packages/transmuter_math/src/errors.rs +++ b/packages/transmuter_math/src/errors.rs @@ -18,6 +18,9 @@ pub enum TransmuterMathError { #[error("`{var_name}` must be within normalized range [0, 1]")] OutOfNormalizedRange { var_name: String }, + #[error("Normalized balance exceeds upper limit")] + NormalizedBalanceExceedsUpperLimit, + #[error("{0}")] DecimalRangeExceeded(#[from] DecimalRangeExceeded), diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index a970f28..7a0de1c 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -58,6 +58,7 @@ pub fn calculate_cumulative_impact_factor_component( Ok(cumulative) } +#[derive(Debug, PartialEq, Eq)] pub struct ImpactFactorParamGroup { prev_normalized_balance: Decimal, update_normalized_balance: Decimal, @@ -73,25 +74,45 @@ impl ImpactFactorParamGroup { ideal_balance_lower_bound: Decimal, ideal_balance_upper_bound: Decimal, upper_limit: Decimal, - ) -> Self { - // // Check if the input parameters are within the valid range [0, 1] - // if ideal_balance_lower_bound <= Decimal::one() { - // panic!("ideal_balance_lower_bound must be between 0 and 1"); - // } - // if ideal_balance_upper_bound <= Decimal::one() { - // panic!("ideal_balance_upper_bound must be between 0 and 1"); - // } - // if upper_limit <= Decimal::one() { - // panic!("upper_limit must be between 0 and 1"); - // } - - Self { + ) -> Result { + // Check if the input parameters are within the valid range [0, 1] + ensure!( + ideal_balance_lower_bound <= Decimal::one(), + TransmuterMathError::OutOfNormalizedRange { + var_name: "ideal_balance_lower_bound".to_string() + } + ); + ensure!( + ideal_balance_upper_bound <= Decimal::one(), + TransmuterMathError::OutOfNormalizedRange { + var_name: "ideal_balance_upper_bound".to_string() + } + ); + ensure!( + upper_limit <= Decimal::one(), + TransmuterMathError::OutOfNormalizedRange { + var_name: "upper_limit".to_string() + } + ); + + // Check if the normalized balance exceeds the upper limit + ensure!( + prev_normalized_balance <= upper_limit, + TransmuterMathError::NormalizedBalanceExceedsUpperLimit + ); + + ensure!( + update_normalized_balance <= upper_limit, + TransmuterMathError::NormalizedBalanceExceedsUpperLimit + ); + + Ok(Self { prev_normalized_balance, update_normalized_balance, ideal_balance_lower_bound, ideal_balance_upper_bound, upper_limit, - } + }) } fn has_no_change_in_balance(&self) -> bool { @@ -561,8 +582,66 @@ mod tests { assert!(c1 < c2, "c1: {c1}, c2: {c2}"); } } + // - ImpactFactorParamGroup + #[rstest] + #[case::valid(Decimal::percent(50), Decimal::percent(60), Decimal::percent(40), Decimal::percent(50), Decimal::percent(60), Ok(ImpactFactorParamGroup{ + prev_normalized_balance, + update_normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + }))] + #[case::valid(Decimal::zero(), Decimal::percent(10), Decimal::percent(40), Decimal::percent(50), Decimal::percent(60), Ok(ImpactFactorParamGroup{ + prev_normalized_balance, + update_normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + }))] + #[case::valid(Decimal::percent(99), Decimal::percent(100), Decimal::percent(40), Decimal::percent(50), Decimal::one(), Ok(ImpactFactorParamGroup{ + prev_normalized_balance, + update_normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + }))] + #[case::invalid(Decimal::percent(50), Decimal::percent(60), Decimal::percent(40), Decimal::percent(50), Decimal::percent(110), Err(TransmuterMathError::OutOfNormalizedRange { var_name: "upper_limit".to_string() }))] + #[case::invalid(Decimal::percent(50), Decimal::percent(60), Decimal::percent(40), Decimal::percent(110), Decimal::percent(60), Err(TransmuterMathError::OutOfNormalizedRange { var_name: "ideal_balance_upper_bound".to_string() }))] + #[case::invalid(Decimal::percent(50), Decimal::percent(60), Decimal::percent(110), Decimal::percent(50), Decimal::percent(60), Err(TransmuterMathError::OutOfNormalizedRange { var_name: "ideal_balance_lower_bound".to_string() }))] + #[case::invalid( + Decimal::percent(110), + Decimal::percent(60), + Decimal::percent(40), + Decimal::percent(50), + Decimal::percent(60), + Err(TransmuterMathError::NormalizedBalanceExceedsUpperLimit) + )] + #[case::invalid( + Decimal::percent(50), + Decimal::percent(110), + Decimal::percent(40), + Decimal::percent(50), + Decimal::percent(60), + Err(TransmuterMathError::NormalizedBalanceExceedsUpperLimit) + )] + fn test_impact_factor_param_group_new( + #[case] prev_normalized_balance: Decimal, + #[case] update_normalized_balance: Decimal, + #[case] ideal_balance_lower_bound: Decimal, + #[case] ideal_balance_upper_bound: Decimal, + #[case] upper_limit: Decimal, + #[case] expected_result: Result, + ) { + let result = ImpactFactorParamGroup::new( + prev_normalized_balance, + update_normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ); + assert_eq!(result, expected_result); + } // TODO: tests - // - ImpactFactorParamGroup // - calculate_impact_factor } From b81107644725c920df943ef0ec017934fe84e306 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Mon, 16 Sep 2024 10:21:24 +0700 Subject: [PATCH 10/13] test has no change in balance --- .../src/rebalancing_incentive.rs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index 7a0de1c..735fdb3 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -642,6 +642,44 @@ mod tests { assert_eq!(result, expected_result); } + proptest! { + #[test] + fn test_has_no_change_in_balance( + normalized_balance in 0..=ONE_DEC_RAW, + update_normalized_balance in 0..=ONE_DEC_RAW, + ) { + prop_assume!(normalized_balance != update_normalized_balance); + let normalized_balance = Decimal::raw(normalized_balance); + let update_normalized_balance = Decimal::raw(update_normalized_balance); + + // all bounds are set to 100% as it's unrelevant to the test + let ideal_balance_lower_bound = Decimal::percent(100); + let ideal_balance_upper_bound = Decimal::percent(100); + let upper_limit = Decimal::percent(100); + + + if let Ok(group) = ImpactFactorParamGroup::new( + normalized_balance, + normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ) { + assert!(group.has_no_change_in_balance()); + } + + if let Ok(group) = ImpactFactorParamGroup::new( + normalized_balance, + update_normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ) { + assert!(!group.has_no_change_in_balance()); + } + } + } + // TODO: tests // - calculate_impact_factor } From 270c2a3a865653e69a47d63745c03a56931c274f Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Mon, 16 Sep 2024 11:09:53 +0700 Subject: [PATCH 11/13] test calculate impact factor component --- .../src/rebalancing_incentive.rs | 81 ++++++++++++++++++- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index 735fdb3..3c973d2 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -453,7 +453,7 @@ mod tests { Decimal::percent(50), Ok(Decimal::zero()) )] - fn test_calculate_impact_factor_component( + fn test_calculate_cumulative_impact_factor_component( #[case] normalized_balance: Decimal, #[case] ideal_balance_lower_bound: Decimal, #[case] ideal_balance_upper_bound: Decimal, @@ -680,6 +680,81 @@ mod tests { } } - // TODO: tests - // - calculate_impact_factor + #[rstest] + #[case::no_change_in_balance( + Decimal::percent(50), + Decimal::percent(50), + Decimal::percent(40), + Decimal::percent(60), + Decimal::one(), + Ok(SignedDecimal256::zero()) + )] + #[case::move_within_ideal_range( + Decimal::percent(45), + Decimal::percent(55), + Decimal::percent(40), + Decimal::percent(60), + Decimal::one(), + Ok(SignedDecimal256::zero()) + )] + #[case::move_away_from_ideal_range( + Decimal::percent(55), + Decimal::percent(65), + Decimal::percent(40), + Decimal::percent(60), + Decimal::one(), + Ok(SignedDecimal256::from_str("0.015625").unwrap()) + )] + #[case::move_towards_ideal_range( + Decimal::percent(55), + Decimal::percent(45), + Decimal::percent(40), + Decimal::percent(50), + Decimal::one(), + Ok(SignedDecimal256::from_str("-0.01").unwrap()) + )] + #[case::cross_ideal_range_negative( + Decimal::percent(30), + Decimal::percent(65), + Decimal::percent(40), + Decimal::percent(60), + Decimal::one(), + Ok(SignedDecimal256::from_str("-0.046875").unwrap()) + )] + #[case::cross_ideal_range_positive( + Decimal::percent(70), + Decimal::percent(25), + Decimal::percent(40), + Decimal::percent(60), + Decimal::one(), + Ok(SignedDecimal256::from_str("0.078125").unwrap()) + )] + // #[case::precision_issue( + // Decimal::from_str("0.600000000000000001").unwrap(), + // Decimal::from_str("0.600000000000000002").unwrap(), + // Decimal::percent(40), + // Decimal::percent(60), + // Decimal::one(), + // Ok(SignedDecimal256::from_str("-0.000000000000000001").unwrap()) + // )] + fn test_calculate_impact_factor_component( + #[case] prev_normalized_balance: Decimal, + #[case] update_normalized_balance: Decimal, + #[case] ideal_balance_lower_bound: Decimal, + #[case] ideal_balance_upper_bound: Decimal, + #[case] upper_limit: Decimal, + #[case] expected: Result, + ) { + let group = ImpactFactorParamGroup::new( + prev_normalized_balance, + update_normalized_balance, + ideal_balance_lower_bound, + ideal_balance_upper_bound, + upper_limit, + ) + .unwrap(); + + let result = group.calculate_impact_factor_component(); + assert_eq!(result, expected); + } } From c524d88f3d7116ceb59066f1f5adaea9a88b56b4 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Mon, 16 Sep 2024 17:39:00 +0700 Subject: [PATCH 12/13] resolve precision loss issue --- .../src/rebalancing_incentive.rs | 94 ++++++++++++++----- 1 file changed, 68 insertions(+), 26 deletions(-) diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index 3c973d2..5ea2bdf 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -2,6 +2,9 @@ use cosmwasm_std::{ensure, Decimal, Decimal256, SignedDecimal256, Uint128}; use crate::TransmuterMathError; + + + /// Calculating impact factor component /// /// Considering change of balance of asset $i$, fee/incentive impact factor component $\gamma_i$ is @@ -24,7 +27,9 @@ use crate::TransmuterMathError; /// \left(\frac{b - \phi_u}{\delta - \phi_u}\right)^2 & \text{if } \phi_u \lt b \leq \delta /// \end{cases} /// $$ -pub fn calculate_cumulative_impact_factor_component( +/// +/// This function returns √C(b) to delay precision loss handling +pub fn calculate_sqrt_cumulative_impact_factor_component( normalized_balance: Decimal, ideal_balance_lower_bound: Decimal, ideal_balance_upper_bound: Decimal, @@ -41,7 +46,6 @@ pub fn calculate_cumulative_impact_factor_component( ideal_balance_lower_bound // phi_l .checked_sub(normalized_balance)? // - b .checked_div(ideal_balance_lower_bound)? // / phi_l - .checked_pow(2)? // ^2 } else if normalized_balance > ideal_balance_upper_bound { normalized_balance // b .checked_sub(ideal_balance_upper_bound)? // - phi_u @@ -49,7 +53,6 @@ pub fn calculate_cumulative_impact_factor_component( // delta - phi_u = 0 then delta = phi_u // since b > delta is restricted by limiter, and delta <= phi_u, this will never happen .checked_div(upper_limit.checked_sub(ideal_balance_upper_bound)?)? // / delta - phi_u - .checked_pow(2)? // ^2 } else { // within ideal balance Decimal::zero() @@ -120,26 +123,39 @@ impl ImpactFactorParamGroup { } fn calculate_impact_factor_component(&self) -> Result { - // C(b) - let c_b = SignedDecimal256::from(calculate_cumulative_impact_factor_component( + // √C(b) + let sqrt_c_b = SignedDecimal256::from(calculate_sqrt_cumulative_impact_factor_component( self.prev_normalized_balance, self.ideal_balance_lower_bound, self.ideal_balance_upper_bound, self.upper_limit, )?); - // C(b') - let c_b_prime = SignedDecimal256::from(calculate_cumulative_impact_factor_component( + // √C(b') + let sqrt_c_b_prime = SignedDecimal256::from(calculate_sqrt_cumulative_impact_factor_component( self.update_normalized_balance, self.ideal_balance_lower_bound, self.ideal_balance_upper_bound, self.upper_limit, )?); + // \gamma_i = C(b') - C(b) - c_b_prime - .checked_sub(c_b) - .map_err(TransmuterMathError::OverflowError) + let c_b_prime = sqrt_c_b_prime.checked_pow(2)?; + let c_b = sqrt_c_b.checked_pow(2)?; + let gamma_i = c_b_prime.checked_sub(c_b)?; + + // gamma_i = 0 might be due to precision loss after squaring + // if C(b') - C(b) > 0 is counted as fee factor + // round to most precise positive number representable in SignedDecimal256 + // + // C(b') - C(b) < 0 case is not handled here, as it will be counted as incentive factor + // keep it as 0 to prevent overincentive + if gamma_i.is_zero() && sqrt_c_b_prime > sqrt_c_b { + return Ok(SignedDecimal256::raw(1)); + } + + Ok(gamma_i) } } @@ -460,12 +476,12 @@ mod tests { #[case] upper_limit: Decimal, #[case] expected: Result, ) { - let actual = calculate_cumulative_impact_factor_component( + let actual = calculate_sqrt_cumulative_impact_factor_component( normalized_balance, ideal_balance_lower_bound, ideal_balance_upper_bound, upper_limit, - ); + ).map(|x| x.pow(2)); assert_eq!(expected, actual); } @@ -484,7 +500,7 @@ mod tests { let ideal_balance_upper_bound = Decimal::raw(ideal_balance_upper_bound); let upper_limit = Decimal::raw(upper_limit); - match calculate_cumulative_impact_factor_component( + match calculate_sqrt_cumulative_impact_factor_component( normalized_balance, ideal_balance_lower_bound, ideal_balance_upper_bound, @@ -505,7 +521,7 @@ mod tests { let ideal_balance_lower_bound = Decimal::raw(normalized_balance.saturating_sub(ideal_balance_lower_bound_from_normalized_balance)); let normalized_balance = Decimal::raw(normalized_balance); let upper_limit = ideal_balance_upper_bound; - let actual = calculate_cumulative_impact_factor_component( + let actual = calculate_sqrt_cumulative_impact_factor_component( normalized_balance, ideal_balance_lower_bound, ideal_balance_upper_bound, @@ -531,14 +547,14 @@ mod tests { let upper_limit = Decimal::raw(upper_limit); let epsilon = Decimal::raw(1000u128); - let c1 = calculate_cumulative_impact_factor_component( + let c1 = calculate_sqrt_cumulative_impact_factor_component( normalized_balance - epsilon, ideal_balance_lower_bound, ideal_balance_upper_bound, upper_limit, ).unwrap(); - let c2 = calculate_cumulative_impact_factor_component( + let c2 = calculate_sqrt_cumulative_impact_factor_component( normalized_balance, ideal_balance_lower_bound, ideal_balance_upper_bound, @@ -565,14 +581,14 @@ mod tests { let upper_limit = Decimal::raw(upper_limit); let epsilon = Decimal::raw(1000u128); - let c1 = calculate_cumulative_impact_factor_component( + let c1 = calculate_sqrt_cumulative_impact_factor_component( normalized_balance - epsilon, ideal_balance_lower_bound, ideal_balance_upper_bound, upper_limit, ).unwrap(); - let c2 = calculate_cumulative_impact_factor_component( + let c2 = calculate_sqrt_cumulative_impact_factor_component( normalized_balance, ideal_balance_lower_bound, ideal_balance_upper_bound, @@ -729,14 +745,40 @@ mod tests { Decimal::one(), Ok(SignedDecimal256::from_str("0.078125").unwrap()) )] - // #[case::precision_issue( - // Decimal::from_str("0.600000000000000001").unwrap(), - // Decimal::from_str("0.600000000000000002").unwrap(), - // Decimal::percent(40), - // Decimal::percent(60), - // Decimal::one(), - // Ok(SignedDecimal256::from_str("-0.000000000000000001").unwrap()) - // )] + // precision loss for fee impact factor >> 0.000000000000000001 + #[case::precision_loss_positive_impact( + Decimal::from_str("0.600000000000000001").unwrap(), + Decimal::from_str("0.600000000000000002").unwrap(), + Decimal::percent(40), + Decimal::percent(60), + Decimal::one(), + Ok(SignedDecimal256::from_str("0.000000000000000001").unwrap()) + )] + #[case::precision_loss_positive_impact( + Decimal::from_str("0.499999999999999999").unwrap(), + Decimal::from_str("0.600000000000000001").unwrap(), + Decimal::percent(40), + Decimal::percent(60), + Decimal::one(), + Ok(SignedDecimal256::from_str("0.000000000000000001").unwrap()) + )] + // precision loss for incentive impact factor >> 0 + #[case::precision_loss_negative_impact( + Decimal::from_str("0.600000000000000002").unwrap(), + Decimal::from_str("0.600000000000000001").unwrap(), + Decimal::percent(40), + Decimal::percent(60), + Decimal::one(), + Ok(SignedDecimal256::zero()) + )] + #[case::precision_loss_negative_impact( + Decimal::from_str("0.600000000000000001").unwrap(), + Decimal::from_str("0.499999999999999999").unwrap(), + Decimal::percent(40), + Decimal::percent(60), + Decimal::one(), + Ok(SignedDecimal256::zero()) + )] fn test_calculate_impact_factor_component( #[case] prev_normalized_balance: Decimal, #[case] update_normalized_balance: Decimal, From 78ad42cb31d60d5e9a059639cc98e6ad94dbe270 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Thu, 19 Sep 2024 17:01:04 +0700 Subject: [PATCH 13/13] test calculate_impact_factor --- .../rebalancing_incentive.txt | 1 + .../src/rebalancing_incentive.rs | 263 ++++++++++++++---- 2 files changed, 217 insertions(+), 47 deletions(-) diff --git a/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt b/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt index 9b7f5a9..ca2d41f 100644 --- a/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt +++ b/packages/transmuter_math/proptest-regressions/rebalancing_incentive.txt @@ -10,3 +10,4 @@ cc 05667d509ee73bc4dc7059dabfd936ca1b83e0858079419ef4ec85d3134e545d # shrinks to cc b254ff7ece5fb165f9e4d53746fc7222427cff1d17afbcd15cb8e3b3a7282cfc # shrinks to normalized_balance = 0, ideal_balance_lower_bound = 1, ideal_balance_upper_bound = 0, upper_limit = 0 cc 6bbf8d95569b53ec005ed88b282ebcb88f2a327770cf267800b744274aeaf323 # shrinks to normalized_balance = 340640889074348996, ideal_balance_lower_bound = 340640889074348997, ideal_balance_upper_bound = 340640889074348998, upper_limit = 340640889074348998 cc 4c6ad67ab30e522b8de8314e2219263f2e0dff53070517988a192b64099320ee # shrinks to normalized_balance = 866170838754561023, ideal_balance_lower_bound = 0, ideal_balance_range = 0 +cc efe12946674c15ab9d9f273f5dba5da2b33de803bd00a3c5397935644bca7b99 # shrinks to prev_balance = 115660145667945757, update_balance = 481327951497769476, ideal_lower = 115660145667945758, ideal_upper = 115660145667945758, upper_limit = 481327951497769476 diff --git a/packages/transmuter_math/src/rebalancing_incentive.rs b/packages/transmuter_math/src/rebalancing_incentive.rs index 5ea2bdf..b63699b 100644 --- a/packages/transmuter_math/src/rebalancing_incentive.rs +++ b/packages/transmuter_math/src/rebalancing_incentive.rs @@ -2,8 +2,81 @@ use cosmwasm_std::{ensure, Decimal, Decimal256, SignedDecimal256, Uint128}; use crate::TransmuterMathError; +#[derive(Debug, PartialEq, Eq)] +pub enum ImpactFactor { + Incentive(Decimal256), + Fee(Decimal256), + None, +} +/// combine all the impact factor components +/// +/// $$ +/// f = \frac{\Vert\vec{\gamma}\Vert}{\sqrt{n}} +/// $$ +/// +/// That gives a normalized magnitude of the vector of $n$ dimension into $[0,1]$. +/// The reason why it needs to include all dimensions is because the case that swapping with alloyed asset, which will effect overall composition rather than just 2 assets. +pub fn calculate_impact_factor( + impact_factor_param_groups: &[ImpactFactorParamGroup], +) -> Result { + if impact_factor_param_groups.is_empty() { + return Ok(ImpactFactor::None); + } + + let mut cumulative_impact_factor_sqaure = Decimal256::zero(); + let mut impact_factor_component_sum = SignedDecimal256::zero(); + // accumulated impact_factor_component_square rounded to smallest possible Decimal256 + // when impact_factor_component is smaller then 10^-9 to prevent fee exploitation + let mut lost_rounded_impact_factor_component_square_sum = Decimal256::zero(); + + let n = Decimal256::from_atomics(impact_factor_param_groups.len() as u64, 0)?; + + for impact_factor_params in impact_factor_param_groups { + // optimiztion: if there is no change in balance, the result will be 0 anyway, accumulating 0 has no effect + if impact_factor_params.has_no_change_in_balance() { + continue; + } + + let impact_factor_component = impact_factor_params.calculate_impact_factor_component()?; + + // when impact_factor_component<= 10^-9, the result after squaring will be 0, then + // - if total is counted as incentive, there will be no incentive and it's fine + // since it's neglectible and will not overincentivize and drain incentive pool + // - if total is counted as fee, it could be exploited by + // making swap with small impact_factor_component over and over again to avoid being counted as fee + let impact_factor_component_dec = impact_factor_component.abs_diff(SignedDecimal256::zero()); + if impact_factor_component_dec <= Decimal256::raw(1_000_000_000u128) { + lost_rounded_impact_factor_component_square_sum = lost_rounded_impact_factor_component_square_sum.checked_add(Decimal256::raw(1u128))?; + } + + let impact_factor_component_square = impact_factor_component_dec.checked_pow(2)?; + + impact_factor_component_sum = + impact_factor_component_sum.checked_add(impact_factor_component)?; + cumulative_impact_factor_sqaure = + cumulative_impact_factor_sqaure.checked_add(impact_factor_component_square)?; + } + + if impact_factor_component_sum.is_zero() { + Ok(ImpactFactor::None) + } else if impact_factor_component_sum.is_negative() { + Ok(ImpactFactor::Incentive( + cumulative_impact_factor_sqaure + .checked_div(n)? + .sqrt() + )) + } else { + // add back lost impact_factor_component_square_sum before normalizing + Ok(ImpactFactor::Fee( + cumulative_impact_factor_sqaure + .checked_add(lost_rounded_impact_factor_component_square_sum)? + .checked_div(n)? + .sqrt() + )) + } +} /// Calculating impact factor component /// @@ -159,53 +232,6 @@ impl ImpactFactorParamGroup { } } -pub enum PayoffType { - Incentive, - Fee, -} - -/// combine all the impact factor components -/// -/// $$ -/// f = \frac{\Vert\vec{\gamma}\Vert}{\sqrt{n}} -/// $$ -/// -/// That gives a normalized magnitude of the vector of $n$ dimension into $[0,1]$. -/// The reason why it needs to include all dimensions is because the case that swapping with alloyed asset, which will effect overall composition rather than just 2 assets. -pub fn calculate_impact_factor( - impact_factor_param_groups: &[ImpactFactorParamGroup], -) -> Result<(PayoffType, Decimal256), TransmuterMathError> { - let mut cumulative_impact_factor_sqaure = Decimal256::zero(); - let mut impact_factor_component_sum = SignedDecimal256::zero(); - - let n = Decimal256::from_atomics(impact_factor_param_groups.len() as u64, 0)?; - - for impact_factor_params in impact_factor_param_groups { - // optimiztion: if there is no change in balance, the result will be 0 anyway, accumulating 0 has no effect - if impact_factor_params.has_no_change_in_balance() { - continue; - } - - let impact_factor_component = impact_factor_params.calculate_impact_factor_component()?; - let impact_factor_component_square = - Decimal256::try_from(impact_factor_component.checked_pow(2)?)?; - - impact_factor_component_sum = - impact_factor_component_sum.checked_add(impact_factor_component)?; - cumulative_impact_factor_sqaure = - cumulative_impact_factor_sqaure.checked_add(impact_factor_component_square)?; - } - - let payoff_type = if impact_factor_component_sum.is_negative() { - PayoffType::Incentive - } else { - PayoffType::Fee - }; - - let impact_factor = cumulative_impact_factor_sqaure.checked_div(n)?.sqrt(); - - Ok((payoff_type, impact_factor)) -} /// Calculate the rebalancing fee /// @@ -799,4 +825,147 @@ mod tests { let result = group.calculate_impact_factor_component(); assert_eq!(result, expected); } + + #[rstest] + #[case::empty_input(Vec::new(), Ok(ImpactFactor::None))] + #[case::all_no_change( + vec![ + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(50), + update_normalized_balance: Decimal::percent(50), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(70), + update_normalized_balance: Decimal::percent(70), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + } + ], + Ok(ImpactFactor::None) + )] + #[case::all_positive_resulted_in_fee( + vec![ + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(70), + update_normalized_balance: Decimal::percent(80), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(65), + update_normalized_balance: Decimal::percent(75), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ], + Ok(ImpactFactor::Fee(Decimal256::from_str("0.159344359799774525").unwrap())) + )] + #[case::all_negative_resulted_in_incentive( + vec![ + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(70), + update_normalized_balance: Decimal::percent(60), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(35), + update_normalized_balance: Decimal::percent(45), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ], + Ok(ImpactFactor::Incentive(Decimal256::from_str("0.045554311678478909").unwrap()))) + ] + #[case::mixed_positive_and_negative_resulted_in_fee( + vec![ + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(70), + update_normalized_balance: Decimal::percent(80), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(35), + update_normalized_balance: Decimal::percent(45), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ], + Ok(ImpactFactor::Fee(Decimal256::from_str("0.133042080983800009").unwrap())) + )] + #[case::mixed_positive_and_negative_resulted_in_incentive( + vec![ + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(70), + update_normalized_balance: Decimal::percent(60), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(35), + update_normalized_balance: Decimal::percent(30), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ], + Ok(ImpactFactor::Incentive(Decimal256::from_str("0.055242717280199025").unwrap())) + )] + #[case::loss_rounding_fee( + vec![ + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(60), + update_normalized_balance: Decimal::from_atomics(600_000_000_000_000_001u128, 18).unwrap(), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::percent(60), + update_normalized_balance: Decimal::from_atomics(600_000_000_000_000_001u128, 18).unwrap(), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ], + Ok(ImpactFactor::Fee(Decimal256::from_str("0.000000001").unwrap())) + )] + #[case::no_loss_rounding_incentive( + vec![ + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::from_atomics(600_000_000_000_000_001u128, 18).unwrap(), + update_normalized_balance: Decimal::percent(60), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ImpactFactorParamGroup { + prev_normalized_balance: Decimal::from_atomics(600_000_000_000_000_001u128, 18).unwrap(), + update_normalized_balance: Decimal::percent(60), + ideal_balance_lower_bound: Decimal::percent(40), + ideal_balance_upper_bound: Decimal::percent(60), + upper_limit: Decimal::percent(100), + }, + ], + Ok(ImpactFactor::None) + )] + fn test_calculate_impact_factor( + #[case] input_param_groups: Vec, + #[case] expected: Result, + ) { + let result = calculate_impact_factor(&input_param_groups); + assert_eq!(result, expected); + } }