@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,41 @@
1
+ import hre from "hardhat"
2
+ import { expect } from "chai"
3
+ import { setupAccounts } from "../accounts"
4
+
5
+ const gasLimit = 12000000
6
+
7
+ function buildTest(
8
+ contractName: string,
9
+ func: string,
10
+ resFunc: string,
11
+ params: (bigint | boolean)[],
12
+ expectedResult: bigint
13
+ ) {
14
+ it(`${contractName}.${func}(${params}) should return ${expectedResult}`, async function () {
15
+ const [owner] = await setupAccounts()
16
+ const provider = owner.provider!
17
+
18
+ const factory = await hre.ethers.getContractFactory(contractName, owner as any)
19
+ const contract = await factory.deploy({ gasLimit })
20
+ await contract.waitForDeployment()
21
+
22
+ const tx = await contract.getFunction(func)(...params, { gasLimit })
23
+ const receipt = await tx.wait()
24
+
25
+ const result = await contract.getFunction(resFunc)()
26
+ expect(result).to.equal(expectedResult)
27
+
28
+ const txFromChain = await provider.getTransactionReceipt(receipt.hash)
29
+ expect(txFromChain).to.not.be.null
30
+ expect(txFromChain?.status).to.equal(1)
31
+ })
32
+ }
33
+
34
+ const bit = false
35
+ const a = BigInt("1000000000000000000")
36
+ const b = BigInt("500000000000000000")
37
+
38
+ describe("Mux 256-bit", function () {
39
+ buildTest("Mux256TestsContract", "muxTest", "getMuxResult", [bit, a, b], bit ? b : a)
40
+ })
41
+
@@ -0,0 +1,478 @@
1
+ import hre from "hardhat"
2
+ import { expect } from "chai"
3
+ import { setupAccounts } from "../accounts"
4
+
5
+ const gasLimit = 12000000
6
+
7
+ describe("Negative Test Cases - 8/16/32/64-bit", function () {
8
+ // Increase timeout for MPC operations, especially overflow detection
9
+ this.timeout(300000) // 5 minutes
10
+
11
+ describe("Division by Zero", function () {
12
+ it("Should handle division by zero for 8-bit (may revert or return special value)", async function () {
13
+ this.timeout(60000) // 1 minute timeout
14
+ const [owner] = await setupAccounts()
15
+
16
+ const factory = await hre.ethers.getContractFactory("MiscellaneousTestsContract", owner as any)
17
+ const contract = await factory.deploy({ gasLimit })
18
+ await contract.waitForDeployment()
19
+
20
+ const a = 10
21
+ const b = 0
22
+
23
+ // Division by zero - check if it reverts or returns a value
24
+ try {
25
+ const tx = await contract.divTest(a, b, { gasLimit })
26
+ const receipt = await tx.wait()
27
+ expect(receipt?.status).to.equal(1)
28
+
29
+ // If it doesn't revert, check what value it returns
30
+ const result = await contract.getDivResult()
31
+ console.log(`Division by zero (8-bit) returned: ${result}`)
32
+ // Note: MPC precompile may handle division by zero differently for smaller bit sizes
33
+ // It might return 0, max value, or some other special value
34
+ } catch (error: any) {
35
+ // If it reverts, that's also valid behavior
36
+ if (error.message && error.message.includes("revert")) {
37
+ console.log("Division by zero (8-bit) correctly reverted")
38
+ } else {
39
+ throw error
40
+ }
41
+ }
42
+ })
43
+
44
+ it("Should handle remainder by zero for 8-bit (returns dividend)", async function () {
45
+ this.timeout(60000) // 1 minute timeout
46
+ const [owner] = await setupAccounts()
47
+
48
+ const factory = await hre.ethers.getContractFactory("MiscellaneousTestsContract", owner as any)
49
+ const contract = await factory.deploy({ gasLimit })
50
+ await contract.waitForDeployment()
51
+
52
+ const a = 10
53
+ const b = 0
54
+
55
+ // Remainder by zero - MPC precompile returns dividend
56
+ const tx = await contract.remTest(a, b, { gasLimit })
57
+ const receipt = await tx.wait()
58
+ expect(receipt?.status).to.equal(1)
59
+
60
+ const result = await contract.getRemResult()
61
+ console.log(`Remainder by zero (8-bit) returned: ${result}`)
62
+ // MPC precompile returns dividend for remainder by zero
63
+ expect(result).to.equal(a)
64
+ })
65
+ })
66
+
67
+ describe("Arithmetic Overflow - Checked Operations", function () {
68
+ // Note: Overflow detection tests are computationally expensive due to MPC operations
69
+ // These tests may take 1-3 minutes each to complete
70
+
71
+ it("Should detect overflow in checkedAdd for 8-bit with max values", async function () {
72
+ this.timeout(180000) // 3 minutes for this specific test
73
+ const [owner] = await setupAccounts()
74
+
75
+ const factory = await hre.ethers.getContractFactory("CheckedArithmeticWithOverflowBitTestsContract", owner as any)
76
+ const contract = await factory.deploy({ gasLimit })
77
+ await contract.waitForDeployment()
78
+
79
+ // Test with values that will overflow for 8-bit
80
+ const nearMax8 = 200 // Close to max uint8 (255)
81
+ const large = 100 // Will overflow when added (200 + 100 = 300 > 255)
82
+
83
+ // This should succeed but overflow bit should be set
84
+ try {
85
+ const tx = await contract.checkedAddWithOverflowBitTest(nearMax8, large, { gasLimit })
86
+ const receipt = await tx.wait()
87
+ expect(receipt?.status).to.equal(1)
88
+
89
+ // Note: The contract doesn't expose overflow bit, but we can check the result
90
+ const result = await contract.getAddResult()
91
+ console.log(`CheckedAdd result (8-bit): ${result}, expected overflow`)
92
+ // Result should be wrapped value: (200 + 100) % 256 = 44
93
+ expect(result).to.equal((nearMax8 + large) % 256)
94
+ } catch (error: any) {
95
+ // Some overflow cases may revert
96
+ if (error.message && error.message.includes("revert")) {
97
+ console.log("CheckedAdd overflow correctly caused revert")
98
+ } else {
99
+ throw error
100
+ }
101
+ }
102
+ })
103
+
104
+ it("Should detect underflow in checkedSub for 8-bit", async function () {
105
+ this.timeout(180000) // 3 minutes for this specific test
106
+ const [owner] = await setupAccounts()
107
+
108
+ const factory = await hre.ethers.getContractFactory("CheckedArithmeticWithOverflowBitTestsContract", owner as any)
109
+ const contract = await factory.deploy({ gasLimit })
110
+ await contract.waitForDeployment()
111
+
112
+ // Test subtraction that would underflow
113
+ const small = 5
114
+ const large = 100
115
+
116
+ // This should succeed but overflow bit should be set (indicating underflow)
117
+ try {
118
+ const tx = await contract.checkedSubWithOverflowBitTest(small, large, { gasLimit })
119
+ const receipt = await tx.wait()
120
+ expect(receipt?.status).to.equal(1)
121
+
122
+ // Check result
123
+ const result = await contract.getSubResult()
124
+ console.log(`CheckedSub result (8-bit): ${result}, expected underflow`)
125
+ // Result should be wrapped value: (5 - 100) % 256 = 161
126
+ expect(result).to.equal((small - large + 256) % 256)
127
+ } catch (error: any) {
128
+ // Some underflow cases may revert
129
+ if (error.message && error.message.includes("revert")) {
130
+ console.log("CheckedSub underflow correctly caused revert")
131
+ } else {
132
+ throw error
133
+ }
134
+ }
135
+ })
136
+
137
+ it("Should detect overflow in checkedMul for 8-bit with large values", async function () {
138
+ this.timeout(180000) // 3 minutes for this specific test
139
+ const [owner] = await setupAccounts()
140
+
141
+ const factory = await hre.ethers.getContractFactory("CheckedArithmeticWithOverflowBitTestsContract", owner as any)
142
+ const contract = await factory.deploy({ gasLimit })
143
+ await contract.waitForDeployment()
144
+
145
+ // Test multiplication that will overflow
146
+ const large1 = 20 // 20 * 20 = 400 > 255, will overflow
147
+ const large2 = 20
148
+
149
+ try {
150
+ const tx = await contract.checkedMulWithOverflowBitTest(large1, large2, { gasLimit })
151
+ const receipt = await tx.wait()
152
+ expect(receipt?.status).to.equal(1)
153
+
154
+ // Check result
155
+ const result = await contract.getMulResult()
156
+ console.log(`CheckedMul result (8-bit): ${result}, expected overflow`)
157
+ // Result should be wrapped value: (20 * 20) % 256 = 144
158
+ expect(result).to.equal((large1 * large2) % 256)
159
+ } catch (error: any) {
160
+ // Some overflow cases may revert
161
+ if (error.message && error.message.includes("revert")) {
162
+ console.log("CheckedMul overflow correctly caused revert")
163
+ } else {
164
+ throw error
165
+ }
166
+ }
167
+ })
168
+ })
169
+
170
+ describe("Invalid Shift Operations", function () {
171
+ it("Should handle shift amount >= 8 bits", async function () {
172
+ const [owner] = await setupAccounts()
173
+
174
+ const factory = await hre.ethers.getContractFactory("ShiftTestsContract", owner as any)
175
+ const contract = await factory.deploy({ gasLimit })
176
+ await contract.waitForDeployment()
177
+
178
+ const a = 10
179
+ const shift8 = 8 // Equal to 8-bit size
180
+ const shift16 = 16 // Greater than 8-bit size
181
+
182
+ // Shift by 8 (equal to bit size) - behavior depends on MPC precompile
183
+ // For 8-bit: 10 << 8 = 2560, but since it's uint8, it wraps to 0
184
+ // However, the contract tests all bit sizes, so 16/32/64-bit results may not be 0
185
+ const tx1 = await contract.shlTest(a, shift8, { gasLimit })
186
+ const receipt1 = await tx1.wait()
187
+ expect(receipt1?.status).to.equal(1)
188
+ const results1 = await contract.getAllShiftResults()
189
+ console.log(`Shift by 8 returned: 8-bit=${results1[0]}, 16-bit=${results1[1]}, 32-bit=${results1[2]}, 64-bit=${results1[3]}`)
190
+ // 8-bit should be 0 (wrapped), others may have actual shifted values
191
+ expect(results1[0]).to.equal(0) // 8-bit: all bits shifted out (wrapped)
192
+
193
+ // Shift by 16 (greater than 8-bit size) - behavior depends on MPC precompile
194
+ const tx2 = await contract.shlTest(a, shift16, { gasLimit })
195
+ const receipt2 = await tx2.wait()
196
+ expect(receipt2?.status).to.equal(1)
197
+ const results2 = await contract.getAllShiftResults()
198
+ console.log(`Shift by 16 returned: 8-bit=${results2[0]}, 16-bit=${results2[1]}, 32-bit=${results2[2]}, 64-bit=${results2[3]}`)
199
+ // 8-bit should be 0, others may have wrapped values
200
+ expect(results2[0]).to.equal(0) // 8-bit: all bits shifted out
201
+ })
202
+
203
+ it("Should handle right shift by >= 8 bits", async function () {
204
+ const [owner] = await setupAccounts()
205
+
206
+ const factory = await hre.ethers.getContractFactory("ShiftTestsContract", owner as any)
207
+ const contract = await factory.deploy({ gasLimit })
208
+ await contract.waitForDeployment()
209
+
210
+ const a = 10
211
+ const shift8 = 8
212
+
213
+ // Right shift by 8 - should result in 0
214
+ const tx = await contract.shrTest(a, shift8, { gasLimit })
215
+ const receipt = await tx.wait()
216
+ expect(receipt?.status).to.equal(1)
217
+ const result = await contract.getResult()
218
+ expect(result).to.equal(0) // All bits shifted out
219
+ })
220
+
221
+ it("Should handle shift amount >= 16 bits", async function () {
222
+ const [owner] = await setupAccounts()
223
+
224
+ const factory = await hre.ethers.getContractFactory("ShiftTestsContract", owner as any)
225
+ const contract = await factory.deploy({ gasLimit })
226
+ await contract.waitForDeployment()
227
+
228
+ const a = 10
229
+ const shift16 = 16 // Equal to 16-bit size
230
+ const shift32 = 32 // Greater than 16-bit size
231
+
232
+ // Shift by 16 - should result in 0 for 16-bit
233
+ const tx1 = await contract.shlTest(a, shift16, { gasLimit })
234
+ const receipt1 = await tx1.wait()
235
+ expect(receipt1?.status).to.equal(1)
236
+ const results1 = await contract.getAllShiftResults()
237
+ expect(results1[1]).to.equal(0) // 16-bit: all bits shifted out
238
+
239
+ // Shift by 32 - should result in 0 for 32-bit
240
+ const tx2 = await contract.shlTest(a, shift32, { gasLimit })
241
+ const receipt2 = await tx2.wait()
242
+ expect(receipt2?.status).to.equal(1)
243
+ const results2 = await contract.getAllShiftResults()
244
+ expect(results2[2]).to.equal(0) // 32-bit: all bits shifted out
245
+ })
246
+
247
+ it("Should handle shift amount >= 64 bits", async function () {
248
+ const [owner] = await setupAccounts()
249
+
250
+ const factory = await hre.ethers.getContractFactory("ShiftTestsContract", owner as any)
251
+ const contract = await factory.deploy({ gasLimit })
252
+ await contract.waitForDeployment()
253
+
254
+ const a = 10
255
+ const shift64 = 64 // Equal to 64-bit size (but uint8 max is 255, so we use 64)
256
+
257
+ // Shift by 64 - should result in 0 for 64-bit
258
+ const tx = await contract.shlTest(a, shift64, { gasLimit })
259
+ const receipt = await tx.wait()
260
+ expect(receipt?.status).to.equal(1)
261
+ const results = await contract.getAllShiftResults()
262
+ expect(results[3]).to.equal(0) // 64-bit: all bits shifted out
263
+ })
264
+ })
265
+
266
+ describe("Transfer with Insufficient Balance", function () {
267
+ it("Should handle transfer when balance < amount for 8-bit", async function () {
268
+ const [owner] = await setupAccounts()
269
+
270
+ const factory = await hre.ethers.getContractFactory("TransferTestsContract", owner as any)
271
+ const contract = await factory.deploy({ gasLimit })
272
+ await contract.waitForDeployment()
273
+
274
+ const smallBalance = 10
275
+ const largeAmount = 100 // 10x balance
276
+
277
+ // Transfer more than available balance
278
+ try {
279
+ const tx = await contract.transferTest(smallBalance, 0, largeAmount, { gasLimit })
280
+ const receipt = await tx.wait()
281
+ expect(receipt?.status).to.equal(1)
282
+
283
+ // Check the result flag
284
+ const results = await contract.getResults()
285
+ console.log(`Transfer result (8-bit): new_a=${results[0]}, new_b=${results[1]}, success=${results[2]}`)
286
+
287
+ // The behavior depends on MPC precompile implementation
288
+ // If transfer fails, success flag should be false
289
+ // Or the new balance might be wrapped/underflowed
290
+ if (results[2] === false) {
291
+ console.log("✅ Transfer correctly returned failure flag for insufficient balance")
292
+ } else {
293
+ console.log("⚠️ Transfer succeeded despite insufficient balance - may allow underflow")
294
+ // If it allows underflow, check wrapped value
295
+ expect(results[0]).to.equal((smallBalance - largeAmount + 256) % 256)
296
+ }
297
+ } catch (error: any) {
298
+ // Reverting is acceptable behavior for insufficient balance
299
+ if (error.message && error.message.includes("revert")) {
300
+ console.log("✅ Insufficient balance correctly caused revert")
301
+ } else {
302
+ throw error
303
+ }
304
+ }
305
+ })
306
+
307
+ it("Should handle transfer with zero balance", async function () {
308
+ const [owner] = await setupAccounts()
309
+
310
+ const factory = await hre.ethers.getContractFactory("TransferTestsContract", owner as any)
311
+ const contract = await factory.deploy({ gasLimit })
312
+ await contract.waitForDeployment()
313
+
314
+ const zeroBalance = 0
315
+ const amount = 10
316
+
317
+ try {
318
+ const tx = await contract.transferTest(zeroBalance, 0, amount, { gasLimit })
319
+ const receipt = await tx.wait()
320
+ expect(receipt?.status).to.equal(1)
321
+
322
+ const results = await contract.getResults()
323
+ console.log(`Transfer from zero balance (8-bit): new_a=${results[0]}, new_b=${results[1]}, success=${results[2]}`)
324
+
325
+ if (results[2] === false) {
326
+ console.log("✅ Transfer correctly returned failure flag for zero balance")
327
+ }
328
+ } catch (error: any) {
329
+ if (error.message && error.message.includes("revert")) {
330
+ console.log("✅ Zero balance transfer correctly caused revert")
331
+ } else {
332
+ throw error
333
+ }
334
+ }
335
+ })
336
+ })
337
+
338
+ describe("Transfer with Insufficient Allowance", function () {
339
+ it("Should handle transferWithAllowance when allowance < amount", async function () {
340
+ const [owner] = await setupAccounts()
341
+
342
+ const factory = await hre.ethers.getContractFactory("TransferWithAllowanceTestsContract", owner as any)
343
+ const contract = await factory.deploy({ gasLimit })
344
+ await contract.waitForDeployment()
345
+
346
+ const balance = 100
347
+ const smallAllowance = 10 // Small allowance
348
+ const largeAmount = 100 // 10x allowance
349
+
350
+ // Transfer more than allowance
351
+ try {
352
+ const tx = await contract.transferWithAllowanceTest(
353
+ balance,
354
+ 0,
355
+ largeAmount,
356
+ smallAllowance,
357
+ { gasLimit }
358
+ )
359
+ const receipt = await tx.wait()
360
+ expect(receipt?.status).to.equal(1)
361
+
362
+ const results = await contract.getResults()
363
+ console.log(`TransferWithAllowance result (8-bit): new_a=${results[0]}, new_b=${results[1]}, success=${results[2]}, new_allowance=${results[3]}`)
364
+
365
+ // Check if allowance was properly enforced
366
+ // The new_allowance should not be negative if enforcement works
367
+ if (results[2] === false) {
368
+ console.log("✅ TransferWithAllowance correctly returned failure flag for insufficient allowance")
369
+ } else {
370
+ console.log("⚠️ TransferWithAllowance succeeded despite insufficient allowance")
371
+ }
372
+ } catch (error: any) {
373
+ if (error.message && error.message.includes("revert")) {
374
+ console.log("✅ Insufficient allowance correctly caused revert")
375
+ } else {
376
+ throw error
377
+ }
378
+ }
379
+ })
380
+
381
+ it("Should handle transferWithAllowance with zero allowance", async function () {
382
+ const [owner] = await setupAccounts()
383
+
384
+ const factory = await hre.ethers.getContractFactory("TransferWithAllowanceTestsContract", owner as any)
385
+ const contract = await factory.deploy({ gasLimit })
386
+ await contract.waitForDeployment()
387
+
388
+ const balance = 100
389
+ const zeroAllowance = 0
390
+ const amount = 10
391
+
392
+ try {
393
+ const tx = await contract.transferWithAllowanceTest(
394
+ balance,
395
+ 0,
396
+ amount,
397
+ zeroAllowance,
398
+ { gasLimit }
399
+ )
400
+ const receipt = await tx.wait()
401
+ expect(receipt?.status).to.equal(1)
402
+
403
+ const results = await contract.getResults()
404
+ console.log(`TransferWithAllowance with zero allowance (8-bit): success=${results[2]}, new_allowance=${results[3]}`)
405
+
406
+ if (results[2] === false) {
407
+ console.log("✅ TransferWithAllowance correctly returned failure flag for zero allowance")
408
+ }
409
+ } catch (error: any) {
410
+ if (error.message && error.message.includes("revert")) {
411
+ console.log("✅ Zero allowance transfer correctly caused revert")
412
+ } else {
413
+ throw error
414
+ }
415
+ }
416
+ })
417
+ })
418
+
419
+ describe("Edge Cases - Boundary Values", function () {
420
+ it("Should handle subtraction resulting in zero", async function () {
421
+ const [owner] = await setupAccounts()
422
+
423
+ const factory = await hre.ethers.getContractFactory("ArithmeticTestsContract", owner as any)
424
+ const contract = await factory.deploy({ gasLimit })
425
+ await contract.waitForDeployment()
426
+
427
+ const a = 10
428
+ const b = a // Same value
429
+
430
+ const tx = await contract.subTest(a, b, { gasLimit })
431
+ const receipt = await tx.wait()
432
+ expect(receipt?.status).to.equal(1)
433
+
434
+ const result = await contract.getSubResult()
435
+ expect(result).to.equal(0)
436
+ })
437
+
438
+ it("Should handle max value operations for 8-bit", async function () {
439
+ const [owner] = await setupAccounts()
440
+
441
+ const factory = await hre.ethers.getContractFactory("ArithmeticTestsContract", owner as any)
442
+ const contract = await factory.deploy({ gasLimit })
443
+ await contract.waitForDeployment()
444
+
445
+ const max8 = 255 // Max uint8
446
+ const zero = 0
447
+
448
+ // Max + 0 should work
449
+ const tx = await contract.addTest(max8, zero, { gasLimit })
450
+ const receipt = await tx.wait()
451
+ expect(receipt?.status).to.equal(1)
452
+
453
+ const result = await contract.getAddResult()
454
+ expect(result).to.equal(max8)
455
+ })
456
+
457
+ it("Should handle max value operations for 16-bit", async function () {
458
+ const [owner] = await setupAccounts()
459
+
460
+ const factory = await hre.ethers.getContractFactory("ArithmeticTestsContract", owner as any)
461
+ const contract = await factory.deploy({ gasLimit })
462
+ await contract.waitForDeployment()
463
+
464
+ // Test with values that will be cast to 16-bit
465
+ const a = 10
466
+ const b = 5
467
+
468
+ // Operations should work across all bit sizes
469
+ const tx = await contract.addTest(a, b, { gasLimit })
470
+ const receipt = await tx.wait()
471
+ expect(receipt?.status).to.equal(1)
472
+
473
+ const result = await contract.getAddResult()
474
+ expect(result).to.equal(a + b)
475
+ })
476
+ })
477
+ })
478
+