@coti-io/coti-contracts 1.2.0 → 1.3.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 (267) hide show
  1. package/.github/workflows/npm-publish.yml +1 -1
  2. package/contracts/messaging/PrivateMessaging.sol +456 -0
  3. package/contracts/mocks/messaging/PrivateMessagingHarness.sol +54 -0
  4. package/contracts/mocks/oracle/CotiPriceConsumerMock.sol +31 -0
  5. package/contracts/mocks/token/ERC20DecimalsMock.sol +21 -0
  6. package/contracts/mocks/token/PrivateERC20/PrivacyBridgeERC20Mock.sol +8 -3
  7. package/contracts/node/SoulboundNodeNFT.sol +22 -22
  8. package/contracts/oracle/CotiPriceConsumer.sol +103 -0
  9. package/contracts/oracle/ICotiPriceConsumer.sol +15 -0
  10. package/contracts/oracle/IStdReference.sol +26 -0
  11. package/contracts/privacyBridge/PrivacyBridge.sol +373 -91
  12. package/contracts/privacyBridge/PrivacyBridgeCotiNative.sol +209 -161
  13. package/contracts/privacyBridge/PrivacyBridgeERC20.sol +241 -159
  14. package/contracts/privacyBridge/PrivacyBridgeUSDCe.sol +7 -1
  15. package/contracts/privacyBridge/PrivacyBridgeUSDT.sol +7 -1
  16. package/contracts/privacyBridge/PrivacyBridgeWADA.sol +7 -1
  17. package/contracts/privacyBridge/PrivacyBridgeWBTC.sol +7 -1
  18. package/contracts/privacyBridge/PrivacyBridgeWETH.sol +7 -1
  19. package/contracts/privacyBridge/PrivacyBridgegCoti.sol +7 -1
  20. package/hardhat.config.ts +5 -2
  21. package/package.json +2 -2
  22. package/scripts/add-bridge-operators.cjs +87 -0
  23. package/scripts/deploy-coti-price-consumer-mainnet.cjs +49 -0
  24. package/scripts/deployCotiNodeRewards.ts +51 -0
  25. package/scripts/redeploy-private-and-bridges.cjs +201 -0
  26. package/scripts/set-bridge-limits-mainnet.cjs +177 -0
  27. package/scripts/verify-mainnet-private-bridges.cjs +289 -0
  28. package/sonar-project.properties +11 -0
  29. package/test/messaging/PrivateMessaging.test.ts +158 -0
  30. package/test/privacyBridge/UnifiedPrivacyBridges.test.cjs +1663 -0
  31. package/test/token/PrivateERC20/PrivacyBridge.fees.test.ts +162 -239
  32. package/typechain-types/@openzeppelin/contracts/access/AccessControl.ts +324 -0
  33. package/typechain-types/@openzeppelin/contracts/access/AccessControlEnumerable.ts +361 -0
  34. package/typechain-types/@openzeppelin/contracts/access/IAccessControl.ts +292 -0
  35. package/typechain-types/@openzeppelin/contracts/access/IAccessControlEnumerable.ts +329 -0
  36. package/typechain-types/@openzeppelin/contracts/access/index.ts +4 -0
  37. package/typechain-types/@openzeppelin/contracts/index.ts +2 -0
  38. package/typechain-types/@openzeppelin/contracts/security/Pausable.ts +150 -0
  39. package/typechain-types/@openzeppelin/contracts/security/index.ts +4 -0
  40. package/typechain-types/@openzeppelin/contracts/token/ERC20/ERC20.ts +330 -0
  41. package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.ts +286 -0
  42. package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/index.ts +1 -0
  43. package/typechain-types/@openzeppelin/contracts/token/ERC20/index.ts +1 -0
  44. package/typechain-types/@openzeppelin/contracts/token/ERC721/ERC721.ts +420 -0
  45. package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.ts +420 -0
  46. package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/index.ts +4 -0
  47. package/typechain-types/@openzeppelin/contracts/token/ERC721/index.ts +3 -0
  48. package/typechain-types/contracts/disperse/coinByRatio/FixedRatioCoinDisperserLeftoverS1.ts +735 -0
  49. package/typechain-types/contracts/disperse/coinByRatio/FixedRatioCoinDisperserUnlimitedWindow.ts +734 -0
  50. package/typechain-types/contracts/disperse/coinByRatio/index.ts +2 -0
  51. package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/IOwnable.ts +95 -0
  52. package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/MintDisperser.ts +22 -0
  53. package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/index.ts +1 -0
  54. package/typechain-types/contracts/index.ts +8 -0
  55. package/typechain-types/contracts/messaging/PrivateMessaging.ts +871 -0
  56. package/typechain-types/contracts/messaging/index.ts +4 -0
  57. package/typechain-types/contracts/mocks/index.ts +4 -0
  58. package/typechain-types/contracts/mocks/messaging/PrivateMessagingHarness.ts +951 -0
  59. package/typechain-types/contracts/mocks/messaging/index.ts +4 -0
  60. package/typechain-types/contracts/mocks/oracle/CotiPriceConsumerMock.ts +163 -0
  61. package/typechain-types/contracts/mocks/oracle/index.ts +4 -0
  62. package/typechain-types/contracts/mocks/token/ERC20DecimalsMock.ts +349 -0
  63. package/typechain-types/contracts/mocks/token/ERC20Mock.ts +368 -0
  64. package/typechain-types/contracts/mocks/token/PrivateERC20/EncryptedTokenReceiverMock.ts +108 -0
  65. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivacyBridgeERC20Mock.ts +1892 -0
  66. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20AuditorSupplyMock.ts +1296 -0
  67. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20CappedMock.ts +1270 -0
  68. package/typechain-types/contracts/mocks/{utils/mpc/Bitwise128BitTestsContract.ts → token/PrivateERC20/PrivateERC20GtCallerMock.ts} +47 -67
  69. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.ts +757 -25
  70. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/IPrivateERC20TransferAndCallEncrypted.ts +102 -0
  71. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/PrivateERC20ReentrantReceiverMock.ts +154 -0
  72. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/index.ts +5 -0
  73. package/typechain-types/contracts/mocks/token/PrivateERC20/PublicReentrantTokenReceiverMock.ts +155 -0
  74. package/typechain-types/contracts/mocks/token/PrivateERC20/PublicTokenReceiverBoolMock.ts +107 -0
  75. package/typechain-types/contracts/mocks/token/PrivateERC20/PublicTokenReceiverMock.ts +100 -0
  76. package/typechain-types/contracts/mocks/token/PrivateERC20/index.ts +10 -0
  77. package/typechain-types/contracts/mocks/token/index.ts +2 -0
  78. package/typechain-types/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.ts +6 -6
  79. package/typechain-types/contracts/node/CotiNodeRewards.ts +566 -0
  80. package/typechain-types/contracts/node/SoulboundNodeNFT.sol/IERC5192.ts +123 -0
  81. package/typechain-types/contracts/node/SoulboundNodeNFT.sol/SoulboundNodeNFT.ts +975 -0
  82. package/typechain-types/contracts/node/SoulboundNodeNFT.sol/index.ts +5 -0
  83. package/typechain-types/contracts/node/index.ts +6 -0
  84. package/typechain-types/contracts/oracle/CotiPriceConsumer.ts +256 -0
  85. package/typechain-types/contracts/oracle/ICotiPriceConsumer.ts +119 -0
  86. package/typechain-types/contracts/oracle/IStdReference.ts +136 -0
  87. package/typechain-types/contracts/oracle/index.ts +6 -0
  88. package/typechain-types/contracts/privacyBridge/PrivacyBridge.ts +1628 -0
  89. package/typechain-types/contracts/privacyBridge/PrivacyBridgeCotiNative.ts +1870 -0
  90. package/typechain-types/contracts/privacyBridge/PrivacyBridgeERC20.sol/IHasDecimals.ts +84 -0
  91. package/typechain-types/contracts/privacyBridge/PrivacyBridgeERC20.sol/PrivacyBridgeERC20.ts +1892 -0
  92. package/typechain-types/contracts/privacyBridge/PrivacyBridgeERC20.sol/index.ts +5 -0
  93. package/typechain-types/contracts/privacyBridge/PrivacyBridgeUSDCe.ts +1892 -0
  94. package/typechain-types/contracts/privacyBridge/PrivacyBridgeUSDT.ts +1892 -0
  95. package/typechain-types/contracts/privacyBridge/PrivacyBridgeWADA.ts +1892 -0
  96. package/typechain-types/contracts/privacyBridge/PrivacyBridgeWBTC.ts +1892 -0
  97. package/typechain-types/contracts/privacyBridge/PrivacyBridgeWETH.ts +1892 -0
  98. package/typechain-types/contracts/privacyBridge/PrivacyBridgegCoti.ts +1892 -0
  99. package/typechain-types/contracts/privacyBridge/index.ts +13 -0
  100. package/typechain-types/contracts/token/PrivateERC20/IPrivateERC20.ts +439 -19
  101. package/typechain-types/contracts/token/PrivateERC20/ITokenReceiver.ts +100 -0
  102. package/typechain-types/contracts/token/PrivateERC20/ITokenReceiverEncrypted.ts +99 -0
  103. package/typechain-types/contracts/token/PrivateERC20/PrivateERC20.ts +763 -15
  104. package/typechain-types/contracts/token/PrivateERC20/index.ts +4 -0
  105. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateBridgedUSDC.ts +1270 -0
  106. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateCOTI.ts +1270 -0
  107. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateCOTITreasuryGovernanceToken.ts +1270 -0
  108. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateTetherUSD.ts +1270 -0
  109. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateWrappedADA.ts +1270 -0
  110. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateWrappedBTC.ts +1270 -0
  111. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateWrappedEther.ts +1270 -0
  112. package/typechain-types/contracts/token/PrivateERC20/tokens/index.ts +10 -0
  113. package/typechain-types/factories/@openzeppelin/contracts/access/AccessControlEnumerable__factory.ts +276 -0
  114. package/typechain-types/factories/@openzeppelin/contracts/access/AccessControl__factory.ts +229 -0
  115. package/typechain-types/factories/@openzeppelin/contracts/access/IAccessControlEnumerable__factory.ts +244 -0
  116. package/typechain-types/factories/@openzeppelin/contracts/access/IAccessControl__factory.ts +197 -0
  117. package/typechain-types/factories/@openzeppelin/contracts/access/index.ts +4 -0
  118. package/typechain-types/factories/@openzeppelin/contracts/index.ts +1 -0
  119. package/typechain-types/factories/@openzeppelin/contracts/security/Pausable__factory.ts +61 -0
  120. package/typechain-types/factories/@openzeppelin/contracts/security/index.ts +4 -0
  121. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/ERC20__factory.ts +356 -0
  122. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata__factory.ts +247 -0
  123. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/index.ts +1 -0
  124. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/index.ts +1 -0
  125. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/ERC721__factory.ts +416 -0
  126. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata__factory.ts +355 -0
  127. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/index.ts +4 -0
  128. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/index.ts +2 -0
  129. package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperserLeftoverS1__factory.ts +791 -0
  130. package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperserUnlimitedWindow__factory.ts +711 -0
  131. package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperser__factory.ts +1 -1
  132. package/typechain-types/factories/contracts/disperse/coinByRatio/index.ts +2 -0
  133. package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/IOwnable__factory.ts +35 -0
  134. package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/MintDisperser__factory.ts +19 -1
  135. package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/index.ts +1 -0
  136. package/typechain-types/factories/contracts/disperse/disperseToken/TokenDisperser__factory.ts +1 -1
  137. package/typechain-types/factories/contracts/index.ts +4 -0
  138. package/typechain-types/factories/contracts/messaging/PrivateMessaging__factory.ts +1035 -0
  139. package/typechain-types/factories/contracts/messaging/index.ts +4 -0
  140. package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock__factory.ts +1 -1
  141. package/typechain-types/factories/contracts/mocks/index.ts +2 -0
  142. package/typechain-types/factories/contracts/mocks/messaging/PrivateMessagingHarness__factory.ts +1161 -0
  143. package/typechain-types/factories/contracts/mocks/messaging/index.ts +4 -0
  144. package/typechain-types/factories/contracts/mocks/oracle/CotiPriceConsumerMock__factory.ts +159 -0
  145. package/typechain-types/factories/contracts/mocks/oracle/index.ts +4 -0
  146. package/typechain-types/factories/contracts/mocks/token/ERC20DecimalsMock__factory.ts +394 -0
  147. package/typechain-types/factories/contracts/mocks/token/ERC20Mock__factory.ts +392 -0
  148. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/EncryptedTokenReceiverMock__factory.ts +125 -0
  149. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivacyBridgeERC20Mock__factory.ts +1797 -0
  150. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20AuditorSupplyMock__factory.ts +1514 -0
  151. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20CappedMock__factory.ts +1466 -0
  152. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20GtCallerMock__factory.ts +165 -0
  153. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20Mock__factory.ts +771 -55
  154. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/IPrivateERC20TransferAndCallEncrypted__factory.ts +54 -0
  155. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/PrivateERC20ReentrantReceiverMock__factory.ts +159 -0
  156. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/index.ts +5 -0
  157. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PublicReentrantTokenReceiverMock__factory.ts +164 -0
  158. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PublicTokenReceiverBoolMock__factory.ts +130 -0
  159. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PublicTokenReceiverMock__factory.ts +102 -0
  160. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/index.ts +9 -0
  161. package/typechain-types/factories/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock__factory.ts +1 -1
  162. package/typechain-types/factories/contracts/mocks/token/index.ts +2 -0
  163. package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic128TestsContract__factory.ts +1 -1
  164. package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic256TestsContract__factory.ts +1 -1
  165. package/typechain-types/factories/contracts/mocks/utils/mpc/ArithmeticTestsContract__factory.ts +1 -1
  166. package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise128TestsContract__factory.ts +1 -1
  167. package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise256TestsContract__factory.ts +1 -1
  168. package/typechain-types/factories/contracts/mocks/utils/mpc/BitwiseTestsContract__factory.ts +1 -1
  169. package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmetic128WithOverflowBitTestsContract__factory.ts +1 -1
  170. package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmetic256WithOverflowBitTestsContract__factory.ts +1 -1
  171. package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmeticWIthOverflowBitTestsContract.sol/CheckedArithmeticWithOverflowBitTestsContract__factory.ts +1 -1
  172. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison128TestsContract__factory.ts +1 -1
  173. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison1TestsContract__factory.ts +1 -1
  174. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison256TestsContract__factory.ts +1 -1
  175. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison2TestsContract__factory.ts +1 -1
  176. package/typechain-types/factories/contracts/mocks/utils/mpc/MinMax128TestsContract__factory.ts +1 -1
  177. package/typechain-types/factories/contracts/mocks/utils/mpc/MinMax256TestsContract__factory.ts +1 -1
  178. package/typechain-types/factories/contracts/mocks/utils/mpc/MinMaxTestsContract__factory.ts +1 -1
  179. package/typechain-types/factories/contracts/mocks/utils/mpc/MinimalImplementation__factory.ts +1 -1
  180. package/typechain-types/factories/contracts/mocks/utils/mpc/MinimalProxy__factory.ts +1 -1
  181. package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous1TestsContract__factory.ts +1 -1
  182. package/typechain-types/factories/contracts/mocks/utils/mpc/MiscellaneousTestsContract__factory.ts +1 -1
  183. package/typechain-types/factories/contracts/mocks/utils/mpc/MpcOperations128TestContract__factory.ts +1 -1
  184. package/typechain-types/factories/contracts/mocks/utils/mpc/MpcOperationsTestContract__factory.ts +1 -1
  185. package/typechain-types/factories/contracts/mocks/utils/mpc/Mux128TestsContract__factory.ts +1 -1
  186. package/typechain-types/factories/contracts/mocks/utils/mpc/Mux256TestsContract__factory.ts +1 -1
  187. package/typechain-types/factories/contracts/mocks/utils/mpc/OffboardToUserKeyTestContract__factory.ts +1 -1
  188. package/typechain-types/factories/contracts/mocks/utils/mpc/OnBoard128TestsContract__factory.ts +1 -1
  189. package/typechain-types/factories/contracts/mocks/utils/mpc/OnBoard256TestsContract__factory.ts +1 -1
  190. package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyImplementationV1__factory.ts +1 -1
  191. package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyImplementationV2__factory.ts +1 -1
  192. package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyProxy__factory.ts +1 -1
  193. package/typechain-types/factories/contracts/mocks/utils/mpc/Random128TestsContract__factory.ts +1 -1
  194. package/typechain-types/factories/contracts/mocks/utils/mpc/Random256TestsContract__factory.ts +1 -1
  195. package/typechain-types/factories/contracts/mocks/utils/mpc/Shift128TestsContract__factory.ts +1 -1
  196. package/typechain-types/factories/contracts/mocks/utils/mpc/Shift256TestsContract__factory.ts +1 -1
  197. package/typechain-types/factories/contracts/mocks/utils/mpc/ShiftTestsContract__factory.ts +1 -1
  198. package/typechain-types/factories/contracts/mocks/utils/mpc/StringTestsContract__factory.ts +1 -1
  199. package/typechain-types/factories/contracts/mocks/utils/mpc/Transfer128TestsContract__factory.ts +1 -1
  200. package/typechain-types/factories/contracts/mocks/utils/mpc/Transfer256TestsContract__factory.ts +1 -1
  201. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferScalarTestsContract__factory.ts +1 -1
  202. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferTestsContract__factory.ts +1 -1
  203. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance128TestsContract__factory.ts +1 -1
  204. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance256TestsContract__factory.ts +1 -1
  205. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_16TestsContract__factory.ts +1 -1
  206. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_32TestsContract__factory.ts +1 -1
  207. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_64TestsContract__factory.ts +1 -1
  208. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_8TestsContract__factory.ts +1 -1
  209. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowanceScalarTestsContract__factory.ts +1 -1
  210. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowanceTestsContract__factory.ts +1 -1
  211. package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertext128TestsContract__factory.ts +1 -1
  212. package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertext256TestsContract__factory.ts +1 -1
  213. package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertextTestsContract__factory.ts +1 -1
  214. package/typechain-types/factories/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock__factory.ts +4 -22
  215. package/typechain-types/factories/contracts/node/CotiNodeRewards__factory.ts +549 -0
  216. package/typechain-types/factories/contracts/node/SoulboundNodeNFT.sol/IERC5192__factory.ts +54 -0
  217. package/typechain-types/factories/contracts/node/SoulboundNodeNFT.sol/SoulboundNodeNFT__factory.ts +947 -0
  218. package/typechain-types/factories/contracts/node/SoulboundNodeNFT.sol/index.ts +5 -0
  219. package/typechain-types/factories/contracts/node/index.ts +5 -0
  220. package/typechain-types/factories/contracts/onboard/AccountOnboard__factory.ts +1 -1
  221. package/typechain-types/factories/contracts/oracle/CotiPriceConsumer__factory.ts +295 -0
  222. package/typechain-types/factories/contracts/oracle/ICotiPriceConsumer__factory.ts +73 -0
  223. package/typechain-types/factories/contracts/oracle/IStdReference__factory.ts +107 -0
  224. package/typechain-types/factories/contracts/oracle/index.ts +6 -0
  225. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeCotiNative__factory.ts +1676 -0
  226. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeERC20.sol/IHasDecimals__factory.ts +38 -0
  227. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeERC20.sol/PrivacyBridgeERC20__factory.ts +1678 -0
  228. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeERC20.sol/index.ts +5 -0
  229. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeUSDCe__factory.ts +1782 -0
  230. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeUSDT__factory.ts +1782 -0
  231. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeWADA__factory.ts +1782 -0
  232. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeWBTC__factory.ts +1782 -0
  233. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeWETH__factory.ts +1782 -0
  234. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridge__factory.ts +1367 -0
  235. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgegCoti__factory.ts +1782 -0
  236. package/typechain-types/factories/contracts/privacyBridge/index.ts +12 -0
  237. package/typechain-types/factories/contracts/token/PrivateERC20/IPrivateERC20__factory.ts +481 -35
  238. package/typechain-types/factories/contracts/token/PrivateERC20/ITokenReceiverEncrypted__factory.ts +53 -0
  239. package/typechain-types/factories/contracts/token/PrivateERC20/ITokenReceiver__factory.ts +54 -0
  240. package/typechain-types/factories/contracts/token/PrivateERC20/PrivateERC20__factory.ts +793 -59
  241. package/typechain-types/factories/contracts/token/PrivateERC20/index.ts +3 -0
  242. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateBridgedUSDC__factory.ts +1445 -0
  243. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateCOTITreasuryGovernanceToken__factory.ts +1451 -0
  244. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateCOTI__factory.ts +1442 -0
  245. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateTetherUSD__factory.ts +1445 -0
  246. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateWrappedADA__factory.ts +1445 -0
  247. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateWrappedBTC__factory.ts +1445 -0
  248. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateWrappedEther__factory.ts +1451 -0
  249. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/index.ts +10 -0
  250. package/typechain-types/factories/contracts/utils/mpc/MpcCore__factory.ts +1 -1
  251. package/typechain-types/hardhat.d.ts +953 -17
  252. package/typechain-types/index.ts +104 -0
  253. package/typechain-types/contracts/mocks/utils/mpc/Arithmetic128BitTestsContract.ts +0 -341
  254. package/typechain-types/contracts/mocks/utils/mpc/Arithmetic256BitTestsContract.ts +0 -347
  255. package/typechain-types/contracts/mocks/utils/mpc/Bitwise256BitTestsContract.ts +0 -186
  256. package/typechain-types/contracts/mocks/utils/mpc/Comparison128BitTestsContract.ts +0 -260
  257. package/typechain-types/contracts/mocks/utils/mpc/Comparison256BitTestsContract.ts +0 -260
  258. package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous128BitTestsContract.ts +0 -302
  259. package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous256BitTestsContract.ts +0 -322
  260. package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic128BitTestsContract__factory.ts +0 -349
  261. package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic256BitTestsContract__factory.ts +0 -364
  262. package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise128BitTestsContract__factory.ts +0 -182
  263. package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise256BitTestsContract__factory.ts +0 -182
  264. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison128BitTestsContract__factory.ts +0 -255
  265. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison256BitTestsContract__factory.ts +0 -255
  266. package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous128BitTestsContract__factory.ts +0 -332
  267. package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous256BitTestsContract__factory.ts +0 -380
@@ -1,327 +1,250 @@
1
1
  import hre from "hardhat"
2
2
  import { expect } from "chai"
3
3
  import { setupAccounts } from "../../utils/accounts"
4
- import { PrivacyBridgeERC20Mock, PrivateERC20Mock } from "../../../typechain-types"
4
+ import {
5
+ CotiPriceConsumerMock,
6
+ ERC20DecimalsMock,
7
+ PrivacyBridgeERC20Mock,
8
+ PrivateERC20Mock,
9
+ } from "../../../typechain-types"
5
10
  import { Wallet } from "@coti-io/coti-ethers"
6
- import { Contract } from "ethers"
11
+ import { parseEther, parseUnits, ZeroAddress } from "ethers"
7
12
  import { txOpts } from "../../utils/privateErc20Helpers"
8
13
 
9
14
  const GAS_LIMIT = 12000000
10
15
 
11
- describe("PrivacyBridge Fees", function () {
16
+ describe("PrivacyBridge Fees (dynamic native COTI)", function () {
12
17
  let bridge: PrivacyBridgeERC20Mock
13
18
  let bridgeAddress: string
14
19
  let privateToken: PrivateERC20Mock
15
20
  let privateTokenAddress: string
16
- let publicToken: Contract
21
+ let publicToken: ERC20DecimalsMock
17
22
  let publicTokenAddress: string
23
+ let oracle: CotiPriceConsumerMock
18
24
  let owner: Wallet
19
25
  let user: Wallet
20
- /** Fee recipient when only two funded accounts exist in `.env` (same as `owner`). */
21
26
  let feeRecipient: Wallet
22
27
 
23
- const INITIAL_SUPPLY = 1000000n
24
- const DEPOSIT_AMOUNT = 10000n
25
- const ONE_PERCENT_FEE = 100n // 100 basis points = 1%
26
- const TEN_PERCENT_FEE = 1000n // 1000 basis points = 10%
27
- const MAX_FEE = 1000n
28
+ const INITIAL_SUPPLY = parseUnits("1000000", 6)
29
+ const DEPOSIT_AMOUNT = parseUnits("10000", 6)
30
+
31
+ async function syncOracleAndEstimateDepositFee(amount: bigint) {
32
+ await (await oracle.sync()).wait()
33
+ return bridge.estimateDepositFee(amount)
34
+ }
35
+
36
+ async function syncOracleAndEstimateWithdrawFee(amount: bigint) {
37
+ await (await oracle.sync()).wait()
38
+ return bridge.estimateWithdrawFee(amount)
39
+ }
28
40
 
29
41
  before(async function () {
30
42
  ;[owner, user] = await setupAccounts()
31
43
  feeRecipient = owner
32
44
 
33
- // Deploy public ERC20 token (mock)
34
- const ERC20Factory = await hre.ethers.getContractFactory("ERC20Mock")
35
- publicToken = await ERC20Factory.connect(owner).deploy("Public Token", "PUB", txOpts)
45
+ const PublicFactory = await hre.ethers.getContractFactory("ERC20DecimalsMock")
46
+ publicToken = await PublicFactory.connect(owner).deploy("Public Token", "PUB", 6, txOpts)
36
47
  await publicToken.waitForDeployment()
37
48
  publicTokenAddress = await publicToken.getAddress()
38
49
 
39
- // Mint tokens to owner and user
40
50
  await publicToken.mint(owner.address, INITIAL_SUPPLY, { gasLimit: GAS_LIMIT })
41
51
  await publicToken.mint(user.address, INITIAL_SUPPLY, { gasLimit: GAS_LIMIT })
42
52
 
43
- // Deploy private ERC20 token
44
53
  const PrivateERC20Factory = await hre.ethers.getContractFactory("PrivateERC20Mock")
45
54
  privateToken = await PrivateERC20Factory.connect(owner).deploy(txOpts)
46
55
  await privateToken.waitForDeployment()
47
56
  privateTokenAddress = await privateToken.getAddress()
48
57
 
49
- // Deploy bridge
58
+ const OracleFactory = await hre.ethers.getContractFactory("CotiPriceConsumerMock")
59
+ oracle = await OracleFactory.connect(owner).deploy(txOpts)
60
+ await oracle.waitForDeployment()
61
+ await (await oracle.setRate("COTI", parseEther("1"))).wait()
62
+ await (await oracle.setRate("USDC", parseEther("1"))).wait()
63
+ const oracleAddress = await oracle.getAddress()
64
+
50
65
  const BridgeFactory = await hre.ethers.getContractFactory("PrivacyBridgeERC20Mock")
51
- bridge = await BridgeFactory.connect(owner).deploy(publicTokenAddress, privateTokenAddress, txOpts)
66
+ bridge = await BridgeFactory.connect(owner).deploy(
67
+ publicTokenAddress,
68
+ privateTokenAddress,
69
+ "USDC",
70
+ feeRecipient.address,
71
+ feeRecipient.address,
72
+ oracleAddress,
73
+ txOpts
74
+ )
52
75
  await bridge.waitForDeployment()
53
76
  bridgeAddress = await bridge.getAddress()
54
77
 
55
- // Fund bridge with public tokens for withdrawals
56
78
  await publicToken.connect(owner).transfer(bridgeAddress, INITIAL_SUPPLY / 2n, { gasLimit: GAS_LIMIT })
79
+
80
+ await owner.sendTransaction({ to: user.address, value: parseEther("50") })
57
81
  })
58
82
 
59
- describe("Fee Configuration", function () {
60
- it("should have zero fees by default", async function () {
61
- expect(await bridge.depositFeeBasisPoints()).to.equal(0n)
62
- expect(await bridge.withdrawFeeBasisPoints()).to.equal(0n)
83
+ describe("Default dynamic fee parameters", function () {
84
+ it("exposes deposit/withdraw floor, percentage divisor scale, and caps", async function () {
85
+ expect(await bridge.depositFixedFee()).to.equal(parseEther("10"))
86
+ expect(await bridge.depositPercentageBps()).to.equal(500n)
87
+ expect(await bridge.depositMaxFee()).to.equal(parseEther("3000"))
88
+ expect(await bridge.withdrawFixedFee()).to.equal(parseEther("3"))
89
+ expect(await bridge.withdrawPercentageBps()).to.equal(250n)
90
+ expect(await bridge.FEE_DIVISOR()).to.equal(1_000_000n)
63
91
  })
92
+ })
64
93
 
65
- it("should allow owner to set deposit fee", async function () {
66
- const tx = await bridge.connect(owner).setDepositFee(ONE_PERCENT_FEE, { gasLimit: GAS_LIMIT })
67
- await tx.wait()
68
-
69
- expect(await bridge.depositFeeBasisPoints()).to.equal(ONE_PERCENT_FEE)
70
- await expect(tx).to.emit(bridge, "FeeUpdated").withArgs("deposit", ONE_PERCENT_FEE)
94
+ describe("Oracle and estimates", function () {
95
+ it("reverts deploy when price oracle is zero", async function () {
96
+ const freshFactory = await hre.ethers.getContractFactory("PrivacyBridgeERC20Mock")
97
+ await expect(
98
+ freshFactory
99
+ .connect(owner)
100
+ .deploy(
101
+ publicTokenAddress,
102
+ privateTokenAddress,
103
+ "USDC",
104
+ feeRecipient.address,
105
+ feeRecipient.address,
106
+ ZeroAddress,
107
+ txOpts
108
+ )
109
+ ).to.be.revertedWithCustomError(bridge, "InvalidAddress")
71
110
  })
72
111
 
73
- it("should allow owner to set withdrawal fee", async function () {
74
- const tx = await bridge.connect(owner).setWithdrawFee(ONE_PERCENT_FEE, { gasLimit: GAS_LIMIT })
75
- await tx.wait()
76
-
77
- expect(await bridge.withdrawFeeBasisPoints()).to.equal(ONE_PERCENT_FEE)
78
- await expect(tx).to.emit(bridge, "FeeUpdated").withArgs("withdraw", ONE_PERCENT_FEE)
112
+ it("reverts setMaxOracleAge(0)", async function () {
113
+ await expect(bridge.connect(owner).setMaxOracleAge(0n, { gasLimit: GAS_LIMIT })).to.be.revertedWithCustomError(
114
+ bridge,
115
+ "OracleMaxAgeZeroDisallowed"
116
+ )
79
117
  })
80
118
 
81
- it("should allow setting fee to zero", async function () {
82
- const tx = await bridge.connect(owner).setDepositFee(0n, { gasLimit: GAS_LIMIT })
83
- await tx.wait()
84
-
85
- expect(await bridge.depositFeeBasisPoints()).to.equal(0n)
119
+ it("estimateDepositFee returns fee and timestamps", async function () {
120
+ const [fee, cotiLu, tokenLu] = await syncOracleAndEstimateDepositFee(DEPOSIT_AMOUNT)
121
+ expect(fee).to.be.gt(0n)
122
+ expect(cotiLu).to.equal(tokenLu)
86
123
  })
124
+ })
87
125
 
88
- it("should allow setting fee to maximum (10%)", async function () {
89
- const tx = await bridge.connect(owner).setDepositFee(MAX_FEE, { gasLimit: GAS_LIMIT })
126
+ describe("Operator fee configuration", function () {
127
+ it("allows operator to set deposit dynamic fee and emits DynamicFeeUpdated", async function () {
128
+ const fixedFee = parseEther("2")
129
+ const pct = 1000n
130
+ const maxFee = parseEther("500")
131
+ const tx = await bridge.connect(owner).setDepositDynamicFee(fixedFee, pct, maxFee, { gasLimit: GAS_LIMIT })
90
132
  await tx.wait()
91
-
92
- expect(await bridge.depositFeeBasisPoints()).to.equal(MAX_FEE)
93
- })
94
-
95
- it("should revert when fee exceeds maximum", async function () {
96
- await expect(
97
- bridge.connect(owner).setDepositFee(MAX_FEE + 1n, { gasLimit: GAS_LIMIT })
98
- ).to.be.revertedWithCustomError(bridge, "InvalidFee")
133
+ expect(await bridge.depositFixedFee()).to.equal(fixedFee)
134
+ expect(await bridge.depositPercentageBps()).to.equal(pct)
135
+ expect(await bridge.depositMaxFee()).to.equal(maxFee)
136
+ await expect(tx)
137
+ .to.emit(bridge, "DynamicFeeUpdated")
138
+ .withArgs("deposit", fixedFee, pct, maxFee)
99
139
  })
100
140
 
101
- it("should revert when non-owner tries to set deposit fee", async function () {
141
+ it("reverts when non-operator sets deposit dynamic fee", async function () {
142
+ const opRole = await bridge.OPERATOR_ROLE()
102
143
  await expect(
103
- bridge.connect(user).setDepositFee(ONE_PERCENT_FEE, { gasLimit: GAS_LIMIT })
104
- ).to.be.revertedWithCustomError(bridge, "OwnableUnauthorizedAccount")
144
+ bridge.connect(user).setDepositDynamicFee(parseEther("1"), 100n, parseEther("100"), {
145
+ gasLimit: GAS_LIMIT,
146
+ })
147
+ )
148
+ .to.be.revertedWithCustomError(bridge, "AccessControlUnauthorizedAccount")
149
+ .withArgs(user.address, opRole)
105
150
  })
106
151
 
107
- it("should revert when non-owner tries to set withdraw fee", async function () {
152
+ it("reverts InvalidFee when percentage exceeds MAX_FEE_UNITS", async function () {
153
+ const maxUnits = await bridge.MAX_FEE_UNITS()
108
154
  await expect(
109
- bridge.connect(user).setWithdrawFee(ONE_PERCENT_FEE, { gasLimit: GAS_LIMIT })
110
- ).to.be.revertedWithCustomError(bridge, "OwnableUnauthorizedAccount")
155
+ bridge.connect(owner).setDepositDynamicFee(parseEther("1"), maxUnits + 1n, parseEther("1000"), {
156
+ gasLimit: GAS_LIMIT,
157
+ })
158
+ ).to.be.revertedWithCustomError(bridge, "InvalidFee")
111
159
  })
112
160
 
113
- // Reset fees to zero for next tests
114
161
  after(async function () {
115
- await bridge.connect(owner).setDepositFee(0n, { gasLimit: GAS_LIMIT })
116
- await bridge.connect(owner).setWithdrawFee(0n, { gasLimit: GAS_LIMIT })
162
+ await bridge
163
+ .connect(owner)
164
+ .setDepositDynamicFee(parseEther("10"), 500n, parseEther("3000"), { gasLimit: GAS_LIMIT })
117
165
  })
118
166
  })
119
167
 
120
- describe("Deposit with Fees", function () {
121
- it("should deposit without fee when fee is zero", async function () {
122
- const balanceBefore = await publicToken.balanceOf(user.address)
168
+ describe("Deposit with native COTI fee", function () {
169
+ it("collects dynamic native fee into accumulatedCotiFees and credits liability", async function () {
170
+ const feesBefore = await bridge.accumulatedCotiFees()
171
+ const liabilityBefore = await bridge.totalUserLiability()
123
172
 
124
- await publicToken.connect(user).approve(bridgeAddress, DEPOSIT_AMOUNT, { gasLimit: GAS_LIMIT })
125
- const tx = await bridge.connect(user).deposit(DEPOSIT_AMOUNT, { gasLimit: GAS_LIMIT })
126
- await tx.wait()
127
-
128
- const balanceAfter = await publicToken.balanceOf(user.address)
129
- expect(balanceBefore - balanceAfter).to.equal(DEPOSIT_AMOUNT)
130
-
131
- // User should receive full amount in private tokens
132
- const ctBalance = await privateToken["balanceOf(address)"](user.address)
133
- const privateBalance = await user.decryptValue256(ctBalance)
134
- expect(privateBalance).to.equal(DEPOSIT_AMOUNT)
135
-
136
- expect(await bridge.accumulatedFees()).to.equal(0n)
137
- })
138
-
139
- it("should deduct 1% fee on deposit", async function () {
140
- // Set 1% fee
141
- await bridge.connect(owner).setDepositFee(ONE_PERCENT_FEE, { gasLimit: GAS_LIMIT })
142
-
143
- const expectedFee = (DEPOSIT_AMOUNT * ONE_PERCENT_FEE) / 10000n
144
- const expectedAmount = DEPOSIT_AMOUNT - expectedFee
173
+ const [fee, cotiTs, tokenTs] = await syncOracleAndEstimateDepositFee(DEPOSIT_AMOUNT)
174
+ expect(fee).to.be.gt(0n)
145
175
 
146
176
  await publicToken.connect(user).approve(bridgeAddress, DEPOSIT_AMOUNT, { gasLimit: GAS_LIMIT })
147
- const tx = await bridge.connect(user).deposit(DEPOSIT_AMOUNT, { gasLimit: GAS_LIMIT })
177
+ const tx = await bridge
178
+ .connect(user)
179
+ .deposit(DEPOSIT_AMOUNT, cotiTs, tokenTs, { gasLimit: GAS_LIMIT, value: fee })
148
180
  await tx.wait()
149
181
 
150
- // User should receive amount minus fee
151
- const ctBalance = await privateToken["balanceOf(address)"](user.address)
152
- const privateBalance = await user.decryptValue256(ctBalance)
153
- expect(privateBalance).to.equal(DEPOSIT_AMOUNT + expectedAmount) // Previous deposit + this one
154
-
155
- expect(await bridge.accumulatedFees()).to.equal(expectedFee)
182
+ expect(await bridge.accumulatedCotiFees()).to.equal(feesBefore + fee)
183
+ expect(await bridge.totalUserLiability()).to.equal(liabilityBefore + DEPOSIT_AMOUNT)
184
+ await expect(tx).to.emit(bridge, "Deposit")
156
185
  })
157
186
 
158
- it("should deduct 10% fee on deposit", async function () {
159
- // Set 10% fee
160
- await bridge.connect(owner).setDepositFee(TEN_PERCENT_FEE, { gasLimit: GAS_LIMIT })
161
-
162
- const previousFees = await bridge.accumulatedFees()
163
- const expectedFee = (DEPOSIT_AMOUNT * TEN_PERCENT_FEE) / 10000n
164
- const expectedAmount = DEPOSIT_AMOUNT - expectedFee
165
-
187
+ it("reverts deposit when msg.value is below computed fee", async function () {
188
+ const [, cotiTs, tokenTs] = await syncOracleAndEstimateDepositFee(DEPOSIT_AMOUNT)
166
189
  await publicToken.connect(user).approve(bridgeAddress, DEPOSIT_AMOUNT, { gasLimit: GAS_LIMIT })
167
- const tx = await bridge.connect(user).deposit(DEPOSIT_AMOUNT, { gasLimit: GAS_LIMIT })
168
- await tx.wait()
169
-
170
- expect(await bridge.accumulatedFees()).to.equal(previousFees + expectedFee)
171
- })
172
-
173
- // Reset fee to zero
174
- after(async function () {
175
- await bridge.connect(owner).setDepositFee(0n, { gasLimit: GAS_LIMIT })
190
+ await expect(
191
+ bridge.connect(user).deposit(DEPOSIT_AMOUNT, cotiTs, tokenTs, {
192
+ gasLimit: GAS_LIMIT,
193
+ value: 1n,
194
+ })
195
+ ).to.be.revertedWithCustomError(bridge, "InsufficientCotiFee")
176
196
  })
177
197
  })
178
198
 
179
- describe("Withdraw with Fees (via onTokenReceived)", function () {
180
- const WITHDRAW_AMOUNT = 5000n
181
-
182
- before(async function () {
183
- // Ensure user has private tokens to withdraw
184
- const ctBalance = await privateToken["balanceOf(address)"](user.address)
185
- const balance = await user.decryptValue256(ctBalance)
186
- if (balance < WITHDRAW_AMOUNT) {
187
- await publicToken.connect(user).approve(bridgeAddress, DEPOSIT_AMOUNT, { gasLimit: GAS_LIMIT })
188
- await bridge.connect(user).deposit(DEPOSIT_AMOUNT, { gasLimit: GAS_LIMIT })
189
- }
190
- })
191
-
192
- it("should withdraw without fee when fee is zero", async function () {
193
- const publicBalanceBefore = await publicToken.balanceOf(user.address)
194
-
195
- const tx = await privateToken.connect(user).transferAndCall(
196
- bridgeAddress,
197
- WITHDRAW_AMOUNT,
198
- "0x",
199
- { gasLimit: GAS_LIMIT }
200
- )
199
+ describe("withdrawCotiFees", function () {
200
+ it("allows owner to sweep accumulated native fees to feeRecipient", async function () {
201
+ const accumulated = await bridge.accumulatedCotiFees()
202
+ expect(accumulated).to.be.gt(0n)
203
+ const recipientBalBefore = await hre.ethers.provider.getBalance(feeRecipient.address)
204
+ const tx = await bridge.connect(owner).withdrawCotiFees(accumulated, { gasLimit: GAS_LIMIT })
201
205
  await tx.wait()
202
-
203
- const publicBalanceAfter = await publicToken.balanceOf(user.address)
204
- expect(publicBalanceAfter - publicBalanceBefore).to.equal(WITHDRAW_AMOUNT)
205
-
206
- // No fees accumulated
207
- expect(await bridge.accumulatedFees()).to.be.greaterThan(0n) // From previous deposit tests
208
- })
209
-
210
- it("should deduct 1% fee on withdrawal", async function () {
211
- // Set 1% fee
212
- await bridge.connect(owner).setWithdrawFee(ONE_PERCENT_FEE, { gasLimit: GAS_LIMIT })
213
-
214
- const previousFees = await bridge.accumulatedFees()
215
- const expectedFee = (WITHDRAW_AMOUNT * ONE_PERCENT_FEE) / 10000n
216
- const expectedAmount = WITHDRAW_AMOUNT - expectedFee
217
-
218
- const publicBalanceBefore = await publicToken.balanceOf(user.address)
219
-
220
- const tx = await privateToken.connect(user).transferAndCall(
221
- bridgeAddress,
222
- WITHDRAW_AMOUNT,
223
- "0x",
224
- { gasLimit: GAS_LIMIT }
225
- )
226
- await tx.wait()
227
-
228
- const publicBalanceAfter = await publicToken.balanceOf(user.address)
229
- expect(publicBalanceAfter - publicBalanceBefore).to.equal(expectedAmount)
230
-
231
- expect(await bridge.accumulatedFees()).to.equal(previousFees + expectedFee)
206
+ const recipientBalAfter = await hre.ethers.provider.getBalance(feeRecipient.address)
207
+ expect(recipientBalAfter - recipientBalBefore).to.equal(accumulated)
208
+ expect(await bridge.accumulatedCotiFees()).to.equal(0n)
232
209
  })
233
210
 
234
- it("should deduct 10% fee on withdrawal", async function () {
235
- // Set 10% fee
236
- await bridge.connect(owner).setWithdrawFee(TEN_PERCENT_FEE, { gasLimit: GAS_LIMIT })
237
-
238
- const previousFees = await bridge.accumulatedFees()
239
- const expectedFee = (WITHDRAW_AMOUNT * TEN_PERCENT_FEE) / 10000n
240
- const expectedAmount = WITHDRAW_AMOUNT - expectedFee
241
-
242
- const publicBalanceBefore = await publicToken.balanceOf(user.address)
243
-
244
- const tx = await privateToken.connect(user).transferAndCall(
245
- bridgeAddress,
246
- WITHDRAW_AMOUNT,
247
- "0x",
248
- { gasLimit: GAS_LIMIT }
249
- )
250
- await tx.wait()
251
-
252
- const publicBalanceAfter = await publicToken.balanceOf(user.address)
253
- expect(publicBalanceAfter - publicBalanceBefore).to.equal(expectedAmount)
254
-
255
- expect(await bridge.accumulatedFees()).to.equal(previousFees + expectedFee)
211
+ it("reverts withdrawCotiFees for non-owner", async function () {
212
+ await expect(
213
+ bridge.connect(user).withdrawCotiFees(1n, { gasLimit: GAS_LIMIT })
214
+ ).to.be.revertedWithCustomError(bridge, "OwnableUnauthorizedAccount")
256
215
  })
257
216
 
258
- // Reset fee to zero
259
- after(async function () {
260
- await bridge.connect(owner).setWithdrawFee(0n, { gasLimit: GAS_LIMIT })
217
+ it("reverts withdrawCotiFees with zero amount", async function () {
218
+ await expect(
219
+ bridge.connect(owner).withdrawCotiFees(0n, { gasLimit: GAS_LIMIT })
220
+ ).to.be.revertedWithCustomError(bridge, "AmountZero")
261
221
  })
262
222
  })
263
223
 
264
- describe("Fee Withdrawal", function () {
265
- it("should allow owner to withdraw accumulated fees", async function () {
266
- const accumulatedFees = await bridge.accumulatedFees()
267
- expect(accumulatedFees).to.be.greaterThan(0n)
268
-
269
- const recipientBalanceBefore = await publicToken.balanceOf(feeRecipient.address)
270
-
271
- const tx = await bridge.connect(owner).withdrawFees(
272
- feeRecipient.address,
273
- accumulatedFees,
274
- { gasLimit: GAS_LIMIT }
275
- )
276
- await tx.wait()
277
-
278
- const recipientBalanceAfter = await publicToken.balanceOf(feeRecipient.address)
279
- expect(recipientBalanceAfter - recipientBalanceBefore).to.equal(accumulatedFees)
280
-
281
- expect(await bridge.accumulatedFees()).to.equal(0n)
282
- await expect(tx).to.emit(bridge, "FeesWithdrawn").withArgs(feeRecipient.address, accumulatedFees)
283
- })
284
-
285
- it("should allow partial withdrawal of fees", async function () {
286
- // Accumulate some fees first
287
- await bridge.connect(owner).setDepositFee(ONE_PERCENT_FEE, { gasLimit: GAS_LIMIT })
224
+ describe("Withdraw path (native fee + public token)", function () {
225
+ before(async function () {
226
+ const [fee, cotiTs, tokenTs] = await syncOracleAndEstimateDepositFee(DEPOSIT_AMOUNT)
288
227
  await publicToken.connect(user).approve(bridgeAddress, DEPOSIT_AMOUNT, { gasLimit: GAS_LIMIT })
289
- await bridge.connect(user).deposit(DEPOSIT_AMOUNT, { gasLimit: GAS_LIMIT })
290
-
291
- const accumulatedFees = await bridge.accumulatedFees()
292
- const withdrawAmount = accumulatedFees / 2n
293
-
294
- await bridge.connect(owner).withdrawFees(feeRecipient.address, withdrawAmount, { gasLimit: GAS_LIMIT })
295
-
296
- expect(await bridge.accumulatedFees()).to.equal(accumulatedFees - withdrawAmount)
297
-
298
- // Reset
299
- await bridge.connect(owner).setDepositFee(0n, { gasLimit: GAS_LIMIT })
228
+ await bridge.connect(user).deposit(DEPOSIT_AMOUNT, cotiTs, tokenTs, {
229
+ gasLimit: GAS_LIMIT,
230
+ value: fee,
231
+ })
300
232
  })
301
233
 
302
- it("should revert when non-owner tries to withdraw fees", async function () {
303
- await expect(
304
- bridge.connect(user).withdrawFees(feeRecipient.address, 100n, { gasLimit: GAS_LIMIT })
305
- ).to.be.revertedWithCustomError(bridge, "OwnableUnauthorizedAccount")
306
- })
234
+ it("withdraw burns private and releases public after paying native fee", async function () {
235
+ const withdrawAmount = parseUnits("1000", 6)
236
+ const [wFee, cotiTs2, tokenTs2] = await syncOracleAndEstimateWithdrawFee(withdrawAmount)
307
237
 
308
- it("should revert when withdrawing to zero address", async function () {
309
- await expect(
310
- bridge.connect(owner).withdrawFees(hre.ethers.ZeroAddress, 100n, { gasLimit: GAS_LIMIT })
311
- ).to.be.revertedWithCustomError(bridge, "InvalidAddress")
312
- })
238
+ await privateToken.connect(user).approve(bridgeAddress, withdrawAmount, { gasLimit: GAS_LIMIT })
313
239
 
314
- it("should revert when withdrawing zero amount", async function () {
315
- await expect(
316
- bridge.connect(owner).withdrawFees(feeRecipient.address, 0n, { gasLimit: GAS_LIMIT })
317
- ).to.be.revertedWithCustomError(bridge, "AmountZero")
318
- })
319
-
320
- it("should revert when withdrawing more than accumulated fees", async function () {
321
- const accumulatedFees = await bridge.accumulatedFees()
322
- await expect(
323
- bridge.connect(owner).withdrawFees(feeRecipient.address, accumulatedFees + 1n, { gasLimit: GAS_LIMIT })
324
- ).to.be.revertedWithCustomError(bridge, "InsufficientAccumulatedFees")
240
+ const publicBefore = await publicToken.balanceOf(user.address)
241
+ const tx = await bridge.connect(user).withdraw(withdrawAmount, cotiTs2, tokenTs2, {
242
+ gasLimit: GAS_LIMIT,
243
+ value: wFee,
244
+ })
245
+ await tx.wait()
246
+ const publicAfter = await publicToken.balanceOf(user.address)
247
+ expect(publicAfter - publicBefore).to.equal(withdrawAmount)
325
248
  })
326
249
  })
327
250
  })