@coti-io/coti-contracts 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/.github/workflows/npm-publish.yml +18 -14
  2. package/README.md +3 -1
  3. package/contracts/disperse/coinByRatio/FixedRatioCoinDisperser.sol +452 -0
  4. package/contracts/disperse/coinByRatio/FixedRatioCoinDisperserLeftoverS1.sol +490 -0
  5. package/contracts/disperse/coinByRatio/FixedRatioCoinDisperserUnlimitedWindow.sol +432 -0
  6. package/contracts/disperse/disperseToken/MintDisperser.sol +120 -0
  7. package/contracts/disperse/disperseToken/TokenDisperser.sol +139 -0
  8. package/contracts/mocks/token/ERC20Mock.sol +19 -0
  9. package/contracts/mocks/token/PrivateERC20/EncryptedTokenReceiverMock.sol +18 -0
  10. package/contracts/mocks/token/PrivateERC20/PrivacyBridgeERC20Mock.sol +13 -0
  11. package/contracts/mocks/token/PrivateERC20/PrivateERC20AuditorSupplyMock.sol +44 -0
  12. package/contracts/mocks/token/PrivateERC20/PrivateERC20CappedMock.sol +23 -0
  13. package/contracts/mocks/token/PrivateERC20/PrivateERC20GtCallerMock.sol +29 -0
  14. package/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.sol +9 -4
  15. package/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol +39 -0
  16. package/contracts/mocks/token/PrivateERC20/PublicReentrantTokenReceiverMock.sol +29 -0
  17. package/contracts/mocks/token/PrivateERC20/PublicTokenReceiverBoolMock.sol +18 -0
  18. package/contracts/mocks/token/PrivateERC20/PublicTokenReceiverMock.sol +12 -0
  19. package/contracts/mocks/utils/mpc/Arithmetic128TestsContract.sol +123 -0
  20. package/contracts/mocks/utils/mpc/Arithmetic256TestsContract.sol +122 -0
  21. package/contracts/mocks/utils/mpc/Bitwise128TestsContract.sol +65 -0
  22. package/contracts/mocks/utils/mpc/Bitwise256TestsContract.sol +65 -0
  23. package/contracts/mocks/utils/mpc/CheckedArithmetic128WithOverflowBitTestsContract.sol +64 -0
  24. package/contracts/mocks/utils/mpc/CheckedArithmetic256WithOverflowBitTestsContract.sol +64 -0
  25. package/contracts/mocks/utils/mpc/Comparison128TestsContract.sol +98 -0
  26. package/contracts/mocks/utils/mpc/Comparison256TestsContract.sol +98 -0
  27. package/contracts/mocks/utils/mpc/MinMax128TestsContract.sol +44 -0
  28. package/contracts/mocks/utils/mpc/MinMax256TestsContract.sol +44 -0
  29. package/contracts/mocks/utils/mpc/MinimalImplementation.sol +55 -0
  30. package/contracts/mocks/utils/mpc/MinimalProxy.sol +27 -0
  31. package/contracts/mocks/utils/mpc/MpcOperations128TestContract.sol +267 -0
  32. package/contracts/mocks/utils/mpc/MpcOperationsTestContract.sol +334 -0
  33. package/contracts/mocks/utils/mpc/Mux128TestsContract.sol +24 -0
  34. package/contracts/mocks/utils/mpc/Mux256TestsContract.sol +24 -0
  35. package/contracts/mocks/utils/mpc/OnBoard128TestsContract.sol +93 -0
  36. package/contracts/mocks/utils/mpc/OnBoard256TestsContract.sol +116 -0
  37. package/contracts/mocks/utils/mpc/PrivacyImplementationV1.sol +157 -0
  38. package/contracts/mocks/utils/mpc/PrivacyImplementationV2.sol +133 -0
  39. package/contracts/mocks/utils/mpc/PrivacyProxy.sol +137 -0
  40. package/contracts/mocks/utils/mpc/Random128TestsContract.sol +32 -0
  41. package/contracts/mocks/utils/mpc/Random256TestsContract.sol +32 -0
  42. package/contracts/mocks/utils/mpc/Shift128TestsContract.sol +36 -0
  43. package/contracts/mocks/utils/mpc/Shift256TestsContract.sol +36 -0
  44. package/contracts/mocks/utils/mpc/Transfer128TestsContract.sol +29 -0
  45. package/contracts/mocks/utils/mpc/Transfer256TestsContract.sol +29 -0
  46. package/contracts/mocks/utils/mpc/TransferWithAllowance128TestsContract.sol +32 -0
  47. package/contracts/mocks/utils/mpc/TransferWithAllowance256TestsContract.sol +32 -0
  48. package/contracts/mocks/utils/mpc/ValidateCiphertext128TestsContract.sol +59 -0
  49. package/contracts/mocks/utils/mpc/ValidateCiphertext256TestsContract.sol +63 -0
  50. package/contracts/mocks/utils/mpc/ValidateCiphertextTestsContract.sol +99 -0
  51. package/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.sol +7 -6
  52. package/contracts/node/CotiNodeRewards.sol +199 -0
  53. package/contracts/node/SoulboundNodeNFT.sol +519 -0
  54. package/contracts/privacyBridge/PrivacyBridge.sol +318 -0
  55. package/contracts/privacyBridge/PrivacyBridgeCotiNative.sol +268 -0
  56. package/contracts/privacyBridge/PrivacyBridgeERC20.sol +251 -0
  57. package/contracts/privacyBridge/PrivacyBridgeUSDCe.sol +16 -0
  58. package/contracts/privacyBridge/PrivacyBridgeUSDT.sol +17 -0
  59. package/contracts/privacyBridge/PrivacyBridgeWADA.sol +17 -0
  60. package/contracts/privacyBridge/PrivacyBridgeWBTC.sol +17 -0
  61. package/contracts/privacyBridge/PrivacyBridgeWETH.sol +17 -0
  62. package/contracts/privacyBridge/PrivacyBridgegCoti.sol +17 -0
  63. package/contracts/token/PrivateERC20/IPrivateERC20.sol +273 -40
  64. package/contracts/token/PrivateERC20/ITokenReceiver.sol +17 -0
  65. package/contracts/token/PrivateERC20/ITokenReceiverEncrypted.sol +20 -0
  66. package/contracts/token/PrivateERC20/PrivateERC20.sol +861 -152
  67. package/contracts/token/PrivateERC20/tokens/PrivateBridgedUSDC.sol +17 -0
  68. package/contracts/token/PrivateERC20/tokens/PrivateCOTI.sol +13 -0
  69. package/contracts/token/PrivateERC20/tokens/PrivateCOTITreasuryGovernanceToken.sol +17 -0
  70. package/contracts/token/PrivateERC20/tokens/PrivateTetherUSD.sol +17 -0
  71. package/contracts/token/PrivateERC20/tokens/PrivateWrappedADA.sol +17 -0
  72. package/contracts/token/PrivateERC20/tokens/PrivateWrappedBTC.sol +17 -0
  73. package/contracts/token/PrivateERC20/tokens/PrivateWrappedEther.sol +13 -0
  74. package/contracts/utils/mpc/MpcCore.sol +10780 -4962
  75. package/contracts/utils/mpc/MpcInterface.sol +7 -2
  76. package/hardhat/gasPriceBump.ts +60 -0
  77. package/hardhat.config.ts +60 -12
  78. package/package.json +21 -3
  79. package/scripts/deploySoulboundNodeNFT.ts +57 -0
  80. package/test/token/PrivateERC20/PrivacyBridge.fees.test.ts +327 -0
  81. package/test/token/PrivateERC20/PrivateERC20.test.ts +1109 -268
  82. package/test/utils/mpc/Bitwise128.test.ts +92 -0
  83. package/test/utils/mpc/Bitwise256.test.ts +101 -0
  84. package/test/utils/mpc/BuildInputText128.test.ts +398 -0
  85. package/test/utils/mpc/CheckedArithmetic128.test.ts +45 -0
  86. package/test/utils/mpc/CheckedArithmetic256.test.ts +45 -0
  87. package/test/utils/mpc/Comparison128.test.ts +48 -0
  88. package/test/utils/mpc/Comparison256.test.ts +48 -0
  89. package/test/utils/mpc/InvalidCiphertext.test.ts +179 -0
  90. package/test/utils/mpc/InvalidCiphertext128.test.ts +179 -0
  91. package/test/utils/mpc/InvalidCiphertext256.test.ts +201 -0
  92. package/test/utils/mpc/InvalidTransfer128.test.ts +166 -0
  93. package/test/utils/mpc/InvalidTransfer256.test.ts +158 -0
  94. package/test/utils/mpc/MinMax128.test.ts +44 -0
  95. package/test/utils/mpc/MinMax256.test.ts +44 -0
  96. package/test/utils/mpc/MinimalProxyDemo.test.ts +280 -0
  97. package/test/utils/mpc/MpcOperations.test.ts +589 -0
  98. package/test/utils/mpc/MpcOperations128.test.ts +632 -0
  99. package/test/utils/mpc/Mux128.test.ts +41 -0
  100. package/test/utils/mpc/Mux256.test.ts +41 -0
  101. package/test/utils/mpc/NegativeCases.test.ts +478 -0
  102. package/test/utils/mpc/NegativeCases128.test.ts +237 -0
  103. package/test/utils/mpc/NegativeCases256.test.ts +236 -0
  104. package/test/utils/mpc/OnBoard128.test.ts +90 -0
  105. package/test/utils/mpc/OnBoard256.test.ts +114 -0
  106. package/test/utils/mpc/Precompile128.test.ts +51 -0
  107. package/test/utils/mpc/Precompile256.test.ts +115 -0
  108. package/test/utils/mpc/ProxyValidation.test.ts +199 -0
  109. package/test/utils/mpc/Random128.test.ts +47 -0
  110. package/test/utils/mpc/Random256.test.ts +47 -0
  111. package/test/utils/mpc/Shift128.test.ts +41 -0
  112. package/test/utils/mpc/Shift256.test.ts +41 -0
  113. package/test/utils/mpc/Transfer128.test.ts +46 -0
  114. package/test/utils/mpc/Transfer256.test.ts +46 -0
  115. package/test/utils/mpc/TransferWithAllowance128.test.ts +48 -0
  116. package/test/utils/mpc/TransferWithAllowance256.test.ts +48 -0
  117. package/test/utils/mpc/UpgradeablePrivacyProxy.test.ts +307 -0
  118. package/test/utils/mpc/ValidateCiphertext.test.ts +221 -0
  119. package/test/utils/mpc/ValidateCiphertext256.test.ts +161 -0
  120. package/test/utils/mpc/ValidateCiphertext256Decryption.test.ts +383 -0
  121. package/test/utils/mpc/WalletEncryptionFailures.test.ts +494 -0
  122. package/test/utils/privateErc20Helpers.ts +97 -0
  123. package/typechain-types/@openzeppelin/contracts/access/Ownable.ts +153 -0
  124. package/typechain-types/@openzeppelin/contracts/access/index.ts +4 -0
  125. package/typechain-types/@openzeppelin/contracts/index.ts +2 -0
  126. package/typechain-types/@openzeppelin/contracts/token/ERC20/IERC20.ts +262 -0
  127. package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.ts +143 -0
  128. package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/index.ts +4 -0
  129. package/typechain-types/@openzeppelin/contracts/token/ERC20/index.ts +6 -0
  130. package/typechain-types/@openzeppelin/contracts/token/index.ts +2 -0
  131. package/typechain-types/contracts/disperse/coinByRatio/FixedRatioCoinDisperser.ts +679 -0
  132. package/typechain-types/contracts/disperse/coinByRatio/index.ts +4 -0
  133. package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/IMintableERC20.ts +97 -0
  134. package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/MintDisperser.ts +206 -0
  135. package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/index.ts +5 -0
  136. package/typechain-types/contracts/disperse/disperseToken/TokenDisperser.ts +191 -0
  137. package/typechain-types/contracts/disperse/disperseToken/index.ts +6 -0
  138. package/typechain-types/contracts/disperse/index.ts +7 -0
  139. package/typechain-types/contracts/index.ts +2 -0
  140. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.ts +77 -60
  141. package/typechain-types/contracts/mocks/utils/mpc/Arithmetic128TestsContract.ts +311 -0
  142. package/typechain-types/contracts/mocks/utils/mpc/Arithmetic256TestsContract.ts +311 -0
  143. package/typechain-types/contracts/mocks/utils/mpc/Bitwise128TestsContract.ts +179 -0
  144. package/typechain-types/contracts/mocks/utils/mpc/Bitwise256TestsContract.ts +179 -0
  145. package/typechain-types/contracts/mocks/utils/mpc/CheckedArithmetic128WithOverflowBitTestsContract.ts +206 -0
  146. package/typechain-types/contracts/mocks/utils/mpc/CheckedArithmetic256WithOverflowBitTestsContract.ts +206 -0
  147. package/typechain-types/contracts/mocks/utils/mpc/Comparison128TestsContract.ts +278 -0
  148. package/typechain-types/contracts/mocks/utils/mpc/Comparison256TestsContract.ts +278 -0
  149. package/typechain-types/contracts/mocks/utils/mpc/MinMax128TestsContract.ts +142 -0
  150. package/typechain-types/contracts/mocks/utils/mpc/MinMax256TestsContract.ts +142 -0
  151. package/typechain-types/contracts/mocks/utils/mpc/MinimalImplementation.ts +259 -0
  152. package/typechain-types/contracts/mocks/utils/mpc/MinimalProxy.ts +90 -0
  153. package/typechain-types/contracts/mocks/utils/mpc/MpcOperations128TestContract.ts +388 -0
  154. package/typechain-types/contracts/mocks/utils/mpc/MpcOperationsTestContract.ts +455 -0
  155. package/typechain-types/contracts/mocks/utils/mpc/Mux128TestsContract.ts +109 -0
  156. package/typechain-types/contracts/mocks/utils/mpc/Mux256TestsContract.ts +109 -0
  157. package/typechain-types/contracts/mocks/utils/mpc/OnBoard128TestsContract.ts +166 -0
  158. package/typechain-types/contracts/mocks/utils/mpc/OnBoard256TestsContract.ts +194 -0
  159. package/typechain-types/contracts/mocks/utils/mpc/PrivacyImplementationV1.ts +385 -0
  160. package/typechain-types/contracts/mocks/utils/mpc/PrivacyImplementationV2.ts +441 -0
  161. package/typechain-types/contracts/mocks/utils/mpc/PrivacyProxy.ts +201 -0
  162. package/typechain-types/contracts/mocks/utils/mpc/Random128TestsContract.ts +131 -0
  163. package/typechain-types/contracts/mocks/utils/mpc/Random256TestsContract.ts +131 -0
  164. package/typechain-types/contracts/mocks/utils/mpc/Shift128TestsContract.ts +142 -0
  165. package/typechain-types/contracts/mocks/utils/mpc/Shift256TestsContract.ts +142 -0
  166. package/typechain-types/contracts/mocks/utils/mpc/Transfer128TestsContract.ts +109 -0
  167. package/typechain-types/contracts/mocks/utils/mpc/Transfer256TestsContract.ts +109 -0
  168. package/typechain-types/contracts/mocks/utils/mpc/TransferWithAllowance128TestsContract.ts +128 -0
  169. package/typechain-types/contracts/mocks/utils/mpc/TransferWithAllowance256TestsContract.ts +128 -0
  170. package/typechain-types/contracts/mocks/utils/mpc/ValidateCiphertext128TestsContract.ts +198 -0
  171. package/typechain-types/contracts/mocks/utils/mpc/ValidateCiphertext256TestsContract.ts +182 -0
  172. package/typechain-types/contracts/mocks/utils/mpc/ValidateCiphertextTestsContract.ts +257 -0
  173. package/typechain-types/contracts/mocks/utils/mpc/index.ts +32 -8
  174. package/typechain-types/contracts/token/PrivateERC20/IPrivateERC20.ts +77 -60
  175. package/typechain-types/contracts/token/PrivateERC20/PrivateERC20.ts +77 -60
  176. package/typechain-types/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations.ts +111 -10
  177. package/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.ts +74 -0
  178. package/typechain-types/factories/@openzeppelin/contracts/access/index.ts +4 -0
  179. package/typechain-types/factories/@openzeppelin/contracts/index.ts +1 -0
  180. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/IERC20__factory.ts +205 -0
  181. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit__factory.ts +100 -0
  182. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/index.ts +4 -0
  183. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/index.ts +5 -0
  184. package/typechain-types/factories/@openzeppelin/contracts/token/index.ts +1 -0
  185. package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperser__factory.ts +759 -0
  186. package/typechain-types/factories/contracts/disperse/coinByRatio/index.ts +4 -0
  187. package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/IMintableERC20__factory.ts +43 -0
  188. package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/MintDisperser__factory.ts +185 -0
  189. package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/index.ts +5 -0
  190. package/typechain-types/factories/contracts/disperse/disperseToken/TokenDisperser__factory.ts +198 -0
  191. package/typechain-types/factories/contracts/disperse/disperseToken/index.ts +5 -0
  192. package/typechain-types/factories/contracts/disperse/index.ts +5 -0
  193. package/typechain-types/factories/contracts/index.ts +1 -0
  194. package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock__factory.ts +1 -1
  195. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20Mock__factory.ts +179 -47
  196. package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic128TestsContract__factory.ts +330 -0
  197. package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic256TestsContract__factory.ts +330 -0
  198. package/typechain-types/factories/contracts/mocks/utils/mpc/ArithmeticTestsContract__factory.ts +1 -1
  199. package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise128TestsContract__factory.ts +184 -0
  200. package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise256TestsContract__factory.ts +184 -0
  201. package/typechain-types/factories/contracts/mocks/utils/mpc/BitwiseTestsContract__factory.ts +1 -1
  202. package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmetic128WithOverflowBitTestsContract__factory.ts +203 -0
  203. package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmetic256WithOverflowBitTestsContract__factory.ts +203 -0
  204. package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmeticWIthOverflowBitTestsContract.sol/CheckedArithmeticWithOverflowBitTestsContract__factory.ts +1 -1
  205. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison128TestsContract__factory.ts +295 -0
  206. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison1TestsContract__factory.ts +1 -1
  207. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison256TestsContract__factory.ts +295 -0
  208. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison2TestsContract__factory.ts +1 -1
  209. package/typechain-types/factories/contracts/mocks/utils/mpc/MinMax128TestsContract__factory.ts +147 -0
  210. package/typechain-types/factories/contracts/mocks/utils/mpc/MinMax256TestsContract__factory.ts +147 -0
  211. package/typechain-types/factories/contracts/mocks/utils/mpc/MinMaxTestsContract__factory.ts +1 -1
  212. package/typechain-types/factories/contracts/mocks/utils/mpc/MinimalImplementation__factory.ts +263 -0
  213. package/typechain-types/factories/contracts/mocks/utils/mpc/MinimalProxy__factory.ts +104 -0
  214. package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous1TestsContract__factory.ts +1 -1
  215. package/typechain-types/factories/contracts/mocks/utils/mpc/MiscellaneousTestsContract__factory.ts +1 -1
  216. package/typechain-types/factories/contracts/mocks/utils/mpc/MpcOperations128TestContract__factory.ts +723 -0
  217. package/typechain-types/factories/contracts/mocks/utils/mpc/MpcOperationsTestContract__factory.ts +1410 -0
  218. package/typechain-types/factories/contracts/mocks/utils/mpc/Mux128TestsContract__factory.ts +115 -0
  219. package/typechain-types/factories/contracts/mocks/utils/mpc/Mux256TestsContract__factory.ts +115 -0
  220. package/typechain-types/factories/contracts/mocks/utils/mpc/OffboardToUserKeyTestContract__factory.ts +1 -1
  221. package/typechain-types/factories/contracts/mocks/utils/mpc/OnBoard128TestsContract__factory.ts +175 -0
  222. package/typechain-types/factories/contracts/mocks/utils/mpc/OnBoard256TestsContract__factory.ts +205 -0
  223. package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyImplementationV1__factory.ts +521 -0
  224. package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyImplementationV2__factory.ts +648 -0
  225. package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyProxy__factory.ts +179 -0
  226. package/typechain-types/factories/contracts/mocks/utils/mpc/Random128TestsContract__factory.ts +131 -0
  227. package/typechain-types/factories/contracts/mocks/utils/mpc/Random256TestsContract__factory.ts +131 -0
  228. package/typechain-types/factories/contracts/mocks/utils/mpc/Shift128TestsContract__factory.ts +147 -0
  229. package/typechain-types/factories/contracts/mocks/utils/mpc/Shift256TestsContract__factory.ts +147 -0
  230. package/typechain-types/factories/contracts/mocks/utils/mpc/ShiftTestsContract__factory.ts +1 -1
  231. package/typechain-types/factories/contracts/mocks/utils/mpc/StringTestsContract__factory.ts +1 -1
  232. package/typechain-types/factories/contracts/mocks/utils/mpc/Transfer128TestsContract__factory.ts +135 -0
  233. package/typechain-types/factories/contracts/mocks/utils/mpc/Transfer256TestsContract__factory.ts +135 -0
  234. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferScalarTestsContract__factory.ts +1 -1
  235. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferTestsContract__factory.ts +1 -1
  236. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance128TestsContract__factory.ts +154 -0
  237. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance256TestsContract__factory.ts +154 -0
  238. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_16TestsContract__factory.ts +1 -1
  239. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_32TestsContract__factory.ts +1 -1
  240. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_64TestsContract__factory.ts +1 -1
  241. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_8TestsContract__factory.ts +1 -1
  242. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowanceScalarTestsContract__factory.ts +1 -1
  243. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowanceTestsContract__factory.ts +1 -1
  244. package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertext128TestsContract__factory.ts +190 -0
  245. package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertext256TestsContract__factory.ts +210 -0
  246. package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertextTestsContract__factory.ts +260 -0
  247. package/typechain-types/factories/contracts/mocks/utils/mpc/index.ts +32 -8
  248. package/typechain-types/factories/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock__factory.ts +7 -7
  249. package/typechain-types/factories/contracts/token/PrivateERC20/IPrivateERC20__factory.ts +174 -42
  250. package/typechain-types/factories/contracts/token/PrivateERC20/PrivateERC20__factory.ts +174 -42
  251. package/typechain-types/factories/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations__factory.ts +126 -0
  252. package/typechain-types/hardhat.d.ts +638 -80
  253. package/typechain-types/index.ts +78 -16
  254. package/contracts/mocks/utils/mpc/Arithmetic128BitTestsContract.sol +0 -260
  255. package/contracts/mocks/utils/mpc/Arithmetic256BitTestsContract.sol +0 -264
  256. package/contracts/mocks/utils/mpc/Bitwise128BitTestsContract.sol +0 -91
  257. package/contracts/mocks/utils/mpc/Bitwise256BitTestsContract.sol +0 -91
  258. package/contracts/mocks/utils/mpc/Comparison128BitTestsContract.sol +0 -158
  259. package/contracts/mocks/utils/mpc/Comparison256BitTestsContract.sol +0 -158
  260. package/contracts/mocks/utils/mpc/Miscellaneous128BitTestsContract.sol +0 -185
  261. package/contracts/mocks/utils/mpc/Miscellaneous256BitTestsContract.sol +0 -190
  262. package/contracts/mocks/utils/mpc/README.md +0 -486
  263. package/test/utils/mpc/Unsigned128BitIntegers.test.ts +0 -945
  264. package/test/utils/mpc/Unsigned256BitIntegers.test.ts +0 -1124
  265. package/test/utils/mpc/helpers.ts +0 -77
@@ -0,0 +1,494 @@
1
+ import hre from "hardhat"
2
+ import { expect } from "chai"
3
+ import { setupAccounts } from "../accounts"
4
+ import { Wallet, ctUint, ctUint256 } from "@coti-io/coti-ethers"
5
+ import { ValidateCiphertext128TestsContract } from "../../../typechain-types"
6
+ import { MpcOperationsTestContract } from "../../../typechain-types"
7
+
8
+ const GAS_LIMIT = 12000000
9
+
10
+ async function deploy128Contract() {
11
+ const [owner] = await setupAccounts()
12
+ const contractFactory = await hre.ethers.getContractFactory("ValidateCiphertext128TestsContract", owner as any)
13
+ const contract = await contractFactory.deploy({ gasLimit: GAS_LIMIT })
14
+ await contract.waitForDeployment()
15
+ return {
16
+ contract,
17
+ contractAddress: await contract.getAddress(),
18
+ owner
19
+ }
20
+ }
21
+
22
+ async function deploy256Contract() {
23
+ const [owner] = await setupAccounts()
24
+ const contractFactory = await hre.ethers.getContractFactory("MpcOperationsTestContract", owner as any)
25
+ const contract = await contractFactory.deploy({ gasLimit: GAS_LIMIT })
26
+ await contract.waitForDeployment()
27
+ return {
28
+ contract,
29
+ contractAddress: await contract.getAddress(),
30
+ owner
31
+ }
32
+ }
33
+
34
+ describe("Wallet Encryption/Decryption Failure Tests with Contract Integration", function () {
35
+ this.timeout(300000) // 5 minutes timeout
36
+ let contract128: ValidateCiphertext128TestsContract
37
+ let contract128Address: string
38
+ let contract256: MpcOperationsTestContract
39
+ let contract256Address: string
40
+ let owner: Wallet
41
+ let walletWithoutAes: Wallet
42
+ let walletWithAutoOnboardOff: Wallet
43
+
44
+ before(async function () {
45
+ // Deploy contracts
46
+ const deployment128 = await deploy128Contract()
47
+ contract128 = deployment128.contract
48
+ contract128Address = deployment128.contractAddress
49
+ owner = deployment128.owner
50
+
51
+ const deployment256 = await deploy256Contract()
52
+ contract256 = deployment256.contract
53
+ contract256Address = deployment256.contractAddress
54
+
55
+ // Get network info and provider from owner's provider
56
+ const networkName = hre.network.name
57
+ const provider = owner.provider as any
58
+
59
+ // Create wallet without AES key (auto-onboard enabled)
60
+ const randomWallet = Wallet.createRandom(provider)
61
+ walletWithoutAes = new Wallet(randomWallet.privateKey, provider)
62
+ // Don't onboard - leave AES key undefined
63
+
64
+ // Create wallet with auto-onboard disabled
65
+ const randomWallet2 = Wallet.createRandom(provider)
66
+ walletWithAutoOnboardOff = new Wallet(randomWallet2.privateKey, provider)
67
+ walletWithAutoOnboardOff.disableAutoOnboard()
68
+ // Don't set AES key
69
+
70
+ const onboardInfo = owner.getUserOnboardInfo()
71
+ if (!onboardInfo || !onboardInfo.aesKey) {
72
+ throw new Error("User AES key not found. Please onboard the user first.")
73
+ }
74
+
75
+ console.log("\n" + "=".repeat(80))
76
+ console.log("🧪 WALLET ENCRYPTION/DECRYPTION FAILURE TESTS")
77
+ console.log("=".repeat(80))
78
+ console.log(`Network: ${networkName}`)
79
+ console.log(`128-bit Contract: ${contract128Address}`)
80
+ console.log(`256-bit Contract: ${contract256Address}`)
81
+ console.log(`Owner Address: ${owner.address}`)
82
+ console.log(`Wallet Without AES: ${walletWithoutAes.address}`)
83
+ console.log(`Wallet Auto-Onboard Off: ${walletWithAutoOnboardOff.address}`)
84
+ console.log("=".repeat(80) + "\n")
85
+ })
86
+
87
+ describe("encryptValue Failure Scenarios with Contract Integration", function () {
88
+ it("Should fail when encrypting 129-bit value (exceeds 128-bit limit)", async function () {
89
+ // 129-bit value (2^128)
90
+ const value129Bits = 2n ** 128n
91
+ const functionSelector = contract128.validateAndReturn.fragment.selector
92
+
93
+ await expect(
94
+ owner.encryptValue(value129Bits, contract128Address, functionSelector)
95
+ ).to.be.rejectedWith("encryptValue: values larger than 128 bits are not supported")
96
+ })
97
+
98
+ it("Should fail when encrypting 256-bit value with encryptValue", async function () {
99
+ // 256-bit value
100
+ const value256Bits = 2n ** 255n
101
+ const functionSelector = contract128.validateAndReturn.fragment.selector
102
+
103
+ await expect(
104
+ owner.encryptValue(value256Bits, contract128Address, functionSelector)
105
+ ).to.be.rejectedWith("encryptValue: values larger than 128 bits are not supported")
106
+ })
107
+
108
+ it("Should succeed with 128-bit value and complete full cycle", async function () {
109
+ // Maximum 128-bit value (2^128 - 1)
110
+ const max128Bits = 2n ** 128n - 1n
111
+ const functionSelector = contract128.validateAndReturn.fragment.selector
112
+
113
+ console.log(`\n✅ Testing 128-bit encryption/decryption full cycle`)
114
+ console.log(` Value: ${max128Bits.toString()}`)
115
+
116
+ // Encrypt
117
+ const encrypted = await owner.encryptValue(max128Bits, contract128Address, functionSelector) as any
118
+ expect(encrypted).to.have.property("ciphertext")
119
+ expect(encrypted).to.have.property("signature")
120
+ console.log(` ✅ Encrypted successfully`)
121
+
122
+ // Call contract
123
+ const tx = await contract128.validateAndReturn(encrypted, { gasLimit: GAS_LIMIT })
124
+ const receipt = await tx.wait()
125
+ expect(receipt?.status).to.equal(1)
126
+ console.log(` ✅ Contract call successful`)
127
+
128
+ // Get result from event
129
+ const resultEvent = receipt?.logs.find((log: any) => {
130
+ try {
131
+ return contract128.interface.parseLog(log)?.name === "ValueOffBoarded128"
132
+ } catch {
133
+ return false
134
+ }
135
+ })
136
+
137
+ expect(resultEvent).to.not.be.undefined
138
+ const parsedLog = contract128.interface.parseLog(resultEvent!)
139
+ const ctResult: ctUint = parsedLog?.args.result
140
+
141
+ // Decrypt
142
+ const decrypted = await owner.decryptValue(ctResult)
143
+ expect(decrypted).to.equal(max128Bits)
144
+ console.log(` ✅ Decrypted successfully: ${decrypted.toString()}\n`)
145
+ })
146
+
147
+ it("Should fail when encrypting without AES key and auto-onboard is off", async function () {
148
+ const functionSelector = contract128.validateAndReturn.fragment.selector
149
+
150
+ await expect(
151
+ walletWithAutoOnboardOff.encryptValue(1000n, contract128Address, functionSelector)
152
+ ).to.be.rejectedWith("user AES key is not defined and auto onboard is off")
153
+ })
154
+
155
+ it("Should fail when encrypting without AES key and account has no balance", async function () {
156
+ const functionSelector = contract128.validateAndReturn.fragment.selector
157
+
158
+ await expect(
159
+ walletWithoutAes.encryptValue(1000n, contract128Address, functionSelector)
160
+ ).to.be.rejected
161
+ })
162
+ })
163
+
164
+ describe("encryptValue256 Failure Scenarios with Contract Integration", function () {
165
+ it("Should fail when encrypting 257-bit value (exceeds 256-bit limit)", async function () {
166
+ // 257-bit value (2^256)
167
+ const value257Bits = 2n ** 256n
168
+ const functionSelector = contract256.add256.fragment.selector
169
+
170
+ await expect(
171
+ owner.encryptValue256(value257Bits, contract256Address, functionSelector)
172
+ ).to.be.rejectedWith("encryptValue256: values larger than 256 bits are not supported")
173
+ })
174
+
175
+ it("Should succeed with 256-bit value and complete full cycle", async function () {
176
+ // Maximum 256-bit value (2^256 - 1)
177
+ const max256Bits = 2n ** 256n - 1n
178
+ const functionSelector = contract256.add256.fragment.selector
179
+
180
+ console.log(`\n✅ Testing 256-bit encryption/decryption full cycle`)
181
+ console.log(` Value: ${max256Bits.toString().substring(0, 50)}...`)
182
+
183
+ // Encrypt
184
+ const encrypted = await owner.encryptValue256(max256Bits, contract256Address, functionSelector)
185
+ expect(encrypted).to.have.property("ciphertext")
186
+ expect(encrypted.ciphertext).to.have.property("ciphertextHigh")
187
+ expect(encrypted.ciphertext).to.have.property("ciphertextLow")
188
+ expect(encrypted).to.have.property("signature")
189
+ console.log(` ✅ Encrypted successfully`)
190
+
191
+ // Call contract (add with zero to get same value back)
192
+ const zero = await owner.encryptValue256(0n, contract256Address, functionSelector)
193
+ const tx = await contract256.add256(encrypted, zero, owner.address, { gasLimit: GAS_LIMIT })
194
+ const receipt = await tx.wait()
195
+ expect(receipt?.status).to.equal(1)
196
+ console.log(` ✅ Contract call successful`)
197
+
198
+ // Get result from event
199
+ const resultEvent = receipt?.logs.find((log: any) => {
200
+ try {
201
+ return contract256.interface.parseLog(log)?.name === "ValueOffBoarded"
202
+ } catch {
203
+ return false
204
+ }
205
+ })
206
+
207
+ expect(resultEvent).to.not.be.undefined
208
+ const parsedLog = contract256.interface.parseLog(resultEvent!)
209
+ const ctResult: ctUint256 = parsedLog?.args.result
210
+
211
+ // Decrypt
212
+ const decrypted = await owner.decryptValue256({
213
+ ciphertextHigh: ctResult.ciphertextHigh,
214
+ ciphertextLow: ctResult.ciphertextLow
215
+ })
216
+ expect(decrypted).to.equal(max256Bits)
217
+ console.log(` ✅ Decrypted successfully\n`)
218
+ })
219
+
220
+ it("Should succeed with 129-bit value using encryptValue256", async function () {
221
+ // 129-bit value should work with encryptValue256
222
+ const value129Bits = 2n ** 128n
223
+ const functionSelector = contract256.add256.fragment.selector
224
+
225
+ console.log(`\n✅ Testing 129-bit value with encryptValue256`)
226
+ console.log(` Value: ${value129Bits.toString()}`)
227
+
228
+ // Encrypt
229
+ const encrypted = await owner.encryptValue256(value129Bits, contract256Address, functionSelector)
230
+ expect(encrypted).to.have.property("ciphertext")
231
+ expect(encrypted.ciphertext).to.have.property("ciphertextHigh")
232
+ expect(encrypted.ciphertext).to.have.property("ciphertextLow")
233
+ console.log(` ✅ Encrypted successfully`)
234
+
235
+ // Call contract
236
+ const zero = await owner.encryptValue256(0n, contract256Address, functionSelector)
237
+ const tx = await contract256.add256(encrypted, zero, owner.address, { gasLimit: GAS_LIMIT })
238
+ const receipt = await tx.wait()
239
+ expect(receipt?.status).to.equal(1)
240
+
241
+ // Get and decrypt result
242
+ const resultEvent = receipt?.logs.find((log: any) => {
243
+ try {
244
+ return contract256.interface.parseLog(log)?.name === "ValueOffBoarded"
245
+ } catch {
246
+ return false
247
+ }
248
+ })
249
+
250
+ const parsedLog = contract256.interface.parseLog(resultEvent!)
251
+ const ctResult: ctUint256 = parsedLog?.args.result
252
+
253
+ const decrypted = await owner.decryptValue256({
254
+ ciphertextHigh: ctResult.ciphertextHigh,
255
+ ciphertextLow: ctResult.ciphertextLow
256
+ })
257
+ expect(decrypted).to.equal(value129Bits)
258
+ console.log(` ✅ Full cycle successful\n`)
259
+ })
260
+
261
+ it("Should fail when encrypting without AES key and auto-onboard is off", async function () {
262
+ const functionSelector = contract256.add256.fragment.selector
263
+
264
+ await expect(
265
+ walletWithAutoOnboardOff.encryptValue256(1000n, contract256Address, functionSelector)
266
+ ).to.be.rejectedWith("user AES key is not defined and auto onboard is off")
267
+ })
268
+
269
+ it("Should fail when encrypting without AES key and account has no balance", async function () {
270
+ const functionSelector = contract256.add256.fragment.selector
271
+
272
+ await expect(
273
+ walletWithoutAes.encryptValue256(1000n, contract256Address, functionSelector)
274
+ ).to.be.rejected
275
+ })
276
+ })
277
+
278
+ describe("Boundary Value Tests with Contract Integration", function () {
279
+ it("Should succeed with 64-bit value using encryptValue and complete full cycle", async function () {
280
+ const value64Bits = 2n ** 64n - 1n // Max 64-bit value
281
+ const functionSelector = contract128.validateAndReturn.fragment.selector
282
+
283
+ console.log(`\n✅ Testing 64-bit value full cycle`)
284
+ const encrypted = await owner.encryptValue(value64Bits, contract128Address, functionSelector) as any
285
+ const tx = await contract128.validateAndReturn(encrypted, { gasLimit: GAS_LIMIT })
286
+ const receipt = await tx.wait()
287
+
288
+ const resultEvent = receipt?.logs.find((log: any) => {
289
+ try {
290
+ return contract128.interface.parseLog(log)?.name === "ValueOffBoarded128"
291
+ } catch {
292
+ return false
293
+ }
294
+ })
295
+
296
+ const parsedLog = contract128.interface.parseLog(resultEvent!)
297
+ const ctResult: ctUint = parsedLog?.args.result
298
+ const decrypted = await owner.decryptValue(ctResult)
299
+ expect(decrypted).to.equal(value64Bits)
300
+ console.log(` ✅ 64-bit full cycle successful\n`)
301
+ })
302
+
303
+ it("Should fail with 129-bit value using encryptValue", async function () {
304
+ const value129Bits = 2n ** 128n // 129-bit value
305
+ const functionSelector = contract128.validateAndReturn.fragment.selector
306
+
307
+ await expect(
308
+ owner.encryptValue(value129Bits, contract128Address, functionSelector)
309
+ ).to.be.rejectedWith("encryptValue: values larger than 128 bits are not supported")
310
+ })
311
+
312
+ it("Should succeed with 128-bit value using encryptValue", async function () {
313
+ const value128Bits = 2n ** 128n - 1n // Max 128-bit value
314
+ const functionSelector = contract128.validateAndReturn.fragment.selector
315
+
316
+ const encrypted = await owner.encryptValue(value128Bits, contract128Address, functionSelector) as any
317
+ const tx = await contract128.validateAndReturn(encrypted, { gasLimit: GAS_LIMIT })
318
+ const receipt = await tx.wait()
319
+
320
+ const resultEvent = receipt?.logs.find((log: any) => {
321
+ try {
322
+ return contract128.interface.parseLog(log)?.name === "ValueOffBoarded128"
323
+ } catch {
324
+ return false
325
+ }
326
+ })
327
+
328
+ const parsedLog = contract128.interface.parseLog(resultEvent!)
329
+ const ctResult: ctUint = parsedLog?.args.result
330
+ const decrypted = await owner.decryptValue(ctResult)
331
+ expect(decrypted).to.equal(value128Bits)
332
+ })
333
+ })
334
+
335
+ describe("Full Cycle Operations with Contract Integration", function () {
336
+ it("Should perform addition with 128-bit values using encryptValue", async function () {
337
+ const a = 2n ** 100n - 1000n
338
+ const b = 2n ** 100n - 2000n
339
+ const expected = a + b
340
+ const functionSelector = contract128.validateAndAdd.fragment.selector
341
+
342
+ console.log(`\n✅ Testing 128-bit addition full cycle`)
343
+ console.log(` A: ${a.toString()}`)
344
+ console.log(` B: ${b.toString()}`)
345
+ console.log(` Expected: ${expected.toString()}`)
346
+
347
+ const itA = await owner.encryptValue(a, contract128Address, functionSelector) as any
348
+ const itB = await owner.encryptValue(b, contract128Address, functionSelector) as any
349
+
350
+ const tx = await contract128.validateAndAdd(itA, itB, { gasLimit: GAS_LIMIT })
351
+ const receipt = await tx.wait()
352
+ expect(receipt?.status).to.equal(1)
353
+
354
+ const resultEvent = receipt?.logs.find((log: any) => {
355
+ try {
356
+ return contract128.interface.parseLog(log)?.name === "ValueOffBoarded128"
357
+ } catch {
358
+ return false
359
+ }
360
+ })
361
+
362
+ const parsedLog = contract128.interface.parseLog(resultEvent!)
363
+ const ctResult: ctUint = parsedLog?.args.result
364
+ const decrypted = await owner.decryptValue(ctResult)
365
+
366
+ expect(decrypted).to.equal(expected)
367
+ console.log(` ✅ Addition verified: ${decrypted.toString()}\n`)
368
+ })
369
+
370
+ it("Should perform addition with 256-bit values using encryptValue256", async function () {
371
+ const a = 2n ** 130n + 1000n
372
+ const b = 2n ** 129n + 500n
373
+ const expected = a + b
374
+ const functionSelector = contract256.add256.fragment.selector
375
+
376
+ console.log(`\n✅ Testing 256-bit addition full cycle`)
377
+ const itA = await owner.encryptValue256(a, contract256Address, functionSelector)
378
+ const itB = await owner.encryptValue256(b, contract256Address, functionSelector)
379
+
380
+ const tx = await contract256.add256(itA, itB, owner.address, { gasLimit: GAS_LIMIT })
381
+ const receipt = await tx.wait()
382
+ expect(receipt?.status).to.equal(1)
383
+
384
+ const resultEvent = receipt?.logs.find((log: any) => {
385
+ try {
386
+ return contract256.interface.parseLog(log)?.name === "ValueOffBoarded"
387
+ } catch {
388
+ return false
389
+ }
390
+ })
391
+
392
+ const parsedLog = contract256.interface.parseLog(resultEvent!)
393
+ const ctResult: ctUint256 = parsedLog?.args.result
394
+ const decrypted = await owner.decryptValue256({
395
+ ciphertextHigh: ctResult.ciphertextHigh,
396
+ ciphertextLow: ctResult.ciphertextLow
397
+ })
398
+
399
+ expect(decrypted).to.equal(expected)
400
+ console.log(` ✅ Addition verified\n`)
401
+ })
402
+
403
+ it("Should fail when trying to use encryptValue for 129-bit value in contract call", async function () {
404
+ const value129Bits = 2n ** 128n
405
+ const functionSelector = contract128.validateAndReturn.fragment.selector
406
+
407
+ // This should fail at encryption stage, before contract call
408
+ await expect(
409
+ owner.encryptValue(value129Bits, contract128Address, functionSelector)
410
+ ).to.be.rejectedWith("encryptValue: values larger than 128 bits are not supported")
411
+ })
412
+
413
+ it("Should succeed when using encryptValue256 for 129-bit value in contract call", async function () {
414
+ const value129Bits = 2n ** 128n
415
+ const functionSelector = contract256.add256.fragment.selector
416
+
417
+ // Should work with encryptValue256
418
+ const encrypted = await owner.encryptValue256(value129Bits, contract256Address, functionSelector)
419
+ const zero = await owner.encryptValue256(0n, contract256Address, functionSelector)
420
+ const tx = await contract256.add256(encrypted, zero, owner.address, { gasLimit: GAS_LIMIT })
421
+ const receipt = await tx.wait()
422
+ expect(receipt?.status).to.equal(1)
423
+
424
+ const resultEvent = receipt?.logs.find((log: any) => {
425
+ try {
426
+ return contract256.interface.parseLog(log)?.name === "ValueOffBoarded"
427
+ } catch {
428
+ return false
429
+ }
430
+ })
431
+
432
+ const parsedLog = contract256.interface.parseLog(resultEvent!)
433
+ const ctResult: ctUint256 = parsedLog?.args.result
434
+ const decrypted = await owner.decryptValue256({
435
+ ciphertextHigh: ctResult.ciphertextHigh,
436
+ ciphertextLow: ctResult.ciphertextLow
437
+ })
438
+
439
+ expect(decrypted).to.equal(value129Bits)
440
+ })
441
+ })
442
+
443
+ describe("Type Conversion Tests with Contract Integration", function () {
444
+ it("Should convert number to bigint in encryptValue and complete full cycle", async function () {
445
+ const value = 1000 // number
446
+ const functionSelector = contract128.validateAndReturn.fragment.selector
447
+
448
+ const encrypted = await owner.encryptValue(value, contract128Address, functionSelector) as any
449
+ const tx = await contract128.validateAndReturn(encrypted, { gasLimit: GAS_LIMIT })
450
+ const receipt = await tx.wait()
451
+
452
+ const resultEvent = receipt?.logs.find((log: any) => {
453
+ try {
454
+ return contract128.interface.parseLog(log)?.name === "ValueOffBoarded128"
455
+ } catch {
456
+ return false
457
+ }
458
+ })
459
+
460
+ const parsedLog = contract128.interface.parseLog(resultEvent!)
461
+ const ctResult: ctUint = parsedLog?.args.result
462
+ const decrypted = await owner.decryptValue(ctResult)
463
+
464
+ expect(decrypted).to.equal(BigInt(value))
465
+ })
466
+
467
+ it("Should convert number to bigint in encryptValue256 and complete full cycle", async function () {
468
+ const value = 1000 // number
469
+ const functionSelector = contract256.add256.fragment.selector
470
+
471
+ const encrypted = await owner.encryptValue256(value, contract256Address, functionSelector)
472
+ const zero = await owner.encryptValue256(0n, contract256Address, functionSelector)
473
+ const tx = await contract256.add256(encrypted, zero, owner.address, { gasLimit: GAS_LIMIT })
474
+ const receipt = await tx.wait()
475
+
476
+ const resultEvent = receipt?.logs.find((log: any) => {
477
+ try {
478
+ return contract256.interface.parseLog(log)?.name === "ValueOffBoarded"
479
+ } catch {
480
+ return false
481
+ }
482
+ })
483
+
484
+ const parsedLog = contract256.interface.parseLog(resultEvent!)
485
+ const ctResult: ctUint256 = parsedLog?.args.result
486
+ const decrypted = await owner.decryptValue256({
487
+ ciphertextHigh: ctResult.ciphertextHigh,
488
+ ciphertextLow: ctResult.ciphertextLow
489
+ })
490
+
491
+ expect(decrypted).to.equal(BigInt(value))
492
+ })
493
+ })
494
+ })
@@ -0,0 +1,97 @@
1
+ import { expect } from "chai"
2
+ import type { BaseContract, ContractTransactionResponse } from "ethers"
3
+ import { prepareIT256, decryptUint256 } from "@coti-io/coti-sdk-typescript"
4
+ import type { ctUint256, itUint256 } from "@coti-io/coti-sdk-typescript"
5
+
6
+ /** Normalize ethers Result / tuple ctUint256 for the SDK. */
7
+ function toCtUint256(
8
+ ct: ctUint256 | readonly [bigint, bigint] | { ciphertextHigh: bigint; ciphertextLow: bigint }
9
+ ): ctUint256 {
10
+ if (Array.isArray(ct)) {
11
+ return { ciphertextHigh: BigInt(ct[0]), ciphertextLow: BigInt(ct[1]) }
12
+ }
13
+ return {
14
+ ciphertextHigh: BigInt(ct.ciphertextHigh),
15
+ ciphertextLow: BigInt(ct.ciphertextLow)
16
+ }
17
+ }
18
+
19
+ /** Canonical empty ciphertext reads as numeric zero on-chain (see IPrivateERC20). */
20
+ function isZeroCt(ct: ctUint256): boolean {
21
+ return ct.ciphertextHigh === 0n && ct.ciphertextLow === 0n
22
+ }
23
+ import type { Wallet } from "@coti-io/coti-ethers"
24
+
25
+ /** Gas limit for COTI testnet txs (MPC-heavy). */
26
+ export const GAS_LIMIT = 12_000_000
27
+
28
+ export const txOpts = { gasLimit: GAS_LIMIT }
29
+
30
+ /** EIP-165 `type(IPrivateERC20).interfaceId` (XOR of function selectors in `IPrivateERC20.sol`). */
31
+ export const IPRIVATE_ERC20_INTERFACE_ID = "0x479eaff4"
32
+
33
+ export async function mintPublic(
34
+ contract: BaseContract,
35
+ signer: Wallet,
36
+ to: string,
37
+ amount: bigint
38
+ ) {
39
+ return contract
40
+ .connect(signer)
41
+ .getFunction("mint(address,uint256)")(to, amount, txOpts)
42
+ }
43
+
44
+ export async function burnPublic(
45
+ contract: BaseContract,
46
+ signer: Wallet,
47
+ from: string,
48
+ amount: bigint
49
+ ) {
50
+ return contract
51
+ .connect(signer)
52
+ .getFunction("burn(address,uint256)")(from, amount, txOpts)
53
+ }
54
+
55
+ /** Encrypted uint256 input text for `itUint256` calldata (PrivateERC20). Uses `prepareIT256`, not 64-bit `Wallet.encryptValue`. */
56
+ export async function encryptItUint256(
57
+ wallet: Wallet,
58
+ plaintext: bigint,
59
+ contractAddress: string,
60
+ functionSelector: string
61
+ ): Promise<itUint256> {
62
+ const info = wallet.getUserOnboardInfo()
63
+ if (!info?.aesKey) {
64
+ throw new Error("Wallet not onboarded: missing aesKey")
65
+ }
66
+ return prepareIT256(plaintext, { wallet, userKey: info.aesKey }, contractAddress, functionSelector)
67
+ }
68
+
69
+ /** Decrypt `ctUint256` from `balanceOf` / allowance views. */
70
+ export function decryptCtUint256(
71
+ wallet: Wallet,
72
+ ct: ctUint256 | readonly [bigint, bigint] | { ciphertextHigh: bigint; ciphertextLow: bigint }
73
+ ): bigint {
74
+ const info = wallet.getUserOnboardInfo()
75
+ if (!info?.aesKey) {
76
+ throw new Error("Wallet not onboarded: missing aesKey")
77
+ }
78
+ const normalized = toCtUint256(ct)
79
+ if (isZeroCt(normalized)) {
80
+ return 0n
81
+ }
82
+ return decryptUint256(normalized, info.aesKey)
83
+ }
84
+
85
+ /**
86
+ * COTI testnet often omits revert data on eth_call; Hardhat custom-error matchers also fail when
87
+ * sendTransaction receipts lack data. Use this for "must revert" smoke checks.
88
+ */
89
+ export async function expectTxFails(txPromise: Promise<ContractTransactionResponse>): Promise<void> {
90
+ try {
91
+ const tx = await txPromise
92
+ await tx.wait()
93
+ expect.fail("expected transaction to revert")
94
+ } catch (e) {
95
+ expect(e).to.be.ok
96
+ }
97
+ }