math.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::{build_solidity, BorshToken};
  3. use num_bigint::BigInt;
  4. use std::str::FromStr;
  5. #[test]
  6. fn safe_math() {
  7. let mut vm = build_solidity(
  8. r#"
  9. library SafeMath {
  10. function add(uint x, uint y) internal pure returns (uint z) {
  11. require((z = x + y) >= x, 'ds-math-add-overflow');
  12. }
  13. function sub(uint x, uint y) internal pure returns (uint z) {
  14. require((z = x - y) <= x, 'ds-math-sub-underflow');
  15. }
  16. function mul(uint x, uint y) internal pure returns (uint z) {
  17. require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
  18. }
  19. }
  20. contract math {
  21. using SafeMath for uint;
  22. function mul_test(uint a, uint b) public returns (uint) {
  23. return a.mul(b);
  24. }
  25. function add_test(uint a, uint b) public returns (uint) {
  26. return a.add(b);
  27. }
  28. function sub_test(uint a, uint b) public returns (uint) {
  29. return a.sub(b);
  30. }
  31. }"#,
  32. );
  33. let data_account = vm.initialize_data_account();
  34. vm.function("new")
  35. .accounts(vec![("dataAccount", data_account)])
  36. .call();
  37. let returns = vm
  38. .function("mul_test")
  39. .arguments(&[
  40. BorshToken::Uint {
  41. width: 256,
  42. value: BigInt::from_str("1000000000000000000").unwrap(),
  43. },
  44. BorshToken::Uint {
  45. width: 256,
  46. value: BigInt::from_str("4000000000000000000").unwrap(),
  47. },
  48. ])
  49. .accounts(vec![("dataAccount", data_account)])
  50. .call()
  51. .unwrap();
  52. assert_eq!(
  53. returns,
  54. BorshToken::Uint {
  55. width: 256,
  56. value: BigInt::from_str("4000000000000000000000000000000000000").unwrap(),
  57. },
  58. );
  59. let returns = vm
  60. .function("add_test")
  61. .arguments(&[
  62. BorshToken::Uint {
  63. width: 256,
  64. value: BigInt::from_str("1000000000000000000").unwrap(),
  65. },
  66. BorshToken::Uint {
  67. width: 256,
  68. value: BigInt::from_str("4000000000000000000").unwrap(),
  69. },
  70. ])
  71. .accounts(vec![("dataAccount", data_account)])
  72. .call()
  73. .unwrap();
  74. assert_eq!(
  75. returns,
  76. BorshToken::Uint {
  77. width: 256,
  78. value: BigInt::from_str("5000000000000000000").unwrap(),
  79. },
  80. );
  81. let returns = vm
  82. .function("sub_test")
  83. .arguments(&[
  84. BorshToken::Uint {
  85. width: 256,
  86. value: BigInt::from_str("4000000000000000000").unwrap(),
  87. },
  88. BorshToken::Uint {
  89. width: 256,
  90. value: BigInt::from_str("1000000000000000000").unwrap(),
  91. },
  92. ])
  93. .accounts(vec![("dataAccount", data_account)])
  94. .call()
  95. .unwrap();
  96. assert_eq!(
  97. returns,
  98. BorshToken::Uint {
  99. width: 256,
  100. value: BigInt::from_str("3000000000000000000").unwrap(),
  101. },
  102. );
  103. vm.function("mul_test")
  104. .arguments(&[
  105. BorshToken::Uint {
  106. width: 256,
  107. value: BigInt::from_str("400000000000000000000000000000000000000").unwrap(),
  108. },
  109. BorshToken::Uint {
  110. width: 256,
  111. value: BigInt::from_str("400000000000000000000000000000000000000").unwrap(),
  112. },
  113. ])
  114. .accounts(vec![("dataAccount", data_account)])
  115. .must_fail();
  116. vm.function(
  117. "add_test")
  118. .arguments(
  119. &[
  120. BorshToken::Uint {
  121. width: 256,
  122. value: BigInt::from_str("100000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(),
  123. },
  124. BorshToken::Uint {
  125. width: 256,
  126. value: BigInt::from_str("100000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(),
  127. },
  128. ],
  129. )
  130. .accounts(vec![("dataAccount", data_account)])
  131. .must_fail();
  132. vm.function("sub_test")
  133. .arguments(&[
  134. BorshToken::Uint {
  135. width: 256,
  136. value: BigInt::from_str("1000000000000000000").unwrap(),
  137. },
  138. BorshToken::Uint {
  139. width: 256,
  140. value: BigInt::from_str("4000000000000000000").unwrap(),
  141. },
  142. ])
  143. .accounts(vec![("dataAccount", data_account)])
  144. .must_fail();
  145. }