@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.
- package/.github/workflows/npm-publish.yml +19 -15
- 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/messaging/PrivateMessaging.sol +456 -0
- package/contracts/mocks/messaging/PrivateMessagingHarness.sol +54 -0
- package/contracts/mocks/oracle/CotiPriceConsumerMock.sol +31 -0
- package/contracts/mocks/token/ERC20DecimalsMock.sol +21 -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 +18 -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/oracle/CotiPriceConsumer.sol +103 -0
- package/contracts/oracle/ICotiPriceConsumer.sol +15 -0
- package/contracts/oracle/IStdReference.sol +26 -0
- package/contracts/privacyBridge/PrivacyBridge.sol +600 -0
- package/contracts/privacyBridge/PrivacyBridgeCotiNative.sol +316 -0
- package/contracts/privacyBridge/PrivacyBridgeERC20.sol +333 -0
- package/contracts/privacyBridge/PrivacyBridgeUSDCe.sol +22 -0
- package/contracts/privacyBridge/PrivacyBridgeUSDT.sol +23 -0
- package/contracts/privacyBridge/PrivacyBridgeWADA.sol +23 -0
- package/contracts/privacyBridge/PrivacyBridgeWBTC.sol +23 -0
- package/contracts/privacyBridge/PrivacyBridgeWETH.sol +23 -0
- package/contracts/privacyBridge/PrivacyBridgegCoti.sol +23 -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 +63 -12
- package/package.json +22 -4
- package/scripts/add-bridge-operators.cjs +87 -0
- package/scripts/deploy-coti-price-consumer-mainnet.cjs +49 -0
- package/scripts/deployCotiNodeRewards.ts +51 -0
- package/scripts/deploySoulboundNodeNFT.ts +57 -0
- package/scripts/redeploy-private-and-bridges.cjs +201 -0
- package/scripts/set-bridge-limits-mainnet.cjs +177 -0
- package/scripts/verify-mainnet-private-bridges.cjs +289 -0
- package/sonar-project.properties +11 -0
- package/test/messaging/PrivateMessaging.test.ts +158 -0
- package/test/privacyBridge/UnifiedPrivacyBridges.test.cjs +1663 -0
- package/test/token/PrivateERC20/PrivacyBridge.fees.test.ts +250 -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/AccessControl.ts +324 -0
- package/typechain-types/@openzeppelin/contracts/access/AccessControlEnumerable.ts +361 -0
- package/typechain-types/@openzeppelin/contracts/access/IAccessControl.ts +292 -0
- package/typechain-types/@openzeppelin/contracts/access/IAccessControlEnumerable.ts +329 -0
- package/typechain-types/@openzeppelin/contracts/access/Ownable.ts +153 -0
- package/typechain-types/@openzeppelin/contracts/access/index.ts +8 -0
- package/typechain-types/@openzeppelin/contracts/index.ts +4 -0
- package/typechain-types/@openzeppelin/contracts/security/Pausable.ts +150 -0
- package/typechain-types/@openzeppelin/contracts/security/index.ts +4 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC20/ERC20.ts +330 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC20/IERC20.ts +262 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.ts +286 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.ts +143 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/index.ts +5 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC20/index.ts +7 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/ERC721.ts +420 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.ts +420 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/index.ts +4 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/index.ts +3 -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/FixedRatioCoinDisperserLeftoverS1.ts +735 -0
- package/typechain-types/contracts/disperse/coinByRatio/FixedRatioCoinDisperserUnlimitedWindow.ts +734 -0
- package/typechain-types/contracts/disperse/coinByRatio/index.ts +6 -0
- package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/IMintableERC20.ts +97 -0
- package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/IOwnable.ts +95 -0
- package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/MintDisperser.ts +228 -0
- package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/index.ts +6 -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 +10 -0
- package/typechain-types/contracts/messaging/PrivateMessaging.ts +871 -0
- package/typechain-types/contracts/messaging/index.ts +4 -0
- package/typechain-types/contracts/mocks/index.ts +4 -0
- package/typechain-types/contracts/mocks/messaging/PrivateMessagingHarness.ts +951 -0
- package/typechain-types/contracts/mocks/messaging/index.ts +4 -0
- package/typechain-types/contracts/mocks/oracle/CotiPriceConsumerMock.ts +163 -0
- package/typechain-types/contracts/mocks/oracle/index.ts +4 -0
- package/typechain-types/contracts/mocks/token/ERC20DecimalsMock.ts +349 -0
- package/typechain-types/contracts/mocks/token/ERC20Mock.ts +368 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/EncryptedTokenReceiverMock.ts +108 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivacyBridgeERC20Mock.ts +1892 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20AuditorSupplyMock.ts +1296 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20CappedMock.ts +1270 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20GtCallerMock.ts +166 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.ts +827 -78
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/IPrivateERC20TransferAndCallEncrypted.ts +102 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/PrivateERC20ReentrantReceiverMock.ts +154 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/index.ts +5 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PublicReentrantTokenReceiverMock.ts +155 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PublicTokenReceiverBoolMock.ts +107 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PublicTokenReceiverMock.ts +100 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/index.ts +10 -0
- package/typechain-types/contracts/mocks/token/index.ts +2 -0
- package/typechain-types/contracts/mocks/utils/mpc/{Arithmetic128BitTestsContract.ts → Arithmetic128TestsContract.ts} +96 -126
- package/typechain-types/contracts/mocks/utils/mpc/{Arithmetic256BitTestsContract.ts → Arithmetic256TestsContract.ts} +97 -133
- package/typechain-types/contracts/mocks/utils/mpc/{Bitwise128BitTestsContract.ts → Bitwise128TestsContract.ts} +52 -59
- package/typechain-types/contracts/mocks/utils/mpc/{Bitwise256BitTestsContract.ts → Bitwise256TestsContract.ts} +52 -59
- 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/{Comparison128BitTestsContract.ts → Comparison128TestsContract.ts} +115 -97
- package/typechain-types/contracts/mocks/utils/mpc/{Comparison256BitTestsContract.ts → Comparison256TestsContract.ts} +115 -97
- 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/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.ts +6 -6
- package/typechain-types/contracts/node/CotiNodeRewards.ts +566 -0
- package/typechain-types/contracts/node/SoulboundNodeNFT.sol/IERC5192.ts +123 -0
- package/typechain-types/contracts/node/SoulboundNodeNFT.sol/SoulboundNodeNFT.ts +975 -0
- package/typechain-types/contracts/node/SoulboundNodeNFT.sol/index.ts +5 -0
- package/typechain-types/contracts/node/index.ts +6 -0
- package/typechain-types/contracts/oracle/CotiPriceConsumer.ts +256 -0
- package/typechain-types/contracts/oracle/ICotiPriceConsumer.ts +119 -0
- package/typechain-types/contracts/oracle/IStdReference.ts +136 -0
- package/typechain-types/contracts/oracle/index.ts +6 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridge.ts +1628 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridgeCotiNative.ts +1870 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridgeERC20.sol/IHasDecimals.ts +84 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridgeERC20.sol/PrivacyBridgeERC20.ts +1892 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridgeERC20.sol/index.ts +5 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridgeUSDCe.ts +1892 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridgeUSDT.ts +1892 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridgeWADA.ts +1892 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridgeWBTC.ts +1892 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridgeWETH.ts +1892 -0
- package/typechain-types/contracts/privacyBridge/PrivacyBridgegCoti.ts +1892 -0
- package/typechain-types/contracts/privacyBridge/index.ts +13 -0
- package/typechain-types/contracts/token/PrivateERC20/IPrivateERC20.ts +507 -70
- package/typechain-types/contracts/token/PrivateERC20/ITokenReceiver.ts +100 -0
- package/typechain-types/contracts/token/PrivateERC20/ITokenReceiverEncrypted.ts +99 -0
- package/typechain-types/contracts/token/PrivateERC20/PrivateERC20.ts +833 -68
- package/typechain-types/contracts/token/PrivateERC20/index.ts +4 -0
- package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateBridgedUSDC.ts +1270 -0
- package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateCOTI.ts +1270 -0
- package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateCOTITreasuryGovernanceToken.ts +1270 -0
- package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateTetherUSD.ts +1270 -0
- package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateWrappedADA.ts +1270 -0
- package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateWrappedBTC.ts +1270 -0
- package/typechain-types/contracts/token/PrivateERC20/tokens/PrivateWrappedEther.ts +1270 -0
- package/typechain-types/contracts/token/PrivateERC20/tokens/index.ts +10 -0
- package/typechain-types/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations.ts +111 -10
- package/typechain-types/factories/@openzeppelin/contracts/access/AccessControlEnumerable__factory.ts +276 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/AccessControl__factory.ts +229 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/IAccessControlEnumerable__factory.ts +244 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/IAccessControl__factory.ts +197 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.ts +74 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/index.ts +8 -0
- package/typechain-types/factories/@openzeppelin/contracts/index.ts +2 -0
- package/typechain-types/factories/@openzeppelin/contracts/security/Pausable__factory.ts +61 -0
- package/typechain-types/factories/@openzeppelin/contracts/security/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/ERC20__factory.ts +356 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/IERC20__factory.ts +205 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata__factory.ts +247 -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 +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/index.ts +6 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/ERC721__factory.ts +416 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata__factory.ts +355 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/index.ts +2 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/index.ts +1 -0
- package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperserLeftoverS1__factory.ts +791 -0
- package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperserUnlimitedWindow__factory.ts +711 -0
- package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperser__factory.ts +759 -0
- package/typechain-types/factories/contracts/disperse/coinByRatio/index.ts +6 -0
- package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/IMintableERC20__factory.ts +43 -0
- package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/IOwnable__factory.ts +35 -0
- package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/MintDisperser__factory.ts +203 -0
- package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/index.ts +6 -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 +5 -0
- package/typechain-types/factories/contracts/messaging/PrivateMessaging__factory.ts +1035 -0
- package/typechain-types/factories/contracts/messaging/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/index.ts +2 -0
- package/typechain-types/factories/contracts/mocks/messaging/PrivateMessagingHarness__factory.ts +1161 -0
- package/typechain-types/factories/contracts/mocks/messaging/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/oracle/CotiPriceConsumerMock__factory.ts +159 -0
- package/typechain-types/factories/contracts/mocks/oracle/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/token/ERC20DecimalsMock__factory.ts +394 -0
- package/typechain-types/factories/contracts/mocks/token/ERC20Mock__factory.ts +392 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/EncryptedTokenReceiverMock__factory.ts +125 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivacyBridgeERC20Mock__factory.ts +1797 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20AuditorSupplyMock__factory.ts +1514 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20CappedMock__factory.ts +1466 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20GtCallerMock__factory.ts +165 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20Mock__factory.ts +975 -127
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/IPrivateERC20TransferAndCallEncrypted__factory.ts +54 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/PrivateERC20ReentrantReceiverMock__factory.ts +159 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol/index.ts +5 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PublicReentrantTokenReceiverMock__factory.ts +164 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PublicTokenReceiverBoolMock__factory.ts +130 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PublicTokenReceiverMock__factory.ts +102 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/index.ts +9 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/token/index.ts +2 -0
- 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 +10 -28
- package/typechain-types/factories/contracts/node/CotiNodeRewards__factory.ts +549 -0
- package/typechain-types/factories/contracts/node/SoulboundNodeNFT.sol/IERC5192__factory.ts +54 -0
- package/typechain-types/factories/contracts/node/SoulboundNodeNFT.sol/SoulboundNodeNFT__factory.ts +947 -0
- package/typechain-types/factories/contracts/node/SoulboundNodeNFT.sol/index.ts +5 -0
- package/typechain-types/factories/contracts/node/index.ts +5 -0
- package/typechain-types/factories/contracts/onboard/AccountOnboard__factory.ts +1 -1
- package/typechain-types/factories/contracts/oracle/CotiPriceConsumer__factory.ts +295 -0
- package/typechain-types/factories/contracts/oracle/ICotiPriceConsumer__factory.ts +73 -0
- package/typechain-types/factories/contracts/oracle/IStdReference__factory.ts +107 -0
- package/typechain-types/factories/contracts/oracle/index.ts +6 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeCotiNative__factory.ts +1676 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeERC20.sol/IHasDecimals__factory.ts +38 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeERC20.sol/PrivacyBridgeERC20__factory.ts +1678 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeERC20.sol/index.ts +5 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeUSDCe__factory.ts +1782 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeUSDT__factory.ts +1782 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeWADA__factory.ts +1782 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeWBTC__factory.ts +1782 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgeWETH__factory.ts +1782 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridge__factory.ts +1367 -0
- package/typechain-types/factories/contracts/privacyBridge/PrivacyBridgegCoti__factory.ts +1782 -0
- package/typechain-types/factories/contracts/privacyBridge/index.ts +12 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/IPrivateERC20__factory.ts +639 -61
- package/typechain-types/factories/contracts/token/PrivateERC20/ITokenReceiverEncrypted__factory.ts +53 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/ITokenReceiver__factory.ts +54 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/PrivateERC20__factory.ts +986 -120
- package/typechain-types/factories/contracts/token/PrivateERC20/index.ts +3 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateBridgedUSDC__factory.ts +1445 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateCOTITreasuryGovernanceToken__factory.ts +1451 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateCOTI__factory.ts +1442 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateTetherUSD__factory.ts +1445 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateWrappedADA__factory.ts +1445 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateWrappedBTC__factory.ts +1445 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/tokens/PrivateWrappedEther__factory.ts +1451 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/tokens/index.ts +10 -0
- package/typechain-types/factories/contracts/utils/mpc/MpcCore__factory.ts +1 -1
- package/typechain-types/factories/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations__factory.ts +126 -0
- package/typechain-types/hardhat.d.ts +1772 -278
- package/typechain-types/index.ts +182 -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
- package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous128BitTestsContract.ts +0 -302
- package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous256BitTestsContract.ts +0 -322
- package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic128BitTestsContract__factory.ts +0 -349
- package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic256BitTestsContract__factory.ts +0 -364
- package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise128BitTestsContract__factory.ts +0 -182
- package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise256BitTestsContract__factory.ts +0 -182
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison128BitTestsContract__factory.ts +0 -255
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison256BitTestsContract__factory.ts +0 -255
- package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous128BitTestsContract__factory.ts +0 -332
- package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous256BitTestsContract__factory.ts +0 -380
|
@@ -4,18 +4,96 @@ pragma solidity ^0.8.19;
|
|
|
4
4
|
|
|
5
5
|
import {Context} from "@openzeppelin/contracts/utils/Context.sol";
|
|
6
6
|
import {IPrivateERC20} from "./IPrivateERC20.sol";
|
|
7
|
+
import {ITokenReceiver} from "./ITokenReceiver.sol";
|
|
8
|
+
import {ITokenReceiverEncrypted} from "./ITokenReceiverEncrypted.sol";
|
|
9
|
+
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
|
|
10
|
+
import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
|
11
|
+
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
|
|
7
12
|
import "../../utils/mpc/MpcCore.sol";
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
/*
|
|
15
|
+
THIS IS THE 256 BIT VERSION OF PRIVATE ERC20.
|
|
16
|
+
|
|
17
|
+
Key Features:
|
|
18
|
+
- Full uint256 support (no scaling factors)
|
|
19
|
+
- AccessControl (for Bridge Integrations)
|
|
20
|
+
- ERC165 Support - Tokens Discoverability
|
|
21
|
+
- Payable Tokens with TransferAndCall (ERC677-like callback pattern)
|
|
22
|
+
- Encrypted Operations (Mint, Burn, Transfer, Approve)
|
|
23
|
+
|
|
24
|
+
Failure semantics (integrators and contract callers):
|
|
25
|
+
- State-changing operations that move value or change supply/allowances are designed to follow a
|
|
26
|
+
revert-on-failure model: if the MPC layer reports that the core update did not succeed, the
|
|
27
|
+
transaction reverts (enforced in {_update} for mint/transfer/burn, and via explicit requires
|
|
28
|
+
where an operation composes multiple steps). Success is therefore implied by a completed call
|
|
29
|
+
that did not revert. Pure/view helpers and read paths that only return ciphertext or onboarded
|
|
30
|
+
values are not “success/failure” token operations in that sense.
|
|
31
|
+
|
|
32
|
+
Storage encoding ({_safeOnboard} — see implementation NatSpec):
|
|
33
|
+
- Uninitialized or zeroed `ctUint256` slots read as both 128-bit limbs zero. The implementation
|
|
34
|
+
treats that as **canonical empty** and maps it to `MpcCore.setPublic256(0)` without calling
|
|
35
|
+
`MpcCore.onBoard` (gas). Any other pattern is onboarded with `MpcCore.onBoard`.
|
|
36
|
+
- Successful updates in this contract only write ciphertext via `MpcCore.offBoard` after MPC
|
|
37
|
+
success, so balances, allowances, and aggregate supply stay consistent with the precompile.
|
|
38
|
+
|
|
39
|
+
Trust assumptions (deploy only when these hold):
|
|
40
|
+
- Deploy only on chains where the MPC precompile at address(0x64) is part of the trusted base.
|
|
41
|
+
You explicitly trust that network: its consensus, node/precompile implementation, and upgrade
|
|
42
|
+
policy. All balances and transfers are ultimately defined by MPC results this contract cannot
|
|
43
|
+
independently verify. If the precompile were malicious or buggy, accounting integrity could fail
|
|
44
|
+
in ways Solidity cannot fix on-chain. Optional mitigations (e.g. admin pause, monitoring) only
|
|
45
|
+
limit further damage after suspicion; they do not prove past MPC correctness or roll back state.
|
|
46
|
+
If the chain allows precompile upgrades, consider monitoring and circuit-breakers.
|
|
47
|
+
- There is **no** trust-minimized substitute on-chain: auditors and integrators should record which
|
|
48
|
+
chain ID, precompile address, and build/version they rely on, and treat MPC upgrades as **trusted**
|
|
49
|
+
migrations unless your organization runs independent off-chain verification against published specs.
|
|
50
|
+
- MINTER_ROLE must only pass valid amounts to mint/mintGt/mint(itUint256). If the MPC layer
|
|
51
|
+
enforces bounds or validity, that dependency applies.
|
|
52
|
+
- Minting is bounded by {supplyCap} (override in concrete tokens like {decimals}); enforced in {_update}.
|
|
53
|
+
- Integrators — {totalSupply} vs supply: the default {totalSupply} returns 0 and does **not** reflect
|
|
54
|
+
circulating aggregate supply (see {totalSupply} NatSpec). Do not plug this token into protocols that
|
|
55
|
+
assume ERC-20 `totalSupply` semantics. Use {supplyCap} only as the **mint ceiling** parameter; for
|
|
56
|
+
actual supply, use off-chain indexing or a dedicated extension (e.g. auditor reencryption mocks).
|
|
57
|
+
- Gas: multiple precompile calls per transfer/approve; no unbounded loops. Document expected
|
|
58
|
+
gas ranges for common operations if needed for integrators.
|
|
59
|
+
- Reentrancy: balance/allowance-changing entry points use nonReentrant so a transferAndCall
|
|
60
|
+
receiver cannot nest transferFrom/transfer/approve/increaseAllowance/decreaseAllowance/mint/burn in the same transaction.
|
|
61
|
+
- transferAndCall: public-amount overload uses {ITokenReceiver}; encrypted-amount overload uses
|
|
62
|
+
{ITokenReceiverEncrypted} (no plaintext amount in callback). Receivers are still fully trusted
|
|
63
|
+
for callback behavior.
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @title PrivateERC20
|
|
68
|
+
* @notice Privacy-oriented ERC-20 base whose balances and transfer rules are enforced through MPC (`MpcCore`), not plain EVM arithmetic on cleartext balances.
|
|
69
|
+
* @dev **MPC trust model:** This contract treats the MPC precompile as the source of truth for
|
|
70
|
+
* garbled/encrypted `uint256` operations. There is no on-chain fallback that validates MPC
|
|
71
|
+
* soundness. See {IPrivateERC20} trust assumptions and the file-level comment block above for
|
|
72
|
+
* deployment and integration requirements. Pausing and `AccessControl` mitigate operational
|
|
73
|
+
* risk; they do not prove MPC correctness retroactively.
|
|
74
|
+
*/
|
|
75
|
+
abstract contract PrivateERC20 is
|
|
76
|
+
Context,
|
|
77
|
+
ERC165,
|
|
78
|
+
IPrivateERC20,
|
|
79
|
+
AccessControl,
|
|
80
|
+
ReentrancyGuard
|
|
81
|
+
{
|
|
82
|
+
uint256 private constant MAX_UINT_256 = type(uint256).max;
|
|
83
|
+
|
|
84
|
+
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
|
|
85
|
+
|
|
86
|
+
/// @dev Controls whether public uint256 operations are allowed (mint/burn/transfer/transferFrom/approve/transferAndCall with clear values).
|
|
87
|
+
bool public publicAmountsEnabled;
|
|
11
88
|
|
|
12
89
|
mapping(address account => address) private _accountEncryptionAddress;
|
|
13
90
|
|
|
14
|
-
mapping(address account =>
|
|
91
|
+
mapping(address account => utUint256) private _balances;
|
|
15
92
|
|
|
16
|
-
mapping(address account => mapping(address spender => Allowance))
|
|
93
|
+
mapping(address account => mapping(address spender => Allowance))
|
|
94
|
+
private _allowances;
|
|
17
95
|
|
|
18
|
-
|
|
96
|
+
ctUint256 private _totalSupply;
|
|
19
97
|
|
|
20
98
|
string private _name;
|
|
21
99
|
|
|
@@ -45,15 +123,54 @@ abstract contract PrivateERC20 is Context, IPrivateERC20 {
|
|
|
45
123
|
*/
|
|
46
124
|
error ERC20InvalidSpender(address spender);
|
|
47
125
|
|
|
126
|
+
/**
|
|
127
|
+
* @dev Indicates that clear (public) uint256 operations are disabled for this token.
|
|
128
|
+
*/
|
|
129
|
+
error PublicAmountsDisabled();
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @dev Indicates that transferAndCall was used with a non-contract recipient.
|
|
133
|
+
* transferAndCall is for contract-to-contract flows; the recipient must have code.
|
|
134
|
+
*/
|
|
135
|
+
error TransferAndCallRequiresContract(address to);
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @dev Indicates that a transfer to self (from == to) was attempted.
|
|
139
|
+
* CRITICAL: Self-transfer is explicitly disallowed. The MPC precompile behavior when
|
|
140
|
+
* from == to is undefined; allowing it could lead to incorrect balance updates or
|
|
141
|
+
* inconsistent state. All transfer/transferFrom paths go through _transfer and are
|
|
142
|
+
* therefore protected.
|
|
143
|
+
*/
|
|
144
|
+
error ERC20SelfTransferNotAllowed(address account);
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @dev Indicates that name or symbol was empty in the constructor.
|
|
148
|
+
*/
|
|
149
|
+
error ERC20InvalidMetadata();
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @dev Emitted when the admin enables or disables public uint256 operations.
|
|
153
|
+
*/
|
|
154
|
+
event PublicAmountsEnabledSet(bool enabled);
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @dev Emitted when an account sets or changes its encryption address for balance reencryption.
|
|
158
|
+
*/
|
|
159
|
+
event AccountEncryptionAddressSet(address indexed account, address indexed newAddress);
|
|
160
|
+
|
|
48
161
|
/**
|
|
49
162
|
* @dev Sets the values for {name} and {symbol}.
|
|
50
163
|
*
|
|
51
|
-
*
|
|
164
|
+
* Both of these values are immutable: they can only be set once during
|
|
52
165
|
* construction.
|
|
53
166
|
*/
|
|
54
167
|
constructor(string memory name_, string memory symbol_) {
|
|
168
|
+
if (bytes(name_).length == 0) revert ERC20InvalidMetadata();
|
|
169
|
+
if (bytes(symbol_).length == 0) revert ERC20InvalidMetadata();
|
|
55
170
|
_name = name_;
|
|
56
171
|
_symbol = symbol_;
|
|
172
|
+
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
|
|
173
|
+
publicAmountsEnabled = true;
|
|
57
174
|
}
|
|
58
175
|
|
|
59
176
|
/**
|
|
@@ -85,49 +202,219 @@ abstract contract PrivateERC20 is Context, IPrivateERC20 {
|
|
|
85
202
|
* {IPrivateERC20-balanceOf} and {IPrivateERC20-transfer}.
|
|
86
203
|
*/
|
|
87
204
|
function decimals() public view virtual returns (uint8) {
|
|
88
|
-
return
|
|
205
|
+
return 18;
|
|
89
206
|
}
|
|
90
207
|
|
|
91
208
|
/**
|
|
92
|
-
* @dev
|
|
209
|
+
* @dev Configurable **upper bound** on how much can be minted in aggregate (checked in {_update} against
|
|
210
|
+
* the encrypted total in storage). This is **not** “current circulating supply” and **not** a live
|
|
211
|
+
* substitute for {totalSupply} on a normal ERC-20. Default: `type(uint256).max`.
|
|
212
|
+
*
|
|
213
|
+
* Override in concrete tokens when a fixed cap is required (e.g. with {decimals} or tokenomics).
|
|
93
214
|
*/
|
|
94
|
-
function
|
|
215
|
+
function supplyCap() public view virtual returns (uint256) {
|
|
216
|
+
return type(uint256).max;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* @inheritdoc IPrivateERC20
|
|
221
|
+
* @notice Deliberately **not** standard ERC-20 circulating supply: returns `0` in this implementation.
|
|
222
|
+
*
|
|
223
|
+
* Do **not** use for vault share math, pro-rata rewards, or oracles that expect `totalSupply` to reflect
|
|
224
|
+
* aggregate issuance. For the mint **ceiling**, use {supplyCap}. For optional encrypted aggregate supply
|
|
225
|
+
* to a designated party, see examples under `contracts/mocks/token/PrivateERC20/`.
|
|
226
|
+
*/
|
|
227
|
+
function totalSupply() public view virtual override returns (uint256) {
|
|
95
228
|
return 0;
|
|
96
229
|
}
|
|
97
230
|
|
|
98
|
-
function
|
|
231
|
+
function mint(
|
|
232
|
+
address to,
|
|
233
|
+
uint256 amount
|
|
234
|
+
) public virtual override onlyRole(MINTER_ROLE) nonReentrant {
|
|
235
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
236
|
+
if (!publicAmountsEnabled) revert PublicAmountsDisabled();
|
|
237
|
+
gtUint256 gtAmount = MpcCore.setPublic256(amount);
|
|
238
|
+
_mint(to, gtAmount);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @dev Mint an already-garbled amount without re-wrapping.
|
|
243
|
+
* Intended for contract-to-contract flows that already hold a gtUint256.
|
|
244
|
+
* Trust: MINTER_ROLE must only pass valid amounts. Reverts if {_update} reports MPC failure.
|
|
245
|
+
*/
|
|
246
|
+
function mintGt(
|
|
247
|
+
address to,
|
|
248
|
+
gtUint256 gtAmount
|
|
249
|
+
) public virtual override onlyRole(MINTER_ROLE) nonReentrant {
|
|
250
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
251
|
+
_mint(to, gtAmount);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* @dev Mint with encrypted (itUint256) amount.
|
|
256
|
+
* Trust: MINTER_ROLE must only pass valid amounts. Reverts if {_update} reports MPC failure.
|
|
257
|
+
*/
|
|
258
|
+
function mint(
|
|
259
|
+
address to,
|
|
260
|
+
itUint256 calldata amount
|
|
261
|
+
) public virtual override onlyRole(MINTER_ROLE) nonReentrant {
|
|
262
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
263
|
+
gtUint256 gtAmount = MpcCore.validateCiphertext(amount);
|
|
264
|
+
_mint(to, gtAmount);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function burn(uint256 amount) public virtual override nonReentrant {
|
|
268
|
+
if (!publicAmountsEnabled) revert PublicAmountsDisabled();
|
|
269
|
+
gtUint256 gtAmount = MpcCore.setPublic256(amount);
|
|
270
|
+
_burn(_msgSender(), gtAmount);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* @dev Burn an already-garbled amount without re-wrapping.
|
|
275
|
+
* Intended for contract-to-contract flows that already hold a gtUint256.
|
|
276
|
+
* Reverts if {_update} reports MPC failure.
|
|
277
|
+
*/
|
|
278
|
+
function burnGt(gtUint256 gtAmount) public virtual override nonReentrant {
|
|
279
|
+
_burn(_msgSender(), gtAmount);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/// @dev Reverts if {_update} reports MPC failure.
|
|
283
|
+
function burn(itUint256 calldata amount) public virtual override nonReentrant {
|
|
284
|
+
gtUint256 gtAmount = MpcCore.validateCiphertext(amount);
|
|
285
|
+
_burn(_msgSender(), gtAmount);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* @dev Transfers tokens to `to` then calls onTokenReceived(to, amount, data).
|
|
290
|
+
* Only use with trusted receivers. `nonReentrant` blocks re-entry into this function and
|
|
291
|
+
* into other guarded entry points (transfer, transferFrom, approve, burn, mint, etc.);
|
|
292
|
+
* the receiver must still be trusted for protocol correctness.
|
|
293
|
+
*/
|
|
294
|
+
function transferAndCall(
|
|
295
|
+
address to,
|
|
296
|
+
uint256 amount,
|
|
297
|
+
bytes calldata data
|
|
298
|
+
) public virtual override nonReentrant {
|
|
299
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
300
|
+
if (to.code.length == 0) revert TransferAndCallRequiresContract(to);
|
|
301
|
+
if (!publicAmountsEnabled) revert PublicAmountsDisabled();
|
|
302
|
+
|
|
303
|
+
gtUint256 gtAmount = MpcCore.setPublic256(amount);
|
|
304
|
+
address sender = _msgSender();
|
|
305
|
+
_transfer(sender, to, gtAmount);
|
|
306
|
+
|
|
307
|
+
require(
|
|
308
|
+
ITokenReceiver(to).onTokenReceived(sender, amount, data),
|
|
309
|
+
"Callback failed"
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* @dev Transfers an encrypted amount to `to`, then calls {ITokenReceiverEncrypted-onPrivateTransferReceived}.
|
|
315
|
+
* The callback does **not** receive a plaintext amount (privacy). Receivers must implement
|
|
316
|
+
* {ITokenReceiverEncrypted}; do not use {ITokenReceiver} for this overload.
|
|
317
|
+
* Only use with **trusted** receivers; see {transferAndCall(address,uint256,bytes)} for reentrancy scope.
|
|
318
|
+
*/
|
|
319
|
+
function transferAndCall(
|
|
320
|
+
address to,
|
|
321
|
+
itUint256 calldata amount,
|
|
322
|
+
bytes calldata data
|
|
323
|
+
) public virtual override nonReentrant {
|
|
324
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
325
|
+
if (to.code.length == 0) revert TransferAndCallRequiresContract(to);
|
|
326
|
+
|
|
327
|
+
gtUint256 gtAmount = MpcCore.validateCiphertext(amount);
|
|
328
|
+
address sender = _msgSender();
|
|
329
|
+
_transfer(sender, to, gtAmount);
|
|
330
|
+
|
|
331
|
+
require(
|
|
332
|
+
ITokenReceiverEncrypted(to).onPrivateTransferReceived(sender, data),
|
|
333
|
+
"Callback failed"
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function supportsInterface(
|
|
338
|
+
bytes4 interfaceId
|
|
339
|
+
) public view virtual override(AccessControl, ERC165) returns (bool) {
|
|
340
|
+
return
|
|
341
|
+
interfaceId == type(IPrivateERC20).interfaceId ||
|
|
342
|
+
super.supportsInterface(interfaceId);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* @dev Returns the encryption address set for `account` for balance reencryption.
|
|
347
|
+
*
|
|
348
|
+
* Requirements:
|
|
349
|
+
* - `account` must not be the zero address.
|
|
350
|
+
*/
|
|
351
|
+
function accountEncryptionAddress(
|
|
352
|
+
address account
|
|
353
|
+
) public view returns (address) {
|
|
354
|
+
if (account == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
99
355
|
return _accountEncryptionAddress[account];
|
|
100
|
-
}
|
|
356
|
+
}
|
|
101
357
|
|
|
102
358
|
/**
|
|
103
359
|
* @dev See {IPrivateERC20-balanceOf}.
|
|
360
|
+
*
|
|
361
|
+
* Requirements:
|
|
362
|
+
* - `account` must not be the zero address.
|
|
104
363
|
*/
|
|
105
|
-
function balanceOf(
|
|
364
|
+
function balanceOf(
|
|
365
|
+
address account
|
|
366
|
+
) public view virtual override returns (ctUint256 memory) {
|
|
367
|
+
if (account == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
106
368
|
return _balances[account].userCiphertext;
|
|
107
369
|
}
|
|
108
370
|
|
|
109
371
|
/**
|
|
110
372
|
* @dev See {IPrivateERC20-balanceOf}.
|
|
373
|
+
* May perform external calls to the MPC precompile via _getBalance.
|
|
374
|
+
* Do not use in staticcall or view contexts; off-chain code must not assume this is view-safe.
|
|
111
375
|
*/
|
|
112
|
-
function balanceOf() public virtual returns (
|
|
376
|
+
function balanceOf() public virtual override returns (gtUint256) {
|
|
113
377
|
return _getBalance(_msgSender());
|
|
114
378
|
}
|
|
115
379
|
|
|
116
380
|
/**
|
|
117
381
|
* @dev See {IPrivateERC20-setAccountEncryptionAddress}.
|
|
118
|
-
*
|
|
382
|
+
*
|
|
119
383
|
* NOTE: This will not reencrypt your allowances until they are changed
|
|
120
384
|
*/
|
|
121
|
-
function setAccountEncryptionAddress(
|
|
122
|
-
|
|
385
|
+
function setAccountEncryptionAddress(
|
|
386
|
+
address offBoardAddress
|
|
387
|
+
) public virtual override nonReentrant returns (bool) {
|
|
388
|
+
if (offBoardAddress == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
389
|
+
|
|
390
|
+
gtUint256 gtBalance = _getBalance(_msgSender());
|
|
391
|
+
|
|
392
|
+
// Compute new user ciphertext first; reverts if precompile fails. Only then update storage
|
|
393
|
+
// so that we never leave _accountEncryptionAddress and userCiphertext out of sync.
|
|
394
|
+
ctUint256 memory newUserCiphertext = MpcCore.offBoardToUser(
|
|
395
|
+
gtBalance,
|
|
396
|
+
offBoardAddress
|
|
397
|
+
);
|
|
123
398
|
|
|
124
|
-
|
|
399
|
+
address account = _msgSender();
|
|
400
|
+
_accountEncryptionAddress[account] = offBoardAddress;
|
|
401
|
+
_balances[account].userCiphertext = newUserCiphertext;
|
|
125
402
|
|
|
126
|
-
|
|
403
|
+
emit AccountEncryptionAddressSet(account, offBoardAddress);
|
|
127
404
|
|
|
128
405
|
return true;
|
|
129
406
|
}
|
|
130
|
-
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* @dev Enables or disables operations that use clear public uint256 amounts
|
|
410
|
+
* (mint, burn, transfer, transferFrom, approve, transferAndCall with uint256).
|
|
411
|
+
* Intended to be called by the token admin to disallow public value usage if desired.
|
|
412
|
+
*/
|
|
413
|
+
function setPublicAmountsEnabled(bool enabled) external onlyRole(DEFAULT_ADMIN_ROLE) {
|
|
414
|
+
publicAmountsEnabled = enabled;
|
|
415
|
+
emit PublicAmountsEnabledSet(enabled);
|
|
416
|
+
}
|
|
417
|
+
|
|
131
418
|
/**
|
|
132
419
|
* @dev See {IPrivateERC20-transfer}.
|
|
133
420
|
*
|
|
@@ -135,105 +422,252 @@ abstract contract PrivateERC20 is Context, IPrivateERC20 {
|
|
|
135
422
|
*
|
|
136
423
|
* - `to` cannot be the zero address.
|
|
137
424
|
* - the caller must have a balance of at least `value`.
|
|
425
|
+
*
|
|
426
|
+
* Reverts if {_update} reports MPC failure. Success is implied by absence of revert.
|
|
138
427
|
*/
|
|
139
|
-
|
|
428
|
+
/// @notice Transfer with encrypted (itUint256) amount
|
|
429
|
+
function transfer(
|
|
430
|
+
address to,
|
|
431
|
+
itUint256 calldata value
|
|
432
|
+
) public virtual override nonReentrant {
|
|
433
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
140
434
|
address owner = _msgSender();
|
|
141
435
|
|
|
142
|
-
|
|
436
|
+
gtUint256 gtValue = MpcCore.validateCiphertext(value);
|
|
143
437
|
|
|
144
|
-
|
|
438
|
+
_transfer(owner, to, gtValue);
|
|
145
439
|
}
|
|
146
440
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
441
|
+
/// @notice Transfer with garbled-text (gtUint256) amount. Reverts if {_update} reports MPC failure.
|
|
442
|
+
function transferGT(
|
|
443
|
+
address to,
|
|
444
|
+
gtUint256 value
|
|
445
|
+
) public virtual override nonReentrant {
|
|
446
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
447
|
+
address owner = _msgSender();
|
|
448
|
+
|
|
449
|
+
_transfer(owner, to, value);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/// @notice Transfer with plain public uint256 amount
|
|
453
|
+
function transfer(
|
|
454
|
+
address to,
|
|
455
|
+
uint256 value
|
|
456
|
+
) public virtual override nonReentrant {
|
|
457
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
458
|
+
if (!publicAmountsEnabled) revert PublicAmountsDisabled();
|
|
156
459
|
address owner = _msgSender();
|
|
157
460
|
|
|
158
|
-
|
|
461
|
+
gtUint256 gtValue = MpcCore.setPublic256(value);
|
|
462
|
+
|
|
463
|
+
_transfer(owner, to, gtValue);
|
|
159
464
|
}
|
|
160
465
|
|
|
161
466
|
/**
|
|
162
467
|
* @dev See {IPrivateERC20-allowance}.
|
|
468
|
+
*
|
|
469
|
+
* Requirements:
|
|
470
|
+
* - `owner` and `spender` must not be the zero address.
|
|
163
471
|
*/
|
|
164
|
-
function allowance(
|
|
472
|
+
function allowance(
|
|
473
|
+
address owner,
|
|
474
|
+
address spender
|
|
475
|
+
) public view virtual override returns (Allowance memory) {
|
|
476
|
+
if (owner == address(0)) revert ERC20InvalidApprover(address(0));
|
|
477
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
165
478
|
return _allowances[owner][spender];
|
|
166
479
|
}
|
|
167
480
|
|
|
168
481
|
/**
|
|
169
482
|
* @dev See {IPrivateERC20-allowance}.
|
|
483
|
+
* May perform external calls to the MPC precompile via _safeOnboard.
|
|
484
|
+
* Do not use in staticcall or view contexts; off-chain code must not assume this is view-safe.
|
|
485
|
+
*
|
|
486
|
+
* Requirements:
|
|
487
|
+
* - `account` must not be the zero address.
|
|
170
488
|
*/
|
|
171
|
-
function allowance(
|
|
489
|
+
function allowance(
|
|
490
|
+
address account,
|
|
491
|
+
bool isSpender
|
|
492
|
+
) public virtual override returns (gtUint256) {
|
|
493
|
+
if (account == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
172
494
|
if (isSpender) {
|
|
173
|
-
|
|
174
|
-
} else {
|
|
495
|
+
// Caller is spender; `account` is owner — read _allowances[owner][spender]
|
|
175
496
|
return _safeOnboard(_allowances[account][_msgSender()].ciphertext);
|
|
497
|
+
} else {
|
|
498
|
+
// Caller is owner; `account` is spender — read _allowances[owner][spender]
|
|
499
|
+
return _safeOnboard(_allowances[_msgSender()][account].ciphertext);
|
|
176
500
|
}
|
|
177
501
|
}
|
|
178
502
|
|
|
179
|
-
|
|
503
|
+
/**
|
|
504
|
+
* @dev Reencrypts the caller's view of an allowance (as owner or spender) using the caller's encryption address.
|
|
505
|
+
*
|
|
506
|
+
* Requirements:
|
|
507
|
+
* - `account` must not be the zero address.
|
|
508
|
+
* - Caller must have an encryption address set (EOA or contract with setAccountEncryptionAddress).
|
|
509
|
+
*
|
|
510
|
+
* Emits an {AllowanceReencrypted} event.
|
|
511
|
+
*/
|
|
512
|
+
function reencryptAllowance(
|
|
513
|
+
address account,
|
|
514
|
+
bool isSpender
|
|
515
|
+
) public virtual nonReentrant {
|
|
516
|
+
if (account == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
180
517
|
address encryptionAddress = _getAccountEncryptionAddress(_msgSender());
|
|
518
|
+
if (encryptionAddress == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
519
|
+
|
|
520
|
+
address owner_;
|
|
521
|
+
address spender_;
|
|
181
522
|
|
|
182
523
|
if (isSpender) {
|
|
183
|
-
|
|
524
|
+
// Caller is spender; `account` is owner — _allowances[owner][spender]
|
|
525
|
+
owner_ = account;
|
|
526
|
+
spender_ = _msgSender();
|
|
527
|
+
Allowance storage allowance_ = _allowances[owner_][spender_];
|
|
184
528
|
|
|
185
|
-
allowance_.
|
|
529
|
+
allowance_.spenderCiphertext = MpcCore.offBoardToUser(
|
|
186
530
|
_safeOnboard(allowance_.ciphertext),
|
|
187
531
|
encryptionAddress
|
|
188
532
|
);
|
|
189
533
|
} else {
|
|
190
|
-
|
|
534
|
+
// Caller is owner; `account` is spender — _allowances[owner][spender]
|
|
535
|
+
owner_ = _msgSender();
|
|
536
|
+
spender_ = account;
|
|
537
|
+
Allowance storage allowance_ = _allowances[owner_][spender_];
|
|
191
538
|
|
|
192
|
-
allowance_.
|
|
539
|
+
allowance_.ownerCiphertext = MpcCore.offBoardToUser(
|
|
193
540
|
_safeOnboard(allowance_.ciphertext),
|
|
194
541
|
encryptionAddress
|
|
195
542
|
);
|
|
196
543
|
}
|
|
197
544
|
|
|
198
|
-
|
|
545
|
+
emit AllowanceReencrypted(owner_, spender_, isSpender);
|
|
199
546
|
}
|
|
200
547
|
|
|
201
548
|
/**
|
|
202
549
|
* @dev See {IPrivateERC20-approve}.
|
|
203
550
|
*
|
|
204
|
-
* NOTE: If `value` is the maximum `
|
|
551
|
+
* NOTE: If `value` is the maximum `itUint256`, the allowance is not updated on
|
|
205
552
|
* `transferFrom`. This is semantically equivalent to an infinite approval.
|
|
206
553
|
*
|
|
554
|
+
* Reverts with {ERC20UnsafeApprove} if both the current allowance and the new value are
|
|
555
|
+
* non-zero (same mitigation as {approve(address,uint256)}). Prefer {increaseAllowance} or
|
|
556
|
+
* {decreaseAllowance} to change a non-zero allowance without a two-step reset.
|
|
557
|
+
*
|
|
207
558
|
* Requirements:
|
|
208
559
|
*
|
|
209
560
|
* - `spender` cannot be the zero address.
|
|
210
561
|
*/
|
|
211
|
-
|
|
562
|
+
/// @notice Approve with encrypted (itUint256) amount
|
|
563
|
+
function approve(
|
|
564
|
+
address spender,
|
|
565
|
+
itUint256 calldata value
|
|
566
|
+
) public virtual override nonReentrant {
|
|
567
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
212
568
|
address owner = _msgSender();
|
|
213
569
|
|
|
214
|
-
|
|
570
|
+
gtUint256 gtValue = MpcCore.validateCiphertext(value);
|
|
571
|
+
|
|
572
|
+
_requireSafeEncryptedApprove(owner, spender, gtValue);
|
|
215
573
|
|
|
216
574
|
_approve(owner, spender, gtValue);
|
|
217
575
|
|
|
218
|
-
return true;
|
|
219
576
|
}
|
|
220
577
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
* Requirements:
|
|
228
|
-
*
|
|
229
|
-
* - `spender` cannot be the zero address.
|
|
230
|
-
*/
|
|
231
|
-
function approve(address spender, gtUint64 value) public virtual returns (bool) {
|
|
578
|
+
/// @notice Approve with garbled-text (gtUint256) amount
|
|
579
|
+
function approveGT(
|
|
580
|
+
address spender,
|
|
581
|
+
gtUint256 value
|
|
582
|
+
) public virtual override nonReentrant {
|
|
583
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
232
584
|
address owner = _msgSender();
|
|
233
585
|
|
|
586
|
+
_requireSafeEncryptedApprove(owner, spender, value);
|
|
587
|
+
|
|
234
588
|
_approve(owner, spender, value);
|
|
235
589
|
|
|
236
|
-
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/// @notice Approve with plain public uint256 amount
|
|
593
|
+
function approve(
|
|
594
|
+
address spender,
|
|
595
|
+
uint256 value
|
|
596
|
+
) public virtual override nonReentrant {
|
|
597
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
598
|
+
if (!publicAmountsEnabled) revert PublicAmountsDisabled();
|
|
599
|
+
address owner = _msgSender();
|
|
600
|
+
|
|
601
|
+
if (value != 0) {
|
|
602
|
+
gtUint256 currentAllowance = _safeOnboard(
|
|
603
|
+
_allowances[owner][spender].ciphertext
|
|
604
|
+
);
|
|
605
|
+
if (!MpcCore.decrypt(MpcCore.eq(currentAllowance, uint256(0)))) {
|
|
606
|
+
revert ERC20UnsafeApprove();
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
gtUint256 gtValue = MpcCore.setPublic256(value);
|
|
611
|
+
|
|
612
|
+
_approve(owner, spender, gtValue);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/// @inheritdoc IPrivateERC20
|
|
616
|
+
function increaseAllowance(
|
|
617
|
+
address spender,
|
|
618
|
+
itUint256 calldata addedValue
|
|
619
|
+
) public virtual override nonReentrant {
|
|
620
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
621
|
+
gtUint256 gtAdded = MpcCore.validateCiphertext(addedValue);
|
|
622
|
+
_increaseAllowance(_msgSender(), spender, gtAdded);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/// @inheritdoc IPrivateERC20
|
|
626
|
+
function increaseAllowance(
|
|
627
|
+
address spender,
|
|
628
|
+
uint256 addedValue
|
|
629
|
+
) public virtual override nonReentrant {
|
|
630
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
631
|
+
if (!publicAmountsEnabled) revert PublicAmountsDisabled();
|
|
632
|
+
_increaseAllowance(_msgSender(), spender, MpcCore.setPublic256(addedValue));
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/// @inheritdoc IPrivateERC20
|
|
636
|
+
function increaseAllowanceGT(
|
|
637
|
+
address spender,
|
|
638
|
+
gtUint256 addedValue
|
|
639
|
+
) public virtual override nonReentrant {
|
|
640
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
641
|
+
_increaseAllowance(_msgSender(), spender, addedValue);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/// @inheritdoc IPrivateERC20
|
|
645
|
+
function decreaseAllowance(
|
|
646
|
+
address spender,
|
|
647
|
+
itUint256 calldata subtractedValue
|
|
648
|
+
) public virtual override nonReentrant {
|
|
649
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
650
|
+
gtUint256 gtSub = MpcCore.validateCiphertext(subtractedValue);
|
|
651
|
+
_decreaseAllowance(_msgSender(), spender, gtSub);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/// @inheritdoc IPrivateERC20
|
|
655
|
+
function decreaseAllowance(
|
|
656
|
+
address spender,
|
|
657
|
+
uint256 subtractedValue
|
|
658
|
+
) public virtual override nonReentrant {
|
|
659
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
660
|
+
if (!publicAmountsEnabled) revert PublicAmountsDisabled();
|
|
661
|
+
_decreaseAllowance(_msgSender(), spender, MpcCore.setPublic256(subtractedValue));
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/// @inheritdoc IPrivateERC20
|
|
665
|
+
function decreaseAllowanceGT(
|
|
666
|
+
address spender,
|
|
667
|
+
gtUint256 subtractedValue
|
|
668
|
+
) public virtual override nonReentrant {
|
|
669
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
670
|
+
_decreaseAllowance(_msgSender(), spender, subtractedValue);
|
|
237
671
|
}
|
|
238
672
|
|
|
239
673
|
/**
|
|
@@ -245,46 +679,106 @@ abstract contract PrivateERC20 is Context, IPrivateERC20 {
|
|
|
245
679
|
* - `from` must have a balance of at least `value`.
|
|
246
680
|
* - the caller must have allowance for ``from``'s tokens of at least
|
|
247
681
|
* `value`.
|
|
682
|
+
*
|
|
683
|
+
* Order: (1) check allowance and revert if insufficient, (2) deduct via {_spendAllowance}
|
|
684
|
+
* (reusing the onboarded allowance from step 1), (3) _transfer.
|
|
248
685
|
*/
|
|
249
|
-
|
|
686
|
+
/// @notice transferFrom with encrypted (itUint256) amount
|
|
687
|
+
function transferFrom(
|
|
688
|
+
address from,
|
|
689
|
+
address to,
|
|
690
|
+
itUint256 calldata value
|
|
691
|
+
) public virtual override nonReentrant {
|
|
692
|
+
if (from == address(0)) revert ERC20InvalidSender(address(0));
|
|
693
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
250
694
|
address spender = _msgSender();
|
|
251
695
|
|
|
252
|
-
|
|
696
|
+
gtUint256 gtValue = MpcCore.validateCiphertext(value);
|
|
697
|
+
|
|
698
|
+
gtUint256 currentAllowance = _safeOnboard(_allowances[from][spender].ciphertext);
|
|
699
|
+
gtBool maxAllowance = _isMaxAllowance(currentAllowance);
|
|
700
|
+
gtBool inSufficientAllowance = MpcCore.lt(currentAllowance, gtValue);
|
|
701
|
+
require(
|
|
702
|
+
MpcCore.decrypt(MpcCore.or(maxAllowance, MpcCore.not(inSufficientAllowance))),
|
|
703
|
+
"ERC20: insufficient allowance"
|
|
704
|
+
);
|
|
705
|
+
bool unlimitedAllowance = MpcCore.decrypt(maxAllowance);
|
|
253
706
|
|
|
254
|
-
_spendAllowance(from, spender, gtValue);
|
|
707
|
+
_spendAllowance(from, spender, gtValue, currentAllowance, unlimitedAllowance);
|
|
255
708
|
|
|
256
|
-
|
|
709
|
+
_transfer(from, to, gtValue);
|
|
257
710
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
* `value`.
|
|
268
|
-
*/
|
|
269
|
-
function transferFrom(address from, address to, gtUint64 value) public virtual returns (gtBool) {
|
|
711
|
+
|
|
712
|
+
/// @notice transferFrom with garbled-text (gtUint256) amount
|
|
713
|
+
function transferFromGT(
|
|
714
|
+
address from,
|
|
715
|
+
address to,
|
|
716
|
+
gtUint256 value
|
|
717
|
+
) public virtual override nonReentrant {
|
|
718
|
+
if (from == address(0)) revert ERC20InvalidSender(address(0));
|
|
719
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
270
720
|
address spender = _msgSender();
|
|
271
721
|
|
|
272
|
-
|
|
722
|
+
gtUint256 currentAllowance = _safeOnboard(_allowances[from][spender].ciphertext);
|
|
723
|
+
gtBool maxAllowance = _isMaxAllowance(currentAllowance);
|
|
724
|
+
gtBool inSufficientAllowance = MpcCore.lt(currentAllowance, value);
|
|
725
|
+
require(
|
|
726
|
+
MpcCore.decrypt(MpcCore.or(maxAllowance, MpcCore.not(inSufficientAllowance))),
|
|
727
|
+
"ERC20: insufficient allowance"
|
|
728
|
+
);
|
|
729
|
+
bool unlimitedAllowance = MpcCore.decrypt(maxAllowance);
|
|
730
|
+
|
|
731
|
+
_spendAllowance(from, spender, value, currentAllowance, unlimitedAllowance);
|
|
273
732
|
|
|
274
|
-
|
|
733
|
+
_transfer(from, to, value);
|
|
275
734
|
}
|
|
276
|
-
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
/// @notice transferFrom with plain public uint256 amount
|
|
738
|
+
function transferFrom(
|
|
739
|
+
address from,
|
|
740
|
+
address to,
|
|
741
|
+
uint256 value
|
|
742
|
+
) public virtual override nonReentrant {
|
|
743
|
+
if (!publicAmountsEnabled) revert PublicAmountsDisabled();
|
|
744
|
+
if (from == address(0)) revert ERC20InvalidSender(address(0));
|
|
745
|
+
if (to == address(0)) revert ERC20InvalidReceiver(address(0));
|
|
746
|
+
address spender = _msgSender();
|
|
747
|
+
|
|
748
|
+
gtUint256 gtValue = MpcCore.setPublic256(value);
|
|
749
|
+
|
|
750
|
+
gtUint256 currentAllowance = _safeOnboard(_allowances[from][spender].ciphertext);
|
|
751
|
+
gtBool maxAllowance = _isMaxAllowance(currentAllowance);
|
|
752
|
+
gtBool inSufficientAllowance = MpcCore.lt(currentAllowance, gtValue);
|
|
753
|
+
require(
|
|
754
|
+
MpcCore.decrypt(MpcCore.or(maxAllowance, MpcCore.not(inSufficientAllowance))),
|
|
755
|
+
"ERC20: insufficient allowance"
|
|
756
|
+
);
|
|
757
|
+
bool unlimitedAllowance = MpcCore.decrypt(maxAllowance);
|
|
758
|
+
|
|
759
|
+
_spendAllowance(from, spender, gtValue, currentAllowance, unlimitedAllowance);
|
|
760
|
+
|
|
761
|
+
_transfer(from, to, gtValue);
|
|
762
|
+
}
|
|
763
|
+
|
|
277
764
|
/**
|
|
278
765
|
* @dev Moves a `value` amount of tokens from `from` to `to`.
|
|
279
766
|
*
|
|
280
767
|
* This internal function is equivalent to {transfer}, and can be used to
|
|
281
768
|
* e.g. implement automatic token fees, slashing mechanisms, etc.
|
|
282
769
|
*
|
|
283
|
-
*
|
|
770
|
+
* Self-transfer (from == to) is not allowed and reverts.
|
|
771
|
+
*
|
|
772
|
+
* On success, emits a {Transfer} event via {_update}; on MPC transfer failure, {_update} reverts
|
|
773
|
+
* and no event is emitted.
|
|
284
774
|
*
|
|
285
775
|
* NOTE: This function is not virtual, {_update} should be overridden instead.
|
|
286
776
|
*/
|
|
287
|
-
function _transfer(
|
|
777
|
+
function _transfer(
|
|
778
|
+
address from,
|
|
779
|
+
address to,
|
|
780
|
+
gtUint256 value
|
|
781
|
+
) internal {
|
|
288
782
|
if (from == address(0)) {
|
|
289
783
|
revert ERC20InvalidSender(address(0));
|
|
290
784
|
}
|
|
@@ -293,86 +787,172 @@ abstract contract PrivateERC20 is Context, IPrivateERC20 {
|
|
|
293
787
|
revert ERC20InvalidReceiver(address(0));
|
|
294
788
|
}
|
|
295
789
|
|
|
296
|
-
|
|
790
|
+
if (from == to) {
|
|
791
|
+
revert ERC20SelfTransferNotAllowed(from);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
_update(from, to, value);
|
|
297
795
|
}
|
|
298
|
-
|
|
796
|
+
|
|
299
797
|
/**
|
|
300
798
|
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
|
|
301
799
|
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
|
|
302
800
|
* this function.
|
|
303
801
|
*
|
|
304
|
-
*
|
|
802
|
+
* Storage and {Transfer} are updated only when the MPC operation succeeds (transfer success bit, or mint
|
|
803
|
+
* add without overflow and within {supplyCap}). On failure, balances and aggregate supply are unchanged,
|
|
804
|
+
* no event is emitted, and this function reverts so the failed operation does not succeed silently.
|
|
305
805
|
*/
|
|
306
|
-
function _update(
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
806
|
+
function _update(
|
|
807
|
+
address from,
|
|
808
|
+
address to,
|
|
809
|
+
gtUint256 value
|
|
810
|
+
) internal virtual {
|
|
811
|
+
gtUint256 newToBalance;
|
|
812
|
+
gtUint256 valueTransferred = value;
|
|
813
|
+
gtBool result;
|
|
814
|
+
bool ok;
|
|
310
815
|
|
|
311
816
|
if (from == address(0)) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
817
|
+
gtUint256 currentBalance = _getBalance(to);
|
|
818
|
+
gtBool balanceOverflow;
|
|
819
|
+
(balanceOverflow, newToBalance) = MpcCore.checkedAddWithOverflowBit(
|
|
820
|
+
currentBalance,
|
|
821
|
+
value
|
|
822
|
+
);
|
|
823
|
+
gtBool balanceOk = MpcCore.not(balanceOverflow);
|
|
315
824
|
|
|
316
|
-
|
|
825
|
+
gtUint256 totalSupply_ = _safeOnboard(_totalSupply);
|
|
826
|
+
(gtBool supplyOverflow, gtUint256 newTotalSupply) = MpcCore.checkedAddWithOverflowBit(
|
|
827
|
+
totalSupply_,
|
|
828
|
+
value
|
|
829
|
+
);
|
|
830
|
+
gtBool supplyOk = MpcCore.not(supplyOverflow);
|
|
831
|
+
gtBool withinCap = MpcCore.le(newTotalSupply, supplyCap());
|
|
317
832
|
|
|
318
|
-
|
|
833
|
+
result = MpcCore.and(balanceOk, MpcCore.and(supplyOk, withinCap));
|
|
834
|
+
ok = MpcCore.decrypt(result);
|
|
835
|
+
if (ok) {
|
|
836
|
+
_totalSupply = MpcCore.offBoard(newTotalSupply);
|
|
319
837
|
|
|
320
|
-
|
|
838
|
+
_updateBalance(to, newToBalance);
|
|
839
|
+
}
|
|
321
840
|
} else {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
841
|
+
gtUint256 fromBalance = _getBalance(from);
|
|
842
|
+
// Burn (`to == address(0)`): use canonical public zero as the sink balance. Do not read
|
|
843
|
+
// `_balances[address(0)]` — that slot must never affect burn accounting if it were ever corrupted.
|
|
844
|
+
gtUint256 toBalance = to == address(0)
|
|
845
|
+
? MpcCore.setPublic256(0)
|
|
846
|
+
: _getBalance(to);
|
|
847
|
+
|
|
848
|
+
gtUint256 newFromBalance;
|
|
849
|
+
|
|
850
|
+
(newFromBalance, newToBalance, result) = MpcCore.transfer(
|
|
851
|
+
fromBalance,
|
|
852
|
+
toBalance,
|
|
853
|
+
value
|
|
854
|
+
);
|
|
326
855
|
|
|
327
|
-
|
|
856
|
+
ok = MpcCore.decrypt(result);
|
|
857
|
+
if (ok) {
|
|
858
|
+
_updateBalance(from, newFromBalance);
|
|
328
859
|
|
|
329
|
-
|
|
860
|
+
valueTransferred = MpcCore.sub(newToBalance, toBalance);
|
|
330
861
|
|
|
331
|
-
|
|
332
|
-
|
|
862
|
+
if (to == address(0)) {
|
|
863
|
+
gtUint256 totalSupply_ = _safeOnboard(_totalSupply);
|
|
333
864
|
|
|
334
|
-
|
|
335
|
-
gtUint64 totalSupply_ = _safeOnboard(_totalSupply);
|
|
865
|
+
totalSupply_ = MpcCore.sub(totalSupply_, valueTransferred);
|
|
336
866
|
|
|
337
|
-
|
|
867
|
+
_totalSupply = MpcCore.offBoard(totalSupply_);
|
|
868
|
+
} else {
|
|
869
|
+
_updateBalance(to, newToBalance);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
338
873
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
874
|
+
if (ok) {
|
|
875
|
+
// When minting or transferring to/from a smart contract (which has no AES key),
|
|
876
|
+
// we must bypass offBoardToUser to prevent on-chain reverts.
|
|
877
|
+
ctUint256 memory senderCt;
|
|
878
|
+
address fromEnc = _getAccountEncryptionAddress(from);
|
|
879
|
+
if (fromEnc != address(0)) {
|
|
880
|
+
senderCt = MpcCore.offBoardToUser(valueTransferred, fromEnc);
|
|
881
|
+
} else {
|
|
882
|
+
senderCt = ctUint256({
|
|
883
|
+
ciphertextHigh: ctUint128.wrap(0),
|
|
884
|
+
ciphertextLow: ctUint128.wrap(0)
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
ctUint256 memory receiverCt;
|
|
889
|
+
address toEnc = _getAccountEncryptionAddress(to);
|
|
890
|
+
if (toEnc != address(0)) {
|
|
891
|
+
receiverCt = MpcCore.offBoardToUser(valueTransferred, toEnc);
|
|
892
|
+
} else {
|
|
893
|
+
receiverCt = ctUint256({
|
|
894
|
+
ciphertextHigh: ctUint128.wrap(0),
|
|
895
|
+
ciphertextLow: ctUint128.wrap(0)
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
emit Transfer(from, to, senderCt, receiverCt);
|
|
342
900
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
from,
|
|
346
|
-
to,
|
|
347
|
-
MpcCore.offBoardToUser(valueTransferred, from),
|
|
348
|
-
MpcCore.offBoardToUser(valueTransferred, to)
|
|
349
|
-
);
|
|
901
|
+
require(MpcCore.decrypt(result), "ERC20: update failed");
|
|
902
|
+
}
|
|
350
903
|
|
|
351
|
-
|
|
904
|
+
/**
|
|
905
|
+
* @dev Aggregate supply as a garbled value (on-boarded from storage ciphertext).
|
|
906
|
+
* Intended for subclasses that expose encrypted total supply to a designated party
|
|
907
|
+
* (e.g. via `MpcCore.offBoardToUser`) without putting plaintext aggregate supply in {totalSupply}.
|
|
908
|
+
*/
|
|
909
|
+
function _getTotalSupplyGarbled() internal returns (gtUint256) {
|
|
910
|
+
return _safeOnboard(_totalSupply);
|
|
352
911
|
}
|
|
353
912
|
|
|
354
|
-
function _getBalance(address account) internal returns (
|
|
355
|
-
|
|
913
|
+
function _getBalance(address account) internal returns (gtUint256) {
|
|
914
|
+
ctUint256 memory ctBalance = _balances[account].ciphertext;
|
|
356
915
|
|
|
357
916
|
return _safeOnboard(ctBalance);
|
|
358
917
|
}
|
|
359
918
|
|
|
360
|
-
function _getAccountEncryptionAddress(
|
|
919
|
+
function _getAccountEncryptionAddress(
|
|
920
|
+
address account
|
|
921
|
+
) internal view returns (address) {
|
|
922
|
+
if (account == address(0)) return address(0);
|
|
923
|
+
|
|
361
924
|
address encryptionAddress = _accountEncryptionAddress[account];
|
|
362
925
|
|
|
363
926
|
if (encryptionAddress == address(0)) {
|
|
927
|
+
if (account.code.length > 0) {
|
|
928
|
+
// Smart contracts don't have AES keys, so we return address(0)
|
|
929
|
+
// as a signal to bypass encryption in offBoardToUser.
|
|
930
|
+
return address(0);
|
|
931
|
+
}
|
|
364
932
|
encryptionAddress = account;
|
|
365
933
|
}
|
|
366
934
|
|
|
367
935
|
return encryptionAddress;
|
|
368
936
|
}
|
|
369
937
|
|
|
370
|
-
function _updateBalance(address account,
|
|
938
|
+
function _updateBalance(address account, gtUint256 balance) internal {
|
|
371
939
|
address encryptionAddress = _getAccountEncryptionAddress(account);
|
|
372
940
|
|
|
373
|
-
|
|
941
|
+
if (encryptionAddress == address(0)) {
|
|
942
|
+
// Contract accounts have no AES key; store ciphertext only, no user reencryption.
|
|
943
|
+
_balances[account].ciphertext = MpcCore.offBoard(balance);
|
|
944
|
+
_balances[account].userCiphertext = ctUint256({
|
|
945
|
+
ciphertextHigh: ctUint128.wrap(0),
|
|
946
|
+
ciphertextLow: ctUint128.wrap(0)
|
|
947
|
+
});
|
|
948
|
+
} else {
|
|
949
|
+
_balances[account] = MpcCore.offBoardCombined(
|
|
950
|
+
balance,
|
|
951
|
+
encryptionAddress
|
|
952
|
+
);
|
|
953
|
+
}
|
|
374
954
|
}
|
|
375
|
-
|
|
955
|
+
|
|
376
956
|
/**
|
|
377
957
|
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
|
|
378
958
|
* Relies on the `_update` mechanism
|
|
@@ -381,12 +961,12 @@ abstract contract PrivateERC20 is Context, IPrivateERC20 {
|
|
|
381
961
|
*
|
|
382
962
|
* NOTE: This function is not virtual, {_update} should be overridden instead.
|
|
383
963
|
*/
|
|
384
|
-
function _mint(address account,
|
|
964
|
+
function _mint(address account, gtUint256 value) internal {
|
|
385
965
|
if (account == address(0)) {
|
|
386
966
|
revert ERC20InvalidReceiver(address(0));
|
|
387
967
|
}
|
|
388
968
|
|
|
389
|
-
|
|
969
|
+
_update(address(0), account, value);
|
|
390
970
|
}
|
|
391
971
|
|
|
392
972
|
/**
|
|
@@ -397,12 +977,12 @@ abstract contract PrivateERC20 is Context, IPrivateERC20 {
|
|
|
397
977
|
*
|
|
398
978
|
* NOTE: This function is not virtual, {_update} should be overridden instead
|
|
399
979
|
*/
|
|
400
|
-
function _burn(address account,
|
|
980
|
+
function _burn(address account, gtUint256 value) internal {
|
|
401
981
|
if (account == address(0)) {
|
|
402
982
|
revert ERC20InvalidSender(address(0));
|
|
403
983
|
}
|
|
404
984
|
|
|
405
|
-
|
|
985
|
+
_update(account, address(0), value);
|
|
406
986
|
}
|
|
407
987
|
|
|
408
988
|
/**
|
|
@@ -420,7 +1000,86 @@ abstract contract PrivateERC20 is Context, IPrivateERC20 {
|
|
|
420
1000
|
*
|
|
421
1001
|
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
|
|
422
1002
|
*/
|
|
423
|
-
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* @dev If the new allowance is non-zero, requires the current allowance to be zero.
|
|
1006
|
+
* Same mitigation as {approve(address,uint256)} / {ERC20UnsafeApprove} for the encrypted and GT approve paths.
|
|
1007
|
+
*/
|
|
1008
|
+
function _requireSafeEncryptedApprove(
|
|
1009
|
+
address owner,
|
|
1010
|
+
address spender,
|
|
1011
|
+
gtUint256 gtNewValue
|
|
1012
|
+
) internal {
|
|
1013
|
+
gtBool newIsZero = MpcCore.eq(gtNewValue, MpcCore.setPublic256(0));
|
|
1014
|
+
if (MpcCore.decrypt(newIsZero)) {
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
gtUint256 currentAllowance = _safeOnboard(
|
|
1019
|
+
_allowances[owner][spender].ciphertext
|
|
1020
|
+
);
|
|
1021
|
+
if (!MpcCore.decrypt(MpcCore.eq(currentAllowance, uint256(0)))) {
|
|
1022
|
+
revert ERC20UnsafeApprove();
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* @dev Atomically adds `added` to the current allowance. Reverts on overflow (mirrors
|
|
1028
|
+
* ERC-20 reference behavior for `type(uint256).max + x`). Does not use
|
|
1029
|
+
* {_requireSafeEncryptedApprove} — intended as the safe alternative to resetting via {approve}.
|
|
1030
|
+
*/
|
|
1031
|
+
function _increaseAllowance(
|
|
1032
|
+
address owner,
|
|
1033
|
+
address spender,
|
|
1034
|
+
gtUint256 added
|
|
1035
|
+
) internal {
|
|
1036
|
+
if (owner == address(0)) revert ERC20InvalidApprover(address(0));
|
|
1037
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
1038
|
+
|
|
1039
|
+
gtUint256 currentAllowance = _safeOnboard(
|
|
1040
|
+
_allowances[owner][spender].ciphertext
|
|
1041
|
+
);
|
|
1042
|
+
(gtBool overflow, gtUint256 newAllowance) = MpcCore.checkedAddWithOverflowBit(
|
|
1043
|
+
currentAllowance,
|
|
1044
|
+
added
|
|
1045
|
+
);
|
|
1046
|
+
require(
|
|
1047
|
+
MpcCore.decrypt(MpcCore.not(overflow)),
|
|
1048
|
+
"ERC20: allowance overflow"
|
|
1049
|
+
);
|
|
1050
|
+
_approve(owner, spender, newAllowance);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* @dev Atomically subtracts `subtracted` from the current allowance. Reverts on underflow.
|
|
1055
|
+
*/
|
|
1056
|
+
function _decreaseAllowance(
|
|
1057
|
+
address owner,
|
|
1058
|
+
address spender,
|
|
1059
|
+
gtUint256 subtracted
|
|
1060
|
+
) internal {
|
|
1061
|
+
if (owner == address(0)) revert ERC20InvalidApprover(address(0));
|
|
1062
|
+
if (spender == address(0)) revert ERC20InvalidSpender(address(0));
|
|
1063
|
+
|
|
1064
|
+
gtUint256 currentAllowance = _safeOnboard(
|
|
1065
|
+
_allowances[owner][spender].ciphertext
|
|
1066
|
+
);
|
|
1067
|
+
(gtBool underflow, gtUint256 newAllowance) = MpcCore.checkedSubWithOverflowBit(
|
|
1068
|
+
currentAllowance,
|
|
1069
|
+
subtracted
|
|
1070
|
+
);
|
|
1071
|
+
require(
|
|
1072
|
+
MpcCore.decrypt(MpcCore.not(underflow)),
|
|
1073
|
+
"ERC20: insufficient allowance"
|
|
1074
|
+
);
|
|
1075
|
+
_approve(owner, spender, newAllowance);
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
function _approve(
|
|
1079
|
+
address owner,
|
|
1080
|
+
address spender,
|
|
1081
|
+
gtUint256 value
|
|
1082
|
+
) internal {
|
|
424
1083
|
if (owner == address(0)) {
|
|
425
1084
|
revert ERC20InvalidApprover(address(0));
|
|
426
1085
|
}
|
|
@@ -429,50 +1088,100 @@ abstract contract PrivateERC20 is Context, IPrivateERC20 {
|
|
|
429
1088
|
revert ERC20InvalidSpender(address(0));
|
|
430
1089
|
}
|
|
431
1090
|
|
|
432
|
-
|
|
1091
|
+
ctUint256 memory ciphertext = MpcCore.offBoard(value);
|
|
433
1092
|
|
|
434
1093
|
address encryptionAddress = _getAccountEncryptionAddress(owner);
|
|
435
1094
|
|
|
436
|
-
|
|
1095
|
+
ctUint256 memory ownerCiphertext;
|
|
1096
|
+
if (encryptionAddress != address(0)) {
|
|
1097
|
+
ownerCiphertext = MpcCore.offBoardToUser(value, encryptionAddress);
|
|
1098
|
+
} else {
|
|
1099
|
+
ownerCiphertext = ctUint256({
|
|
1100
|
+
ciphertextHigh: ctUint128.wrap(0),
|
|
1101
|
+
ciphertextLow: ctUint128.wrap(0)
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
437
1104
|
|
|
438
1105
|
encryptionAddress = _getAccountEncryptionAddress(spender);
|
|
439
1106
|
|
|
440
|
-
|
|
1107
|
+
ctUint256 memory spenderCiphertext;
|
|
1108
|
+
if (encryptionAddress != address(0)) {
|
|
1109
|
+
spenderCiphertext = MpcCore.offBoardToUser(
|
|
1110
|
+
value,
|
|
1111
|
+
encryptionAddress
|
|
1112
|
+
);
|
|
1113
|
+
} else {
|
|
1114
|
+
spenderCiphertext = ctUint256({
|
|
1115
|
+
ciphertextHigh: ctUint128.wrap(0),
|
|
1116
|
+
ciphertextLow: ctUint128.wrap(0)
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
441
1119
|
|
|
442
|
-
_allowances[owner][spender] = Allowance(
|
|
1120
|
+
_allowances[owner][spender] = Allowance(
|
|
1121
|
+
ciphertext,
|
|
1122
|
+
ownerCiphertext,
|
|
1123
|
+
spenderCiphertext
|
|
1124
|
+
);
|
|
443
1125
|
|
|
444
1126
|
emit Approval(owner, spender, ownerCiphertext, spenderCiphertext);
|
|
445
1127
|
}
|
|
446
1128
|
|
|
447
1129
|
/**
|
|
448
|
-
* @dev
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
* Does not decrease the allowance if not enough allowance is available.
|
|
452
|
-
*
|
|
1130
|
+
* @dev Unlimited allowance: semantic equality to `type(uint256).max` via secret-vs-public
|
|
1131
|
+
* `eq` (MPC RHS_PUBLIC). Using this instead of `eq(allowance, setPublic256(max))` ensures
|
|
1132
|
+
* any valid garbled encoding of max is recognized, not only one canonical pair.
|
|
453
1133
|
*/
|
|
454
|
-
function
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
gtBool maxAllowance = MpcCore.eq(currentAllowance, MpcCore.setPublic64(MAX_UINT_64));
|
|
459
|
-
gtBool insufficientBalance = MpcCore.lt(currentBalance, value);
|
|
460
|
-
gtBool inSufficientAllowance = MpcCore.lt(currentAllowance, value);
|
|
461
|
-
|
|
462
|
-
gtUint64 newAllowance = MpcCore.mux(
|
|
463
|
-
MpcCore.or(maxAllowance, MpcCore.or(insufficientBalance, inSufficientAllowance)),
|
|
464
|
-
MpcCore.sub(currentAllowance, value),
|
|
465
|
-
currentAllowance
|
|
466
|
-
);
|
|
1134
|
+
function _isMaxAllowance(gtUint256 gtAllowance) internal returns (gtBool) {
|
|
1135
|
+
return MpcCore.eq(gtAllowance, MAX_UINT_256);
|
|
1136
|
+
}
|
|
467
1137
|
|
|
1138
|
+
/**
|
|
1139
|
+
* @dev Deducts `value` from `owner`/`spender` allowance after {transferFrom} prechecks.
|
|
1140
|
+
* @param currentAllowance Garbled allowance from the same `_safeOnboard` pass as the insufficient-allowance check (avoids a second onboard + duplicate `eq`/`lt`).
|
|
1141
|
+
* @param unlimitedAllowance Result of `MpcCore.decrypt(_isMaxAllowance(currentAllowance))` for the same slot.
|
|
1142
|
+
*
|
|
1143
|
+
* If unlimited, returns without writing storage or emitting {Approval} (OZ-style). Otherwise
|
|
1144
|
+
* subtracts `value`, which is safe because {transferFrom} already enforced sufficiency when not unlimited.
|
|
1145
|
+
*/
|
|
1146
|
+
function _spendAllowance(
|
|
1147
|
+
address owner,
|
|
1148
|
+
address spender,
|
|
1149
|
+
gtUint256 value,
|
|
1150
|
+
gtUint256 currentAllowance,
|
|
1151
|
+
bool unlimitedAllowance
|
|
1152
|
+
) internal virtual {
|
|
1153
|
+
if (unlimitedAllowance) {
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
gtUint256 newAllowance = MpcCore.sub(currentAllowance, value);
|
|
468
1157
|
_approve(owner, spender, newAllowance);
|
|
469
1158
|
}
|
|
470
1159
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
1160
|
+
/// @dev EVM-uninitialized or fully cleared `ctUint256` storage reads as both limbs zero.
|
|
1161
|
+
function _isCanonicalEmptyCtUint256(
|
|
1162
|
+
ctUint256 memory ct
|
|
1163
|
+
) private pure returns (bool) {
|
|
1164
|
+
return
|
|
1165
|
+
ctUint128.unwrap(ct.ciphertextHigh) == 0 &&
|
|
1166
|
+
ctUint128.unwrap(ct.ciphertextLow) == 0;
|
|
1167
|
+
}
|
|
475
1168
|
|
|
1169
|
+
/**
|
|
1170
|
+
* @dev Converts persisted `ctUint256` into garbled `gtUint256` for MPC operations.
|
|
1171
|
+
*
|
|
1172
|
+
* **Canonical zero:** Storage that has never been written, or reads as all-zero limbs, is
|
|
1173
|
+
* treated as semantic zero via `MpcCore.setPublic256(0)` without `MpcCore.onBoard`, to avoid a
|
|
1174
|
+
* precompile round-trip on empty balances/allowances/supply. Any non–all-zero encoding is
|
|
1175
|
+
* onboarded with `MpcCore.onBoard`.
|
|
1176
|
+
*
|
|
1177
|
+
* Invariant: values persisted by this contract come from `MpcCore.offBoard` after successful MPC
|
|
1178
|
+
* updates, so normal state is consistent with the precompile. Subclasses or integrations must not
|
|
1179
|
+
* inject arbitrary ciphertext into these slots unless it matches MPC encoding expectations.
|
|
1180
|
+
*/
|
|
1181
|
+
function _safeOnboard(ctUint256 memory value) internal returns (gtUint256) {
|
|
1182
|
+
if (_isCanonicalEmptyCtUint256(value)) {
|
|
1183
|
+
return MpcCore.setPublic256(0);
|
|
1184
|
+
}
|
|
476
1185
|
return MpcCore.onBoard(value);
|
|
477
1186
|
}
|
|
478
|
-
}
|
|
1187
|
+
}
|