cosmwasm_bignumber/
math.rs

1use schemars::JsonSchema;
2use serde::{de, ser, Deserialize, Deserializer, Serialize};
3use std::convert::TryFrom;
4use std::fmt::{self, Write};
5use std::ops;
6use std::str::FromStr;
7
8use bigint::U256;
9use cosmwasm_std::{Decimal, StdError, Uint128};
10
11/// A fixed-point decimal value with 18 fractional digits, i.e. Decimal256(1_000_000_000_000_000_000) == 1.0
12/// The greatest possible value that can be represented is 115792089237316195423570985008687907853269984665640564039457.584007913129639935 (which is (2^128 - 1) / 10^18)
13#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
14pub struct Decimal256(#[schemars(with = "String")] pub U256);
15
16impl Decimal256 {
17    pub const MAX: Decimal256 = Decimal256(U256::MAX);
18    pub const DECIMAL_FRACTIONAL: U256 = U256([1_000_000_000_000_000_000u64, 0, 0, 0]);
19
20    /// Create a 1.0 Decimal256
21    pub const fn one() -> Decimal256 {
22        Decimal256(Decimal256::DECIMAL_FRACTIONAL)
23    }
24
25    /// Create a 0.0 Decimal256
26    pub const fn zero() -> Decimal256 {
27        Decimal256(U256([0, 0, 0, 0]))
28    }
29
30    /// Convert x% into Decimal256
31    pub fn percent(x: u64) -> Decimal256 {
32        Decimal256(U256::from(x) * U256::from(10_000_000_000_000_000u64))
33    }
34
35    /// Convert permille (x/1000) into Decimal256
36    pub fn permille(x: u64) -> Decimal256 {
37        Decimal256(U256::from(x) * U256::from(1_000_000_000_000_000u64))
38    }
39
40    /// Returns the ratio (nominator / denominator) as a Decimal256
41    pub fn from_ratio<A: Into<U256>, B: Into<U256>>(nominator: A, denominator: B) -> Decimal256 {
42        let nominator: U256 = nominator.into();
43        let denominator: U256 = denominator.into();
44        if denominator.is_zero() {
45            panic!("Denominator must not be zero");
46        }
47
48        Decimal256(nominator * Decimal256::DECIMAL_FRACTIONAL / denominator)
49    }
50
51    pub fn from_uint256<A: Into<Uint256>>(val: A) -> Decimal256 {
52        let num: Uint256 = val.into();
53        Decimal256(num.0 * Decimal256::DECIMAL_FRACTIONAL)
54    }
55
56    pub fn is_zero(&self) -> bool {
57        self.0.is_zero()
58    }
59}
60
61impl From<Decimal> for Decimal256 {
62    fn from(val: Decimal) -> Self {
63        Decimal256::from_str(&val.to_string()).unwrap()
64    }
65}
66
67impl From<Decimal256> for Decimal {
68    fn from(n: Decimal256) -> Self {
69        let U256(ref arr) = n.0;
70        assert!(arr[2] == 0u64);
71        assert!(arr[3] == 0u64);
72        Decimal::from_str(&n.to_string()).unwrap()
73    }
74}
75
76impl FromStr for Decimal256 {
77    type Err = StdError;
78
79    /// Converts the decimal string to a Decimal256
80    /// Possible inputs: "1.23", "1", "000012", "1.123000000"
81    /// Disallowed: "", ".23"
82    ///
83    /// This never performs any kind of rounding.
84    /// More than 18 fractional digits, even zeros, result in an error.
85    fn from_str(input: &str) -> Result<Self, Self::Err> {
86        let parts: Vec<&str> = input.split('.').collect();
87        match parts.len() {
88            1 => {
89                let whole = U256::from_dec_str(parts[0])
90                    .map_err(|_| StdError::generic_err("Error parsing whole"))?;
91
92                let whole_as_atomics = whole * Decimal256::DECIMAL_FRACTIONAL;
93                Ok(Decimal256(whole_as_atomics))
94            }
95            2 => {
96                let whole = U256::from_dec_str(parts[0])
97                    .map_err(|_| StdError::generic_err("Error parsing whole"))?;
98                let fractional = U256::from_dec_str(parts[1])
99                    .map_err(|_| StdError::generic_err("Error parsing fractional"))?;
100                let exp = (18usize.checked_sub(parts[1].len())).ok_or_else(|| {
101                    StdError::generic_err("Cannot parse more than 18 fractional digits")
102                })?;
103                let fractional_factor = U256::from(10).pow(exp.into());
104
105                let whole_as_atomics = whole * Decimal256::DECIMAL_FRACTIONAL;
106                let atomics = whole_as_atomics + fractional * fractional_factor;
107                Ok(Decimal256(atomics))
108            }
109            _ => Err(StdError::generic_err("Unexpected number of dots")),
110        }
111    }
112}
113
114impl fmt::Display for Decimal256 {
115    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116        let whole = (self.0) / Decimal256::DECIMAL_FRACTIONAL;
117        let fractional = (self.0) % Decimal256::DECIMAL_FRACTIONAL;
118
119        if fractional.is_zero() {
120            write!(f, "{}", whole)
121        } else {
122            let fractional_string = fractional.to_string();
123            let fractional_string = "0".repeat(18 - fractional_string.len()) + &fractional_string;
124
125            f.write_str(&whole.to_string())?;
126            f.write_char('.')?;
127            f.write_str(fractional_string.trim_end_matches('0'))?;
128
129            Ok(())
130        }
131    }
132}
133
134impl ops::Add for Decimal256 {
135    type Output = Self;
136
137    fn add(self, rhs: Self) -> Self {
138        Decimal256(self.0 + rhs.0)
139    }
140}
141
142impl ops::AddAssign for Decimal256 {
143    fn add_assign(&mut self, rhs: Self) {
144        self.0 = self.0 + rhs.0;
145    }
146}
147
148impl ops::Sub for Decimal256 {
149    type Output = Self;
150
151    fn sub(self, rhs: Self) -> Self {
152        assert!(self.0 >= rhs.0);
153        Decimal256(self.0 - rhs.0)
154    }
155}
156
157impl ops::Mul for Decimal256 {
158    type Output = Self;
159
160    fn mul(self, rhs: Self) -> Self {
161        Decimal256(self.0 * rhs.0 / Decimal256::DECIMAL_FRACTIONAL)
162    }
163}
164
165impl ops::Div for Decimal256 {
166    type Output = Self;
167
168    fn div(self, rhs: Self) -> Self {
169        assert!(!rhs.is_zero());
170
171        Decimal256(self.0 * Decimal256::DECIMAL_FRACTIONAL / rhs.0)
172    }
173}
174
175/// Serializes as a decimal string
176impl Serialize for Decimal256 {
177    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
178    where
179        S: ser::Serializer,
180    {
181        serializer.serialize_str(&self.to_string())
182    }
183}
184
185/// Deserializes as a base64 string
186impl<'de> Deserialize<'de> for Decimal256 {
187    fn deserialize<D>(deserializer: D) -> Result<Decimal256, D::Error>
188    where
189        D: Deserializer<'de>,
190    {
191        deserializer.deserialize_str(Decimal256Visitor)
192    }
193}
194
195struct Decimal256Visitor;
196
197impl<'de> de::Visitor<'de> for Decimal256Visitor {
198    type Value = Decimal256;
199
200    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
201        formatter.write_str("string-encoded decimal")
202    }
203
204    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
205    where
206        E: de::Error,
207    {
208        match Decimal256::from_str(v) {
209            Ok(d) => Ok(d),
210            Err(e) => Err(E::custom(format!("Error parsing decimal '{}': {}", v, e))),
211        }
212    }
213}
214
215//*** Uint256 ***/
216#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
217pub struct Uint256(#[schemars(with = "String")] pub U256);
218
219impl Uint256 {
220    /// Creates a Uint256(0)
221    pub const fn zero() -> Self {
222        Uint256(U256([0, 0, 0, 0]))
223    }
224
225    /// Create a 1.0 Decimal256
226    pub const fn one() -> Self {
227        Uint256(U256([1, 0, 0, 0]))
228    }
229
230    pub fn is_zero(&self) -> bool {
231        self.0.is_zero()
232    }
233}
234
235impl From<U256> for Uint256 {
236    fn from(val: U256) -> Self {
237        Uint256(val)
238    }
239}
240
241impl From<Uint256> for U256 {
242    fn from(val: Uint256) -> Self {
243        val.0
244    }
245}
246
247#[inline(always)]
248fn split_u128(a: u128) -> (u64, u64) {
249    ((a >> 64) as _, (a & 0xFFFFFFFFFFFFFFFF) as _)
250}
251
252impl From<Uint128> for Uint256 {
253    fn from(val: Uint128) -> Self {
254        Uint256::from(val.u128())
255    }
256}
257
258impl From<u128> for Uint256 {
259    fn from(val: u128) -> Self {
260        let (hi, low) = split_u128(val);
261        Uint256(U256([low, hi, 0, 0]))
262    }
263}
264
265impl From<u64> for Uint256 {
266    fn from(val: u64) -> Self {
267        Uint256(val.into())
268    }
269}
270
271impl TryFrom<&str> for Uint256 {
272    type Error = StdError;
273
274    fn try_from(val: &str) -> Result<Self, Self::Error> {
275        match U256::from_dec_str(val) {
276            Ok(u) => Ok(Uint256(u)),
277            Err(_e) => Err(StdError::generic_err(format!("invalid Uint256 '{}'", val))),
278        }
279    }
280}
281
282impl FromStr for Uint256 {
283    type Err = StdError;
284
285    fn from_str(input: &str) -> Result<Self, Self::Err> {
286        let number =
287            U256::from_dec_str(input).map_err(|_| StdError::generic_err("Error parsing number"))?;
288        Ok(Uint256(number))
289    }
290}
291
292impl From<Uint256> for String {
293    fn from(n: Uint256) -> Self {
294        n.0.to_string()
295    }
296}
297
298impl From<Uint256> for u128 {
299    fn from(n: Uint256) -> Self {
300        let U256(ref arr) = n.0;
301        assert!(arr[2] == 0u64);
302        assert!(arr[3] == 0u64);
303
304        let (hi, low) = (arr[1], arr[0]);
305        ((hi as u128) << 64) + (low as u128)
306    }
307}
308
309impl From<Uint256> for Uint128 {
310    fn from(n: Uint256) -> Self {
311        let num: u128 = n.into();
312        Uint128::from(num)
313    }
314}
315
316impl fmt::Display for Uint256 {
317    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
318        write!(f, "{}", self.0)
319    }
320}
321
322impl ops::Add for Uint256 {
323    type Output = Self;
324
325    fn add(self, rhs: Self) -> Self {
326        Uint256(self.0 + rhs.0)
327    }
328}
329
330impl ops::AddAssign for Uint256 {
331    fn add_assign(&mut self, other: Self) {
332        self.0 = self.0 + other.0;
333    }
334}
335
336impl ops::Sub for Uint256 {
337    type Output = Self;
338
339    fn sub(self, rhs: Self) -> Self::Output {
340        assert!(self.0 >= rhs.0);
341        Uint256(self.0 - rhs.0)
342    }
343}
344
345impl ops::Mul<Uint256> for Uint256 {
346    type Output = Self;
347
348    #[allow(clippy::suspicious_arithmetic_impl)]
349    fn mul(self, rhs: Uint256) -> Self::Output {
350        // 0*a and b*0 is always 0
351        if self.is_zero() || rhs.is_zero() {
352            return Uint256::zero();
353        }
354
355        Uint256(self.0 * rhs.0)
356    }
357}
358
359/// Both d*u and u*d with d: Decimal256 and u: Uint256 returns an Uint256. There is no
360/// specific reason for this decision other than the initial use cases we have. If you
361/// need a Decimal256 result for the same calculation, use Decimal256(d*u) or Decimal256(u*d).
362impl ops::Mul<Decimal256> for Uint256 {
363    type Output = Self;
364
365    #[allow(clippy::suspicious_arithmetic_impl)]
366    fn mul(self, rhs: Decimal256) -> Self::Output {
367        // 0*a and b*0 is always 0
368        if self.is_zero() || rhs.is_zero() {
369            return Uint256::zero();
370        }
371
372        self.multiply_ratio(rhs.0, Decimal256::DECIMAL_FRACTIONAL)
373    }
374}
375
376impl ops::Div<Decimal256> for Uint256 {
377    type Output = Self;
378
379    fn div(self, rhs: Decimal256) -> Self::Output {
380        assert!(!rhs.is_zero());
381
382        if self.is_zero() {
383            return Uint256::zero();
384        }
385
386        self.multiply_ratio(Decimal256::DECIMAL_FRACTIONAL, rhs.0)
387    }
388}
389
390impl ops::Mul<Uint256> for Decimal256 {
391    type Output = Uint256;
392
393    fn mul(self, rhs: Uint256) -> Self::Output {
394        rhs * self
395    }
396}
397
398impl Uint256 {
399    /// returns self * nom / denom
400    pub fn multiply_ratio<A: Into<U256>, B: Into<U256>>(&self, nom: A, denom: B) -> Uint256 {
401        let nominator: U256 = nom.into();
402        let denominator: U256 = denom.into();
403        if denominator.is_zero() {
404            panic!("Denominator must not be zero");
405        }
406
407        // TODO: minimize rounding that takes place (using gcd algorithm)
408        let val = self.0 * nominator / denominator;
409        Uint256::from(val)
410    }
411}
412
413/// Serializes as a base64 string
414impl Serialize for Uint256 {
415    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
416    where
417        S: ser::Serializer,
418    {
419        serializer.serialize_str(&self.to_string())
420    }
421}
422
423/// Deserializes as a base64 string
424impl<'de> Deserialize<'de> for Uint256 {
425    fn deserialize<D>(deserializer: D) -> Result<Uint256, D::Error>
426    where
427        D: Deserializer<'de>,
428    {
429        deserializer.deserialize_str(Uint256Visitor)
430    }
431}
432
433struct Uint256Visitor;
434
435impl<'de> de::Visitor<'de> for Uint256Visitor {
436    type Value = Uint256;
437
438    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
439        formatter.write_str("string-encoded integer")
440    }
441
442    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
443    where
444        E: de::Error,
445    {
446        match U256::from_dec_str(v) {
447            Ok(u) => Ok(Uint256(u)),
448            Err(_e) => Err(E::custom(format!("invalid Uint256 '{}'", v))),
449        }
450    }
451}
452
453#[cfg(test)]
454mod test {
455    use super::*;
456    use cosmwasm_std::{from_slice, to_vec, StdResult};
457    use std::convert::TryInto;
458
459    #[test]
460    fn decimal_one() {
461        let value = Decimal256::one();
462        assert_eq!(value.0, Decimal256::DECIMAL_FRACTIONAL);
463    }
464
465    #[test]
466    fn decimal_zero() {
467        let value = Decimal256::zero();
468        assert_eq!(value.0, U256::zero());
469    }
470
471    #[test]
472    fn decimal_percent() {
473        let value = Decimal256::percent(50);
474        assert_eq!(value.0, Decimal256::DECIMAL_FRACTIONAL / 2.into());
475    }
476
477    #[test]
478    fn decimal_permille() {
479        let value = Decimal256::permille(125);
480        assert_eq!(value.0, Decimal256::DECIMAL_FRACTIONAL / 8.into());
481    }
482
483    #[test]
484    fn decimal_from_ratio_works() {
485        // 1.0
486        assert_eq!(Decimal256::from_ratio(1, 1), Decimal256::one());
487        assert_eq!(Decimal256::from_ratio(53, 53), Decimal256::one());
488        assert_eq!(Decimal256::from_ratio(125, 125), Decimal256::one());
489
490        // 1.5
491        assert_eq!(Decimal256::from_ratio(3, 2), Decimal256::percent(150));
492        assert_eq!(Decimal256::from_ratio(150, 100), Decimal256::percent(150));
493        assert_eq!(Decimal256::from_ratio(333, 222), Decimal256::percent(150));
494
495        // 0.125
496        assert_eq!(Decimal256::from_ratio(1, 8), Decimal256::permille(125));
497        assert_eq!(Decimal256::from_ratio(125, 1000), Decimal256::permille(125));
498
499        // 1/3 (result floored)
500        assert_eq!(
501            Decimal256::from_ratio(1, 3),
502            Decimal256(0_333_333_333_333_333_333u64.into())
503        );
504
505        // 2/3 (result floored)
506        assert_eq!(
507            Decimal256::from_ratio(2, 3),
508            Decimal256(0_666_666_666_666_666_666u64.into())
509        );
510    }
511
512    #[test]
513    #[should_panic(expected = "Denominator must not be zero")]
514    fn decimal_from_ratio_panics_for_zero_denominator() {
515        Decimal256::from_ratio(1, 0);
516    }
517
518    #[test]
519    fn decimal_from_str_works() {
520        // Integers
521        assert_eq!(Decimal256::from_str("").unwrap(), Decimal256::percent(0));
522        assert_eq!(Decimal256::from_str("0").unwrap(), Decimal256::percent(0));
523        assert_eq!(Decimal256::from_str("1").unwrap(), Decimal256::percent(100));
524        assert_eq!(Decimal256::from_str("5").unwrap(), Decimal256::percent(500));
525        assert_eq!(
526            Decimal256::from_str("42").unwrap(),
527            Decimal256::percent(4200)
528        );
529        assert_eq!(Decimal256::from_str("000").unwrap(), Decimal256::percent(0));
530        assert_eq!(
531            Decimal256::from_str("001").unwrap(),
532            Decimal256::percent(100)
533        );
534        assert_eq!(
535            Decimal256::from_str("005").unwrap(),
536            Decimal256::percent(500)
537        );
538        assert_eq!(
539            Decimal256::from_str("0042").unwrap(),
540            Decimal256::percent(4200)
541        );
542
543        // Decimal256s
544        assert_eq!(
545            Decimal256::from_str("1.").unwrap(),
546            Decimal256::percent(100)
547        );
548        assert_eq!(
549            Decimal256::from_str("1.0").unwrap(),
550            Decimal256::percent(100)
551        );
552        assert_eq!(
553            Decimal256::from_str("1.5").unwrap(),
554            Decimal256::percent(150)
555        );
556        assert_eq!(
557            Decimal256::from_str("0.5").unwrap(),
558            Decimal256::percent(50)
559        );
560        assert_eq!(
561            Decimal256::from_str("0.123").unwrap(),
562            Decimal256::permille(123)
563        );
564
565        assert_eq!(
566            Decimal256::from_str("40.00").unwrap(),
567            Decimal256::percent(4000)
568        );
569        assert_eq!(
570            Decimal256::from_str("04.00").unwrap(),
571            Decimal256::percent(0400)
572        );
573        assert_eq!(
574            Decimal256::from_str("00.40").unwrap(),
575            Decimal256::percent(0040)
576        );
577        assert_eq!(
578            Decimal256::from_str("00.04").unwrap(),
579            Decimal256::percent(0004)
580        );
581
582        // Can handle 18 fractional digits
583        assert_eq!(
584            Decimal256::from_str("7.123456789012345678").unwrap(),
585            Decimal256(7123456789012345678u64.into())
586        );
587        assert_eq!(
588            Decimal256::from_str("7.999999999999999999").unwrap(),
589            Decimal256(7999999999999999999u64.into())
590        );
591
592        // Works for documented max value
593        assert_eq!(
594            Decimal256::from_str(
595                "115792089237316195423570985008687907853269984665640564039457.584007913129639935"
596            )
597            .unwrap(),
598            Decimal256::MAX
599        );
600    }
601
602    #[test]
603    fn decimal_from_str_errors_for_broken_whole_part() {
604        match Decimal256::from_str(" ").unwrap_err() {
605            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
606            e => panic!("Unexpected error: {:?}", e),
607        }
608
609        match Decimal256::from_str("-1").unwrap_err() {
610            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
611            e => panic!("Unexpected error: {:?}", e),
612        }
613    }
614
615    #[test]
616    fn decimal_from_str_errors_for_broken_fractinal_part() {
617        match Decimal256::from_str("1. ").unwrap_err() {
618            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
619            e => panic!("Unexpected error: {:?}", e),
620        }
621
622        match Decimal256::from_str("1.e").unwrap_err() {
623            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
624            e => panic!("Unexpected error: {:?}", e),
625        }
626
627        match Decimal256::from_str("1.2e3").unwrap_err() {
628            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
629            e => panic!("Unexpected error: {:?}", e),
630        }
631    }
632
633    #[test]
634    fn decimal_from_str_errors_for_more_than_18_fractional_digits() {
635        match Decimal256::from_str("7.1234567890123456789").unwrap_err() {
636            StdError::GenericErr { msg, .. } => {
637                assert_eq!(msg, "Cannot parse more than 18 fractional digits")
638            }
639            e => panic!("Unexpected error: {:?}", e),
640        }
641
642        // No special rules for trailing zeros. This could be changed but adds gas cost for the happy path.
643        match Decimal256::from_str("7.1230000000000000000").unwrap_err() {
644            StdError::GenericErr { msg, .. } => {
645                assert_eq!(msg, "Cannot parse more than 18 fractional digits")
646            }
647            e => panic!("Unexpected error: {:?}", e),
648        }
649    }
650
651    #[test]
652    fn decimal_from_str_errors_for_invalid_number_of_dots() {
653        match Decimal256::from_str("1.2.3").unwrap_err() {
654            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
655            e => panic!("Unexpected error: {:?}", e),
656        }
657
658        match Decimal256::from_str("1.2.3.4").unwrap_err() {
659            StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
660            e => panic!("Unexpected error: {:?}", e),
661        }
662    }
663
664    #[test]
665    #[should_panic(expected = "arithmetic operation overflow")]
666    fn decimal_from_str_errors_for_more_than_max_value_integer_part() {
667        let _ =
668            Decimal256::from_str("115792089237316195423570985008687907853269984665640564039458");
669    }
670
671    #[test]
672    #[should_panic(expected = "arithmetic operation overflow")]
673    fn decimal_from_str_errors_for_more_than_max_value_integer_part_with_decimal() {
674        let _ =
675            Decimal256::from_str("115792089237316195423570985008687907853269984665640564039458.0");
676    }
677    #[test]
678    #[should_panic(expected = "arithmetic operation overflow")]
679    fn decimal_from_str_errors_for_more_than_max_value_decimal_part() {
680        let _ = Decimal256::from_str(
681            "115792089237316195423570985008687907853269984665640564039457.584007913129639936",
682        );
683    }
684
685    #[test]
686    fn decimal_is_zero_works() {
687        assert_eq!(Decimal256::zero().is_zero(), true);
688        assert_eq!(Decimal256::percent(0).is_zero(), true);
689        assert_eq!(Decimal256::permille(0).is_zero(), true);
690
691        assert_eq!(Decimal256::one().is_zero(), false);
692        assert_eq!(Decimal256::percent(123).is_zero(), false);
693        assert_eq!(Decimal256::permille(1234).is_zero(), false);
694    }
695
696    #[test]
697    fn decimal_add() {
698        let value = Decimal256::one() + Decimal256::percent(50); // 1.5
699        assert_eq!(
700            value.0,
701            Decimal256::DECIMAL_FRACTIONAL * U256::from(3) / U256::from(2)
702        );
703    }
704
705    #[test]
706    fn decimal_sub() {
707        assert_eq!(
708            Decimal256::percent(50),
709            Decimal256::one() - Decimal256::percent(50)
710        );
711    }
712
713    #[test]
714    fn decimal_mul() {
715        assert_eq!(
716            Decimal256::percent(25),
717            Decimal256::percent(50) * Decimal256::percent(50)
718        );
719    }
720
721    #[test]
722    fn decimal_div() {
723        assert_eq!(
724            Decimal256::one() + Decimal256::one(),
725            Decimal256::percent(50) / Decimal256::percent(25)
726        );
727    }
728
729    #[test]
730    fn decimal_to_string() {
731        // Integers
732        assert_eq!(Decimal256::zero().to_string(), "0");
733        assert_eq!(Decimal256::one().to_string(), "1");
734        assert_eq!(Decimal256::percent(500).to_string(), "5");
735
736        // Decimal256s
737        assert_eq!(Decimal256::percent(125).to_string(), "1.25");
738        assert_eq!(Decimal256::percent(42638).to_string(), "426.38");
739        assert_eq!(Decimal256::percent(1).to_string(), "0.01");
740        assert_eq!(Decimal256::permille(987).to_string(), "0.987");
741
742        assert_eq!(Decimal256(1u64.into()).to_string(), "0.000000000000000001");
743        assert_eq!(Decimal256(10u64.into()).to_string(), "0.00000000000000001");
744        assert_eq!(Decimal256(100u64.into()).to_string(), "0.0000000000000001");
745        assert_eq!(Decimal256(1000u64.into()).to_string(), "0.000000000000001");
746        assert_eq!(Decimal256(10000u64.into()).to_string(), "0.00000000000001");
747        assert_eq!(Decimal256(100000u64.into()).to_string(), "0.0000000000001");
748        assert_eq!(Decimal256(1000000u64.into()).to_string(), "0.000000000001");
749        assert_eq!(Decimal256(10000000u64.into()).to_string(), "0.00000000001");
750        assert_eq!(Decimal256(100000000u64.into()).to_string(), "0.0000000001");
751        assert_eq!(Decimal256(1000000000u64.into()).to_string(), "0.000000001");
752        assert_eq!(Decimal256(10000000000u64.into()).to_string(), "0.00000001");
753        assert_eq!(Decimal256(100000000000u64.into()).to_string(), "0.0000001");
754        assert_eq!(Decimal256(10000000000000u64.into()).to_string(), "0.00001");
755        assert_eq!(Decimal256(100000000000000u64.into()).to_string(), "0.0001");
756        assert_eq!(Decimal256(1000000000000000u64.into()).to_string(), "0.001");
757        assert_eq!(Decimal256(10000000000000000u64.into()).to_string(), "0.01");
758        assert_eq!(Decimal256(100000000000000000u64.into()).to_string(), "0.1");
759    }
760
761    #[test]
762    fn decimal_serialize() {
763        assert_eq!(to_vec(&Decimal256::zero()).unwrap(), br#""0""#);
764        assert_eq!(to_vec(&Decimal256::one()).unwrap(), br#""1""#);
765        assert_eq!(to_vec(&Decimal256::percent(8)).unwrap(), br#""0.08""#);
766        assert_eq!(to_vec(&Decimal256::percent(87)).unwrap(), br#""0.87""#);
767        assert_eq!(to_vec(&Decimal256::percent(876)).unwrap(), br#""8.76""#);
768        assert_eq!(to_vec(&Decimal256::percent(8765)).unwrap(), br#""87.65""#);
769    }
770
771    #[test]
772    fn decimal_deserialize() {
773        assert_eq!(
774            from_slice::<Decimal256>(br#""0""#).unwrap(),
775            Decimal256::zero()
776        );
777        assert_eq!(
778            from_slice::<Decimal256>(br#""1""#).unwrap(),
779            Decimal256::one()
780        );
781        assert_eq!(
782            from_slice::<Decimal256>(br#""000""#).unwrap(),
783            Decimal256::zero()
784        );
785        assert_eq!(
786            from_slice::<Decimal256>(br#""001""#).unwrap(),
787            Decimal256::one()
788        );
789
790        assert_eq!(
791            from_slice::<Decimal256>(br#""0.08""#).unwrap(),
792            Decimal256::percent(8)
793        );
794        assert_eq!(
795            from_slice::<Decimal256>(br#""0.87""#).unwrap(),
796            Decimal256::percent(87)
797        );
798        assert_eq!(
799            from_slice::<Decimal256>(br#""8.76""#).unwrap(),
800            Decimal256::percent(876)
801        );
802        assert_eq!(
803            from_slice::<Decimal256>(br#""87.65""#).unwrap(),
804            Decimal256::percent(8765)
805        );
806    }
807
808    #[test]
809    fn to_and_from_uint256() {
810        let a: Uint256 = 12345u64.into();
811        assert_eq!(U256::from(12345), a.0);
812        assert_eq!("12345", a.to_string());
813
814        let a: Uint256 = "34567".try_into().unwrap();
815        assert_eq!(U256::from(34567), a.0);
816        assert_eq!("34567", a.to_string());
817
818        let a: StdResult<Uint256> = "1.23".try_into();
819        assert!(a.is_err());
820    }
821
822    #[test]
823    fn uint256_is_zero_works() {
824        assert_eq!(Uint256::zero().is_zero(), true);
825        assert_eq!(Uint256::from(0u64).is_zero(), true);
826
827        assert_eq!(Uint256::from(1u64).is_zero(), false);
828        assert_eq!(Uint256::from(123u64).is_zero(), false);
829    }
830
831    #[test]
832    fn uint256_json() {
833        let orig = Uint256::from(1234567890987654321u64);
834        let serialized = to_vec(&orig).unwrap();
835        assert_eq!(serialized.as_slice(), b"\"1234567890987654321\"");
836        let parsed: Uint256 = from_slice(&serialized).unwrap();
837        assert_eq!(parsed, orig);
838    }
839
840    #[test]
841    fn uint256_compare() {
842        let a = Uint256::from(12345u64);
843        let b = Uint256::from(23456u64);
844
845        assert!(a < b);
846        assert!(b > a);
847        assert_eq!(a, Uint256::from(12345u64));
848    }
849
850    #[test]
851    fn uint256_math() {
852        let a = Uint256::from(12345u64);
853        let b = Uint256::from(23456u64);
854
855        // test + and - for valid values
856        assert_eq!(a + b, Uint256::from(35801u64));
857        assert_eq!(b - a, Uint256::from(11111u64));
858
859        // test +=
860        let mut c = Uint256::from(300000u64);
861        c += b;
862        assert_eq!(c, Uint256::from(323456u64));
863    }
864    #[test]
865    #[should_panic]
866    fn uint256_math_sub_underflow() {
867        let _ = Uint256::from(12345u64) - Uint256::from(23456u64);
868    }
869
870    #[test]
871    #[should_panic]
872    fn uint256_math_overflow_panics() {
873        // almost_max is 2^256 - 10
874        let almost_max = Uint256::from(U256([
875            18446744073709551615,
876            18446744073709551615,
877            18446744073709551615,
878            18446744073709551615,
879        ]));
880        let _ = almost_max + Uint256::from(12u64);
881    }
882
883    #[test]
884    // in this test the Decimal256 is on the right
885    fn uint256_decimal_multiply() {
886        // a*b
887        let left = Uint256::from(300u64);
888        let right = Decimal256::one() + Decimal256::percent(50); // 1.5
889        assert_eq!(left * right, Uint256::from(450u64));
890
891        // a*0
892        let left = Uint256::from(300u64);
893        let right = Decimal256::zero();
894        assert_eq!(left * right, Uint256::from(0u64));
895
896        // 0*a
897        let left = Uint256::zero();
898        let right = Decimal256::one() + Decimal256::percent(50); // 1.5
899        assert_eq!(left * right, Uint256::zero());
900    }
901
902    #[test]
903    fn u256_multiply_ratio_works() {
904        let base = Uint256::from(500u64);
905
906        // factor 1/1
907        assert_eq!(base.multiply_ratio(1, 1), Uint256::from(500u64));
908        assert_eq!(base.multiply_ratio(3, 3), Uint256::from(500u64));
909        assert_eq!(base.multiply_ratio(654321, 654321), Uint256::from(500u64));
910
911        // factor 3/2
912        assert_eq!(base.multiply_ratio(3, 2), Uint256::from(750u64));
913        assert_eq!(base.multiply_ratio(333333, 222222), Uint256::from(750u64));
914
915        // factor 2/3 (integer devision always floors the result)
916        assert_eq!(base.multiply_ratio(2, 3), Uint256::from(333u64));
917        assert_eq!(base.multiply_ratio(222222, 333333), Uint256::from(333u64));
918
919        // factor 5/6 (integer devision always floors the result)
920        assert_eq!(base.multiply_ratio(5, 6), Uint256::from(416u64));
921        assert_eq!(base.multiply_ratio(100, 120), Uint256::from(416u64));
922    }
923
924    #[test]
925    fn u256_from_u128() {
926        assert_eq!(Uint256::from(100u64), Uint256::from(100u128));
927        let num = Uint256::from(1_000_000_000_000_000_000_000_000u128);
928        assert_eq!(num.to_string(), "1000000000000000000000000");
929    }
930
931    #[test]
932    #[should_panic(expected = "Denominator must not be zero")]
933    fn u256_multiply_ratio_panics_for_zero_denominator() {
934        Uint256::from(500u64).multiply_ratio(1, 0);
935    }
936
937    #[test]
938    fn u256_zero_one() {
939        assert_eq!(Uint256::zero().0, U256::zero());
940        assert_eq!(Uint256::one().0, U256::one());
941    }
942
943    #[test]
944    fn u256_into_u128() {
945        let val: u128 = Uint256::from(1234556700000000000999u128).into();
946        assert_eq!(val, 1234556700000000000999u128);
947    }
948
949    #[test]
950    #[should_panic]
951    fn u256_into_u128_panics_for_overflow() {
952        let _: u128 = Uint256::from_str("2134982317498312749832174923184732198471983247")
953            .unwrap()
954            .into();
955    }
956
957    #[test]
958    // in this test the Decimal256 is on the left
959    fn decimal_uint256_multiply() {
960        // a*b
961        let left = Decimal256::one() + Decimal256::percent(50); // 1.5
962        let right = Uint256::from(300u64);
963        assert_eq!(left * right, Uint256::from(450u64));
964
965        // 0*a
966        let left = Decimal256::zero();
967        let right = Uint256::from(300u64);
968        assert_eq!(left * right, Uint256::from(0u64));
969
970        // a*0
971        let left = Decimal256::one() + Decimal256::percent(50); // 1.5
972        let right = Uint256::from(0u64);
973        assert_eq!(left * right, Uint256::from(0u64));
974    }
975}