@coti-io/coti-contracts 1.1.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 (433) hide show
  1. package/.github/workflows/npm-publish.yml +19 -15
  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/messaging/PrivateMessaging.sol +456 -0
  9. package/contracts/mocks/messaging/PrivateMessagingHarness.sol +54 -0
  10. package/contracts/mocks/oracle/CotiPriceConsumerMock.sol +31 -0
  11. package/contracts/mocks/token/ERC20DecimalsMock.sol +21 -0
  12. package/contracts/mocks/token/ERC20Mock.sol +19 -0
  13. package/contracts/mocks/token/PrivateERC20/EncryptedTokenReceiverMock.sol +18 -0
  14. package/contracts/mocks/token/PrivateERC20/PrivacyBridgeERC20Mock.sol +18 -0
  15. package/contracts/mocks/token/PrivateERC20/PrivateERC20AuditorSupplyMock.sol +44 -0
  16. package/contracts/mocks/token/PrivateERC20/PrivateERC20CappedMock.sol +23 -0
  17. package/contracts/mocks/token/PrivateERC20/PrivateERC20GtCallerMock.sol +29 -0
  18. package/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.sol +9 -4
  19. package/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol +39 -0
  20. package/contracts/mocks/token/PrivateERC20/PublicReentrantTokenReceiverMock.sol +29 -0
  21. package/contracts/mocks/token/PrivateERC20/PublicTokenReceiverBoolMock.sol +18 -0
  22. package/contracts/mocks/token/PrivateERC20/PublicTokenReceiverMock.sol +12 -0
  23. package/contracts/mocks/utils/mpc/Arithmetic128TestsContract.sol +123 -0
  24. package/contracts/mocks/utils/mpc/Arithmetic256TestsContract.sol +122 -0
  25. package/contracts/mocks/utils/mpc/Bitwise128TestsContract.sol +65 -0
  26. package/contracts/mocks/utils/mpc/Bitwise256TestsContract.sol +65 -0
  27. package/contracts/mocks/utils/mpc/CheckedArithmetic128WithOverflowBitTestsContract.sol +64 -0
  28. package/contracts/mocks/utils/mpc/CheckedArithmetic256WithOverflowBitTestsContract.sol +64 -0
  29. package/contracts/mocks/utils/mpc/Comparison128TestsContract.sol +98 -0
  30. package/contracts/mocks/utils/mpc/Comparison256TestsContract.sol +98 -0
  31. package/contracts/mocks/utils/mpc/MinMax128TestsContract.sol +44 -0
  32. package/contracts/mocks/utils/mpc/MinMax256TestsContract.sol +44 -0
  33. package/contracts/mocks/utils/mpc/MinimalImplementation.sol +55 -0
  34. package/contracts/mocks/utils/mpc/MinimalProxy.sol +27 -0
  35. package/contracts/mocks/utils/mpc/MpcOperations128TestContract.sol +267 -0
  36. package/contracts/mocks/utils/mpc/MpcOperationsTestContract.sol +334 -0
  37. package/contracts/mocks/utils/mpc/Mux128TestsContract.sol +24 -0
  38. package/contracts/mocks/utils/mpc/Mux256TestsContract.sol +24 -0
  39. package/contracts/mocks/utils/mpc/OnBoard128TestsContract.sol +93 -0
  40. package/contracts/mocks/utils/mpc/OnBoard256TestsContract.sol +116 -0
  41. package/contracts/mocks/utils/mpc/PrivacyImplementationV1.sol +157 -0
  42. package/contracts/mocks/utils/mpc/PrivacyImplementationV2.sol +133 -0
  43. package/contracts/mocks/utils/mpc/PrivacyProxy.sol +137 -0
  44. package/contracts/mocks/utils/mpc/Random128TestsContract.sol +32 -0
  45. package/contracts/mocks/utils/mpc/Random256TestsContract.sol +32 -0
  46. package/contracts/mocks/utils/mpc/Shift128TestsContract.sol +36 -0
  47. package/contracts/mocks/utils/mpc/Shift256TestsContract.sol +36 -0
  48. package/contracts/mocks/utils/mpc/Transfer128TestsContract.sol +29 -0
  49. package/contracts/mocks/utils/mpc/Transfer256TestsContract.sol +29 -0
  50. package/contracts/mocks/utils/mpc/TransferWithAllowance128TestsContract.sol +32 -0
  51. package/contracts/mocks/utils/mpc/TransferWithAllowance256TestsContract.sol +32 -0
  52. package/contracts/mocks/utils/mpc/ValidateCiphertext128TestsContract.sol +59 -0
  53. package/contracts/mocks/utils/mpc/ValidateCiphertext256TestsContract.sol +63 -0
  54. package/contracts/mocks/utils/mpc/ValidateCiphertextTestsContract.sol +99 -0
  55. package/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.sol +7 -6
  56. package/contracts/node/CotiNodeRewards.sol +199 -0
  57. package/contracts/node/SoulboundNodeNFT.sol +519 -0
  58. package/contracts/oracle/CotiPriceConsumer.sol +103 -0
  59. package/contracts/oracle/ICotiPriceConsumer.sol +15 -0
  60. package/contracts/oracle/IStdReference.sol +26 -0
  61. package/contracts/privacyBridge/PrivacyBridge.sol +600 -0
  62. package/contracts/privacyBridge/PrivacyBridgeCotiNative.sol +316 -0
  63. package/contracts/privacyBridge/PrivacyBridgeERC20.sol +333 -0
  64. package/contracts/privacyBridge/PrivacyBridgeUSDCe.sol +22 -0
  65. package/contracts/privacyBridge/PrivacyBridgeUSDT.sol +23 -0
  66. package/contracts/privacyBridge/PrivacyBridgeWADA.sol +23 -0
  67. package/contracts/privacyBridge/PrivacyBridgeWBTC.sol +23 -0
  68. package/contracts/privacyBridge/PrivacyBridgeWETH.sol +23 -0
  69. package/contracts/privacyBridge/PrivacyBridgegCoti.sol +23 -0
  70. package/contracts/token/PrivateERC20/IPrivateERC20.sol +273 -40
  71. package/contracts/token/PrivateERC20/ITokenReceiver.sol +17 -0
  72. package/contracts/token/PrivateERC20/ITokenReceiverEncrypted.sol +20 -0
  73. package/contracts/token/PrivateERC20/PrivateERC20.sol +861 -152
  74. package/contracts/token/PrivateERC20/tokens/PrivateBridgedUSDC.sol +17 -0
  75. package/contracts/token/PrivateERC20/tokens/PrivateCOTI.sol +13 -0
  76. package/contracts/token/PrivateERC20/tokens/PrivateCOTITreasuryGovernanceToken.sol +17 -0
  77. package/contracts/token/PrivateERC20/tokens/PrivateTetherUSD.sol +17 -0
  78. package/contracts/token/PrivateERC20/tokens/PrivateWrappedADA.sol +17 -0
  79. package/contracts/token/PrivateERC20/tokens/PrivateWrappedBTC.sol +17 -0
  80. package/contracts/token/PrivateERC20/tokens/PrivateWrappedEther.sol +13 -0
  81. package/contracts/utils/mpc/MpcCore.sol +10780 -4962
  82. package/contracts/utils/mpc/MpcInterface.sol +7 -2
  83. package/hardhat/gasPriceBump.ts +60 -0
  84. package/hardhat.config.ts +63 -12
  85. package/package.json +22 -4
  86. package/scripts/add-bridge-operators.cjs +87 -0
  87. package/scripts/deploy-coti-price-consumer-mainnet.cjs +49 -0
  88. package/scripts/deployCotiNodeRewards.ts +51 -0
  89. package/scripts/deploySoulboundNodeNFT.ts +57 -0
  90. package/scripts/redeploy-private-and-bridges.cjs +201 -0
  91. package/scripts/set-bridge-limits-mainnet.cjs +177 -0
  92. package/scripts/verify-mainnet-private-bridges.cjs +289 -0
  93. package/sonar-project.properties +11 -0
  94. package/test/messaging/PrivateMessaging.test.ts +158 -0
  95. package/test/privacyBridge/UnifiedPrivacyBridges.test.cjs +1663 -0
  96. package/test/token/PrivateERC20/PrivacyBridge.fees.test.ts +250 -0
  97. package/test/token/PrivateERC20/PrivateERC20.test.ts +1109 -268
  98. package/test/utils/mpc/Bitwise128.test.ts +92 -0
  99. package/test/utils/mpc/Bitwise256.test.ts +101 -0
  100. package/test/utils/mpc/BuildInputText128.test.ts +398 -0
  101. package/test/utils/mpc/CheckedArithmetic128.test.ts +45 -0
  102. package/test/utils/mpc/CheckedArithmetic256.test.ts +45 -0
  103. package/test/utils/mpc/Comparison128.test.ts +48 -0
  104. package/test/utils/mpc/Comparison256.test.ts +48 -0
  105. package/test/utils/mpc/InvalidCiphertext.test.ts +179 -0
  106. package/test/utils/mpc/InvalidCiphertext128.test.ts +179 -0
  107. package/test/utils/mpc/InvalidCiphertext256.test.ts +201 -0
  108. package/test/utils/mpc/InvalidTransfer128.test.ts +166 -0
  109. package/test/utils/mpc/InvalidTransfer256.test.ts +158 -0
  110. package/test/utils/mpc/MinMax128.test.ts +44 -0
  111. package/test/utils/mpc/MinMax256.test.ts +44 -0
  112. package/test/utils/mpc/MinimalProxyDemo.test.ts +280 -0
  113. package/test/utils/mpc/MpcOperations.test.ts +589 -0
  114. package/test/utils/mpc/MpcOperations128.test.ts +632 -0
  115. package/test/utils/mpc/Mux128.test.ts +41 -0
  116. package/test/utils/mpc/Mux256.test.ts +41 -0
  117. package/test/utils/mpc/NegativeCases.test.ts +478 -0
  118. package/test/utils/mpc/NegativeCases128.test.ts +237 -0
  119. package/test/utils/mpc/NegativeCases256.test.ts +236 -0
  120. package/test/utils/mpc/OnBoard128.test.ts +90 -0
  121. package/test/utils/mpc/OnBoard256.test.ts +114 -0
  122. package/test/utils/mpc/Precompile128.test.ts +51 -0
  123. package/test/utils/mpc/Precompile256.test.ts +115 -0
  124. package/test/utils/mpc/ProxyValidation.test.ts +199 -0
  125. package/test/utils/mpc/Random128.test.ts +47 -0
  126. package/test/utils/mpc/Random256.test.ts +47 -0
  127. package/test/utils/mpc/Shift128.test.ts +41 -0
  128. package/test/utils/mpc/Shift256.test.ts +41 -0
  129. package/test/utils/mpc/Transfer128.test.ts +46 -0
  130. package/test/utils/mpc/Transfer256.test.ts +46 -0
  131. package/test/utils/mpc/TransferWithAllowance128.test.ts +48 -0
  132. package/test/utils/mpc/TransferWithAllowance256.test.ts +48 -0
  133. package/test/utils/mpc/UpgradeablePrivacyProxy.test.ts +307 -0
  134. package/test/utils/mpc/ValidateCiphertext.test.ts +221 -0
  135. package/test/utils/mpc/ValidateCiphertext256.test.ts +161 -0
  136. package/test/utils/mpc/ValidateCiphertext256Decryption.test.ts +383 -0
  137. package/test/utils/mpc/WalletEncryptionFailures.test.ts +494 -0
  138. package/test/utils/privateErc20Helpers.ts +97 -0
  139. package/typechain-types/@openzeppelin/contracts/access/AccessControl.ts +324 -0
  140. package/typechain-types/@openzeppelin/contracts/access/AccessControlEnumerable.ts +361 -0
  141. package/typechain-types/@openzeppelin/contracts/access/IAccessControl.ts +292 -0
  142. package/typechain-types/@openzeppelin/contracts/access/IAccessControlEnumerable.ts +329 -0
  143. package/typechain-types/@openzeppelin/contracts/access/Ownable.ts +153 -0
  144. package/typechain-types/@openzeppelin/contracts/access/index.ts +8 -0
  145. package/typechain-types/@openzeppelin/contracts/index.ts +4 -0
  146. package/typechain-types/@openzeppelin/contracts/security/Pausable.ts +150 -0
  147. package/typechain-types/@openzeppelin/contracts/security/index.ts +4 -0
  148. package/typechain-types/@openzeppelin/contracts/token/ERC20/ERC20.ts +330 -0
  149. package/typechain-types/@openzeppelin/contracts/token/ERC20/IERC20.ts +262 -0
  150. package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.ts +286 -0
  151. package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.ts +143 -0
  152. package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/index.ts +5 -0
  153. package/typechain-types/@openzeppelin/contracts/token/ERC20/index.ts +7 -0
  154. package/typechain-types/@openzeppelin/contracts/token/ERC721/ERC721.ts +420 -0
  155. package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.ts +420 -0
  156. package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/index.ts +4 -0
  157. package/typechain-types/@openzeppelin/contracts/token/ERC721/index.ts +3 -0
  158. package/typechain-types/@openzeppelin/contracts/token/index.ts +2 -0
  159. package/typechain-types/contracts/disperse/coinByRatio/FixedRatioCoinDisperser.ts +679 -0
  160. package/typechain-types/contracts/disperse/coinByRatio/FixedRatioCoinDisperserLeftoverS1.ts +735 -0
  161. package/typechain-types/contracts/disperse/coinByRatio/FixedRatioCoinDisperserUnlimitedWindow.ts +734 -0
  162. package/typechain-types/contracts/disperse/coinByRatio/index.ts +6 -0
  163. package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/IMintableERC20.ts +97 -0
  164. package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/IOwnable.ts +95 -0
  165. package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/MintDisperser.ts +228 -0
  166. package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/index.ts +6 -0
  167. package/typechain-types/contracts/disperse/disperseToken/TokenDisperser.ts +191 -0
  168. package/typechain-types/contracts/disperse/disperseToken/index.ts +6 -0
  169. package/typechain-types/contracts/disperse/index.ts +7 -0
  170. package/typechain-types/contracts/index.ts +10 -0
  171. package/typechain-types/contracts/messaging/PrivateMessaging.ts +871 -0
  172. package/typechain-types/contracts/messaging/index.ts +4 -0
  173. package/typechain-types/contracts/mocks/index.ts +4 -0
  174. package/typechain-types/contracts/mocks/messaging/PrivateMessagingHarness.ts +951 -0
  175. package/typechain-types/contracts/mocks/messaging/index.ts +4 -0
  176. package/typechain-types/contracts/mocks/oracle/CotiPriceConsumerMock.ts +163 -0
  177. package/typechain-types/contracts/mocks/oracle/index.ts +4 -0
  178. package/typechain-types/contracts/mocks/token/ERC20DecimalsMock.ts +349 -0
  179. package/typechain-types/contracts/mocks/token/ERC20Mock.ts +368 -0
  180. package/typechain-types/contracts/mocks/token/PrivateERC20/EncryptedTokenReceiverMock.ts +108 -0
  181. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivacyBridgeERC20Mock.ts +1892 -0
  182. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20AuditorSupplyMock.ts +1296 -0
  183. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20CappedMock.ts +1270 -0
  184. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20GtCallerMock.ts +166 -0
  185. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.ts +827 -78
  186. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/IPrivateERC20TransferAndCallEncrypted.ts +102 -0
  187. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/PrivateERC20ReentrantReceiverMock.ts +154 -0
  188. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/index.ts +5 -0
  189. package/typechain-types/contracts/mocks/token/PrivateERC20/PublicReentrantTokenReceiverMock.ts +155 -0
  190. package/typechain-types/contracts/mocks/token/PrivateERC20/PublicTokenReceiverBoolMock.ts +107 -0
  191. package/typechain-types/contracts/mocks/token/PrivateERC20/PublicTokenReceiverMock.ts +100 -0
  192. package/typechain-types/contracts/mocks/token/PrivateERC20/index.ts +10 -0
  193. package/typechain-types/contracts/mocks/token/index.ts +2 -0
  194. package/typechain-types/contracts/mocks/utils/mpc/{Arithmetic128BitTestsContract.ts → Arithmetic128TestsContract.ts} +96 -126
  195. package/typechain-types/contracts/mocks/utils/mpc/{Arithmetic256BitTestsContract.ts → Arithmetic256TestsContract.ts} +97 -133
  196. package/typechain-types/contracts/mocks/utils/mpc/{Bitwise128BitTestsContract.ts → Bitwise128TestsContract.ts} +52 -59
  197. package/typechain-types/contracts/mocks/utils/mpc/{Bitwise256BitTestsContract.ts → Bitwise256TestsContract.ts} +52 -59
  198. package/typechain-types/contracts/mocks/utils/mpc/CheckedArithmetic128WithOverflowBitTestsContract.ts +206 -0
  199. package/typechain-types/contracts/mocks/utils/mpc/CheckedArithmetic256WithOverflowBitTestsContract.ts +206 -0
  200. package/typechain-types/contracts/mocks/utils/mpc/{Comparison128BitTestsContract.ts → Comparison128TestsContract.ts} +115 -97
  201. package/typechain-types/contracts/mocks/utils/mpc/{Comparison256BitTestsContract.ts → Comparison256TestsContract.ts} +115 -97
  202. package/typechain-types/contracts/mocks/utils/mpc/MinMax128TestsContract.ts +142 -0
  203. package/typechain-types/contracts/mocks/utils/mpc/MinMax256TestsContract.ts +142 -0
  204. package/typechain-types/contracts/mocks/utils/mpc/MinimalImplementation.ts +259 -0
  205. package/typechain-types/contracts/mocks/utils/mpc/MinimalProxy.ts +90 -0
  206. package/typechain-types/contracts/mocks/utils/mpc/MpcOperations128TestContract.ts +388 -0
  207. package/typechain-types/contracts/mocks/utils/mpc/MpcOperationsTestContract.ts +455 -0
  208. package/typechain-types/contracts/mocks/utils/mpc/Mux128TestsContract.ts +109 -0
  209. package/typechain-types/contracts/mocks/utils/mpc/Mux256TestsContract.ts +109 -0
  210. package/typechain-types/contracts/mocks/utils/mpc/OnBoard128TestsContract.ts +166 -0
  211. package/typechain-types/contracts/mocks/utils/mpc/OnBoard256TestsContract.ts +194 -0
  212. package/typechain-types/contracts/mocks/utils/mpc/PrivacyImplementationV1.ts +385 -0
  213. package/typechain-types/contracts/mocks/utils/mpc/PrivacyImplementationV2.ts +441 -0
  214. package/typechain-types/contracts/mocks/utils/mpc/PrivacyProxy.ts +201 -0
  215. package/typechain-types/contracts/mocks/utils/mpc/Random128TestsContract.ts +131 -0
  216. package/typechain-types/contracts/mocks/utils/mpc/Random256TestsContract.ts +131 -0
  217. package/typechain-types/contracts/mocks/utils/mpc/Shift128TestsContract.ts +142 -0
  218. package/typechain-types/contracts/mocks/utils/mpc/Shift256TestsContract.ts +142 -0
  219. package/typechain-types/contracts/mocks/utils/mpc/Transfer128TestsContract.ts +109 -0
  220. package/typechain-types/contracts/mocks/utils/mpc/Transfer256TestsContract.ts +109 -0
  221. package/typechain-types/contracts/mocks/utils/mpc/TransferWithAllowance128TestsContract.ts +128 -0
  222. package/typechain-types/contracts/mocks/utils/mpc/TransferWithAllowance256TestsContract.ts +128 -0
  223. package/typechain-types/contracts/mocks/utils/mpc/ValidateCiphertext128TestsContract.ts +198 -0
  224. package/typechain-types/contracts/mocks/utils/mpc/ValidateCiphertext256TestsContract.ts +182 -0
  225. package/typechain-types/contracts/mocks/utils/mpc/ValidateCiphertextTestsContract.ts +257 -0
  226. package/typechain-types/contracts/mocks/utils/mpc/index.ts +32 -8
  227. package/typechain-types/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.ts +6 -6
  228. package/typechain-types/contracts/node/CotiNodeRewards.ts +566 -0
  229. package/typechain-types/contracts/node/SoulboundNodeNFT.sol/IERC5192.ts +123 -0
  230. package/typechain-types/contracts/node/SoulboundNodeNFT.sol/SoulboundNodeNFT.ts +975 -0
  231. package/typechain-types/contracts/node/SoulboundNodeNFT.sol/index.ts +5 -0
  232. package/typechain-types/contracts/node/index.ts +6 -0
  233. package/typechain-types/contracts/oracle/CotiPriceConsumer.ts +256 -0
  234. package/typechain-types/contracts/oracle/ICotiPriceConsumer.ts +119 -0
  235. package/typechain-types/contracts/oracle/IStdReference.ts +136 -0
  236. package/typechain-types/contracts/oracle/index.ts +6 -0
  237. package/typechain-types/contracts/privacyBridge/PrivacyBridge.ts +1628 -0
  238. package/typechain-types/contracts/privacyBridge/PrivacyBridgeCotiNative.ts +1870 -0
  239. package/typechain-types/contracts/privacyBridge/PrivacyBridgeERC20.sol/IHasDecimals.ts +84 -0
  240. package/typechain-types/contracts/privacyBridge/PrivacyBridgeERC20.sol/PrivacyBridgeERC20.ts +1892 -0
  241. package/typechain-types/contracts/privacyBridge/PrivacyBridgeERC20.sol/index.ts +5 -0
  242. package/typechain-types/contracts/privacyBridge/PrivacyBridgeUSDCe.ts +1892 -0
  243. package/typechain-types/contracts/privacyBridge/PrivacyBridgeUSDT.ts +1892 -0
  244. package/typechain-types/contracts/privacyBridge/PrivacyBridgeWADA.ts +1892 -0
  245. package/typechain-types/contracts/privacyBridge/PrivacyBridgeWBTC.ts +1892 -0
  246. package/typechain-types/contracts/privacyBridge/PrivacyBridgeWETH.ts +1892 -0
  247. package/typechain-types/contracts/privacyBridge/PrivacyBridgegCoti.ts +1892 -0
  248. package/typechain-types/contracts/privacyBridge/index.ts +13 -0
  249. package/typechain-types/contracts/token/PrivateERC20/IPrivateERC20.ts +507 -70
  250. package/typechain-types/contracts/token/PrivateERC20/ITokenReceiver.ts +100 -0
  251. package/typechain-types/contracts/token/PrivateERC20/ITokenReceiverEncrypted.ts +99 -0
  252. package/typechain-types/contracts/token/PrivateERC20/PrivateERC20.ts +833 -68
  253. package/typechain-types/contracts/token/PrivateERC20/index.ts +4 -0
  254. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateBridgedUSDC.ts +1270 -0
  255. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateCOTI.ts +1270 -0
  256. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateCOTITreasuryGovernanceToken.ts +1270 -0
  257. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateTetherUSD.ts +1270 -0
  258. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateWrappedADA.ts +1270 -0
  259. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateWrappedBTC.ts +1270 -0
  260. package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateWrappedEther.ts +1270 -0
  261. package/typechain-types/contracts/token/PrivateERC20/tokens/index.ts +10 -0
  262. package/typechain-types/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations.ts +111 -10
  263. package/typechain-types/factories/@openzeppelin/contracts/access/AccessControlEnumerable__factory.ts +276 -0
  264. package/typechain-types/factories/@openzeppelin/contracts/access/AccessControl__factory.ts +229 -0
  265. package/typechain-types/factories/@openzeppelin/contracts/access/IAccessControlEnumerable__factory.ts +244 -0
  266. package/typechain-types/factories/@openzeppelin/contracts/access/IAccessControl__factory.ts +197 -0
  267. package/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.ts +74 -0
  268. package/typechain-types/factories/@openzeppelin/contracts/access/index.ts +8 -0
  269. package/typechain-types/factories/@openzeppelin/contracts/index.ts +2 -0
  270. package/typechain-types/factories/@openzeppelin/contracts/security/Pausable__factory.ts +61 -0
  271. package/typechain-types/factories/@openzeppelin/contracts/security/index.ts +4 -0
  272. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/ERC20__factory.ts +356 -0
  273. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/IERC20__factory.ts +205 -0
  274. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata__factory.ts +247 -0
  275. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit__factory.ts +100 -0
  276. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/index.ts +5 -0
  277. package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/index.ts +6 -0
  278. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/ERC721__factory.ts +416 -0
  279. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata__factory.ts +355 -0
  280. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/index.ts +4 -0
  281. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/index.ts +2 -0
  282. package/typechain-types/factories/@openzeppelin/contracts/token/index.ts +1 -0
  283. package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperserLeftoverS1__factory.ts +791 -0
  284. package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperserUnlimitedWindow__factory.ts +711 -0
  285. package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperser__factory.ts +759 -0
  286. package/typechain-types/factories/contracts/disperse/coinByRatio/index.ts +6 -0
  287. package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/IMintableERC20__factory.ts +43 -0
  288. package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/IOwnable__factory.ts +35 -0
  289. package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/MintDisperser__factory.ts +203 -0
  290. package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/index.ts +6 -0
  291. package/typechain-types/factories/contracts/disperse/disperseToken/TokenDisperser__factory.ts +198 -0
  292. package/typechain-types/factories/contracts/disperse/disperseToken/index.ts +5 -0
  293. package/typechain-types/factories/contracts/disperse/index.ts +5 -0
  294. package/typechain-types/factories/contracts/index.ts +5 -0
  295. package/typechain-types/factories/contracts/messaging/PrivateMessaging__factory.ts +1035 -0
  296. package/typechain-types/factories/contracts/messaging/index.ts +4 -0
  297. package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock__factory.ts +1 -1
  298. package/typechain-types/factories/contracts/mocks/index.ts +2 -0
  299. package/typechain-types/factories/contracts/mocks/messaging/PrivateMessagingHarness__factory.ts +1161 -0
  300. package/typechain-types/factories/contracts/mocks/messaging/index.ts +4 -0
  301. package/typechain-types/factories/contracts/mocks/oracle/CotiPriceConsumerMock__factory.ts +159 -0
  302. package/typechain-types/factories/contracts/mocks/oracle/index.ts +4 -0
  303. package/typechain-types/factories/contracts/mocks/token/ERC20DecimalsMock__factory.ts +394 -0
  304. package/typechain-types/factories/contracts/mocks/token/ERC20Mock__factory.ts +392 -0
  305. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/EncryptedTokenReceiverMock__factory.ts +125 -0
  306. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivacyBridgeERC20Mock__factory.ts +1797 -0
  307. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20AuditorSupplyMock__factory.ts +1514 -0
  308. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20CappedMock__factory.ts +1466 -0
  309. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20GtCallerMock__factory.ts +165 -0
  310. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20Mock__factory.ts +975 -127
  311. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/IPrivateERC20TransferAndCallEncrypted__factory.ts +54 -0
  312. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/PrivateERC20ReentrantReceiverMock__factory.ts +159 -0
  313. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/index.ts +5 -0
  314. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PublicReentrantTokenReceiverMock__factory.ts +164 -0
  315. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PublicTokenReceiverBoolMock__factory.ts +130 -0
  316. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PublicTokenReceiverMock__factory.ts +102 -0
  317. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/index.ts +9 -0
  318. package/typechain-types/factories/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock__factory.ts +1 -1
  319. package/typechain-types/factories/contracts/mocks/token/index.ts +2 -0
  320. package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic128TestsContract__factory.ts +330 -0
  321. package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic256TestsContract__factory.ts +330 -0
  322. package/typechain-types/factories/contracts/mocks/utils/mpc/ArithmeticTestsContract__factory.ts +1 -1
  323. package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise128TestsContract__factory.ts +184 -0
  324. package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise256TestsContract__factory.ts +184 -0
  325. package/typechain-types/factories/contracts/mocks/utils/mpc/BitwiseTestsContract__factory.ts +1 -1
  326. package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmetic128WithOverflowBitTestsContract__factory.ts +203 -0
  327. package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmetic256WithOverflowBitTestsContract__factory.ts +203 -0
  328. package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmeticWIthOverflowBitTestsContract.sol/CheckedArithmeticWithOverflowBitTestsContract__factory.ts +1 -1
  329. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison128TestsContract__factory.ts +295 -0
  330. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison1TestsContract__factory.ts +1 -1
  331. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison256TestsContract__factory.ts +295 -0
  332. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison2TestsContract__factory.ts +1 -1
  333. package/typechain-types/factories/contracts/mocks/utils/mpc/MinMax128TestsContract__factory.ts +147 -0
  334. package/typechain-types/factories/contracts/mocks/utils/mpc/MinMax256TestsContract__factory.ts +147 -0
  335. package/typechain-types/factories/contracts/mocks/utils/mpc/MinMaxTestsContract__factory.ts +1 -1
  336. package/typechain-types/factories/contracts/mocks/utils/mpc/MinimalImplementation__factory.ts +263 -0
  337. package/typechain-types/factories/contracts/mocks/utils/mpc/MinimalProxy__factory.ts +104 -0
  338. package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous1TestsContract__factory.ts +1 -1
  339. package/typechain-types/factories/contracts/mocks/utils/mpc/MiscellaneousTestsContract__factory.ts +1 -1
  340. package/typechain-types/factories/contracts/mocks/utils/mpc/MpcOperations128TestContract__factory.ts +723 -0
  341. package/typechain-types/factories/contracts/mocks/utils/mpc/MpcOperationsTestContract__factory.ts +1410 -0
  342. package/typechain-types/factories/contracts/mocks/utils/mpc/Mux128TestsContract__factory.ts +115 -0
  343. package/typechain-types/factories/contracts/mocks/utils/mpc/Mux256TestsContract__factory.ts +115 -0
  344. package/typechain-types/factories/contracts/mocks/utils/mpc/OffboardToUserKeyTestContract__factory.ts +1 -1
  345. package/typechain-types/factories/contracts/mocks/utils/mpc/OnBoard128TestsContract__factory.ts +175 -0
  346. package/typechain-types/factories/contracts/mocks/utils/mpc/OnBoard256TestsContract__factory.ts +205 -0
  347. package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyImplementationV1__factory.ts +521 -0
  348. package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyImplementationV2__factory.ts +648 -0
  349. package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyProxy__factory.ts +179 -0
  350. package/typechain-types/factories/contracts/mocks/utils/mpc/Random128TestsContract__factory.ts +131 -0
  351. package/typechain-types/factories/contracts/mocks/utils/mpc/Random256TestsContract__factory.ts +131 -0
  352. package/typechain-types/factories/contracts/mocks/utils/mpc/Shift128TestsContract__factory.ts +147 -0
  353. package/typechain-types/factories/contracts/mocks/utils/mpc/Shift256TestsContract__factory.ts +147 -0
  354. package/typechain-types/factories/contracts/mocks/utils/mpc/ShiftTestsContract__factory.ts +1 -1
  355. package/typechain-types/factories/contracts/mocks/utils/mpc/StringTestsContract__factory.ts +1 -1
  356. package/typechain-types/factories/contracts/mocks/utils/mpc/Transfer128TestsContract__factory.ts +135 -0
  357. package/typechain-types/factories/contracts/mocks/utils/mpc/Transfer256TestsContract__factory.ts +135 -0
  358. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferScalarTestsContract__factory.ts +1 -1
  359. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferTestsContract__factory.ts +1 -1
  360. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance128TestsContract__factory.ts +154 -0
  361. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance256TestsContract__factory.ts +154 -0
  362. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_16TestsContract__factory.ts +1 -1
  363. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_32TestsContract__factory.ts +1 -1
  364. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_64TestsContract__factory.ts +1 -1
  365. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_8TestsContract__factory.ts +1 -1
  366. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowanceScalarTestsContract__factory.ts +1 -1
  367. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowanceTestsContract__factory.ts +1 -1
  368. package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertext128TestsContract__factory.ts +190 -0
  369. package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertext256TestsContract__factory.ts +210 -0
  370. package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertextTestsContract__factory.ts +260 -0
  371. package/typechain-types/factories/contracts/mocks/utils/mpc/index.ts +32 -8
  372. package/typechain-types/factories/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock__factory.ts +10 -28
  373. package/typechain-types/factories/contracts/node/CotiNodeRewards__factory.ts +549 -0
  374. package/typechain-types/factories/contracts/node/SoulboundNodeNFT.sol/IERC5192__factory.ts +54 -0
  375. package/typechain-types/factories/contracts/node/SoulboundNodeNFT.sol/SoulboundNodeNFT__factory.ts +947 -0
  376. package/typechain-types/factories/contracts/node/SoulboundNodeNFT.sol/index.ts +5 -0
  377. package/typechain-types/factories/contracts/node/index.ts +5 -0
  378. package/typechain-types/factories/contracts/onboard/AccountOnboard__factory.ts +1 -1
  379. package/typechain-types/factories/contracts/oracle/CotiPriceConsumer__factory.ts +295 -0
  380. package/typechain-types/factories/contracts/oracle/ICotiPriceConsumer__factory.ts +73 -0
  381. package/typechain-types/factories/contracts/oracle/IStdReference__factory.ts +107 -0
  382. package/typechain-types/factories/contracts/oracle/index.ts +6 -0
  383. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeCotiNative__factory.ts +1676 -0
  384. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeERC20.sol/IHasDecimals__factory.ts +38 -0
  385. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeERC20.sol/PrivacyBridgeERC20__factory.ts +1678 -0
  386. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeERC20.sol/index.ts +5 -0
  387. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeUSDCe__factory.ts +1782 -0
  388. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeUSDT__factory.ts +1782 -0
  389. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeWADA__factory.ts +1782 -0
  390. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeWBTC__factory.ts +1782 -0
  391. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeWETH__factory.ts +1782 -0
  392. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridge__factory.ts +1367 -0
  393. package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgegCoti__factory.ts +1782 -0
  394. package/typechain-types/factories/contracts/privacyBridge/index.ts +12 -0
  395. package/typechain-types/factories/contracts/token/PrivateERC20/IPrivateERC20__factory.ts +639 -61
  396. package/typechain-types/factories/contracts/token/PrivateERC20/ITokenReceiverEncrypted__factory.ts +53 -0
  397. package/typechain-types/factories/contracts/token/PrivateERC20/ITokenReceiver__factory.ts +54 -0
  398. package/typechain-types/factories/contracts/token/PrivateERC20/PrivateERC20__factory.ts +986 -120
  399. package/typechain-types/factories/contracts/token/PrivateERC20/index.ts +3 -0
  400. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateBridgedUSDC__factory.ts +1445 -0
  401. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateCOTITreasuryGovernanceToken__factory.ts +1451 -0
  402. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateCOTI__factory.ts +1442 -0
  403. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateTetherUSD__factory.ts +1445 -0
  404. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateWrappedADA__factory.ts +1445 -0
  405. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateWrappedBTC__factory.ts +1445 -0
  406. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateWrappedEther__factory.ts +1451 -0
  407. package/typechain-types/factories/contracts/token/PrivateERC20/tokens/index.ts +10 -0
  408. package/typechain-types/factories/contracts/utils/mpc/MpcCore__factory.ts +1 -1
  409. package/typechain-types/factories/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations__factory.ts +126 -0
  410. package/typechain-types/hardhat.d.ts +1772 -278
  411. package/typechain-types/index.ts +182 -16
  412. package/contracts/mocks/utils/mpc/Arithmetic128BitTestsContract.sol +0 -260
  413. package/contracts/mocks/utils/mpc/Arithmetic256BitTestsContract.sol +0 -264
  414. package/contracts/mocks/utils/mpc/Bitwise128BitTestsContract.sol +0 -91
  415. package/contracts/mocks/utils/mpc/Bitwise256BitTestsContract.sol +0 -91
  416. package/contracts/mocks/utils/mpc/Comparison128BitTestsContract.sol +0 -158
  417. package/contracts/mocks/utils/mpc/Comparison256BitTestsContract.sol +0 -158
  418. package/contracts/mocks/utils/mpc/Miscellaneous128BitTestsContract.sol +0 -185
  419. package/contracts/mocks/utils/mpc/Miscellaneous256BitTestsContract.sol +0 -190
  420. package/contracts/mocks/utils/mpc/README.md +0 -486
  421. package/test/utils/mpc/Unsigned128BitIntegers.test.ts +0 -945
  422. package/test/utils/mpc/Unsigned256BitIntegers.test.ts +0 -1124
  423. package/test/utils/mpc/helpers.ts +0 -77
  424. package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous128BitTestsContract.ts +0 -302
  425. package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous256BitTestsContract.ts +0 -322
  426. package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic128BitTestsContract__factory.ts +0 -349
  427. package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic256BitTestsContract__factory.ts +0 -364
  428. package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise128BitTestsContract__factory.ts +0 -182
  429. package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise256BitTestsContract__factory.ts +0 -182
  430. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison128BitTestsContract__factory.ts +0 -255
  431. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison256BitTestsContract__factory.ts +0 -255
  432. package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous128BitTestsContract__factory.ts +0 -332
  433. package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous256BitTestsContract__factory.ts +0 -380
@@ -0,0 +1,519 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.20;
3
+
4
+ import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
5
+ import "@openzeppelin/contracts/access/Ownable.sol";
6
+ import "@openzeppelin/contracts/utils/Strings.sol";
7
+ import "@openzeppelin/contracts/utils/Base64.sol";
8
+
9
+ /**
10
+ * @title SoulboundNodeNFT
11
+ * @notice ERC-721 Soulbound Node Identity NFT with ERC-5192 support
12
+ *
13
+ * @dev High-level properties:
14
+ * - Non-transferable (Soulbound)
15
+ * - ERC-5192 compliant (locked NFTs)
16
+ * - Only contract owner can mint
17
+ * - One NFT per wallet enforced
18
+ * - Minting can be paused by owner
19
+ * - Unlimited total supply
20
+ * - Burnable by token owner or contract owner
21
+ * - On-chain base64-encoded JSON metadata
22
+ * - Uses custom Solidity errors (gas efficient)
23
+ *
24
+ * @dev Intended use case:
25
+ * - Node / validator identity
26
+ * - Credentials
27
+ * - Non-transferable attestations
28
+ */
29
+
30
+ /// -----------------------------------------------------------------------
31
+ /// ERC-5192: Minimal Soulbound NFTs
32
+ /// -----------------------------------------------------------------------
33
+
34
+ /**
35
+ * @dev ERC-5192 interface for signaling soulbound (non-transferable) NFTs.
36
+ * See: https://eips.ethereum.org/EIPS/eip-5192
37
+ */
38
+ interface IERC5192 {
39
+ /// @notice Emitted when a token is locked (becomes soulbound)
40
+ event Locked(uint256 tokenId);
41
+
42
+ /// @notice Returns whether a token is locked (non-transferable)
43
+ function locked(uint256 tokenId) external view returns (bool);
44
+ }
45
+
46
+ /// -----------------------------------------------------------------------
47
+ /// Custom errors (cheaper than revert strings)
48
+ /// -----------------------------------------------------------------------
49
+
50
+ error InvalidRecipient();
51
+ error AlreadyOwnsNodeNFT();
52
+ error NodeNameRequired();
53
+ error NodeNameTooLong();
54
+ error SocialURLTooLong();
55
+ error NonexistentToken();
56
+ error SoulboundOperation();
57
+ error NotAuthorized();
58
+ error MintPaused();
59
+
60
+ /// -----------------------------------------------------------------------
61
+ /// Main contract
62
+ /// -----------------------------------------------------------------------
63
+
64
+ contract SoulboundNodeNFT is ERC721, Ownable, IERC5192 {
65
+ using Strings for uint256;
66
+
67
+ /// @notice Last minted token ID (starts at 0, first mint = 1)
68
+ uint256 public nextTokenId;
69
+
70
+ /// @notice Maximum length (in bytes) for name and socialURL
71
+ uint256 public constant MAX_TEXT_BYTES = 150;
72
+
73
+ /**
74
+ * @notice If true, minting is paused.
75
+ * @dev Burn operations are NOT affected.
76
+ */
77
+ bool public mintPaused;
78
+
79
+ /// @notice Node-specific metadata stored on-chain
80
+ struct NodeData {
81
+ string name; // required
82
+ string image; // optional (ipfs:// or https://)
83
+ string socialURL; // optional
84
+ bool isHot; // true = hot node, false = cold node
85
+ }
86
+
87
+ /// @dev tokenId => NodeData
88
+ mapping(uint256 => NodeData) private _nodeData;
89
+
90
+ /// @notice Emitted when a new node NFT is minted
91
+ event NodeMinted(
92
+ address indexed to,
93
+ uint256 indexed tokenId,
94
+ string name,
95
+ string image,
96
+ string socialURL
97
+ );
98
+
99
+ /// @notice Emitted when mint pause state is changed
100
+ event MintPausedSet(bool paused);
101
+
102
+ /// @notice Emitted when a token's image URI is updated
103
+ event ImageURIUpdated(uint256 indexed tokenId, string newImageURI);
104
+
105
+ /// @notice Emitted when a token's social URL is updated
106
+ event SocialURLUpdated(uint256 indexed tokenId, string newSocialURL);
107
+
108
+ /// @notice Emitted when a token's node name is updated
109
+ event NodeNameUpdated(uint256 indexed tokenId, string newNodeName);
110
+
111
+ /// @notice Emitted when a token's hot/cold status is updated
112
+ event NodeHotStatusUpdated(uint256 indexed tokenId, bool isHot);
113
+
114
+ /**
115
+ * @notice Contract constructor
116
+ * @param name_ ERC-721 collection name
117
+ * @param symbol_ ERC-721 collection symbol
118
+ * @param initialOwner Address that becomes contract owner
119
+ */
120
+ constructor(
121
+ string memory name_,
122
+ string memory symbol_,
123
+ address initialOwner
124
+ ) ERC721(name_, symbol_) {
125
+ _transferOwnership(initialOwner);
126
+ mintPaused = false;
127
+ }
128
+
129
+ /// -----------------------------------------------------------------------
130
+ /// Admin: pause / unpause minting
131
+ /// -----------------------------------------------------------------------
132
+
133
+ /**
134
+ * @notice Pause minting operations
135
+ * @dev Only the contract owner can call this function
136
+ * @dev Only affects minting, not burning operations
137
+ * @dev Emits MintPausedSet event with true
138
+ */
139
+ function pauseMint() external onlyOwner {
140
+ mintPaused = true;
141
+ emit MintPausedSet(true);
142
+ }
143
+
144
+ /**
145
+ * @notice Unpause minting operations
146
+ * @dev Only the contract owner can call this function
147
+ * @dev Emits MintPausedSet event with false
148
+ */
149
+ function unpauseMint() external onlyOwner {
150
+ mintPaused = false;
151
+ emit MintPausedSet(false);
152
+ }
153
+
154
+ /// -----------------------------------------------------------------------
155
+ /// ERC-5192 (Soulbound signaling)
156
+ /// -----------------------------------------------------------------------
157
+
158
+ /**
159
+ * @notice Check whether a token is locked (soulbound)
160
+ * @param tokenId Token ID to check
161
+ * @return Always true for existing tokens
162
+ * @dev Reverts if token does not exist
163
+ */
164
+ function locked(uint256 tokenId) external view override returns (bool) {
165
+ if (_ownerOf(tokenId) == address(0)) revert NonexistentToken();
166
+ return true;
167
+ }
168
+
169
+ /**
170
+ * @notice ERC-165 interface support
171
+ * @param interfaceId Interface identifier to check
172
+ * @return true if the contract supports the interface, false otherwise
173
+ * @dev Supports ERC721, ERC165, and ERC5192 interfaces
174
+ */
175
+ function supportsInterface(
176
+ bytes4 interfaceId
177
+ ) public view override(ERC721) returns (bool) {
178
+ return
179
+ interfaceId == type(IERC5192).interfaceId ||
180
+ super.supportsInterface(interfaceId);
181
+ }
182
+
183
+ /// -----------------------------------------------------------------------
184
+ /// Minting (ONLY OWNER)
185
+ /// -----------------------------------------------------------------------
186
+
187
+ /**
188
+ * @notice Mint a new soulbound Node NFT
189
+ * @param to Recipient address
190
+ * @param name Node name (required, <=150 bytes)
191
+ * @param image Optional image URI
192
+ * @param socialURL Optional social URL (<=150 bytes)
193
+ * @return tokenId The ID of the newly minted token
194
+ * @dev Restrictions:
195
+ * - Only contract owner can mint
196
+ * - Minting must not be paused
197
+ * - Recipient may own at most one NFT
198
+ * @dev Reverts if:
199
+ * - Minting is paused (MintPaused)
200
+ * - to is the zero address (InvalidRecipient)
201
+ * - to already owns an NFT (AlreadyOwnsNodeNFT)
202
+ * - name is empty (NodeNameRequired)
203
+ * - name exceeds MAX_TEXT_BYTES (NodeNameTooLong)
204
+ * - socialURL exceeds MAX_TEXT_BYTES (SocialURLTooLong)
205
+ * @dev Emits Locked and NodeMinted events
206
+ */
207
+ function mintNode(
208
+ address to,
209
+ string calldata name,
210
+ string calldata image,
211
+ string calldata socialURL
212
+ ) external onlyOwner returns (uint256 tokenId) {
213
+ if (mintPaused) revert MintPaused();
214
+ if (to == address(0)) revert InvalidRecipient();
215
+ if (balanceOf(to) != 0) revert AlreadyOwnsNodeNFT();
216
+ if (bytes(name).length == 0) revert NodeNameRequired();
217
+ if (bytes(name).length > MAX_TEXT_BYTES) revert NodeNameTooLong();
218
+ if (bytes(socialURL).length > MAX_TEXT_BYTES) revert SocialURLTooLong();
219
+
220
+ tokenId = ++nextTokenId;
221
+
222
+ _safeMint(to, tokenId);
223
+
224
+ _nodeData[tokenId] = NodeData({
225
+ name: name,
226
+ image: image,
227
+ socialURL: socialURL,
228
+ // Default new nodes to hot; can be updated later via setNodeHotStatus
229
+ isHot: true
230
+ });
231
+
232
+ emit Locked(tokenId);
233
+ emit NodeMinted(to, tokenId, name, image, socialURL);
234
+ }
235
+
236
+ /**
237
+ * @notice Get node metadata for a token
238
+ * @param tokenId Token ID to query
239
+ * @return NodeData struct containing name, image, and socialURL
240
+ * @dev Reverts if the token does not exist (NonexistentToken)
241
+ */
242
+ function nodeData(uint256 tokenId) external view returns (NodeData memory) {
243
+ if (_ownerOf(tokenId) == address(0)) revert NonexistentToken();
244
+ return _nodeData[tokenId];
245
+ }
246
+
247
+ /**
248
+ * @notice Returns whether a node is marked as hot or cold
249
+ * @param tokenId Token ID to query
250
+ * @return isHot True if the node is hot, false if cold
251
+ * @dev Reverts if the token does not exist (NonexistentToken)
252
+ */
253
+ function isHotNode(uint256 tokenId) external view returns (bool isHot) {
254
+ if (_ownerOf(tokenId) == address(0)) revert NonexistentToken();
255
+ return _nodeData[tokenId].isHot;
256
+ }
257
+
258
+ /**
259
+ * @notice Get token ID for a given owner address
260
+ * @param owner The address to query
261
+ * @return tokenId The ID of the token owned by the address, or 0 if none
262
+ * @dev Iterates over token IDs. Since mints are sequential and users only own 1, this is a linear scan.
263
+ * In a production environment with millions of NFTs an off-chain indexer is preferred,
264
+ * but for this scale and testnet use-case, this convenience function works.
265
+ */
266
+ function tokenOfOwner(address owner) external view returns (uint256) {
267
+ if (owner == address(0)) revert InvalidRecipient();
268
+ if (balanceOf(owner) == 0) return 0;
269
+
270
+ // Since the user only has 1 NFT due to the mint restriction, we can find it
271
+ for (uint256 i = 1; i <= nextTokenId; ++i) {
272
+ if (_ownerOf(i) == owner) {
273
+ return i;
274
+ }
275
+ }
276
+ return 0; // Should never reach here if balanceOf > 0, but fallback
277
+ }
278
+
279
+ /**
280
+ * @notice Update the image URI for a token
281
+ * @param tokenId Token ID to update
282
+ * @param newImageURI New image URI (ipfs:// or https://)
283
+ * @dev Token owner or contract owner can call this function
284
+ * @dev Reverts if:
285
+ * - Token does not exist (NonexistentToken)
286
+ * - Caller is not authorized (NotAuthorized)
287
+ * @dev Emits ImageURIUpdated event
288
+ */
289
+ function setImageURI(
290
+ uint256 tokenId,
291
+ string calldata newImageURI
292
+ ) external {
293
+ address tokenOwner = _ownerOf(tokenId);
294
+ if (tokenOwner == address(0)) revert NonexistentToken();
295
+ if (msg.sender != tokenOwner && msg.sender != owner())
296
+ revert NotAuthorized();
297
+
298
+ _nodeData[tokenId].image = newImageURI;
299
+ emit ImageURIUpdated(tokenId, newImageURI);
300
+ }
301
+
302
+ /**
303
+ * @notice Update the social URL for a token
304
+ * @param tokenId Token ID to update
305
+ * @param newSocialURL New social URL (<=150 bytes)
306
+ * @dev Token owner or contract owner can call this function
307
+ * @dev Reverts if:
308
+ * - Token does not exist (NonexistentToken)
309
+ * - newSocialURL exceeds MAX_TEXT_BYTES (SocialURLTooLong)
310
+ * - Caller is not authorized (NotAuthorized)
311
+ * @dev Emits SocialURLUpdated event
312
+ */
313
+ function setSocialURL(
314
+ uint256 tokenId,
315
+ string calldata newSocialURL
316
+ ) external {
317
+ address tokenOwner = _ownerOf(tokenId);
318
+ if (tokenOwner == address(0)) revert NonexistentToken();
319
+ if (msg.sender != tokenOwner && msg.sender != owner())
320
+ revert NotAuthorized();
321
+ if (bytes(newSocialURL).length > MAX_TEXT_BYTES)
322
+ revert SocialURLTooLong();
323
+
324
+ _nodeData[tokenId].socialURL = newSocialURL;
325
+ emit SocialURLUpdated(tokenId, newSocialURL);
326
+ }
327
+
328
+ /**
329
+ * @notice Update the node name for a token
330
+ * @param tokenId Token ID to update
331
+ * @param newNodeName New node name (required, <=150 bytes)
332
+ * @dev Token owner or contract owner can call this function
333
+ * @dev Reverts if:
334
+ * - Token does not exist (NonexistentToken)
335
+ * - newNodeName is empty (NodeNameRequired)
336
+ * - newNodeName exceeds MAX_TEXT_BYTES (NodeNameTooLong)
337
+ * - Caller is not authorized (NotAuthorized)
338
+ * @dev Emits NodeNameUpdated event
339
+ */
340
+ function setNodeName(
341
+ uint256 tokenId,
342
+ string calldata newNodeName
343
+ ) external {
344
+ address tokenOwner = _ownerOf(tokenId);
345
+ if (tokenOwner == address(0)) revert NonexistentToken();
346
+ if (msg.sender != tokenOwner && msg.sender != owner())
347
+ revert NotAuthorized();
348
+ if (bytes(newNodeName).length == 0) revert NodeNameRequired();
349
+ if (bytes(newNodeName).length > MAX_TEXT_BYTES)
350
+ revert NodeNameTooLong();
351
+
352
+ _nodeData[tokenId].name = newNodeName;
353
+ emit NodeNameUpdated(tokenId, newNodeName);
354
+ }
355
+
356
+ /**
357
+ * @notice Update the hot/cold status for a node
358
+ * @param tokenId Token ID to update
359
+ * @param isHot True to mark the node as hot, false to mark as cold
360
+ * @dev Contract owner can call this function
361
+ * @dev Reverts if:
362
+ * - Token does not exist (NonexistentToken)
363
+ * - Caller is not authorized (NotAuthorized)
364
+ * @dev Emits NodeHotStatusUpdated event
365
+ */
366
+ function setNodeHotStatus(uint256 tokenId, bool isHot) external {
367
+ address tokenOwner = _ownerOf(tokenId);
368
+ if (tokenOwner == address(0)) revert NonexistentToken();
369
+ if (msg.sender != owner()) revert NotAuthorized();
370
+
371
+ _nodeData[tokenId].isHot = isHot;
372
+ emit NodeHotStatusUpdated(tokenId, isHot);
373
+ }
374
+
375
+ /// -----------------------------------------------------------------------
376
+ /// Soulbound restrictions (disable transfers & approvals)
377
+ /// -----------------------------------------------------------------------
378
+
379
+ /**
380
+ * @notice Approve an address to transfer a token (disabled for soulbound NFTs)
381
+ * @dev Always reverts with SoulboundOperation error since tokens cannot be transferred
382
+ * @dev Parameters match ERC721 interface but are unused
383
+ */
384
+ function approve(
385
+ address /* operator */,
386
+ uint256 /* tokenId */
387
+ ) public pure override {
388
+ revert SoulboundOperation();
389
+ }
390
+
391
+ /**
392
+ * @notice Approve an operator for all tokens (disabled for soulbound NFTs)
393
+ * @dev Always reverts with SoulboundOperation error since tokens cannot be transferred
394
+ * @dev Parameters match ERC721 interface but are unused
395
+ */
396
+ function setApprovalForAll(
397
+ address /* operator */,
398
+ bool /* approved */
399
+ ) public pure override {
400
+ revert SoulboundOperation();
401
+ }
402
+
403
+ /**
404
+ * @notice Transfer a token (disabled for soulbound NFTs)
405
+ * @dev Always reverts with SoulboundOperation error since tokens are soulbound
406
+ * @dev Parameters match ERC721 interface but are unused
407
+ */
408
+ function transferFrom(
409
+ address /* from */,
410
+ address /* to */,
411
+ uint256 /* tokenId */
412
+ ) public pure override {
413
+ revert SoulboundOperation();
414
+ }
415
+
416
+ /// -----------------------------------------------------------------------
417
+ /// Burning
418
+ /// -----------------------------------------------------------------------
419
+
420
+ /**
421
+ * @notice Burn a token, permanently removing it from circulation
422
+ * @param tokenId Token ID to burn
423
+ * @dev Callable by token owner or contract owner
424
+ * @dev Reverts if:
425
+ * - Caller is not the token owner and not the contract owner (NotAuthorized)
426
+ * - Token does not exist
427
+ * @dev Deletes the associated node data after burning
428
+ */
429
+ function burn(uint256 tokenId) external {
430
+ address tokenOwner = ownerOf(tokenId);
431
+ if (msg.sender != tokenOwner && msg.sender != owner())
432
+ revert NotAuthorized();
433
+
434
+ _burn(tokenId);
435
+ delete _nodeData[tokenId];
436
+ }
437
+
438
+ /// -----------------------------------------------------------------------
439
+ /// Metadata (on-chain JSON)
440
+ /// -----------------------------------------------------------------------
441
+
442
+ /**
443
+ * @notice Return token metadata as base64-encoded JSON
444
+ * @param tokenId Token ID to query
445
+ * @return A base64-encoded JSON data URI containing the token metadata
446
+ * @dev Returns on-chain JSON metadata as a data URI (data:application/json;base64,...)
447
+ * @dev Includes token name, description, attributes (node name, social URL), and optional image
448
+ * @dev Reverts if the token does not exist (NonexistentToken)
449
+ */
450
+ function tokenURI(
451
+ uint256 tokenId
452
+ ) public view override returns (string memory) {
453
+ if (_ownerOf(tokenId) == address(0)) revert NonexistentToken();
454
+
455
+ NodeData memory d = _nodeData[tokenId];
456
+
457
+ string memory attributes = string.concat(
458
+ '[{"trait_type":"Node name","value":"',
459
+ _escapeJSON(d.name),
460
+ '"}',
461
+ ',{"trait_type":"Social URL","value":"',
462
+ _escapeJSON(d.socialURL),
463
+ '"}]'
464
+ );
465
+
466
+ string memory imagePart = bytes(d.image).length == 0
467
+ ? ""
468
+ : string.concat(',"image":"', _escapeJSON(d.image), '"');
469
+
470
+ string memory json = string.concat(
471
+ '{"name":"Node #',
472
+ tokenId.toString(),
473
+ '","description":"Soulbound Node NFT",',
474
+ '"attributes":',
475
+ attributes,
476
+ imagePart,
477
+ "}"
478
+ );
479
+
480
+ return
481
+ string.concat(
482
+ "data:application/json;base64,",
483
+ Base64.encode(bytes(json))
484
+ );
485
+ }
486
+
487
+ /// -----------------------------------------------------------------------
488
+ /// Internal helpers
489
+ /// -----------------------------------------------------------------------
490
+
491
+ /**
492
+ * @notice Escape special JSON characters in a string
493
+ * @param s The string to escape
494
+ * @return The escaped string with backslashes added before quotes and backslashes
495
+ * @dev Used internally to safely embed strings in JSON metadata
496
+ * @dev Escapes double quotes (") and backslashes (\) by prefixing them with a backslash
497
+ */
498
+ function _escapeJSON(
499
+ string memory s
500
+ ) internal pure returns (string memory) {
501
+ bytes memory b = bytes(s);
502
+ bytes memory out = new bytes(b.length * 2);
503
+ uint256 j;
504
+
505
+ for (uint256 i = 0; i < b.length; i++) {
506
+ bytes1 c = b[i];
507
+ if (c == bytes1('"') || c == bytes1("\\")) {
508
+ out[j++] = bytes1("\\");
509
+ out[j++] = c;
510
+ } else {
511
+ out[j++] = c;
512
+ }
513
+ }
514
+
515
+ bytes memory trimmed = new bytes(j);
516
+ for (uint256 k = 0; k < j; k++) trimmed[k] = out[k];
517
+ return string(trimmed);
518
+ }
519
+ }
@@ -0,0 +1,103 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.20;
3
+
4
+ import "./IStdReference.sol";
5
+
6
+ /**
7
+ * @title CotiPriceConsumer
8
+ * @notice Retrieves token/USD prices from the Band Protocol oracle.
9
+ * @dev All prices returned by Band Protocol are scaled by 1e18.
10
+ * For example, a rate of 50000000000000000 means $0.05.
11
+ */
12
+ contract CotiPriceConsumer {
13
+ /// @notice Band Protocol StdReferenceProxy on COTI .
14
+ IStdReference public immutable ref;
15
+
16
+ /// @notice Maximum acceptable age (in seconds) for oracle data before it is considered stale.
17
+ uint256 public maxStaleness;
18
+
19
+ /// @notice Emitted when the staleness threshold is updated.
20
+ event MaxStalenessUpdated(uint256 oldValue, uint256 newValue);
21
+
22
+ /// @notice Thrown when the oracle data is older than the allowed staleness window.
23
+ error StaleOracleData(uint256 lastUpdated, uint256 threshold);
24
+
25
+ address public owner;
26
+
27
+ /// @notice Minimum allowed staleness threshold (1 hour).
28
+ uint256 public constant MIN_STALENESS = 1 hours;
29
+
30
+ /// @notice Thrown when the staleness value is below the minimum.
31
+ error StalenessTooLow(uint256 provided, uint256 minimum);
32
+
33
+ modifier onlyOwner() {
34
+ require(msg.sender == owner, "CotiPriceConsumer: caller is not the owner");
35
+ _;
36
+ }
37
+
38
+ /**
39
+ * @param _ref Address of the Band Protocol StdReferenceProxy contract.
40
+ * @param _maxStaleness Maximum acceptable data age in seconds (0 = no staleness check).
41
+ */
42
+ constructor(address _ref, uint256 _maxStaleness) {
43
+ require(_ref != address(0), "CotiPriceConsumer: zero ref address");
44
+ if (_maxStaleness < MIN_STALENESS) revert StalenessTooLow(_maxStaleness, MIN_STALENESS);
45
+ ref = IStdReference(_ref);
46
+ maxStaleness = _maxStaleness;
47
+ owner = msg.sender;
48
+ }
49
+
50
+ /// @notice Returns the rate, last update timestamp, and current block timestamp for any base/USD pair.
51
+ /// @return rate The price scaled by 1e18
52
+ /// @return lastUpdated Block timestamp when the oracle data was last updated
53
+ /// @return blockTimestamp The current block.timestamp
54
+ function getPriceWithMeta(string calldata _base) external view returns (uint256 rate, uint256 lastUpdated, uint256 blockTimestamp) {
55
+ IStdReference.ReferenceData memory data = _getPrice(_base);
56
+ rate = data.rate;
57
+ lastUpdated = data.lastUpdatedBase;
58
+ blockTimestamp = block.timestamp;
59
+ }
60
+
61
+
62
+ // ──────────────────────────────────────────────────────────────────────
63
+ // Internal helper
64
+ // ──────────────────────────────────────────────────────────────────────
65
+
66
+ /**
67
+ * @dev Queries the Band oracle for `_base`/USD and optionally enforces staleness.
68
+ */
69
+ function _getPrice(string memory _base) internal view returns (IStdReference.ReferenceData memory data) {
70
+ data = ref.getReferenceData(_base, "USD");
71
+
72
+ uint256 threshold = block.timestamp - maxStaleness;
73
+ if (data.lastUpdatedBase < threshold) {
74
+ revert StaleOracleData(data.lastUpdatedBase, threshold);
75
+ }
76
+ }
77
+
78
+
79
+ // ──────────────────────────────────────────────────────────────────────
80
+ // Generic getter — query any symbol the oracle supports
81
+ // ──────────────────────────────────────────────────────────────────────
82
+
83
+ /// @notice Returns the rate for an arbitrary base/USD pair scaled by 1e18.
84
+ function getPrice(string calldata _base) external view returns (uint256) {
85
+ return _getPrice(_base).rate;
86
+ }
87
+
88
+
89
+ /// @notice Returns the full ReferenceData for an arbitrary base/USD pair.
90
+ function getPriceData(string calldata _base) external view returns (IStdReference.ReferenceData memory) {
91
+ return _getPrice(_base);
92
+ }
93
+
94
+ /**
95
+ * @notice Updates the maximum staleness threshold.
96
+ * @param _maxStaleness New threshold in seconds (0 = disable check).
97
+ */
98
+ function setMaxStaleness(uint256 _maxStaleness) external onlyOwner {
99
+ if (_maxStaleness < MIN_STALENESS) revert StalenessTooLow(_maxStaleness, MIN_STALENESS);
100
+ emit MaxStalenessUpdated(maxStaleness, _maxStaleness);
101
+ maxStaleness = _maxStaleness;
102
+ }
103
+ }
@@ -0,0 +1,15 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.19;
3
+
4
+ /**
5
+ * @title ICotiPriceConsumer
6
+ * @notice Minimal interface for the CotiPriceConsumer oracle used by the bridge
7
+ */
8
+ interface ICotiPriceConsumer {
9
+
10
+ /// @notice Returns the rate for an arbitrary base/USD pair scaled by 1e18.
11
+ function getPrice(string calldata _base) external view returns (uint256);
12
+
13
+ /// @notice Returns rate + metadata for any base/USD pair.
14
+ function getPriceWithMeta(string calldata _base) external view returns (uint256 rate, uint256 lastUpdated, uint256 blockTimestamp);
15
+ }
@@ -0,0 +1,26 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.20;
3
+
4
+ /**
5
+ * @title IStdReference
6
+ * @notice Band Protocol Standard Reference interface for querying price data.
7
+ */
8
+ interface IStdReference {
9
+ struct ReferenceData {
10
+ uint256 rate; // base/quote exchange rate, scaled by 1e18
11
+ uint256 lastUpdatedBase; // UNIX epoch when the base price was last updated
12
+ uint256 lastUpdatedQuote; // UNIX epoch when the quote price was last updated
13
+ }
14
+
15
+ /// @notice Returns the price data for a single base/quote pair.
16
+ function getReferenceData(
17
+ string memory _base,
18
+ string memory _quote
19
+ ) external view returns (ReferenceData memory);
20
+
21
+ /// @notice Returns the price data for multiple base/quote pairs.
22
+ function getReferenceDataBulk(
23
+ string[] memory _bases,
24
+ string[] memory _quotes
25
+ ) external view returns (ReferenceData[] memory);
26
+ }