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