@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
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.19;
|
|
3
|
+
|
|
4
|
+
import "./PrivacyBridge.sol";
|
|
5
|
+
import "@openzeppelin/contracts/utils/math/Math.sol";
|
|
6
|
+
import "../token/PrivateERC20/tokens/PrivateCOTI.sol";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @title PrivacyBridgeCotiNative
|
|
10
|
+
* @notice Bridge contract for converting between native COTI and privacy-preserving COTI.p tokens
|
|
11
|
+
* @dev Withdraw pulls private balance via `IPrivateERC20(address(privateCoti)).transferFrom` so the call matches
|
|
12
|
+
* the canonical {IPrivateERC20} surface (`contracts/token/PrivateERC20/IPrivateERC20.sol`) while `privateCoti`
|
|
13
|
+
* remains the concrete {PrivateCOTI} type for mint/burn. Deploy `_privateCoti` as that implementation (or a
|
|
14
|
+
* fully ABI-compatible successor); do not point at arbitrary ERC-20s.
|
|
15
|
+
*
|
|
16
|
+
* **Two native deposit paths (document for wallets / indexers):**
|
|
17
|
+
* - {deposit(uint256,uint256)}: user passes `cotiOracleTimestamp` and `tokenOracleTimestamp` (same value
|
|
18
|
+
* twice for `"COTI"`); {_validateOracleTimestamps} enforces they match the on-chain Band row—same quote row
|
|
19
|
+
* as {estimateDepositFee}. Use this when you need binding between off-chain estimate and execution.
|
|
20
|
+
* - {receive} / plain ETH send: uses {_directDeposit}; fee still uses {_computeCotiFee} with staleness
|
|
21
|
+
* ({_requireOracleFreshness}) but **does not** require equality to estimate timestamps—no prior estimate row
|
|
22
|
+
* is pinned. Prefer explicit {deposit} for predictable “what I quoted is what executes.”
|
|
23
|
+
*
|
|
24
|
+
* **Unsolicited native:** balance can increase via `selfdestruct` or other forced transfers without invoking
|
|
25
|
+
* {receive}; that ETH does not mint private tokens and does not update {PrivacyBridge.totalUserLiability}.
|
|
26
|
+
*/
|
|
27
|
+
contract PrivacyBridgeCotiNative is PrivacyBridge {
|
|
28
|
+
PrivateCOTI public privateCoti;
|
|
29
|
+
|
|
30
|
+
event NativeRescued(address indexed to, uint256 amount);
|
|
31
|
+
|
|
32
|
+
// Scaling factor removed (using native 18 decimals due to uint256 upgrade)
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @notice Initialize the Native Bridge
|
|
36
|
+
* @param _privateCoti Address of the PrivateCoti token contract
|
|
37
|
+
* @param _priceOracle Non-zero price oracle (see {PrivacyBridge}'s constructor)
|
|
38
|
+
*/
|
|
39
|
+
constructor(address _privateCoti, address _feeRecipient, address _rescueRecipient, address _priceOracle) PrivacyBridge(_feeRecipient, _rescueRecipient, _priceOracle) {
|
|
40
|
+
if (_privateCoti == address(0)) revert InvalidAddress();
|
|
41
|
+
privateCoti = PrivateCOTI(_privateCoti);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @dev Native COTI fee math + one {getPriceWithMeta("COTI")} read. Used by {_computeCotiFee} and
|
|
46
|
+
* {estimateDepositFee}/{estimateWithdrawFee}. Each {Math.mulDiv} truncates toward zero (see
|
|
47
|
+
* {PrivacyBridge.FEE_DIVISOR} NatSpec). Extreme `cotiAmount`×`cotiUsdRate` values can make {Math.mulDiv}
|
|
48
|
+
* revert—keep amounts within configured max deposit/withdraw limits.
|
|
49
|
+
* @param cotiAmount Amount in COTI wei the fee is computed for
|
|
50
|
+
* @param fixedFee Minimum fee floor in COTI wei
|
|
51
|
+
* @param percentageBps Percentage parameter scaled by {PrivacyBridge.FEE_DIVISOR}
|
|
52
|
+
* @param maxFee Maximum fee cap in COTI wei
|
|
53
|
+
* @return fee Computed fee in COTI wei
|
|
54
|
+
* @return cotiLastUpdated COTI oracle row `lastUpdated`
|
|
55
|
+
* @return blockTimestamp Third field from the COTI oracle row
|
|
56
|
+
*/
|
|
57
|
+
function _computeCotiFeeAndMeta(
|
|
58
|
+
uint256 cotiAmount,
|
|
59
|
+
uint256 fixedFee,
|
|
60
|
+
uint256 percentageBps,
|
|
61
|
+
uint256 maxFee
|
|
62
|
+
) internal view returns (uint256 fee, uint256 cotiLastUpdated, uint256 blockTimestamp) {
|
|
63
|
+
_requirePriceOracle();
|
|
64
|
+
(uint256 cotiUsdRate, uint256 cotiLU, uint256 cotiBts) = ICotiPriceConsumer(priceOracle).getPriceWithMeta("COTI");
|
|
65
|
+
_requirePositiveOracleRate(cotiUsdRate);
|
|
66
|
+
_requireOracleFreshness(cotiLU);
|
|
67
|
+
uint256 txValueUsd = Math.mulDiv(cotiAmount, cotiUsdRate, 1e18);
|
|
68
|
+
uint256 percentageFeeUsd = Math.mulDiv(txValueUsd, percentageBps, FEE_DIVISOR);
|
|
69
|
+
uint256 percentageFeeCoti = Math.mulDiv(percentageFeeUsd, 1e18, cotiUsdRate);
|
|
70
|
+
fee = _calculateDynamicFee(percentageFeeCoti, fixedFee, maxFee);
|
|
71
|
+
cotiLastUpdated = cotiLU;
|
|
72
|
+
blockTimestamp = cotiBts;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function _computeCotiFee(
|
|
76
|
+
uint256 cotiAmount,
|
|
77
|
+
uint256 fixedFee,
|
|
78
|
+
uint256 percentageBps,
|
|
79
|
+
uint256 maxFee
|
|
80
|
+
) internal view returns (uint256) {
|
|
81
|
+
(uint256 f,,) = _computeCotiFeeAndMeta(cotiAmount, fixedFee, percentageBps, maxFee);
|
|
82
|
+
return f;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @notice Simulate fee calculation for native COTI with arbitrary parameters.
|
|
87
|
+
* @dev Public view — allows frontends/operators to preview fees with custom fee params.
|
|
88
|
+
* Reads live COTI oracle price but accepts custom fee configuration.
|
|
89
|
+
* @param cotiAmount The COTI amount to compute fee for (wei; very large values can revert in fee math)
|
|
90
|
+
* @param fixedFee The minimum fee floor in COTI wei
|
|
91
|
+
* @param percentageBps The percentage in basis points (relative to {FEE_DIVISOR})
|
|
92
|
+
* @param maxFee The maximum fee cap in COTI wei
|
|
93
|
+
* @return The computed fee in COTI wei
|
|
94
|
+
*/
|
|
95
|
+
function computeCotiFee(
|
|
96
|
+
uint256 cotiAmount,
|
|
97
|
+
uint256 fixedFee,
|
|
98
|
+
uint256 percentageBps,
|
|
99
|
+
uint256 maxFee
|
|
100
|
+
) external view returns (uint256) {
|
|
101
|
+
return _computeCotiFee(cotiAmount, fixedFee, percentageBps, maxFee);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @notice Estimate the deposit fee in COTI for a given COTI amount
|
|
106
|
+
* @param cotiAmount The amount of native COTI to deposit (wei; very large values can revert in fee math)
|
|
107
|
+
* @return fee The estimated fee in COTI wei
|
|
108
|
+
* @return cotiLastUpdated COTI oracle data last update timestamp
|
|
109
|
+
* @return blockTimestamp Third field from the COTI oracle row (same as pre-refactor behavior)
|
|
110
|
+
* @dev Use `cotiLastUpdated` for **both** `cotiOracleTimestamp` and `tokenOracleTimestamp` on {deposit}/{withdraw}
|
|
111
|
+
* (native bridge validates `"COTI"` twice). See {PrivacyBridge._validateOracleTimestamps}.
|
|
112
|
+
*/
|
|
113
|
+
function estimateDepositFee(uint256 cotiAmount) external view returns (uint256 fee, uint256 cotiLastUpdated, uint256 blockTimestamp) {
|
|
114
|
+
(fee, cotiLastUpdated, blockTimestamp) = _computeCotiFeeAndMeta(
|
|
115
|
+
cotiAmount,
|
|
116
|
+
depositFixedFee,
|
|
117
|
+
depositPercentageBps,
|
|
118
|
+
depositMaxFee
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @notice Estimate the withdrawal fee in COTI for a given COTI amount
|
|
124
|
+
* @param cotiAmount The amount of native COTI to withdraw (wei; very large values can revert in fee math)
|
|
125
|
+
* @return fee The estimated fee in COTI wei
|
|
126
|
+
* @return cotiLastUpdated COTI oracle data last update timestamp
|
|
127
|
+
* @return blockTimestamp Third field from the COTI oracle row (same as pre-refactor behavior)
|
|
128
|
+
* @dev Same timestamp usage as {estimateDepositFee} for the subsequent {withdraw}.
|
|
129
|
+
*/
|
|
130
|
+
function estimateWithdrawFee(uint256 cotiAmount) external view returns (uint256 fee, uint256 cotiLastUpdated, uint256 blockTimestamp) {
|
|
131
|
+
(fee, cotiLastUpdated, blockTimestamp) = _computeCotiFeeAndMeta(
|
|
132
|
+
cotiAmount,
|
|
133
|
+
withdrawFixedFee,
|
|
134
|
+
withdrawPercentageBps,
|
|
135
|
+
withdrawMaxFee
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @notice Internal function to handle deposits
|
|
141
|
+
* @param sender Address of the depositor
|
|
142
|
+
*/
|
|
143
|
+
function _deposit(address sender, uint256 cotiOracleTimestamp, uint256 tokenOracleTimestamp) internal {
|
|
144
|
+
if (!isDepositEnabled) revert DepositDisabled();
|
|
145
|
+
if (msg.value == 0) revert AmountZero();
|
|
146
|
+
|
|
147
|
+
_checkDepositLimits(msg.value);
|
|
148
|
+
_validateOracleTimestamps(cotiOracleTimestamp, tokenOracleTimestamp, "COTI");
|
|
149
|
+
|
|
150
|
+
// Compute dynamic fee in COTI
|
|
151
|
+
uint256 fee = _computeCotiFee(msg.value, depositFixedFee, depositPercentageBps, depositMaxFee);
|
|
152
|
+
uint256 netAmount = msg.value - fee;
|
|
153
|
+
if (netAmount == 0) revert AmountZero();
|
|
154
|
+
|
|
155
|
+
accumulatedCotiFees += fee;
|
|
156
|
+
|
|
157
|
+
totalUserLiability += netAmount;
|
|
158
|
+
privateCoti.mint(sender, netAmount);
|
|
159
|
+
|
|
160
|
+
// Emit gross deposit amount and net private tokens minted
|
|
161
|
+
emit Deposit(sender, msg.value, netAmount);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @notice Deposit native COTI to receive private COTI (COTI.p)
|
|
166
|
+
* @param cotiOracleTimestamp COTI `lastUpdated` from the latest `estimateDepositFee` (must still equal on-chain at execution).
|
|
167
|
+
* @param tokenOracleTimestamp Same value as `cotiOracleTimestamp` for this bridge (both checks use `"COTI"`).
|
|
168
|
+
* @dev User sends native COTI with the transaction. Oracle races: {OracleTimestampMismatch} — re-estimate; see {_validateOracleTimestamps}.
|
|
169
|
+
*/
|
|
170
|
+
function deposit(uint256 cotiOracleTimestamp, uint256 tokenOracleTimestamp) external payable nonReentrant whenNotPaused notBlacklisted {
|
|
171
|
+
_deposit(msg.sender, cotiOracleTimestamp, tokenOracleTimestamp);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @notice Withdraw native COTI by burning private COTI
|
|
176
|
+
* @param amount Amount of private COTI to burn
|
|
177
|
+
* @param cotiOracleTimestamp COTI `lastUpdated` from the latest `estimateWithdrawFee` (must still equal on-chain at execution).
|
|
178
|
+
* @param tokenOracleTimestamp Same value as `cotiOracleTimestamp` for this bridge.
|
|
179
|
+
* @dev User must have approved the bridge to spend their private tokens. Oracle rules: {_validateOracleTimestamps}.
|
|
180
|
+
*/
|
|
181
|
+
function withdraw(uint256 amount, uint256 cotiOracleTimestamp, uint256 tokenOracleTimestamp) external nonReentrant whenNotPaused notBlacklisted {
|
|
182
|
+
_withdraw(msg.sender, amount, cotiOracleTimestamp, tokenOracleTimestamp);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function _withdraw(
|
|
186
|
+
address to,
|
|
187
|
+
uint256 amount,
|
|
188
|
+
uint256 cotiOracleTimestamp,
|
|
189
|
+
uint256 tokenOracleTimestamp
|
|
190
|
+
) internal {
|
|
191
|
+
if (amount == 0) revert AmountZero();
|
|
192
|
+
_checkWithdrawLimits(amount);
|
|
193
|
+
_validateOracleTimestamps(cotiOracleTimestamp, tokenOracleTimestamp, "COTI");
|
|
194
|
+
|
|
195
|
+
// Compute dynamic withdrawal fee in COTI
|
|
196
|
+
uint256 fee = _computeCotiFee(amount, withdrawFixedFee, withdrawPercentageBps, withdrawMaxFee);
|
|
197
|
+
uint256 publicAmount = amount - fee;
|
|
198
|
+
if (publicAmount == 0) revert AmountZero();
|
|
199
|
+
|
|
200
|
+
accumulatedCotiFees += fee;
|
|
201
|
+
|
|
202
|
+
if (address(this).balance < publicAmount)
|
|
203
|
+
revert InsufficientEthBalance();
|
|
204
|
+
|
|
205
|
+
// Extinguish liability for the full private amount burned (fee stays with bridge as native revenue).
|
|
206
|
+
totalUserLiability -= amount;
|
|
207
|
+
|
|
208
|
+
// Pull and burn private tokens
|
|
209
|
+
IPrivateERC20(address(privateCoti)).transferFrom(
|
|
210
|
+
msg.sender,
|
|
211
|
+
address(this),
|
|
212
|
+
amount
|
|
213
|
+
);
|
|
214
|
+
privateCoti.burn(amount);
|
|
215
|
+
|
|
216
|
+
(bool success, ) = to.call{value: publicAmount}("");
|
|
217
|
+
if (!success) revert EthTransferFailed();
|
|
218
|
+
|
|
219
|
+
emit Withdraw(to, amount, publicAmount);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* @notice Internal deposit without binding to a prior estimate’s oracle `lastUpdated` snapshot.
|
|
224
|
+
* @dev Used by {receive}. Fee uses {_computeCotiFee}, which still enforces: oracle configured
|
|
225
|
+
* ({PriceOracleNotSet}), non-zero COTI/USD rate ({InvalidOraclePrice}), and max age of
|
|
226
|
+
* `lastUpdated` when {PrivacyBridge.maxOracleAge} is set ({OraclePriceStale} /
|
|
227
|
+
* {OracleLastUpdatedInFuture}). What plain sends do **not** do is equality to timestamps
|
|
228
|
+
* passed into {deposit} from an off-chain estimate—users who need that binding should call {deposit}.
|
|
229
|
+
*/
|
|
230
|
+
function _directDeposit(address sender) internal {
|
|
231
|
+
if (!isDepositEnabled) revert DepositDisabled();
|
|
232
|
+
if (msg.value == 0) revert AmountZero();
|
|
233
|
+
|
|
234
|
+
_checkDepositLimits(msg.value);
|
|
235
|
+
|
|
236
|
+
uint256 fee = _computeCotiFee(msg.value, depositFixedFee, depositPercentageBps, depositMaxFee);
|
|
237
|
+
uint256 netAmount = msg.value - fee;
|
|
238
|
+
if (netAmount == 0) revert AmountZero();
|
|
239
|
+
|
|
240
|
+
accumulatedCotiFees += fee;
|
|
241
|
+
|
|
242
|
+
totalUserLiability += netAmount;
|
|
243
|
+
privateCoti.mint(sender, netAmount);
|
|
244
|
+
|
|
245
|
+
emit Deposit(sender, msg.value, netAmount);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @notice Fallback for plain native transfers: same fee path as {_directDeposit}.
|
|
250
|
+
* @dev See {_directDeposit}: zero/stale oracle rates are rejected via {_computeCotiFee}; use {deposit}
|
|
251
|
+
* when you must match `lastUpdated` from {estimateDepositFee} to the on-chain row (see {_validateOracleTimestamps}).
|
|
252
|
+
*/
|
|
253
|
+
receive() external payable nonReentrant whenNotPaused notBlacklisted {
|
|
254
|
+
_directDeposit(msg.sender);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* @notice Get the native COTI balance held by the bridge
|
|
259
|
+
* @return The contract's balance in native units (wei-equivalent)
|
|
260
|
+
*/
|
|
261
|
+
function getBridgeBalance() external view returns (uint256) {
|
|
262
|
+
return address(this).balance;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* @notice Withdraw accumulated fees to feeRecipient (Native implementation)
|
|
267
|
+
* @param amount Amount of fees to withdraw
|
|
268
|
+
* @dev Only the owner can call this function
|
|
269
|
+
*/
|
|
270
|
+
function withdrawFees(
|
|
271
|
+
uint256 amount
|
|
272
|
+
) external onlyOwner nonReentrant {
|
|
273
|
+
if (feeRecipient == address(0)) revert FeeRecipientNotSet();
|
|
274
|
+
if (amount == 0) revert AmountZero();
|
|
275
|
+
if (amount > accumulatedCotiFees) revert InsufficientAccumulatedFees();
|
|
276
|
+
if (amount > address(this).balance) revert InsufficientEthBalance();
|
|
277
|
+
|
|
278
|
+
accumulatedCotiFees -= amount;
|
|
279
|
+
|
|
280
|
+
// Transfer native COTI tokens to feeRecipient
|
|
281
|
+
(bool success, ) = feeRecipient.call{value: amount}("");
|
|
282
|
+
if (!success) revert EthTransferFailed();
|
|
283
|
+
|
|
284
|
+
emit FeesWithdrawn(feeRecipient, amount);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* @notice Move native COTI from this bridge to {rescueRecipient} while the bridge is paused.
|
|
289
|
+
* @dev Emergency / migration path: sends up to `amount` (typically the full {address(this).balance}) to
|
|
290
|
+
* {rescueRecipient}. That balance can include all user-deposited native liquidity and unswept fee
|
|
291
|
+
* float—there is no on-chain carve-out that keeps “user principal” behind. Intended for bug recovery
|
|
292
|
+
* or handover to a new bridge; a malicious or compromised owner who has paused can drain TVL to
|
|
293
|
+
* {rescueRecipient} in one or more calls. See {PrivacyBridge} contract-level @dev (3) for governance
|
|
294
|
+
* mitigations (multisig, timelock, monitoring). After a partial rescue, {accumulatedCotiFees} is capped
|
|
295
|
+
* to the remaining balance so fee accounting cannot exceed what is still on the contract. {totalUserLiability}
|
|
296
|
+
* is **not** adjusted: rescue only moves native to {rescueRecipient}; it does not burn private tokens or
|
|
297
|
+
* reduce user obligations on this contract, so the counter may exceed {address(this).balance} until a
|
|
298
|
+
* separate migration makes users whole.
|
|
299
|
+
* @param amount Amount of native currency to send (often the full balance for migration).
|
|
300
|
+
*/
|
|
301
|
+
function rescueNative(uint256 amount) external onlyOwner nonReentrant whenPaused {
|
|
302
|
+
if (amount == 0) revert AmountZero();
|
|
303
|
+
if (amount > address(this).balance) revert InsufficientEthBalance();
|
|
304
|
+
|
|
305
|
+
(bool success, ) = rescueRecipient.call{value: amount}("");
|
|
306
|
+
if (!success) revert EthTransferFailed();
|
|
307
|
+
|
|
308
|
+
uint256 remaining = address(this).balance;
|
|
309
|
+
if (accumulatedCotiFees > remaining) {
|
|
310
|
+
accumulatedCotiFees = remaining;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
emit NativeRescued(rescueRecipient, amount);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.19;
|
|
3
|
+
|
|
4
|
+
import "./PrivacyBridge.sol";
|
|
5
|
+
import "@openzeppelin/contracts/utils/math/Math.sol";
|
|
6
|
+
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
7
|
+
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
8
|
+
import "../token/PrivateERC20/IPrivateERC20.sol";
|
|
9
|
+
|
|
10
|
+
/// @dev Minimal interface to read decimals from tokens without modifying IPrivateERC20
|
|
11
|
+
interface IHasDecimals {
|
|
12
|
+
function decimals() external view returns (uint8);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @dev Abstract base contract for ERC20 Token Privacy Bridges
|
|
17
|
+
* @dev Handles the logic for bridging ERC20 tokens to their private counterparts.
|
|
18
|
+
* @dev The public ERC20 must match standard transfer semantics: {safeTransferFrom} of `amount` must
|
|
19
|
+
* increase the bridge balance by exactly `amount` ({UnexpectedTransferBalance} otherwise). This
|
|
20
|
+
* rejects common fee-on-transfer / deflationary patterns. Rebasing, blacklist hooks, and other
|
|
21
|
+
* non-standard behavior remain unsupported—deployment must still use a suitable asset.
|
|
22
|
+
* @dev **Private token:** The constructor stores `_privateToken` as {IPrivateERC20} from
|
|
23
|
+
* `contracts/token/PrivateERC20/IPrivateERC20.sol` (same `pragma` family as this contract). Integrators should
|
|
24
|
+
* bind ABIs/codegen to that canonical interface in this repo; alternate compiler pipelines (e.g. via-IR-only)
|
|
25
|
+
* should still target the same ABI, not ad-hoc casts to incompatible shapes.
|
|
26
|
+
*/
|
|
27
|
+
abstract contract PrivacyBridgeERC20 is PrivacyBridge {
|
|
28
|
+
using SafeERC20 for IERC20;
|
|
29
|
+
|
|
30
|
+
/// @notice The public ERC20 token being bridged (e.g., USDC, WETH)
|
|
31
|
+
IERC20 public token;
|
|
32
|
+
|
|
33
|
+
/// @notice Private token contract being minted/burned
|
|
34
|
+
IPrivateERC20 public privateToken;
|
|
35
|
+
|
|
36
|
+
/// @notice Band oracle symbol for the bridged token (e.g., "ETH", "WBTC", "ADA", "USDC", "USDT")
|
|
37
|
+
string public tokenSymbol;
|
|
38
|
+
|
|
39
|
+
/// @notice Cached ERC20 decimals (matches private token; set in constructor).
|
|
40
|
+
uint8 internal immutable bridgedTokenDecimals;
|
|
41
|
+
|
|
42
|
+
error InvalidTokenAddress();
|
|
43
|
+
error InvalidPrivateTokenAddress();
|
|
44
|
+
error CannotRescueBridgeToken();
|
|
45
|
+
error InvalidScalingFactor();
|
|
46
|
+
error AmountTooLarge();
|
|
47
|
+
error AmountTooSmall();
|
|
48
|
+
error InsufficientBridgeLiquidity();
|
|
49
|
+
error TokenTransferFailed();
|
|
50
|
+
error InvalidTokenSender();
|
|
51
|
+
error NativeFeeRequiredForTransferAndCallWithdraw();
|
|
52
|
+
error DecimalsMismatch();
|
|
53
|
+
/// @notice Pulled balance increase did not match `amount` (e.g. fee-on-transfer or deflationary token).
|
|
54
|
+
error UnexpectedTransferBalance(uint256 expected, uint256 received);
|
|
55
|
+
event ERC20Rescued(address indexed token, address indexed to, uint256 amount);
|
|
56
|
+
|
|
57
|
+
function _computeErc20Fee(
|
|
58
|
+
uint256 tokenAmount,
|
|
59
|
+
uint256 fixedFee,
|
|
60
|
+
uint256 percentageBps,
|
|
61
|
+
uint256 maxFee
|
|
62
|
+
) internal view returns (uint256) {
|
|
63
|
+
(uint256 fee,,,) = _computeErc20FeeAndMeta(tokenAmount, fixedFee, percentageBps, maxFee, tokenSymbol, bridgedTokenDecimals);
|
|
64
|
+
return fee;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @notice Simulate fee calculation for any token symbol and decimals.
|
|
69
|
+
* @dev Public view — allows frontends/operators to preview fees with arbitrary parameters.
|
|
70
|
+
* Reads live oracle prices but accepts custom fee params and token config.
|
|
71
|
+
* @param tokenAmount The token amount to simulate fee for (raw units; very large values can revert in fee math)
|
|
72
|
+
* @param fixedFee The minimum fee floor in COTI wei
|
|
73
|
+
* @param percentageBps The percentage in basis points (relative to {FEE_DIVISOR})
|
|
74
|
+
* @param maxFee The maximum fee cap in COTI wei
|
|
75
|
+
* @param _tokenSymbol The Band oracle symbol (e.g. "ETH", "WBTC", "ADA")
|
|
76
|
+
* @param _tokenDecimals The decimal precision of the token (e.g. 18, 8, 6)
|
|
77
|
+
* @return The computed fee in native COTI (18 decimals)
|
|
78
|
+
*/
|
|
79
|
+
function computeErc20Fee(
|
|
80
|
+
uint256 tokenAmount,
|
|
81
|
+
uint256 fixedFee,
|
|
82
|
+
uint256 percentageBps,
|
|
83
|
+
uint256 maxFee,
|
|
84
|
+
string calldata _tokenSymbol,
|
|
85
|
+
uint8 _tokenDecimals
|
|
86
|
+
) external view returns (uint256) {
|
|
87
|
+
(uint256 fee,,,) = _computeErc20FeeAndMeta(tokenAmount, fixedFee, percentageBps, maxFee, _tokenSymbol, _tokenDecimals);
|
|
88
|
+
return fee;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @dev ERC20 fee math + two {getPriceWithMeta} reads (token then COTI). Used by {_computeErc20Fee}
|
|
93
|
+
* and {estimateDepositFee}/{estimateWithdrawFee}. Each {Math.mulDiv} step truncates toward zero
|
|
94
|
+
* (see {PrivacyBridge.FEE_DIVISOR} NatSpec). Extreme `tokenAmount`×`tokenUsdRate` values can make
|
|
95
|
+
* {Math.mulDiv} revert—keep amounts within configured max deposit/withdraw limits.
|
|
96
|
+
*/
|
|
97
|
+
function _computeErc20FeeAndMeta(
|
|
98
|
+
uint256 tokenAmount,
|
|
99
|
+
uint256 fixedFee,
|
|
100
|
+
uint256 percentageBps,
|
|
101
|
+
uint256 maxFee,
|
|
102
|
+
string memory oracleTokenSymbol,
|
|
103
|
+
uint8 tokenDecimals
|
|
104
|
+
)
|
|
105
|
+
internal
|
|
106
|
+
view
|
|
107
|
+
returns (uint256 fee, uint256 cotiLastUpdated, uint256 tokenLastUpdated, uint256 blockTimestamp)
|
|
108
|
+
{
|
|
109
|
+
_requirePriceOracle();
|
|
110
|
+
ICotiPriceConsumer oracle = ICotiPriceConsumer(priceOracle);
|
|
111
|
+
(uint256 tokenUsdRate, uint256 tokenLU,) = oracle.getPriceWithMeta(oracleTokenSymbol);
|
|
112
|
+
(uint256 cotiUsdRate, uint256 cotiLU, uint256 cotiBts) = oracle.getPriceWithMeta("COTI");
|
|
113
|
+
_requirePositiveOracleRate(tokenUsdRate);
|
|
114
|
+
_requirePositiveOracleRate(cotiUsdRate);
|
|
115
|
+
_requireOracleFreshness(tokenLU);
|
|
116
|
+
_requireOracleFreshness(cotiLU);
|
|
117
|
+
uint256 txValueUsd = Math.mulDiv(tokenAmount, tokenUsdRate, 10 ** uint256(tokenDecimals));
|
|
118
|
+
uint256 percentageFeeUsd = Math.mulDiv(txValueUsd, percentageBps, FEE_DIVISOR);
|
|
119
|
+
uint256 percentageFeeCoti = Math.mulDiv(percentageFeeUsd, 1e18, cotiUsdRate);
|
|
120
|
+
fee = _calculateDynamicFee(percentageFeeCoti, fixedFee, maxFee);
|
|
121
|
+
cotiLastUpdated = cotiLU;
|
|
122
|
+
tokenLastUpdated = tokenLU;
|
|
123
|
+
blockTimestamp = cotiBts;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @notice Estimate the deposit fee in COTI for a given token amount
|
|
128
|
+
* @param tokenAmount The amount of ERC20 tokens to deposit (raw token units; very large values can revert in fee math)
|
|
129
|
+
* @return fee The estimated fee in native COTI (18 decimals)
|
|
130
|
+
* @return cotiLastUpdated COTI oracle data last update timestamp
|
|
131
|
+
* @return tokenLastUpdated Token oracle data last update timestamp
|
|
132
|
+
* @return blockTimestamp Third field from the COTI oracle row (same as pre-refactor behavior)
|
|
133
|
+
* @dev Pass the returned `cotiLastUpdated` and `tokenLastUpdated` verbatim into {deposit}/{withdraw} together
|
|
134
|
+
* with the same `tokenAmount` path; see {PrivacyBridge._validateOracleTimestamps} for strict equality UX.
|
|
135
|
+
*/
|
|
136
|
+
function estimateDepositFee(uint256 tokenAmount) external view returns (uint256 fee, uint256 cotiLastUpdated, uint256 tokenLastUpdated, uint256 blockTimestamp) {
|
|
137
|
+
(fee, cotiLastUpdated, tokenLastUpdated, blockTimestamp) = _computeErc20FeeAndMeta(
|
|
138
|
+
tokenAmount,
|
|
139
|
+
depositFixedFee,
|
|
140
|
+
depositPercentageBps,
|
|
141
|
+
depositMaxFee,
|
|
142
|
+
tokenSymbol,
|
|
143
|
+
bridgedTokenDecimals
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @notice Estimate the withdrawal fee in COTI for a given token amount
|
|
149
|
+
* @param tokenAmount The amount of ERC20 tokens to withdraw (raw units; very large values can revert in fee math)
|
|
150
|
+
* @return fee The estimated fee in native COTI (18 decimals)
|
|
151
|
+
* @return cotiLastUpdated COTI oracle data last update timestamp
|
|
152
|
+
* @return tokenLastUpdated Token oracle data last update timestamp
|
|
153
|
+
* @return blockTimestamp Third field from the COTI oracle row (same as pre-refactor behavior)
|
|
154
|
+
* @dev Same timestamp handoff as {estimateDepositFee}: use return values unchanged on the subsequent {withdraw}.
|
|
155
|
+
*/
|
|
156
|
+
function estimateWithdrawFee(uint256 tokenAmount) external view returns (uint256 fee, uint256 cotiLastUpdated, uint256 tokenLastUpdated, uint256 blockTimestamp) {
|
|
157
|
+
(fee, cotiLastUpdated, tokenLastUpdated, blockTimestamp) = _computeErc20FeeAndMeta(
|
|
158
|
+
tokenAmount,
|
|
159
|
+
withdrawFixedFee,
|
|
160
|
+
withdrawPercentageBps,
|
|
161
|
+
withdrawMaxFee,
|
|
162
|
+
tokenSymbol,
|
|
163
|
+
bridgedTokenDecimals
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @notice Collect the dynamic native COTI fee from msg.value and refund any excess
|
|
169
|
+
* @param fee The computed fee in native COTI
|
|
170
|
+
* @dev Reverts with {InsufficientCotiFee} if msg.value < fee.
|
|
171
|
+
* Excess above `fee` is sent back to `msg.sender` with a plain `call` (no receive hook guarantee).
|
|
172
|
+
* Smart wallets or contracts that revert or return false on unsolicited ETH will not receive the push;
|
|
173
|
+
* the excess is then credited to {refundableNativeExcess}[msg.sender] and emits `NativeRefundExcessPushFailed`
|
|
174
|
+
* (see {PrivacyBridge._creditRefundableNativeExcess} and {PrivacyBridge.claimRefundableNativeExcess}). Excess
|
|
175
|
+
* is never added to {accumulatedCotiFees}.
|
|
176
|
+
*/
|
|
177
|
+
function _collectDynamicNativeFee(uint256 fee) internal {
|
|
178
|
+
if (msg.value < fee) revert InsufficientCotiFee();
|
|
179
|
+
// Verify contract balance covers the fee before accounting
|
|
180
|
+
if (address(this).balance < fee) revert InsufficientEthBalance();
|
|
181
|
+
accumulatedCotiFees += fee;
|
|
182
|
+
if (msg.value > fee) {
|
|
183
|
+
uint256 excess = msg.value - fee;
|
|
184
|
+
(bool ok, ) = msg.sender.call{value: excess}("");
|
|
185
|
+
if (!ok) {
|
|
186
|
+
_creditRefundableNativeExcess(msg.sender, excess);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* @notice Initialize the PrivacyBridgeERC20 contract
|
|
193
|
+
* @param _token Address of the public ERC20 token (must be standard: no fee-on-transfer, no rebasing; same decimals as private token)
|
|
194
|
+
* @param _privateToken Address of the private token
|
|
195
|
+
* @param _tokenSymbol Band oracle symbol for the bridged token (e.g., "ETH", "WBTC") — required for Band Protocol compatibility check
|
|
196
|
+
* @param _priceOracle Non-zero price oracle (same requirement as {PrivacyBridge}'s constructor)
|
|
197
|
+
* @dev **Decimals:** reads `decimals()` on both tokens at deploy; reverts {DecimalsMismatch} if they differ—so
|
|
198
|
+
* mis-paired tokens fail **at construction**, not on first user tx. {bridgedTokenDecimals} is then cached
|
|
199
|
+
* immutably for fee math. After deploy, a mismatch cannot appear unless token contracts were misconfigured
|
|
200
|
+
* at deploy time or an upgradeable token later changes `decimals()` (exceptional external risk; not re-checked on-chain).
|
|
201
|
+
*/
|
|
202
|
+
constructor(
|
|
203
|
+
address _token,
|
|
204
|
+
address _privateToken,
|
|
205
|
+
string memory _tokenSymbol,
|
|
206
|
+
address _feeRecipient,
|
|
207
|
+
address _rescueRecipient,
|
|
208
|
+
address _priceOracle
|
|
209
|
+
) PrivacyBridge(_feeRecipient, _rescueRecipient, _priceOracle) {
|
|
210
|
+
if (_token == address(0)) revert InvalidTokenAddress();
|
|
211
|
+
if (_privateToken == address(0)) revert InvalidPrivateTokenAddress();
|
|
212
|
+
|
|
213
|
+
uint8 pubDecimals = IHasDecimals(_token).decimals();
|
|
214
|
+
if (pubDecimals != IHasDecimals(_privateToken).decimals()) revert DecimalsMismatch();
|
|
215
|
+
bridgedTokenDecimals = pubDecimals;
|
|
216
|
+
|
|
217
|
+
token = IERC20(_token);
|
|
218
|
+
privateToken = IPrivateERC20(_privateToken);
|
|
219
|
+
tokenSymbol = _tokenSymbol;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* @notice Deposit public ERC20 tokens to receive equivalent private tokens
|
|
224
|
+
* @param amount Amount of public ERC20 tokens to deposit
|
|
225
|
+
* @param cotiOracleTimestamp COTI `lastUpdated` from the latest `estimateDepositFee` (must still equal on-chain at execution).
|
|
226
|
+
* @param tokenOracleTimestamp Token `lastUpdated` from the same estimate (must still equal on-chain at execution).
|
|
227
|
+
* @dev Native COTI fee: send msg.value >= computed fee. Excess native is push-refunded then pull-credited on failure
|
|
228
|
+
* ({_collectDynamicNativeFee}). If the Band row advances before inclusion, tx reverts with {OracleTimestampMismatch}—re-estimate and resubmit (see {_validateOracleTimestamps}).
|
|
229
|
+
*/
|
|
230
|
+
function deposit(
|
|
231
|
+
uint256 amount,
|
|
232
|
+
uint256 cotiOracleTimestamp,
|
|
233
|
+
uint256 tokenOracleTimestamp
|
|
234
|
+
) external payable nonReentrant whenNotPaused notBlacklisted {
|
|
235
|
+
_deposit(amount, cotiOracleTimestamp, tokenOracleTimestamp);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* @dev Pulls public tokens before collecting the native COTI fee so a non-standard transfer
|
|
240
|
+
* (e.g. fee-on-transfer) reverts before debiting `msg.value`, and insufficient `msg.value`
|
|
241
|
+
* still reverts the whole tx including the token transfer.
|
|
242
|
+
*/
|
|
243
|
+
function _deposit(uint256 amount, uint256 cotiOracleTimestamp, uint256 tokenOracleTimestamp) internal {
|
|
244
|
+
if (!isDepositEnabled) revert DepositDisabled();
|
|
245
|
+
if (amount == 0) revert AmountZero();
|
|
246
|
+
_checkDepositLimits(amount);
|
|
247
|
+
_validateOracleTimestamps(cotiOracleTimestamp, tokenOracleTimestamp, tokenSymbol);
|
|
248
|
+
|
|
249
|
+
uint256 fee = _computeErc20Fee(amount, depositFixedFee, depositPercentageBps, depositMaxFee);
|
|
250
|
+
|
|
251
|
+
uint256 balBefore = token.balanceOf(address(this));
|
|
252
|
+
token.safeTransferFrom(msg.sender, address(this), amount);
|
|
253
|
+
uint256 received = token.balanceOf(address(this)) - balBefore;
|
|
254
|
+
if (received != amount) revert UnexpectedTransferBalance(amount, received);
|
|
255
|
+
|
|
256
|
+
_collectDynamicNativeFee(fee);
|
|
257
|
+
|
|
258
|
+
totalUserLiability += received;
|
|
259
|
+
privateToken.mint(msg.sender, received);
|
|
260
|
+
|
|
261
|
+
emit Deposit(msg.sender, amount, received);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @notice Withdraw public ERC20 tokens by burning private tokens
|
|
266
|
+
* @param amount Amount of private tokens to burn
|
|
267
|
+
* @param cotiOracleTimestamp COTI `lastUpdated` from the latest `estimateWithdrawFee` (must still equal on-chain at execution).
|
|
268
|
+
* @param tokenOracleTimestamp Token `lastUpdated` from the same estimate (must still equal on-chain at execution).
|
|
269
|
+
* @dev Requires prior approval on the private token. Send `msg.value >= fee`; native fee is
|
|
270
|
+
* collected only after the public token transfer succeeds (mirrors {deposit} ordering). Oracle
|
|
271
|
+
* timestamp rules match {deposit} / {_validateOracleTimestamps}. Native excess handling matches {deposit}.
|
|
272
|
+
*/
|
|
273
|
+
function withdraw(
|
|
274
|
+
uint256 amount,
|
|
275
|
+
uint256 cotiOracleTimestamp,
|
|
276
|
+
uint256 tokenOracleTimestamp
|
|
277
|
+
) external payable nonReentrant whenNotPaused notBlacklisted {
|
|
278
|
+
_withdraw(amount, cotiOracleTimestamp, tokenOracleTimestamp);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @dev Mirrors {_deposit}: native fee is collected only after the ERC20 leg succeeds by standard
|
|
283
|
+
* semantics (here: burn + public transfer with full `userGain`). Insufficient `msg.value`
|
|
284
|
+
* then reverts the entire withdrawal including private burn and public transfer.
|
|
285
|
+
*/
|
|
286
|
+
function _withdraw(uint256 amount, uint256 cotiOracleTimestamp, uint256 tokenOracleTimestamp) internal {
|
|
287
|
+
if (amount == 0) revert AmountZero();
|
|
288
|
+
_checkWithdrawLimits(amount);
|
|
289
|
+
_validateOracleTimestamps(cotiOracleTimestamp, tokenOracleTimestamp, tokenSymbol);
|
|
290
|
+
|
|
291
|
+
uint256 fee = _computeErc20Fee(amount, withdrawFixedFee, withdrawPercentageBps, withdrawMaxFee);
|
|
292
|
+
|
|
293
|
+
uint256 bridgeBalance = token.balanceOf(address(this));
|
|
294
|
+
if (bridgeBalance < amount) revert InsufficientBridgeLiquidity();
|
|
295
|
+
|
|
296
|
+
totalUserLiability -= amount;
|
|
297
|
+
privateToken.transferFrom(msg.sender, address(this), amount);
|
|
298
|
+
privateToken.burn(amount);
|
|
299
|
+
|
|
300
|
+
uint256 userBalBefore = token.balanceOf(msg.sender);
|
|
301
|
+
token.safeTransfer(msg.sender, amount);
|
|
302
|
+
uint256 userGain = token.balanceOf(msg.sender) - userBalBefore;
|
|
303
|
+
if (userGain != amount) revert UnexpectedTransferBalance(amount, userGain);
|
|
304
|
+
|
|
305
|
+
_collectDynamicNativeFee(fee);
|
|
306
|
+
|
|
307
|
+
emit Withdraw(msg.sender, amount, amount);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* @notice Move ERC20 from this contract to {rescueRecipient} while the bridge is paused.
|
|
312
|
+
* @dev Requires {whenPaused} for every `_token` so rescue never runs concurrently with user flows.
|
|
313
|
+
* For the live public {token}, `amount` can be the full balance—including all TVL backing withdrawals.
|
|
314
|
+
* Same governance risk as {PrivacyBridgeCotiNative.rescueNative}: owner + pause can send user funds
|
|
315
|
+
* to {rescueRecipient}; see {PrivacyBridge} contract @dev (3). Private token cannot be rescued here
|
|
316
|
+
* ({CannotRescueBridgeToken}). {totalUserLiability} is intentionally **not** updated here: rescue only
|
|
317
|
+
* moves collateral to {rescueRecipient}; it does not burn private tokens or unwind user obligations on
|
|
318
|
+
* this ledger, so outstanding claims can exceed {token} held by this contract until a separate migration
|
|
319
|
+
* path makes users whole.
|
|
320
|
+
*/
|
|
321
|
+
function rescueERC20(
|
|
322
|
+
address _token,
|
|
323
|
+
uint256 amount
|
|
324
|
+
) external onlyOwner nonReentrant whenPaused {
|
|
325
|
+
if (amount == 0) revert AmountZero();
|
|
326
|
+
|
|
327
|
+
if (_token == address(privateToken)) revert CannotRescueBridgeToken();
|
|
328
|
+
|
|
329
|
+
IERC20(_token).safeTransfer(rescueRecipient, amount);
|
|
330
|
+
|
|
331
|
+
emit ERC20Rescued(_token, rescueRecipient, amount);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.19;
|
|
3
|
+
|
|
4
|
+
import "./PrivacyBridgeERC20.sol";
|
|
5
|
+
import "../token/PrivateERC20/tokens/PrivateBridgedUSDC.sol";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @title PrivacyBridgeUSDCe
|
|
9
|
+
* @notice Bridge contract for converting between USDC.e and privacy-preserving p.USDC.e tokens
|
|
10
|
+
*/
|
|
11
|
+
contract PrivacyBridgeUSDCe is PrivacyBridgeERC20 {
|
|
12
|
+
|
|
13
|
+
constructor(
|
|
14
|
+
address _usdc,
|
|
15
|
+
address _privateUsdc,
|
|
16
|
+
address _feeRecipient,
|
|
17
|
+
address _rescueRecipient,
|
|
18
|
+
address _priceOracle
|
|
19
|
+
) PrivacyBridgeERC20(_usdc, _privateUsdc, "USDC", _feeRecipient, _rescueRecipient, _priceOracle) {
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
}
|