From 18fefffb419c56340f4adb83fcbdb5bf23a4670a Mon Sep 17 00:00:00 2001 From: Art3miX <40179351+Art3miX@users.noreply.github.com> Date: Fri, 28 Jun 2024 07:21:18 +0200 Subject: [PATCH] Switch to Std SignedDecimal (#78) --- README.md | 2 +- contracts/services/rebalancer/src/contract.rs | 3 +- contracts/services/rebalancer/src/error.rs | 8 +- .../services/rebalancer/src/rebalance.rs | 43 +- packages/valence-package/src/error.rs | 3 + packages/valence-package/src/lib.rs | 1 - .../src/services/rebalancer.rs | 25 +- .../valence-package/src/signed_decimal.rs | 498 ------------------ scripts/migrate.sh | 2 +- .../live_debugging/test_specific_config.rs | 15 +- tests/rust-tests/src/suite/suite_auction.rs | 11 +- .../rust-tests/src/test_service_management.rs | 33 +- .../src/tests_rebalancer/pid_tunning.rs | 27 +- .../src/tests_rebalancer/test_system.rs | 3 +- .../src/tests_rebalancer/tests_unit.rs | 7 +- 15 files changed, 90 insertions(+), 591 deletions(-) delete mode 100644 packages/valence-package/src/signed_decimal.rs diff --git a/README.md b/README.md index 34ba0895..69ff4563 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ - auctions manager = `1404` - auction = `1408` - oracle = `1446` -- rebalancer = `1442` +- rebalancer = `1462` - services manager = `1405` - account = `1403` diff --git a/contracts/services/rebalancer/src/contract.rs b/contracts/services/rebalancer/src/contract.rs index 0ca4f3be..18d6482b 100644 --- a/contracts/services/rebalancer/src/contract.rs +++ b/contracts/services/rebalancer/src/contract.rs @@ -6,7 +6,7 @@ use auction_package::Pair; use cosmwasm_std::entry_point; use cosmwasm_std::{ to_json_binary, Addr, Binary, Coin, Decimal, Deps, DepsMut, Env, Event, MessageInfo, Reply, - Response, StdError, StdResult, Uint128, + Response, SignedDecimal, StdError, StdResult, Uint128, }; use cw2::set_contract_version; use cw_storage_plus::Bound; @@ -16,7 +16,6 @@ use valence_package::helpers::{approve_admin_change, verify_services_manager, Op use valence_package::services::rebalancer::{ PauseData, RebalancerExecuteMsg, SystemRebalanceStatus, }; -use valence_package::signed_decimal::SignedDecimal; use valence_package::states::{QueryFeeAction, ADMIN, SERVICES_MANAGER, SERVICE_FEE_CONFIG}; use crate::error::ContractError; diff --git a/contracts/services/rebalancer/src/error.rs b/contracts/services/rebalancer/src/error.rs index 8eaf47a4..82c6eb4f 100644 --- a/contracts/services/rebalancer/src/error.rs +++ b/contracts/services/rebalancer/src/error.rs @@ -1,4 +1,7 @@ -use cosmwasm_std::{CheckedFromRatioError, DecimalRangeExceeded, OverflowError, StdError}; +use cosmwasm_std::{ + CheckedFromRatioError, DecimalRangeExceeded, OverflowError, SignedDecimalRangeExceeded, + StdError, +}; use cw_utils::PaymentError; use thiserror::Error; use valence_package::error::ValenceError; @@ -14,6 +17,9 @@ pub enum ContractError { #[error(transparent)] OverflowError(#[from] OverflowError), + #[error(transparent)] + SignedDecimalRangeExceeded(#[from] SignedDecimalRangeExceeded), + #[error(transparent)] CheckedFromRatioError(#[from] CheckedFromRatioError), diff --git a/contracts/services/rebalancer/src/rebalance.rs b/contracts/services/rebalancer/src/rebalance.rs index 4c9b6c85..f569713f 100644 --- a/contracts/services/rebalancer/src/rebalance.rs +++ b/contracts/services/rebalancer/src/rebalance.rs @@ -7,7 +7,7 @@ use auction_package::{ }; use cosmwasm_std::{ coins, to_json_binary, Addr, CosmosMsg, Decimal, Deps, DepsMut, Empty, Env, Event, Order, - Response, StdError, SubMsg, Uint128, WasmMsg, + Response, SignedDecimal, StdError, SubMsg, Uint128, WasmMsg, }; use cw_storage_plus::Bound; use valence_package::{ @@ -17,7 +17,6 @@ use valence_package::{ ParsedPID, PauseData, RebalanceTrade, RebalancerConfig, SystemRebalanceStatus, TargetOverrideStrategy, }, - signed_decimal::SignedDecimal, CLOSEST_TO_ONE_POSSIBLE, }; @@ -262,7 +261,12 @@ pub fn do_rebalance( .min(Decimal::from_atomics(MAX_PID_DT_VALUE, 0)?) }; - let (mut to_sell, to_buy) = do_pid(total_value, &mut target_helpers, config.pid.clone(), dt)?; + let (mut to_sell, to_buy) = do_pid( + total_value, + &mut target_helpers, + config.pid.clone(), + dt.try_into()?, + )?; // Update targets in config only the last data we need for the next rebalance calculation for target in config.targets.iter_mut() { @@ -449,55 +453,48 @@ fn do_pid( total_value: Decimal, targets: &mut [TargetHelper], pid: ParsedPID, - dt: Decimal, + dt: SignedDecimal, ) -> Result { let mut to_sell: Vec = vec![]; let mut to_buy: Vec = vec![]; - // turn values into signed decimals - let signed_p: SignedDecimal = pid.p.into(); - let signed_i: SignedDecimal = pid.i.into(); - let signed_d: SignedDecimal = pid.d.into(); - - let signed_dt: SignedDecimal = dt.into(); - - targets.iter_mut().for_each(|target| { - let signed_input: SignedDecimal = target.balance_value.into(); + for target in targets.iter_mut() { + let signed_input: SignedDecimal = target.balance_value.try_into()?; // Reset to trade value target.value_to_trade = Decimal::zero(); - let target_value = SignedDecimal::from(total_value * target.target.percentage); + let target_value: SignedDecimal = (total_value * target.target.percentage).try_into()?; let error = target_value - signed_input; - let p = error * signed_p; - let i = target.target.last_i + (error * signed_i * signed_dt); + let p = error * pid.p; + let i = target.target.last_i + (error * pid.i * dt); let mut d = match target.target.last_input { - Some(last_input) => signed_input - last_input.into(), + Some(last_input) => signed_input - last_input, None => SignedDecimal::zero(), }; - d = d * signed_d / signed_dt; + d = d * pid.d / dt; let output = p + i - d; - target.value_to_trade = output.value(); + target.value_to_trade = output.abs_diff(SignedDecimal::zero()); - target.target.last_input = Some(target.balance_value); + target.target.last_input = Some(target.balance_value.try_into()?); target.target.last_i = i; if output.is_zero() { - return; + continue; } - match output.sign() { + match !output.is_negative() { // output is negative, we need to sell false => to_sell.push(target.clone()), // output is positive, we need to buy true => to_buy.push(target.clone()), } - }); + } Ok((to_sell, to_buy)) } diff --git a/packages/valence-package/src/error.rs b/packages/valence-package/src/error.rs index 44656802..0fcde915 100644 --- a/packages/valence-package/src/error.rs +++ b/packages/valence-package/src/error.rs @@ -34,6 +34,9 @@ pub enum ValenceError { #[error("PID values cannot be more then 1")] PIDErrorOver, + #[error("PID values cannot be negative")] + PIDErrorNegative, + #[error("max_limit_bps must be between 1-10000")] InvalidMaxLimitRange, diff --git a/packages/valence-package/src/lib.rs b/packages/valence-package/src/lib.rs index 17a1767f..dac5f78d 100644 --- a/packages/valence-package/src/lib.rs +++ b/packages/valence-package/src/lib.rs @@ -3,7 +3,6 @@ pub mod event_indexing; pub mod helpers; pub mod msgs; pub mod services; -pub mod signed_decimal; pub mod states; pub const CLOSEST_TO_ONE_POSSIBLE: &str = "0.9999"; diff --git a/packages/valence-package/src/services/rebalancer.rs b/packages/valence-package/src/services/rebalancer.rs index 90e1537d..d287d780 100644 --- a/packages/valence-package/src/services/rebalancer.rs +++ b/packages/valence-package/src/services/rebalancer.rs @@ -1,7 +1,8 @@ use auction_package::Pair; use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - coins, Addr, Api, BankMsg, CosmosMsg, Decimal, Env, MessageInfo, Timestamp, Uint128, + coins, Addr, Api, BankMsg, CosmosMsg, Decimal, Env, MessageInfo, SignedDecimal, Timestamp, + Uint128, }; use cw_utils::{must_pay, Expiration}; use std::borrow::Borrow; @@ -9,7 +10,7 @@ use std::hash::Hash; use std::{collections::HashSet, hash::Hasher, str::FromStr}; use valence_macros::valence_service_execute_msgs; -use crate::{error::ValenceError, helpers::OptionalField, signed_decimal::SignedDecimal}; +use crate::{error::ValenceError, helpers::OptionalField}; /// Rebalancer execute msgs. #[valence_service_execute_msgs] @@ -239,7 +240,7 @@ pub struct ParsedTarget { /// Can only be a single one for an account pub min_balance: Option, /// The input we got from the last rebalance. - pub last_input: Option, + pub last_input: Option, /// The last I value we got from the last rebalance PID calculation. pub last_i: SignedDecimal, } @@ -275,9 +276,9 @@ pub struct PID { impl PID { pub fn into_parsed(self) -> Result { ParsedPID { - p: Decimal::from_str(&self.p)?, - i: Decimal::from_str(&self.i)?, - d: Decimal::from_str(&self.d)?, + p: SignedDecimal::from_str(&self.p)?, + i: SignedDecimal::from_str(&self.i)?, + d: SignedDecimal::from_str(&self.d)?, } .verify() } @@ -285,17 +286,21 @@ impl PID { #[cw_serde] pub struct ParsedPID { - pub p: Decimal, - pub i: Decimal, - pub d: Decimal, + pub p: SignedDecimal, + pub i: SignedDecimal, + pub d: SignedDecimal, } impl ParsedPID { pub fn verify(self) -> Result { - if self.p > Decimal::one() || self.i > Decimal::one() { + if self.p > SignedDecimal::one() || self.i > SignedDecimal::one() { return Err(ValenceError::PIDErrorOver); } + if self.p.is_negative() || self.i.is_negative() || self.d.is_negative() { + return Err(ValenceError::PIDErrorNegative); + } + Ok(self) } } diff --git a/packages/valence-package/src/signed_decimal.rs b/packages/valence-package/src/signed_decimal.rs deleted file mode 100644 index 430fe6c9..00000000 --- a/packages/valence-package/src/signed_decimal.rs +++ /dev/null @@ -1,498 +0,0 @@ -use std::{ - fmt, - ops::{Add, Div, Mul, Sub}, - str::FromStr, -}; - -use cosmwasm_schema::{ - schemars::JsonSchema, - serde::{ - de, - ser::{self}, - Deserialize, Deserializer, Serialize, - }, -}; -use cosmwasm_std::{Decimal, StdError, Uint128}; - -/// A helper struct to have a signed decimal -/// This allows us to keep track if the number is positive or negative -/// -/// Our usecse / example: -/// In the rebalancer, when we are doing the rebalance calculation, we can either have -/// a positive number or a negetive number. -/// positive number means we need to buy the asset, while negetive menas we need to sell. -/// -/// This struct makes it easier for us to do the calculation, and act upon the sign only after -/// the calculation is done, in order to know if we should buy or sell. -#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, JsonSchema, Debug)] -#[schemars(crate = "::cosmwasm_schema::schemars")] -pub struct SignedDecimal(Decimal, bool); - -impl From for SignedDecimal { - fn from(value: Decimal) -> Self { - Self(value, true) - } -} - -impl From for Decimal { - fn from(val: SignedDecimal) -> Self { - val.0 - } -} - -impl From for SignedDecimal { - fn from(value: Uint128) -> Self { - Self(Decimal::from_atomics(value, 0).unwrap(), true) - } -} - -// impl for signed decimal -impl SignedDecimal { - pub fn new(num: Decimal, mut sign: bool) -> Self { - if num.is_zero() { - sign = true; - } - SignedDecimal(num, sign) - } - pub fn __add(self, add: impl Into) -> Self { - let add: SignedDecimal = add.into(); - let mut res = match (self.1, add.1) { - (true, true) => { - // ("+" + "+") = + - Self(self.0 + add.0, true) - } - (false, false) => { - // ("-" + "-") = - - Self(self.0 + add.0, false) - } - (true, false) => { - // ("+" + "-") = -/+ - if self.0 > add.0 { - // ("+" > "-") = + - Self(self.0 - add.0, true) - } else { - // ("+" < "-") = - - Self(add.0 - self.0, false) - } - } - (false, true) => { - // ("-" + "+") = -/+ - if self.0 > add.0 { - // ("-" > "+") = - - Self(self.0 - add.0, false) - } else { - // ("-" < "+") = + - Self(add.0 - self.0, true) - } - } - }; - - if res.is_zero() { - res.1 = true; - } - res - } - - pub fn __sub(self, sub: impl Into) -> Self { - let sub: SignedDecimal = sub.into(); - let mut res = match (self.1, sub.1) { - (true, true) => { - // ("+" - "+") = -/+ - if self.0 > sub.0 { - Self(self.0 - sub.0, true) - } else { - Self(sub.0 - self.0, false) - } - } - (false, false) => { - // ("-" - "-") = -/+ - if self.0 > sub.0 { - Self(self.0 - sub.0, false) - } else { - Self(sub.0 - self.0, true) - } - } - (true, false) => { - // ("+" - "-") = + - Self(self.0 + sub.0, true) - } - (false, true) => { - // ("-" - "+") = - - Self(self.0 + sub.0, false) - } - }; - - if res.is_zero() { - res.1 = true; - } - res - } - - pub fn __mul(self, mul: impl Into) -> Self { - let mul: SignedDecimal = mul.into(); - match (self.1, mul.1) { - (true, true) | (false, false) => Self(self.0 * mul.0, true), - (true, false) | (false, true) => Self(self.0 * mul.0, false), - } - } - - pub fn __div(self, div: impl Into) -> Self { - let div: SignedDecimal = div.into(); - match (self.1, div.1) { - (true, true) | (false, false) => Self(self.0 / div.0, true), - (true, false) | (false, true) => Self(self.0 / div.0, false), - } - } - - pub fn value(self) -> Decimal { - self.0 - } - - pub fn sign(self) -> bool { - self.1 - } - - pub fn zero() -> Self { - Self(Decimal::zero(), true) - } - - pub fn positive_one() -> Self { - Self(Decimal::one(), true) - } - - pub fn neg_one() -> Self { - Self(Decimal::one(), false) - } - - pub fn to_uint_floor(self) -> Uint128 { - self.0.to_uint_floor() - } - - pub fn to_uint_ceil(self) -> Uint128 { - self.0.to_uint_ceil() - } -} - -impl SignedDecimal { - pub fn is_zero(self) -> bool { - self.0.is_zero() - } - - /// If our number is positive - pub fn is_pos(self) -> bool { - self.1 - } - - /// If our number is negetive - pub fn is_neg(self) -> bool { - !self.1 - } -} - -impl Add for SignedDecimal { - type Output = Self; - - fn add(self, other: Self) -> Self { - self.__add(other) - } -} - -impl Sub for SignedDecimal { - type Output = Self; - - fn sub(self, other: Self) -> Self { - self.__sub(other) - } -} - -impl Mul for SignedDecimal { - type Output = Self; - - fn mul(self, other: Self) -> Self { - self.__mul(other) - } -} - -impl Div for SignedDecimal { - type Output = Self; - - fn div(self, other: Self) -> Self { - self.__div(other) - } -} - -impl FromStr for SignedDecimal { - type Err = StdError; - - fn from_str(s: &str) -> Result { - let (sign, str) = match s.chars().next() { - Some('-') => (false, &s[1..]), - Some('+') => (true, &s[1..]), - _ => (true, s), - }; - - let decimal = Decimal::from_str(str)?; - - Ok(SignedDecimal(decimal, sign)) - } -} - -/// Serializes as a decimal string -impl Serialize for SignedDecimal { - fn serialize(&self, serializer: S) -> Result - where - S: ser::Serializer, - { - let sign = if self.1 { "+" } else { "-" }; - let str = format!("{}{}", sign, self.0); - serializer.serialize_str(&str) - } -} - -/// Deserializes as a base64 string -impl<'de> Deserialize<'de> for SignedDecimal { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_str(SignedDecimalVisitor) - } -} - -struct SignedDecimalVisitor; - -impl<'de> de::Visitor<'de> for SignedDecimalVisitor { - type Value = SignedDecimal; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("string-encoded signed decimal") - } - - fn visit_str(self, v: &str) -> Result - where - E: de::Error, - { - match SignedDecimal::from_str(v) { - Ok(d) => Ok(d), - Err(e) => Err(E::custom(format!( - "Error parsing signed decimal '{v}': {e}" - ))), - } - } -} - -#[cfg(test)] -mod test { - use std::str::FromStr; - - use cosmwasm_std::{Decimal, Uint128}; - - use super::SignedDecimal; - - #[test] - fn test_from_into() { - let from = SignedDecimal::from(Decimal::one()); - assert_eq!(from, SignedDecimal(Decimal::one(), true)); - - let from = SignedDecimal::from(Uint128::one()); - assert_eq!(from, SignedDecimal(Decimal::one(), true)); - - let into: Decimal = SignedDecimal(Decimal::one(), true).into(); - assert_eq!(into, Decimal::one()); - } - - #[test] - fn test_helpers() { - let dec = SignedDecimal::zero(); - assert_eq!(dec, SignedDecimal(Decimal::zero(), true)); - assert!(dec.is_zero()); - - let dec = SignedDecimal::positive_one(); - assert_eq!(dec, SignedDecimal(Decimal::one(), true)); - - let dec = SignedDecimal::neg_one(); - assert_eq!(dec, SignedDecimal(Decimal::one(), false)); - - let dec = SignedDecimal(Decimal::from_str("1.5").unwrap(), true); - assert_eq!(dec.to_uint_floor(), Uint128::one()); - assert_eq!(dec.to_uint_ceil(), Uint128::from(2_u128)); - } - - #[test] - fn test_parse() { - let correct_pos = SignedDecimal(Decimal::from_str("1.5").unwrap(), true); - let correct_neg = SignedDecimal(Decimal::from_str("1.5").unwrap(), false); - - assert_eq!(SignedDecimal::from_str("+1.5").unwrap(), correct_pos); - assert_eq!(SignedDecimal::from_str("1.5").unwrap(), correct_pos); - assert_eq!(SignedDecimal::from_str("-1.5").unwrap(), correct_neg); - - assert_eq!( - SignedDecimal::from_str("-1").unwrap(), - SignedDecimal::neg_one() - ); - assert_eq!( - SignedDecimal::from_str("1").unwrap(), - SignedDecimal::positive_one() - ); - - // should err - SignedDecimal::from_str("-f1").unwrap_err(); - SignedDecimal::from_str("-1f").unwrap_err(); - SignedDecimal::from_str("f").unwrap_err(); - SignedDecimal::from_str("1f").unwrap_err(); - } - - #[test] - fn test_assertion() { - let pos = SignedDecimal(Decimal::one(), true); - assert!(pos.is_pos()); - - let neg = SignedDecimal(Decimal::one(), false); - assert!(neg.is_neg()); - } - - #[test] - fn test_add() { - let ten = Decimal::from_atomics(10_u128, 0).unwrap(); - let two = Decimal::from_atomics(2_u128, 0).unwrap(); - - let big_positive = SignedDecimal(ten, true); - let big_negative = SignedDecimal(ten, false); - let small_positive = SignedDecimal(two, true); - let small_negative = SignedDecimal(two, false); - - // "+" + "+" = "+" - let res = big_positive + big_positive; - assert!(res.1); - - // "-" + "-" = "-" - let res = big_negative + big_negative; - assert!(!res.1); - - // "+" + "-" where "+" > "-" = "+" - let res: SignedDecimal = big_positive + small_negative; - assert!(res.1); - - // "+" + "-" where "+" < "-" = "-" - let res = small_positive + big_negative; - assert!(!res.1); - - // "-" + "+" where "-" > "+" = "-" - let res = big_negative + small_positive; - assert!(!res.1); - - // "-" + "+" where "-" < "+" = "+" - let res = small_negative + big_positive; - assert!(res.1); - } - - #[test] - fn test_sub() { - let ten = Decimal::from_atomics(10_u128, 0).unwrap(); - let two = Decimal::from_atomics(2_u128, 0).unwrap(); - - let big_positive = SignedDecimal(ten, true); - let big_negative = SignedDecimal(ten, false); - let small_positive = SignedDecimal(two, true); - let small_negative = SignedDecimal(two, false); - - // "+" - "+" where "+" > "+" = "+" - let res = big_positive - small_positive; - assert!(res.1); - - // "+" - "+" where "+" < "+" = "-" - let res = small_positive - big_positive; - assert!(!res.1); - - // "-" - "-" where "-" > "-" = "-" - let res = big_negative - small_negative; - assert!(!res.1); - assert_eq!(res.0.to_uint_floor().u128(), 8); - - // "-" - "-" where "-" < "-" = "+" - let res = small_negative - big_negative; - assert!(res.1); - assert_eq!(res.0.to_uint_floor().u128(), 8); - - // "+" - "-" = "+" - let res = small_positive - big_negative; - assert!(res.1); - - // "-" - "+" = "-" - let res = small_negative - big_positive; - assert!(!res.1); - } - - #[test] - fn test_mul() { - let ten = Decimal::from_atomics(10_u128, 0).unwrap(); - - let positive = SignedDecimal(ten, true); - let negative = SignedDecimal(ten, false); - - // "+" * "+" = "+" - let res = positive * positive; - assert!(res.1); - - // "-" * "-" = "+" - let res = negative * negative; - assert!(res.1); - - // "+" * "-" = "-" - let res = positive * negative; - assert!(!res.1); - - // "-" * "+" = "-" - let res = negative * positive; - assert!(!res.1); - } - - #[test] - fn test_div() { - let ten = Decimal::from_atomics(10_u128, 0).unwrap(); - - let positive = SignedDecimal(ten, true); - let negative = SignedDecimal(ten, false); - - // "+" * "+" = "+" - let res = positive / positive; - assert!(res.1); - - // "-" * "-" = "+" - let res = negative / negative; - assert!(res.1); - - // "+" * "-" = "-" - let res = positive / negative; - assert!(!res.1); - - // "-" * "+" = "-" - let res = negative / positive; - assert!(!res.1); - } - - #[test] - fn test_verify_0_always_pos() { - let one = SignedDecimal::positive_one(); - let neg_one = SignedDecimal::neg_one(); - - let res = SignedDecimal::zero(); - assert!(res.is_pos()); - - let res = SignedDecimal::new(Decimal::zero(), false); - assert!(res.is_pos()); - - let res = one - one; - assert!(res.is_pos()); - - let res = neg_one - neg_one; - assert!(res.is_pos()); - - let res = neg_one + one; - assert!(res.is_pos()); - - let res = one + neg_one; - assert!(res.is_pos()); - } -} diff --git a/scripts/migrate.sh b/scripts/migrate.sh index 665ec9b8..23f581c5 100755 --- a/scripts/migrate.sh +++ b/scripts/migrate.sh @@ -15,7 +15,7 @@ SERVICES_MANAGER_ADDR="neutron1gantvpnat0la8kkkzrnj48d5d8wxdjllh5r2w4r2hcrpwy00s AUCTIONS_MANAGER_ADDR="neutron13exc5wdc7y5qpqazc34djnu934lqvfw2dru30j52ahhjep6jzx8ssjxcyz" # Code ids -REBALANCER_CODE_ID=1442 +REBALANCER_CODE_ID=1462 ORACLE_CODE_ID=1446 SERVICES_MANAGER_CODE_ID=1259 AUCTIONS_MANAGER_CODE_ID=1263 diff --git a/tests/rust-tests/src/live_debugging/test_specific_config.rs b/tests/rust-tests/src/live_debugging/test_specific_config.rs index b2ebb2b7..0a99cb49 100644 --- a/tests/rust-tests/src/live_debugging/test_specific_config.rs +++ b/tests/rust-tests/src/live_debugging/test_specific_config.rs @@ -149,7 +149,14 @@ fn live_debugging() { // make sure the config is set in our mock rebalancer assert_eq!(account_config, config); // make sure prices in oracle are matching mainnet prices - assert_eq!(all_prices, prices); + for all_price in all_prices.iter() { + let p = prices + .iter() + .find(|(pair, _)| *pair == all_price.0) + .unwrap(); + assert_eq!(all_price.1.price, p.1.price); + } + // assert_eq!(all_prices, prices); // After we confirmed everything is in place, we can do rebalance, and read the response (events should tell us the info we need) let res = suite.rebalance(None).unwrap(); @@ -164,4 +171,10 @@ fn live_debugging() { ); } }); + + let new_config = suite + .query_rebalancer_config(suite.account_addrs[0].clone()) + .unwrap(); + println!("old config: {:?}", account_config); + println!("New config: {:?}", new_config); } diff --git a/tests/rust-tests/src/suite/suite_auction.rs b/tests/rust-tests/src/suite/suite_auction.rs index 29d9aafb..475b57fd 100644 --- a/tests/rust-tests/src/suite/suite_auction.rs +++ b/tests/rust-tests/src/suite/suite_auction.rs @@ -8,11 +8,10 @@ use auction_package::{ states::MinAmount, AuctionStrategy, Pair, Price, PriceFreshnessStrategy, }; -use cosmwasm_std::{coin, coins, Addr, Coin, Decimal, Uint128}; +use cosmwasm_std::{coin, coins, Addr, Coin, Decimal, SignedDecimal, Uint128}; use cw_multi_test::{AppResponse, Executor}; use price_oracle::state::PriceStep; use rand::{rngs::ThreadRng, Rng}; -use valence_package::signed_decimal::SignedDecimal; use super::suite::{Suite, ATOM, DAY, DEFAULT_BLOCK_TIME, HALF_DAY, NTRN}; @@ -316,12 +315,8 @@ impl Suite { // price_change in percentage pub fn change_price_perc(&mut self, pair: Pair, price_change: SignedDecimal) { - let price = self.get_price(pair.clone()); - let new_price = if price_change.is_pos() { - price + price * price_change.value() - } else { - price - price * price_change.value() - }; + let price: SignedDecimal = self.get_price(pair.clone()).try_into().unwrap(); + let new_price: Decimal = (price + (price * price_change)).try_into().unwrap(); self.manual_update_price(pair, new_price).unwrap(); } diff --git a/tests/rust-tests/src/test_service_management.rs b/tests/rust-tests/src/test_service_management.rs index c0a85f77..f3f5b4e1 100644 --- a/tests/rust-tests/src/test_service_management.rs +++ b/tests/rust-tests/src/test_service_management.rs @@ -1,17 +1,14 @@ use std::{collections::HashSet, str::FromStr}; -use cosmwasm_std::{Addr, Decimal, Timestamp}; +use cosmwasm_std::{Addr, Decimal, SignedDecimal, Timestamp}; use cw_multi_test::Executor; use cw_utils::Expiration; -use valence_package::{ - services::{ - rebalancer::{ - ParsedPID, ParsedTarget, RebalancerConfig, RebalancerUpdateData, Target, - TargetOverrideStrategy, PID, - }, - ValenceServices, +use valence_package::services::{ + rebalancer::{ + ParsedPID, ParsedTarget, RebalancerConfig, RebalancerUpdateData, Target, + TargetOverrideStrategy, PID, }, - signed_decimal::SignedDecimal, + ValenceServices, }; use crate::suite::{ @@ -116,9 +113,9 @@ fn test_register() { }, ], pid: ParsedPID { - p: Decimal::from_str(DEFAULT_P).unwrap(), - i: Decimal::from_str(DEFAULT_I).unwrap(), - d: Decimal::from_str(DEFAULT_D).unwrap(), + p: SignedDecimal::from_str(DEFAULT_P).unwrap(), + i: SignedDecimal::from_str(DEFAULT_I).unwrap(), + d: SignedDecimal::from_str(DEFAULT_D).unwrap(), }, max_limit: Decimal::one(), last_rebalance: Timestamp::from_seconds(0), @@ -162,9 +159,9 @@ fn test_register() { }, ], pid: ParsedPID { - p: Decimal::from_str(DEFAULT_P).unwrap(), - i: Decimal::from_str(DEFAULT_I).unwrap(), - d: Decimal::from_str(DEFAULT_D).unwrap(), + p: SignedDecimal::from_str(DEFAULT_P).unwrap(), + i: SignedDecimal::from_str(DEFAULT_I).unwrap(), + d: SignedDecimal::from_str(DEFAULT_D).unwrap(), }, max_limit: Decimal::bps(1000), last_rebalance: Timestamp::from_seconds(0), @@ -420,9 +417,9 @@ fn test_update() { }, ], pid: ParsedPID { - p: Decimal::bps(10000), - i: Decimal::bps(5000), - d: Decimal::bps(5000), + p: SignedDecimal::bps(10000), + i: SignedDecimal::bps(5000), + d: SignedDecimal::bps(5000), }, max_limit: Decimal::bps(5000), last_rebalance: Timestamp::from_seconds(0), diff --git a/tests/rust-tests/src/tests_rebalancer/pid_tunning.rs b/tests/rust-tests/src/tests_rebalancer/pid_tunning.rs index 1c05e8ff..738c00cf 100644 --- a/tests/rust-tests/src/tests_rebalancer/pid_tunning.rs +++ b/tests/rust-tests/src/tests_rebalancer/pid_tunning.rs @@ -7,13 +7,10 @@ use std::{ use auction_package::Pair; use colored::Colorize; -use cosmwasm_std::{coin, Coin, Decimal}; +use cosmwasm_std::{coin, Coin, Decimal, SignedDecimal}; use rgb::RGB; use textplots::{Chart, ColorPlot}; -use valence_package::{ - services::rebalancer::{RebalancerData, PID}, - signed_decimal::SignedDecimal, -}; +use valence_package::services::rebalancer::{RebalancerData, PID}; use crate::suite::{ suite::{Suite, ATOM, NTRN}, @@ -202,25 +199,13 @@ fn terminal_play() { // Do price changes every X days if x % 100 == 0 && x % 200 != 0 { - suite.change_price_perc( - pair.clone(), - SignedDecimal::new(Decimal::from_str("0.05").unwrap(), true), - ); + suite.change_price_perc(pair.clone(), SignedDecimal::from_str("0.05").unwrap()); } else if x % 20 == 0 { - suite.change_price_perc( - pair.clone(), - SignedDecimal::new(Decimal::from_str("0.10").unwrap(), false), - ); + suite.change_price_perc(pair.clone(), SignedDecimal::from_str("-0.10").unwrap()); } else if x % 5 == 0 { - suite.change_price_perc( - pair.clone(), - SignedDecimal::new(Decimal::from_str("0.02").unwrap(), false), - ); + suite.change_price_perc(pair.clone(), SignedDecimal::from_str("-0.02").unwrap()); } else { - suite.change_price_perc( - pair.clone(), - SignedDecimal::new(Decimal::from_str("0.01").unwrap(), true), - ); + suite.change_price_perc(pair.clone(), SignedDecimal::from_str("0.01").unwrap()); } // Get values before rebalance diff --git a/tests/rust-tests/src/tests_rebalancer/test_system.rs b/tests/rust-tests/src/tests_rebalancer/test_system.rs index c055f07a..61cdf20b 100644 --- a/tests/rust-tests/src/tests_rebalancer/test_system.rs +++ b/tests/rust-tests/src/tests_rebalancer/test_system.rs @@ -342,7 +342,8 @@ fn test_rebalancer_cycle_next_day_while_processing() { assert!(config.last_rebalance.seconds() == 0); // Do another rebalance for both accounts now. - suite.rebalance_with_update_block(None).unwrap(); + let res = suite.rebalance_with_update_block(None).unwrap(); + println!("{:?}", res); let config1 = suite .query_rebalancer_config(suite.get_account_addr(1)) diff --git a/tests/rust-tests/src/tests_rebalancer/tests_unit.rs b/tests/rust-tests/src/tests_rebalancer/tests_unit.rs index 7bc84380..33ee63da 100644 --- a/tests/rust-tests/src/tests_rebalancer/tests_unit.rs +++ b/tests/rust-tests/src/tests_rebalancer/tests_unit.rs @@ -1,11 +1,8 @@ use std::str::FromStr; -use cosmwasm_std::{testing::mock_dependencies, Decimal, Uint128}; +use cosmwasm_std::{testing::mock_dependencies, Decimal, SignedDecimal, Uint128}; use rebalancer::{helpers::TargetHelper, rebalance::verify_targets}; -use valence_package::{ - services::rebalancer::{ParsedTarget, TargetOverrideStrategy}, - signed_decimal::SignedDecimal, -}; +use valence_package::services::rebalancer::{ParsedTarget, TargetOverrideStrategy}; use crate::suite::{ suite::{ATOM, NTRN, OSMO},