1use schemars::JsonSchema;
4use serde::{de, ser, Deserialize, Deserializer, Serialize};
5use std::fmt::{self, Write};
6use std::ops;
7use std::str::FromStr;
8
9use cosmwasm_std::Decimal as StdDecimal;
10use cosmwasm_std::{Fraction, StdError, StdResult, Uint128, Uint256};
11use std::convert::TryInto;
12
13#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
17pub struct Decimal(#[schemars(with = "String")] Uint128);
18
19impl Decimal {
20 const DECIMAL_FRACTIONAL: Uint128 = Uint128::new(1_000_000_000_000_000_000u128); const DECIMAL_FRACTIONAL_SQUARED: Uint128 =
22 Uint128::new(1_000_000_000_000_000_000_000_000_000_000_000_000u128); const DECIMAL_PLACES: usize = 18; pub const MAX: Self = Self(Uint128::MAX);
26
27 pub const fn one() -> Self {
29 Decimal(Self::DECIMAL_FRACTIONAL)
30 }
31
32 pub const fn zero() -> Self {
34 Decimal(Uint128::zero())
35 }
36
37 pub fn percent(x: u64) -> Self {
39 Decimal(((x as u128) * 10_000_000_000_000_000).into())
40 }
41
42 pub fn permille(x: u64) -> Self {
44 Decimal(((x as u128) * 1_000_000_000_000_000).into())
45 }
46
47 pub fn from_ratio(numerator: impl Into<Uint128>, denominator: impl Into<Uint128>) -> Self {
49 let numerator: Uint128 = numerator.into();
50 let denominator: Uint128 = denominator.into();
51 if denominator.is_zero() {
52 panic!("Denominator must not be zero");
53 }
54
55 Decimal(
56 numerator.multiply_ratio(Self::DECIMAL_FRACTIONAL, denominator),
58 )
59 }
60
61 pub fn is_zero(&self) -> bool {
62 self.0.is_zero()
63 }
64
65 pub fn checked_mul(self, other: Self) -> StdResult<Self> {
70 let a_numerator = self.numerator();
71 let b_numerator = other.numerator();
72
73 let mul_result = Uint256::from(a_numerator).checked_mul(Uint256::from(b_numerator))?;
74 let result = (mul_result / Uint256::from(Self::DECIMAL_FRACTIONAL)).try_into()?;
75 Ok(Decimal(result))
76 }
77
78 pub fn checked_div(self, other: Self) -> StdResult<Self> {
84 let a_numerator = self.numerator();
85 let b_numerator = other.numerator();
86
87 let mul_result =
88 Uint256::from(a_numerator).checked_mul(Uint256::from(Self::DECIMAL_FRACTIONAL))?;
89 let result = (mul_result.checked_div(Uint256::from(b_numerator)))?.try_into()?;
90 Ok(Decimal(result))
91 }
92
93 pub fn divide_uint128_by_decimal(a: Uint128, b: Decimal) -> StdResult<Uint128> {
96 let numerator_u256 = a.full_mul(b.denominator());
98 let denominator_u256 = Uint256::from(b.numerator());
99
100 let result_u256 = numerator_u256 / denominator_u256;
101
102 let result = result_u256.try_into()?;
103 Ok(result)
104 }
105
106 pub fn divide_uint128_by_decimal_and_ceil(a: Uint128, b: Decimal) -> StdResult<Uint128> {
108 let numerator_u256 = a.full_mul(b.denominator());
110 let denominator_u256 = Uint256::from(b.numerator());
111
112 let mut result_u256 = numerator_u256 / denominator_u256;
113
114 if numerator_u256.checked_rem(denominator_u256)? > Uint256::zero() {
115 result_u256 += Uint256::from(1_u32);
116 }
117
118 let result = result_u256.try_into()?;
119 Ok(result)
120 }
121
122 pub fn multiply_uint128_by_decimal_and_ceil(a: Uint128, b: Decimal) -> StdResult<Uint128> {
124 let numerator_u256 = a.full_mul(b.numerator());
125 let denominator_u256 = Uint256::from(b.denominator());
126
127 let mut result_u256 = numerator_u256 / denominator_u256;
128
129 if numerator_u256.checked_rem(denominator_u256)? > Uint256::zero() {
130 result_u256 += Uint256::from(1_u32);
131 }
132
133 let result = result_u256.try_into()?;
134 Ok(result)
135 }
136
137 pub fn to_std_decimal(&self) -> StdDecimal {
138 StdDecimal::from_str(self.to_string().as_str()).unwrap()
139 }
140}
141
142impl Fraction<u128> for Decimal {
143 #[inline]
144 fn numerator(&self) -> u128 {
145 self.0.u128()
146 }
147
148 #[inline]
149 fn denominator(&self) -> u128 {
150 Self::DECIMAL_FRACTIONAL.u128()
151 }
152
153 fn inv(&self) -> Option<Self> {
157 if self.is_zero() {
158 None
159 } else {
160 Some(Decimal(Self::DECIMAL_FRACTIONAL_SQUARED / self.0))
164 }
165 }
166}
167
168impl From<StdDecimal> for Decimal {
169 fn from(std_decimal: StdDecimal) -> Decimal {
170 Decimal(Uint128::new(std_decimal.numerator()))
171 }
172}
173
174impl FromStr for Decimal {
175 type Err = StdError;
176
177 fn from_str(input: &str) -> Result<Self, Self::Err> {
184 let mut parts_iter = input.split('.');
185
186 let whole_part = parts_iter.next().unwrap(); let whole = whole_part
188 .parse::<Uint128>()
189 .map_err(|_| StdError::generic_err("Error parsing whole"))?;
190 let mut atomics = whole
191 .checked_mul(Self::DECIMAL_FRACTIONAL)
192 .map_err(|_| StdError::generic_err("Value too big"))?;
193
194 if let Some(fractional_part) = parts_iter.next() {
195 let fractional = fractional_part
196 .parse::<Uint128>()
197 .map_err(|_| StdError::generic_err("Error parsing fractional"))?;
198 let exp =
199 (Self::DECIMAL_PLACES.checked_sub(fractional_part.len())).ok_or_else(|| {
200 StdError::generic_err(format!(
201 "Cannot parse more than {} fractional digits",
202 Self::DECIMAL_PLACES
203 ))
204 })?;
205 debug_assert!(exp <= Self::DECIMAL_PLACES);
206 let fractional_factor = Uint128::from(10u128.pow(exp as u32));
207 atomics = atomics
208 .checked_add(
209 fractional.checked_mul(fractional_factor).unwrap(),
212 )
213 .map_err(|_| StdError::generic_err("Value too big"))?;
214 }
215
216 if parts_iter.next().is_some() {
217 return Err(StdError::generic_err("Unexpected number of dots"));
218 }
219
220 Ok(Decimal(atomics))
221 }
222}
223
224impl fmt::Display for Decimal {
225 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
226 let whole = (self.0) / Self::DECIMAL_FRACTIONAL;
227 let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap();
228
229 if fractional.is_zero() {
230 write!(f, "{}", whole)
231 } else {
232 let fractional_string =
233 format!("{:0>padding$}", fractional, padding = Self::DECIMAL_PLACES);
234 f.write_str(&whole.to_string())?;
235 f.write_char('.')?;
236 f.write_str(fractional_string.trim_end_matches('0'))?;
237 Ok(())
238 }
239 }
240}
241
242impl ops::Add for Decimal {
243 type Output = Self;
244
245 fn add(self, other: Self) -> Self {
246 Decimal(self.0 + other.0)
247 }
248}
249
250impl ops::Sub for Decimal {
251 type Output = Self;
252
253 fn sub(self, other: Self) -> Self {
254 Decimal(self.0 - other.0)
255 }
256}
257
258impl ops::Mul<Decimal> for Uint128 {
262 type Output = Self;
263
264 #[allow(clippy::suspicious_arithmetic_impl)]
265 fn mul(self, rhs: Decimal) -> Self::Output {
266 if self.is_zero() || rhs.is_zero() {
268 return Uint128::zero();
269 }
270 self.multiply_ratio(rhs.0, Decimal::DECIMAL_FRACTIONAL)
271 }
272}
273
274impl ops::Mul<Uint128> for Decimal {
275 type Output = Uint128;
276
277 fn mul(self, rhs: Uint128) -> Self::Output {
278 rhs * self
279 }
280}
281
282impl ops::Div<Uint128> for Decimal {
283 type Output = Self;
284
285 fn div(self, rhs: Uint128) -> Self::Output {
286 Decimal(self.0 / rhs)
287 }
288}
289
290impl ops::DivAssign<Uint128> for Decimal {
291 fn div_assign(&mut self, rhs: Uint128) {
292 self.0 /= rhs;
293 }
294}
295
296impl Serialize for Decimal {
298 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
299 where
300 S: ser::Serializer,
301 {
302 serializer.serialize_str(&self.to_string())
303 }
304}
305
306impl<'de> Deserialize<'de> for Decimal {
308 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
309 where
310 D: Deserializer<'de>,
311 {
312 deserializer.deserialize_str(DecimalVisitor)
313 }
314}
315
316struct DecimalVisitor;
317
318impl<'de> de::Visitor<'de> for DecimalVisitor {
319 type Value = Decimal;
320
321 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
322 formatter.write_str("string-encoded decimal")
323 }
324
325 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
326 where
327 E: de::Error,
328 {
329 match Decimal::from_str(v) {
330 Ok(d) => Ok(d),
331 Err(e) => Err(E::custom(format!("Error parsing decimal '{}': {}", v, e))),
332 }
333 }
334}
335
336#[cfg(test)]
337mod tests {
338 use super::*;
339 use cosmwasm_std::{from_slice, to_vec, ConversionOverflowError};
340
341 #[test]
342 fn decimal_one() {
343 let value = Decimal::one();
344 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL);
345 }
346
347 #[test]
348 fn decimal_zero() {
349 let value = Decimal::zero();
350 assert!(value.0.is_zero());
351 }
352
353 #[test]
354 fn decimal_percent() {
355 let value = Decimal::percent(50);
356 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
357 }
358
359 #[test]
360 fn decimal_permille() {
361 let value = Decimal::permille(125);
362 assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(8u8));
363 }
364
365 #[test]
366 fn decimal_from_ratio_works() {
367 assert_eq!(Decimal::from_ratio(1u128, 1u128), Decimal::one());
369 assert_eq!(Decimal::from_ratio(53u128, 53u128), Decimal::one());
370 assert_eq!(Decimal::from_ratio(125u128, 125u128), Decimal::one());
371
372 assert_eq!(Decimal::from_ratio(3u128, 2u128), Decimal::percent(150));
374 assert_eq!(Decimal::from_ratio(150u128, 100u128), Decimal::percent(150));
375 assert_eq!(Decimal::from_ratio(333u128, 222u128), Decimal::percent(150));
376
377 assert_eq!(Decimal::from_ratio(1u64, 8u64), Decimal::permille(125));
379 assert_eq!(Decimal::from_ratio(125u64, 1000u64), Decimal::permille(125));
380
381 assert_eq!(
383 Decimal::from_ratio(1u64, 3u64),
384 Decimal(Uint128::from(333_333_333_333_333_333u128))
385 );
386
387 assert_eq!(
389 Decimal::from_ratio(2u64, 3u64),
390 Decimal(Uint128::from(666_666_666_666_666_666u128))
391 );
392
393 assert_eq!(Decimal::from_ratio(0u128, u128::MAX), Decimal::zero());
395 assert_eq!(Decimal::from_ratio(u128::MAX, u128::MAX), Decimal::one());
396 assert_eq!(
398 Decimal::from_ratio(340282366920938463463u128, 1u128),
399 Decimal::from_str("340282366920938463463").unwrap()
400 );
401 }
402
403 #[test]
404 #[should_panic(expected = "Denominator must not be zero")]
405 fn decimal_from_ratio_panics_for_zero_denominator() {
406 Decimal::from_ratio(1u128, 0u128);
407 }
408
409 #[test]
410 fn decimal_implements_fraction() {
411 let fraction = Decimal::from_str("1234.567").unwrap();
412 assert_eq!(fraction.numerator(), 1_234_567_000_000_000_000_000u128);
413 assert_eq!(fraction.denominator(), 1_000_000_000_000_000_000u128);
414 }
415
416 #[test]
417 fn decimal_from_str_works() {
418 assert_eq!(Decimal::from_str("0").unwrap(), Decimal::percent(0));
420 assert_eq!(Decimal::from_str("1").unwrap(), Decimal::percent(100));
421 assert_eq!(Decimal::from_str("5").unwrap(), Decimal::percent(500));
422 assert_eq!(Decimal::from_str("42").unwrap(), Decimal::percent(4200));
423 assert_eq!(Decimal::from_str("000").unwrap(), Decimal::percent(0));
424 assert_eq!(Decimal::from_str("001").unwrap(), Decimal::percent(100));
425 assert_eq!(Decimal::from_str("005").unwrap(), Decimal::percent(500));
426 assert_eq!(Decimal::from_str("0042").unwrap(), Decimal::percent(4200));
427
428 assert_eq!(Decimal::from_str("1.0").unwrap(), Decimal::percent(100));
430 assert_eq!(Decimal::from_str("1.5").unwrap(), Decimal::percent(150));
431 assert_eq!(Decimal::from_str("0.5").unwrap(), Decimal::percent(50));
432 assert_eq!(Decimal::from_str("0.123").unwrap(), Decimal::permille(123));
433
434 assert_eq!(Decimal::from_str("40.00").unwrap(), Decimal::percent(4000));
435 assert_eq!(Decimal::from_str("04.00").unwrap(), Decimal::percent(400));
436 assert_eq!(Decimal::from_str("00.40").unwrap(), Decimal::percent(40));
437 assert_eq!(Decimal::from_str("00.04").unwrap(), Decimal::percent(4));
438
439 assert_eq!(
441 Decimal::from_str("7.123456789012345678").unwrap(),
442 Decimal(Uint128::from(7123456789012345678u128))
443 );
444 assert_eq!(
445 Decimal::from_str("7.999999999999999999").unwrap(),
446 Decimal(Uint128::from(7999999999999999999u128))
447 );
448
449 assert_eq!(
451 Decimal::from_str("340282366920938463463.374607431768211455").unwrap(),
452 Decimal::MAX
453 );
454 }
455
456 #[test]
457 fn decimal_from_str_errors_for_broken_whole_part() {
458 match Decimal::from_str("").unwrap_err() {
459 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
460 e => panic!("Unexpected error: {:?}", e),
461 }
462
463 match Decimal::from_str(" ").unwrap_err() {
464 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
465 e => panic!("Unexpected error: {:?}", e),
466 }
467
468 match Decimal::from_str("-1").unwrap_err() {
469 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"),
470 e => panic!("Unexpected error: {:?}", e),
471 }
472 }
473
474 #[test]
475 fn decimal_from_str_errors_for_broken_fractinal_part() {
476 match Decimal::from_str("1.").unwrap_err() {
477 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
478 e => panic!("Unexpected error: {:?}", e),
479 }
480
481 match Decimal::from_str("1. ").unwrap_err() {
482 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
483 e => panic!("Unexpected error: {:?}", e),
484 }
485
486 match Decimal::from_str("1.e").unwrap_err() {
487 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
488 e => panic!("Unexpected error: {:?}", e),
489 }
490
491 match Decimal::from_str("1.2e3").unwrap_err() {
492 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"),
493 e => panic!("Unexpected error: {:?}", e),
494 }
495 }
496
497 #[test]
498 fn decimal_from_str_errors_for_more_than_18_fractional_digits() {
499 match Decimal::from_str("7.1234567890123456789").unwrap_err() {
500 StdError::GenericErr { msg, .. } => {
501 assert_eq!(msg, "Cannot parse more than 18 fractional digits",)
502 }
503 e => panic!("Unexpected error: {:?}", e),
504 }
505
506 match Decimal::from_str("7.1230000000000000000").unwrap_err() {
508 StdError::GenericErr { msg, .. } => {
509 assert_eq!(msg, "Cannot parse more than 18 fractional digits")
510 }
511 e => panic!("Unexpected error: {:?}", e),
512 }
513 }
514
515 #[test]
516 fn decimal_from_str_errors_for_invalid_number_of_dots() {
517 match Decimal::from_str("1.2.3").unwrap_err() {
518 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
519 e => panic!("Unexpected error: {:?}", e),
520 }
521
522 match Decimal::from_str("1.2.3.4").unwrap_err() {
523 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"),
524 e => panic!("Unexpected error: {:?}", e),
525 }
526 }
527
528 #[test]
529 fn decimal_from_str_errors_for_more_than_max_value() {
530 match Decimal::from_str("340282366920938463464").unwrap_err() {
532 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
533 e => panic!("Unexpected error: {:?}", e),
534 }
535
536 match Decimal::from_str("340282366920938463464.0").unwrap_err() {
538 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
539 e => panic!("Unexpected error: {:?}", e),
540 }
541 match Decimal::from_str("340282366920938463463.374607431768211456").unwrap_err() {
542 StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"),
543 e => panic!("Unexpected error: {:?}", e),
544 }
545 }
546
547 #[test]
548 fn decimal_is_zero_works() {
549 assert!(Decimal::zero().is_zero());
550 assert!(Decimal::percent(0).is_zero());
551 assert!(Decimal::permille(0).is_zero());
552
553 assert!(!Decimal::one().is_zero());
554 assert!(!Decimal::percent(123).is_zero());
555 assert!(!Decimal::permille(1234).is_zero());
556 }
557
558 #[test]
559 fn decimal_inv_works() {
560 assert_eq!(Decimal::zero().inv(), None);
562
563 assert_eq!(Decimal::one().inv(), Some(Decimal::one()));
565
566 assert_eq!(
568 Decimal::from_str("2").unwrap().inv(),
569 Some(Decimal::from_str("0.5").unwrap())
570 );
571 assert_eq!(
572 Decimal::from_str("20").unwrap().inv(),
573 Some(Decimal::from_str("0.05").unwrap())
574 );
575 assert_eq!(
576 Decimal::from_str("200").unwrap().inv(),
577 Some(Decimal::from_str("0.005").unwrap())
578 );
579 assert_eq!(
580 Decimal::from_str("2000").unwrap().inv(),
581 Some(Decimal::from_str("0.0005").unwrap())
582 );
583
584 assert_eq!(
586 Decimal::from_str("3").unwrap().inv(),
587 Some(Decimal::from_str("0.333333333333333333").unwrap())
588 );
589 assert_eq!(
590 Decimal::from_str("6").unwrap().inv(),
591 Some(Decimal::from_str("0.166666666666666666").unwrap())
592 );
593
594 assert_eq!(
596 Decimal::from_str("0.5").unwrap().inv(),
597 Some(Decimal::from_str("2").unwrap())
598 );
599 assert_eq!(
600 Decimal::from_str("0.05").unwrap().inv(),
601 Some(Decimal::from_str("20").unwrap())
602 );
603 assert_eq!(
604 Decimal::from_str("0.005").unwrap().inv(),
605 Some(Decimal::from_str("200").unwrap())
606 );
607 assert_eq!(
608 Decimal::from_str("0.0005").unwrap().inv(),
609 Some(Decimal::from_str("2000").unwrap())
610 );
611 }
612
613 #[test]
614 fn decimal_add() {
615 let value = Decimal::one() + Decimal::percent(50); assert_eq!(
617 value.0,
618 Decimal::DECIMAL_FRACTIONAL * Uint128::from(3u8) / Uint128::from(2u8)
619 );
620 }
621
622 #[test]
623 #[should_panic(expected = "attempt to add with overflow")]
624 fn decimal_add_overflow_panics() {
625 let _value = Decimal::MAX + Decimal::percent(50);
626 }
627
628 #[test]
629 fn decimal_sub() {
630 let value = Decimal::one() - Decimal::percent(50); assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(2u8));
632 }
633
634 #[test]
635 #[should_panic(expected = "attempt to subtract with overflow")]
636 fn decimal_sub_overflow_panics() {
637 let _value = Decimal::zero() - Decimal::percent(50);
638 }
639
640 #[test]
641 fn uint128_decimal_multiply() {
643 let left = Uint128::new(300);
645 let right = Decimal::one() + Decimal::percent(50); assert_eq!(left * right, Uint128::new(450));
647
648 let left = Uint128::new(300);
650 let right = Decimal::zero();
651 assert_eq!(left * right, Uint128::new(0));
652
653 let left = Uint128::new(0);
655 let right = Decimal::one() + Decimal::percent(50); assert_eq!(left * right, Uint128::new(0));
657 }
658
659 #[test]
660 fn decimal_uint128_multiply() {
662 let left = Decimal::one() + Decimal::percent(50); let right = Uint128::new(300);
665 assert_eq!(left * right, Uint128::new(450));
666
667 let left = Decimal::zero();
669 let right = Uint128::new(300);
670 assert_eq!(left * right, Uint128::new(0));
671
672 let left = Decimal::one() + Decimal::percent(50); let right = Uint128::new(0);
675 assert_eq!(left * right, Uint128::new(0));
676 }
677
678 #[test]
679 fn decimal_uint128_division() {
680 let left = Decimal::percent(150); let right = Uint128::new(3);
683 assert_eq!(left / right, Decimal::percent(50));
684
685 let left = Decimal::zero();
687 let right = Uint128::new(300);
688 assert_eq!(left / right, Decimal::zero());
689 }
690
691 #[test]
692 #[should_panic(expected = "attempt to divide by zero")]
693 fn decimal_uint128_divide_by_zero() {
694 let left = Decimal::percent(150); let right = Uint128::new(0);
696 let _result = left / right;
697 }
698
699 #[test]
700 fn decimal_uint128_div_assign() {
701 let mut dec = Decimal::percent(150); dec /= Uint128::new(3);
704 assert_eq!(dec, Decimal::percent(50));
705
706 let mut dec = Decimal::zero();
708 dec /= Uint128::new(300);
709 assert_eq!(dec, Decimal::zero());
710 }
711
712 #[test]
713 #[should_panic(expected = "attempt to divide by zero")]
714 fn decimal_uint128_div_assign_by_zero() {
715 let mut dec = Decimal::percent(50);
717 dec /= Uint128::new(0);
718 }
719
720 #[test]
721 fn checked_decimal_multiplication() {
722 let a = Decimal::from_ratio(33u128, 10u128);
723 let b = Decimal::from_ratio(45u128, 10u128);
724 let c = Decimal::checked_mul(a, b).unwrap();
725 assert_eq!(c, Decimal::from_str("14.85").unwrap());
726
727 let a = Decimal::from_ratio(340282366920u128, 1u128);
728 let b = Decimal::from_ratio(12345678u128, 100000000u128);
729 let c = Decimal::checked_mul(a, b).unwrap();
730 assert_eq!(c, Decimal::from_str("42010165310.7217176").unwrap());
731
732 let a = Decimal::MAX;
733 let b = Decimal::one();
734 let c = Decimal::checked_mul(a, b).unwrap();
735 assert_eq!(c, Decimal::MAX);
736
737 let a = Decimal::MAX;
738 let b = Decimal::MAX;
739 let res_error = Decimal::checked_mul(a, b).unwrap_err();
740 assert_eq!(
741 res_error,
742 ConversionOverflowError::new(
743 "Uint256",
744 "Uint128",
745 "115792089237316195423570985008687907852589419931798687112530"
746 )
747 .into()
748 );
749 }
750
751 #[test]
752 fn checked_decimal_division() {
753 let a = Decimal::from_ratio(99988u128, 100u128);
754 let b = Decimal::from_ratio(24997u128, 100u128);
755 let c = Decimal::checked_div(a, b).unwrap();
756 assert_eq!(c, Decimal::from_str("4.0").unwrap());
757
758 let a = Decimal::from_ratio(123456789u128, 1000000u128);
759 let b = Decimal::from_ratio(33u128, 1u128);
760 let c = Decimal::checked_div(a, b).unwrap();
761 assert_eq!(c, Decimal::from_str("3.741114818181818181").unwrap());
762
763 let a = Decimal::MAX;
764 let b = Decimal::MAX;
765 let c = Decimal::checked_div(a, b).unwrap();
766 assert_eq!(c, Decimal::one());
767
768 let a = Decimal::one();
770 let b = Decimal::zero();
771 Decimal::checked_div(a, b).unwrap_err();
772
773 let a = Decimal::MAX;
774 let b = Decimal::from_ratio(1u128, Decimal::DECIMAL_FRACTIONAL);
775 let res_error = Decimal::checked_div(a, b).unwrap_err();
776 assert_eq!(
777 res_error,
778 ConversionOverflowError::new(
779 "Uint256",
780 "Uint128",
781 "340282366920938463463374607431768211455000000000000000000"
782 )
783 .into()
784 );
785 }
786
787 #[test]
788 fn test_divide_uint128_by_decimal() {
789 let a = Uint128::new(120u128);
790 let b = Decimal::from_ratio(120u128, 15u128);
791 let c = Decimal::divide_uint128_by_decimal(a, b).unwrap();
792 assert_eq!(c, Uint128::new(15u128));
793
794 let a = Uint128::new(Decimal::DECIMAL_FRACTIONAL.u128());
795 let b = Decimal::from_ratio(Decimal::DECIMAL_FRACTIONAL.u128(), 1u128);
796 let c = Decimal::divide_uint128_by_decimal(a, b).unwrap();
797 assert_eq!(c, Uint128::new(1u128));
798
799 let a = Uint128::new(Decimal::DECIMAL_FRACTIONAL.u128());
800 let b = Decimal::from_ratio(1u128, Decimal::DECIMAL_FRACTIONAL.u128());
801 let c = Decimal::divide_uint128_by_decimal(a, b).unwrap();
802 assert_eq!(c, Uint128::new(Decimal::DECIMAL_FRACTIONAL_SQUARED.u128()));
803
804 let a = Uint128::MAX;
805 let b = Decimal::one();
806 let c = Decimal::divide_uint128_by_decimal(a, b).unwrap();
807 assert_eq!(c, Uint128::MAX);
808
809 let a = Uint128::new(1_000_000_000_000_000_000);
810 let b = Decimal::from_ratio(1u128, Decimal::DECIMAL_FRACTIONAL);
811 let c = Decimal::divide_uint128_by_decimal(a, b).unwrap();
812 assert_eq!(
813 c,
814 Uint128::new(1_000_000_000_000_000_000_000_000_000_000_000_000)
815 );
816
817 let a = Uint128::new(100);
819 let b = Decimal::from_ratio(3u128, 1u128);
820 let c = Decimal::divide_uint128_by_decimal(a, b).unwrap();
821 assert_eq!(c, Uint128::new(33));
822
823 let a = Uint128::new(75);
824 let b = Decimal::from_ratio(100u128, 1u128);
825 let c = Decimal::divide_uint128_by_decimal(a, b).unwrap();
826 assert_eq!(c, Uint128::new(0));
827
828 let a = Uint128::MAX;
830 let b = Decimal::from_ratio(1_u128, 10_u128);
831 let res_error = Decimal::divide_uint128_by_decimal(a, b).unwrap_err();
832 assert_eq!(
833 res_error,
834 ConversionOverflowError::new(
835 "Uint256",
836 "Uint128",
837 "3402823669209384634633746074317682114550"
838 )
839 .into()
840 );
841 }
842
843 #[test]
844 fn test_divide_uint128_by_decimal_and_ceil() {
845 let a = Uint128::new(120u128);
846 let b = Decimal::from_ratio(120u128, 15u128);
847 let c = Decimal::divide_uint128_by_decimal_and_ceil(a, b).unwrap();
848 assert_eq!(c, Uint128::new(15u128));
849
850 let a = Uint128::new(Decimal::DECIMAL_FRACTIONAL.u128());
851 let b = Decimal::from_ratio(Decimal::DECIMAL_FRACTIONAL.u128(), 1u128);
852 let c = Decimal::divide_uint128_by_decimal_and_ceil(a, b).unwrap();
853 assert_eq!(c, Uint128::new(1u128));
854
855 let a = Uint128::new(Decimal::DECIMAL_FRACTIONAL.u128());
856 let b = Decimal::from_ratio(1u128, Decimal::DECIMAL_FRACTIONAL.u128());
857 let c = Decimal::divide_uint128_by_decimal_and_ceil(a, b).unwrap();
858 assert_eq!(c, Uint128::new(Decimal::DECIMAL_FRACTIONAL_SQUARED.u128()));
859
860 let a = Uint128::MAX;
861 let b = Decimal::one();
862 let c = Decimal::divide_uint128_by_decimal_and_ceil(a, b).unwrap();
863 assert_eq!(c, Uint128::MAX);
864
865 let a = Uint128::new(1_000_000_000_000_000_000);
866 let b = Decimal::from_ratio(1u128, Decimal::DECIMAL_FRACTIONAL);
867 let c = Decimal::divide_uint128_by_decimal_and_ceil(a, b).unwrap();
868 assert_eq!(
869 c,
870 Uint128::new(1_000_000_000_000_000_000_000_000_000_000_000_000)
871 );
872
873 let a = Uint128::new(100);
875 let b = Decimal::from_ratio(3u128, 1u128);
876 let c = Decimal::divide_uint128_by_decimal_and_ceil(a, b).unwrap();
877 assert_eq!(c, Uint128::new(34));
878
879 let a = Uint128::new(75);
880 let b = Decimal::from_ratio(100u128, 1u128);
881 let c = Decimal::divide_uint128_by_decimal_and_ceil(a, b).unwrap();
882 assert_eq!(c, Uint128::new(1));
883
884 let a = Uint128::MAX;
886 let b = Decimal::from_ratio(1_u128, 10_u128);
887 let res_error = Decimal::divide_uint128_by_decimal_and_ceil(a, b).unwrap_err();
888 assert_eq!(
889 res_error,
890 ConversionOverflowError::new(
891 "Uint256",
892 "Uint128",
893 "3402823669209384634633746074317682114550"
894 )
895 .into()
896 );
897 }
898
899 #[test]
900 fn decimal_to_std_decimal() {
901 let custom_decimal_1 = Decimal::from_ratio(240u128, 500u128);
902 let std_decimal_1_expected = StdDecimal::from_ratio(240u128, 500u128);
903 assert_eq!(custom_decimal_1.to_std_decimal(), std_decimal_1_expected);
904
905 let custom_decimal_2 = Decimal::from_ratio(333u128, 1000u128);
906 let std_decimal_2_expected = StdDecimal::from_ratio(333u128, 1000u128);
907 assert_eq!(custom_decimal_2.to_std_decimal(), std_decimal_2_expected);
908 }
909
910 #[test]
911 fn decimal_to_string() {
912 assert_eq!(Decimal::zero().to_string(), "0");
914 assert_eq!(Decimal::one().to_string(), "1");
915 assert_eq!(Decimal::percent(500).to_string(), "5");
916
917 assert_eq!(Decimal::percent(125).to_string(), "1.25");
919 assert_eq!(Decimal::percent(42638).to_string(), "426.38");
920 assert_eq!(Decimal::percent(3).to_string(), "0.03");
921 assert_eq!(Decimal::permille(987).to_string(), "0.987");
922
923 assert_eq!(
924 Decimal(Uint128::from(1u128)).to_string(),
925 "0.000000000000000001"
926 );
927 assert_eq!(
928 Decimal(Uint128::from(10u128)).to_string(),
929 "0.00000000000000001"
930 );
931 assert_eq!(
932 Decimal(Uint128::from(100u128)).to_string(),
933 "0.0000000000000001"
934 );
935 assert_eq!(
936 Decimal(Uint128::from(1000u128)).to_string(),
937 "0.000000000000001"
938 );
939 assert_eq!(
940 Decimal(Uint128::from(10000u128)).to_string(),
941 "0.00000000000001"
942 );
943 assert_eq!(
944 Decimal(Uint128::from(100000u128)).to_string(),
945 "0.0000000000001"
946 );
947 assert_eq!(
948 Decimal(Uint128::from(1000000u128)).to_string(),
949 "0.000000000001"
950 );
951 assert_eq!(
952 Decimal(Uint128::from(10000000u128)).to_string(),
953 "0.00000000001"
954 );
955 assert_eq!(
956 Decimal(Uint128::from(100000000u128)).to_string(),
957 "0.0000000001"
958 );
959 assert_eq!(
960 Decimal(Uint128::from(1000000000u128)).to_string(),
961 "0.000000001"
962 );
963 assert_eq!(
964 Decimal(Uint128::from(10000000000u128)).to_string(),
965 "0.00000001"
966 );
967 assert_eq!(
968 Decimal(Uint128::from(100000000000u128)).to_string(),
969 "0.0000001"
970 );
971 assert_eq!(
972 Decimal(Uint128::from(10000000000000u128)).to_string(),
973 "0.00001"
974 );
975 assert_eq!(
976 Decimal(Uint128::from(100000000000000u128)).to_string(),
977 "0.0001"
978 );
979 assert_eq!(
980 Decimal(Uint128::from(1000000000000000u128)).to_string(),
981 "0.001"
982 );
983 assert_eq!(
984 Decimal(Uint128::from(10000000000000000u128)).to_string(),
985 "0.01"
986 );
987 assert_eq!(
988 Decimal(Uint128::from(100000000000000000u128)).to_string(),
989 "0.1"
990 );
991 }
992
993 #[test]
994 fn decimal_serialize() {
995 assert_eq!(to_vec(&Decimal::zero()).unwrap(), br#""0""#);
996 assert_eq!(to_vec(&Decimal::one()).unwrap(), br#""1""#);
997 assert_eq!(to_vec(&Decimal::percent(8)).unwrap(), br#""0.08""#);
998 assert_eq!(to_vec(&Decimal::percent(87)).unwrap(), br#""0.87""#);
999 assert_eq!(to_vec(&Decimal::percent(876)).unwrap(), br#""8.76""#);
1000 assert_eq!(to_vec(&Decimal::percent(8765)).unwrap(), br#""87.65""#);
1001 }
1002
1003 #[test]
1004 fn decimal_deserialize() {
1005 assert_eq!(from_slice::<Decimal>(br#""0""#).unwrap(), Decimal::zero());
1006 assert_eq!(from_slice::<Decimal>(br#""1""#).unwrap(), Decimal::one());
1007 assert_eq!(from_slice::<Decimal>(br#""000""#).unwrap(), Decimal::zero());
1008 assert_eq!(from_slice::<Decimal>(br#""001""#).unwrap(), Decimal::one());
1009
1010 assert_eq!(
1011 from_slice::<Decimal>(br#""0.08""#).unwrap(),
1012 Decimal::percent(8)
1013 );
1014 assert_eq!(
1015 from_slice::<Decimal>(br#""0.87""#).unwrap(),
1016 Decimal::percent(87)
1017 );
1018 assert_eq!(
1019 from_slice::<Decimal>(br#""8.76""#).unwrap(),
1020 Decimal::percent(876)
1021 );
1022 assert_eq!(
1023 from_slice::<Decimal>(br#""87.65""#).unwrap(),
1024 Decimal::percent(8765)
1025 );
1026 }
1027
1028 #[test]
1029 fn std_decimal_compatibility() {
1030 assert_eq!(
1032 from_slice::<Decimal>(&to_vec(&StdDecimal::zero()).unwrap()).unwrap(),
1033 Decimal::zero()
1034 );
1035 assert_eq!(
1036 from_slice::<Decimal>(&to_vec(&StdDecimal::percent(8)).unwrap()).unwrap(),
1037 Decimal::percent(8)
1038 );
1039 assert_eq!(
1040 from_slice::<Decimal>(&to_vec(&StdDecimal::percent(87)).unwrap()).unwrap(),
1041 Decimal::percent(87)
1042 );
1043 assert_eq!(
1044 from_slice::<Decimal>(&to_vec(&StdDecimal::percent(876)).unwrap()).unwrap(),
1045 Decimal::percent(876)
1046 );
1047 assert_eq!(
1048 from_slice::<Decimal>(&to_vec(&StdDecimal::percent(8765)).unwrap()).unwrap(),
1049 Decimal::percent(8765)
1050 );
1051 assert_eq!(
1052 from_slice::<Decimal>(
1053 &to_vec(&StdDecimal::from_ratio(3423423424000000_u128, 223_u128)).unwrap()
1054 )
1055 .unwrap(),
1056 Decimal::from_ratio(3423423424000000_u128, 223_u128)
1057 );
1058 assert_eq!(
1059 from_slice::<Decimal>(
1060 &to_vec(&StdDecimal::from_ratio(
1061 123_u128,
1062 3424234234823842093840923848098409238_u128
1063 ))
1064 .unwrap()
1065 )
1066 .unwrap(),
1067 Decimal::from_ratio(123_u128, 3424234234823842093840923848098409238_u128)
1068 );
1069
1070 assert_eq!(
1072 from_slice::<StdDecimal>(&to_vec(&Decimal::zero()).unwrap()).unwrap(),
1073 StdDecimal::zero()
1074 );
1075 assert_eq!(
1076 from_slice::<StdDecimal>(&to_vec(&Decimal::percent(8)).unwrap()).unwrap(),
1077 StdDecimal::percent(8)
1078 );
1079 assert_eq!(
1080 from_slice::<StdDecimal>(&to_vec(&Decimal::percent(87)).unwrap()).unwrap(),
1081 StdDecimal::percent(87)
1082 );
1083 assert_eq!(
1084 from_slice::<StdDecimal>(&to_vec(&Decimal::percent(876)).unwrap()).unwrap(),
1085 StdDecimal::percent(876)
1086 );
1087 assert_eq!(
1088 from_slice::<StdDecimal>(&to_vec(&Decimal::percent(8765)).unwrap()).unwrap(),
1089 StdDecimal::percent(8765)
1090 );
1091 assert_eq!(
1092 from_slice::<StdDecimal>(
1093 &to_vec(&Decimal::from_ratio(3423423424000000_u128, 223_u128)).unwrap()
1094 )
1095 .unwrap(),
1096 StdDecimal::from_ratio(3423423424000000_u128, 223_u128)
1097 );
1098 assert_eq!(
1099 from_slice::<StdDecimal>(
1100 &to_vec(&Decimal::from_ratio(
1101 123_u128,
1102 3424234234823842093840923848098409238_u128
1103 ))
1104 .unwrap()
1105 )
1106 .unwrap(),
1107 StdDecimal::from_ratio(123_u128, 3424234234823842093840923848098409238_u128)
1108 );
1109 }
1110}