Skip to content

Commit

Permalink
restrict decimals to u8 and add token tests
Browse files Browse the repository at this point in the history
  • Loading branch information
shuhuiluo committed Dec 25, 2023
1 parent c101f93 commit 39e4582
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/entities/base_currency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub trait BaseCurrency: Clone {
fn chain_id(&self) -> u32;

/// The decimals used in representing currency amounts
fn decimals(&self) -> u32;
fn decimals(&self) -> u8;

/// The symbol of the currency, i.e. a short textual non-unique identifier
fn symbol(&self) -> Option<String>;
Expand Down
2 changes: 1 addition & 1 deletion src/entities/currency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl BaseCurrency for Currency {
}
}

fn decimals(&self) -> u32 {
fn decimals(&self) -> u8 {
match self {
Currency::NativeCurrency(native_currency) => native_currency.decimals(),
Currency::Token(token) => token.decimals(),
Expand Down
7 changes: 3 additions & 4 deletions src/entities/ether.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::{base_currency::BaseCurrency, currency::CurrencyTrait, token::Token};
use crate::entities::weth9::WETH9;
use super::{base_currency::BaseCurrency, currency::CurrencyTrait, token::Token, weth9::WETH9};
use lazy_static::lazy_static;
use std::{collections::HashMap, sync::Mutex};

Expand All @@ -11,7 +10,7 @@ lazy_static! {
#[derive(Clone, PartialEq)]
pub struct Ether {
pub chain_id: u32,
pub decimals: u32,
pub decimals: u8,
pub symbol: Option<String>,
pub name: Option<String>,
}
Expand Down Expand Up @@ -54,7 +53,7 @@ impl BaseCurrency for Ether {
self.chain_id
}

fn decimals(&self) -> u32 {
fn decimals(&self) -> u8 {
self.decimals
}

Expand Down
6 changes: 3 additions & 3 deletions src/entities/fractions/currency_amount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl<T: CurrencyTrait> CurrencyAmount<T> {
denominator,
meta: CurrencyMeta {
currency,
decimal_scale: BigUint::from(10u64).pow(exponent),
decimal_scale: BigUint::from(10u64).pow(exponent as u32),
},
}
}
Expand Down Expand Up @@ -156,7 +156,7 @@ impl<T: CurrencyTrait> FractionTrait<CurrencyMeta<T>> for CurrencyAmount<T> {
)
}

fn to_significant(&self, significant_digits: u32, rounding: Rounding) -> String {
fn to_significant(&self, significant_digits: u8, rounding: Rounding) -> String {
self.as_fraction()
.divide(&Fraction::new(
self.meta.decimal_scale.to_bigint().unwrap(),
Expand All @@ -166,7 +166,7 @@ impl<T: CurrencyTrait> FractionTrait<CurrencyMeta<T>> for CurrencyAmount<T> {
.to_significant(significant_digits, rounding)
}

fn to_fixed(&self, decimal_places: u32, rounding: Rounding) -> String {
fn to_fixed(&self, decimal_places: u8, rounding: Rounding) -> String {
assert!(decimal_places <= self.meta.currency.decimals(), "DECIMALS");
self.as_fraction()
.divide(&Fraction::new(
Expand Down
8 changes: 4 additions & 4 deletions src/entities/fractions/fraction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ pub trait FractionTrait<M>: Sized {
.div(Decimal::from_str(&self.denominator().to_str_radix(10)).unwrap())
}

fn to_significant(&self, significant_digits: u32, rounding: Rounding) -> String {
fn to_significant(&self, significant_digits: u8, rounding: Rounding) -> String {
assert!(
significant_digits > 0,
"Significant digits must be positive."
Expand All @@ -125,16 +125,16 @@ pub trait FractionTrait<M>: Sized {
let rounding_strategy = to_rounding_strategy(rounding);
let quotient = self
.to_decimal()
.round_sf_with_strategy(significant_digits, rounding_strategy);
.round_sf_with_strategy(significant_digits as u32, rounding_strategy);

quotient.unwrap().normalize().to_string()
}

fn to_fixed(&self, decimal_places: u32, rounding: Rounding) -> String {
fn to_fixed(&self, decimal_places: u8, rounding: Rounding) -> String {
let rounding_strategy = to_rounding_strategy(rounding);
let quotient = self
.to_decimal()
.round_dp_with_strategy(decimal_places, rounding_strategy);
.round_dp_with_strategy(decimal_places as u32, rounding_strategy);

format!("{:.1$}", quotient, decimal_places as usize)
}
Expand Down
4 changes: 2 additions & 2 deletions src/entities/fractions/percent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ impl FractionTrait<()> for Percent {
&self.denominator
}

fn to_significant(&self, significant_digits: u32, rounding: Rounding) -> String {
fn to_significant(&self, significant_digits: u8, rounding: Rounding) -> String {
self.as_fraction()
.multiply(&ONE_HUNDRED)
.to_significant(significant_digits, rounding)
}

fn to_fixed(&self, decimal_places: u32, rounding: Rounding) -> String {
fn to_fixed(&self, decimal_places: u8, rounding: Rounding) -> String {
self.as_fraction()
.multiply(&ONE_HUNDRED)
.to_fixed(decimal_places, rounding)
Expand Down
8 changes: 4 additions & 4 deletions src/entities/fractions/price.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ where
&self.denominator
}

fn to_significant(&self, significant_digits: u32, rounding: Rounding) -> String {
fn to_significant(&self, significant_digits: u8, rounding: Rounding) -> String {
self.adjusted_for_decimals()
.to_significant(significant_digits, rounding)
}

fn to_fixed(&self, decimal_places: u32, rounding: Rounding) -> String {
fn to_fixed(&self, decimal_places: u8, rounding: Rounding) -> String {
self.adjusted_for_decimals()
.to_fixed(decimal_places, rounding)
}
Expand All @@ -84,8 +84,8 @@ where
numerator: impl Into<BigInt>,
) -> Self {
let scalar = Fraction::new(
BigInt::from(10).pow(base_currency.decimals()),
BigInt::from(10).pow(quote_currency.decimals()),
BigInt::from(10).pow(base_currency.decimals() as u32),
BigInt::from(10).pow(quote_currency.decimals() as u32),
(),
);
Self {
Expand Down
119 changes: 87 additions & 32 deletions src/entities/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use num_bigint::BigUint;
pub struct Token {
pub chain_id: u32,
pub address: String,
pub decimals: u32,
pub decimals: u8,
pub symbol: Option<String>,
pub name: Option<String>,
pub buy_fee_bps: Option<BigUint>,
Expand All @@ -28,7 +28,7 @@ impl BaseCurrency for Token {
self.chain_id
}

fn decimals(&self) -> u32 {
fn decimals(&self) -> u8 {
self.decimals
}

Expand Down Expand Up @@ -68,7 +68,7 @@ impl Token {
pub fn new(
chain_id: u32,
address: String,
decimals: u32,
decimals: u8,
symbol: Option<String>,
name: Option<String>,
buy_fee_bps: Option<BigUint>,
Expand Down Expand Up @@ -107,7 +107,6 @@ impl Token {

#[cfg(test)]
mod tests {
use crate::entities::currency::Currency;
//should test for neg chain_id or neg decimals or neg buy_fee or neg sell_fee, but the compiler will panic by itself, so no need
use super::*;

Expand Down Expand Up @@ -141,12 +140,12 @@ mod tests {
}

#[test]
#[should_panic]
#[should_panic(expected = "DECIMALS")]
fn test_expect_revert_overflow_dec() {
let _token = Token::new(
4,
ADDRESS_ONE.to_string(),
256,
255,
Some("Test".to_string()),
Some("Te".to_string()),
None,
Expand All @@ -155,8 +154,7 @@ mod tests {
}

#[test]
#[should_panic]
fn test_expect_revert_diff_chain_id() {
fn test_false_if_diff_chain_id() {
let token = Token::new(
4,
ADDRESS_ONE.to_string(),
Expand All @@ -166,7 +164,6 @@ mod tests {
None,
None,
);

let token_1 = Token::new(
3,
ADDRESS_ONE.to_string(),
Expand All @@ -177,10 +174,7 @@ mod tests {
None,
);

assert!(
token.equals(&Currency::Token(token_1)),
"SHOULD_FAILS_EVEN_THOUGH_CHAIN_ID_IS_DIFFERENT"
);
assert!(!token.equals(&token_1));
}

#[test]
Expand All @@ -194,7 +188,6 @@ mod tests {
None,
None,
);

let token_1 = Token::new(
4,
ADDRESS_ONE.to_string(),
Expand All @@ -205,10 +198,7 @@ mod tests {
None,
);

assert!(
token.equals(&Currency::Token(token_1)),
"true even if names differ"
);
assert!(token.equals(&token_1), "true even if names differ");
}

#[test]
Expand All @@ -222,7 +212,6 @@ mod tests {
None,
None,
);

let token_1 = Token::new(
4,
ADDRESS_ONE.to_string(),
Expand All @@ -233,15 +222,11 @@ mod tests {
None,
);

assert!(
token.equals(&Currency::Token(token_1)),
"true even if symbols differ"
);
assert!(token.equals(&token_1), "true even if symbols differ");
}

#[test]
#[should_panic]
fn test_expect_revert_diff_address() {
fn test_false_if_diff_address() {
let token = Token::new(
4,
ADDRESS_ONE.to_string(),
Expand All @@ -251,7 +236,6 @@ mod tests {
None,
None,
);

let token_1 = Token::new(
4,
DAI_MAINNET.to_string(),
Expand All @@ -262,9 +246,21 @@ mod tests {
None,
);

assert!(!token.equals(&token_1));
}

#[test]
fn test_true_if_diff_decimals() {
assert!(
token.equals(&Currency::Token(token_1)),
"SHOULD_FAILS_EVEN_THOUGH_ADDRESS_IS_DIFFERENT"
Token::new(1, ADDRESS_ONE.to_string(), 9, None, None, None, None,).equals(&Token::new(
1,
ADDRESS_ONE.to_string(),
18,
None,
None,
None,
None,
))
);
}

Expand All @@ -290,10 +286,69 @@ mod tests {
None,
);

assert_eq!(
token.equals(&Currency::Token(token_1.clone())),
token_1.equals(&Currency::Token(token)),
"SHOULD_FAILS_EVEN_THOUGH_ADDRESS_IS_DIFFERENT, SHOULD ONLY REVERT FOR DIFFERENT CHAIN_ID"
assert_eq!(token.equals(&token_1), token_1.equals(&token));
}

#[test]
fn test_true_on_reference_equality() {
let token = Token::new(
1,
ADDRESS_ONE.to_string(),
18,
Some("Test".to_string()),
Some("Te".to_string()),
None,
None,
);

assert!(token.equals(&token));
}

#[test]
fn test_true_if_same_address() {
let token = Token::new(
1,
ADDRESS_ONE.to_string(),
9,
Some("abc".to_string()),
Some("def".to_string()),
None,
None,
);
let token_1 = Token::new(
1,
ADDRESS_ONE.to_string(),
18,
Some("ghi".to_string()),
Some("jkl".to_string()),
None,
None,
);

assert!(token.equals(&token_1));
}

#[test]
fn test_true_if_one_token_is_checksummed_and_the_other_is_not() {
let token_a = Token::new(
1,
DAI_MAINNET.to_string(),
18,
Some("DAI".to_string()),
None,
None,
None,
);
let token_b = Token::new(
1,
DAI_MAINNET.to_string().to_lowercase(),
18,
Some("DAI".to_string()),
None,
None,
None,
);

assert!(token_a.equals(&token_b));
}
}

0 comments on commit 39e4582

Please sign in to comment.