@coti-io/coti-contracts 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +18 -14
- package/README.md +3 -1
- package/contracts/disperse/coinByRatio/FixedRatioCoinDisperser.sol +452 -0
- package/contracts/disperse/coinByRatio/FixedRatioCoinDisperserLeftoverS1.sol +490 -0
- package/contracts/disperse/coinByRatio/FixedRatioCoinDisperserUnlimitedWindow.sol +432 -0
- package/contracts/disperse/disperseToken/MintDisperser.sol +120 -0
- package/contracts/disperse/disperseToken/TokenDisperser.sol +139 -0
- package/contracts/mocks/token/ERC20Mock.sol +19 -0
- package/contracts/mocks/token/PrivateERC20/EncryptedTokenReceiverMock.sol +18 -0
- package/contracts/mocks/token/PrivateERC20/PrivacyBridgeERC20Mock.sol +13 -0
- package/contracts/mocks/token/PrivateERC20/PrivateERC20AuditorSupplyMock.sol +44 -0
- package/contracts/mocks/token/PrivateERC20/PrivateERC20CappedMock.sol +23 -0
- package/contracts/mocks/token/PrivateERC20/PrivateERC20GtCallerMock.sol +29 -0
- package/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.sol +9 -4
- package/contracts/mocks/token/PrivateERC20/PrivateERC20ReentrantReceiverMock.sol +39 -0
- package/contracts/mocks/token/PrivateERC20/PublicReentrantTokenReceiverMock.sol +29 -0
- package/contracts/mocks/token/PrivateERC20/PublicTokenReceiverBoolMock.sol +18 -0
- package/contracts/mocks/token/PrivateERC20/PublicTokenReceiverMock.sol +12 -0
- package/contracts/mocks/utils/mpc/Arithmetic128TestsContract.sol +123 -0
- package/contracts/mocks/utils/mpc/Arithmetic256TestsContract.sol +122 -0
- package/contracts/mocks/utils/mpc/Bitwise128TestsContract.sol +65 -0
- package/contracts/mocks/utils/mpc/Bitwise256TestsContract.sol +65 -0
- package/contracts/mocks/utils/mpc/CheckedArithmetic128WithOverflowBitTestsContract.sol +64 -0
- package/contracts/mocks/utils/mpc/CheckedArithmetic256WithOverflowBitTestsContract.sol +64 -0
- package/contracts/mocks/utils/mpc/Comparison128TestsContract.sol +98 -0
- package/contracts/mocks/utils/mpc/Comparison256TestsContract.sol +98 -0
- package/contracts/mocks/utils/mpc/MinMax128TestsContract.sol +44 -0
- package/contracts/mocks/utils/mpc/MinMax256TestsContract.sol +44 -0
- package/contracts/mocks/utils/mpc/MinimalImplementation.sol +55 -0
- package/contracts/mocks/utils/mpc/MinimalProxy.sol +27 -0
- package/contracts/mocks/utils/mpc/MpcOperations128TestContract.sol +267 -0
- package/contracts/mocks/utils/mpc/MpcOperationsTestContract.sol +334 -0
- package/contracts/mocks/utils/mpc/Mux128TestsContract.sol +24 -0
- package/contracts/mocks/utils/mpc/Mux256TestsContract.sol +24 -0
- package/contracts/mocks/utils/mpc/OnBoard128TestsContract.sol +93 -0
- package/contracts/mocks/utils/mpc/OnBoard256TestsContract.sol +116 -0
- package/contracts/mocks/utils/mpc/PrivacyImplementationV1.sol +157 -0
- package/contracts/mocks/utils/mpc/PrivacyImplementationV2.sol +133 -0
- package/contracts/mocks/utils/mpc/PrivacyProxy.sol +137 -0
- package/contracts/mocks/utils/mpc/Random128TestsContract.sol +32 -0
- package/contracts/mocks/utils/mpc/Random256TestsContract.sol +32 -0
- package/contracts/mocks/utils/mpc/Shift128TestsContract.sol +36 -0
- package/contracts/mocks/utils/mpc/Shift256TestsContract.sol +36 -0
- package/contracts/mocks/utils/mpc/Transfer128TestsContract.sol +29 -0
- package/contracts/mocks/utils/mpc/Transfer256TestsContract.sol +29 -0
- package/contracts/mocks/utils/mpc/TransferWithAllowance128TestsContract.sol +32 -0
- package/contracts/mocks/utils/mpc/TransferWithAllowance256TestsContract.sol +32 -0
- package/contracts/mocks/utils/mpc/ValidateCiphertext128TestsContract.sol +59 -0
- package/contracts/mocks/utils/mpc/ValidateCiphertext256TestsContract.sol +63 -0
- package/contracts/mocks/utils/mpc/ValidateCiphertextTestsContract.sol +99 -0
- package/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.sol +7 -6
- package/contracts/node/CotiNodeRewards.sol +199 -0
- package/contracts/node/SoulboundNodeNFT.sol +519 -0
- package/contracts/privacyBridge/PrivacyBridge.sol +318 -0
- package/contracts/privacyBridge/PrivacyBridgeCotiNative.sol +268 -0
- package/contracts/privacyBridge/PrivacyBridgeERC20.sol +251 -0
- package/contracts/privacyBridge/PrivacyBridgeUSDCe.sol +16 -0
- package/contracts/privacyBridge/PrivacyBridgeUSDT.sol +17 -0
- package/contracts/privacyBridge/PrivacyBridgeWADA.sol +17 -0
- package/contracts/privacyBridge/PrivacyBridgeWBTC.sol +17 -0
- package/contracts/privacyBridge/PrivacyBridgeWETH.sol +17 -0
- package/contracts/privacyBridge/PrivacyBridgegCoti.sol +17 -0
- package/contracts/token/PrivateERC20/IPrivateERC20.sol +273 -40
- package/contracts/token/PrivateERC20/ITokenReceiver.sol +17 -0
- package/contracts/token/PrivateERC20/ITokenReceiverEncrypted.sol +20 -0
- package/contracts/token/PrivateERC20/PrivateERC20.sol +861 -152
- package/contracts/token/PrivateERC20/tokens/PrivateBridgedUSDC.sol +17 -0
- package/contracts/token/PrivateERC20/tokens/PrivateCOTI.sol +13 -0
- package/contracts/token/PrivateERC20/tokens/PrivateCOTITreasuryGovernanceToken.sol +17 -0
- package/contracts/token/PrivateERC20/tokens/PrivateTetherUSD.sol +17 -0
- package/contracts/token/PrivateERC20/tokens/PrivateWrappedADA.sol +17 -0
- package/contracts/token/PrivateERC20/tokens/PrivateWrappedBTC.sol +17 -0
- package/contracts/token/PrivateERC20/tokens/PrivateWrappedEther.sol +13 -0
- package/contracts/utils/mpc/MpcCore.sol +10780 -4962
- package/contracts/utils/mpc/MpcInterface.sol +7 -2
- package/hardhat/gasPriceBump.ts +60 -0
- package/hardhat.config.ts +60 -12
- package/package.json +21 -3
- package/scripts/deploySoulboundNodeNFT.ts +57 -0
- package/test/token/PrivateERC20/PrivacyBridge.fees.test.ts +327 -0
- package/test/token/PrivateERC20/PrivateERC20.test.ts +1109 -268
- package/test/utils/mpc/Bitwise128.test.ts +92 -0
- package/test/utils/mpc/Bitwise256.test.ts +101 -0
- package/test/utils/mpc/BuildInputText128.test.ts +398 -0
- package/test/utils/mpc/CheckedArithmetic128.test.ts +45 -0
- package/test/utils/mpc/CheckedArithmetic256.test.ts +45 -0
- package/test/utils/mpc/Comparison128.test.ts +48 -0
- package/test/utils/mpc/Comparison256.test.ts +48 -0
- package/test/utils/mpc/InvalidCiphertext.test.ts +179 -0
- package/test/utils/mpc/InvalidCiphertext128.test.ts +179 -0
- package/test/utils/mpc/InvalidCiphertext256.test.ts +201 -0
- package/test/utils/mpc/InvalidTransfer128.test.ts +166 -0
- package/test/utils/mpc/InvalidTransfer256.test.ts +158 -0
- package/test/utils/mpc/MinMax128.test.ts +44 -0
- package/test/utils/mpc/MinMax256.test.ts +44 -0
- package/test/utils/mpc/MinimalProxyDemo.test.ts +280 -0
- package/test/utils/mpc/MpcOperations.test.ts +589 -0
- package/test/utils/mpc/MpcOperations128.test.ts +632 -0
- package/test/utils/mpc/Mux128.test.ts +41 -0
- package/test/utils/mpc/Mux256.test.ts +41 -0
- package/test/utils/mpc/NegativeCases.test.ts +478 -0
- package/test/utils/mpc/NegativeCases128.test.ts +237 -0
- package/test/utils/mpc/NegativeCases256.test.ts +236 -0
- package/test/utils/mpc/OnBoard128.test.ts +90 -0
- package/test/utils/mpc/OnBoard256.test.ts +114 -0
- package/test/utils/mpc/Precompile128.test.ts +51 -0
- package/test/utils/mpc/Precompile256.test.ts +115 -0
- package/test/utils/mpc/ProxyValidation.test.ts +199 -0
- package/test/utils/mpc/Random128.test.ts +47 -0
- package/test/utils/mpc/Random256.test.ts +47 -0
- package/test/utils/mpc/Shift128.test.ts +41 -0
- package/test/utils/mpc/Shift256.test.ts +41 -0
- package/test/utils/mpc/Transfer128.test.ts +46 -0
- package/test/utils/mpc/Transfer256.test.ts +46 -0
- package/test/utils/mpc/TransferWithAllowance128.test.ts +48 -0
- package/test/utils/mpc/TransferWithAllowance256.test.ts +48 -0
- package/test/utils/mpc/UpgradeablePrivacyProxy.test.ts +307 -0
- package/test/utils/mpc/ValidateCiphertext.test.ts +221 -0
- package/test/utils/mpc/ValidateCiphertext256.test.ts +161 -0
- package/test/utils/mpc/ValidateCiphertext256Decryption.test.ts +383 -0
- package/test/utils/mpc/WalletEncryptionFailures.test.ts +494 -0
- package/test/utils/privateErc20Helpers.ts +97 -0
- package/typechain-types/@openzeppelin/contracts/access/Ownable.ts +153 -0
- package/typechain-types/@openzeppelin/contracts/access/index.ts +4 -0
- package/typechain-types/@openzeppelin/contracts/index.ts +2 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC20/IERC20.ts +262 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.ts +143 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC20/extensions/index.ts +4 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC20/index.ts +6 -0
- package/typechain-types/@openzeppelin/contracts/token/index.ts +2 -0
- package/typechain-types/contracts/disperse/coinByRatio/FixedRatioCoinDisperser.ts +679 -0
- package/typechain-types/contracts/disperse/coinByRatio/index.ts +4 -0
- package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/IMintableERC20.ts +97 -0
- package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/MintDisperser.ts +206 -0
- package/typechain-types/contracts/disperse/disperseToken/MintDisperser.sol/index.ts +5 -0
- package/typechain-types/contracts/disperse/disperseToken/TokenDisperser.ts +191 -0
- package/typechain-types/contracts/disperse/disperseToken/index.ts +6 -0
- package/typechain-types/contracts/disperse/index.ts +7 -0
- package/typechain-types/contracts/index.ts +2 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.ts +77 -60
- package/typechain-types/contracts/mocks/utils/mpc/Arithmetic128TestsContract.ts +311 -0
- package/typechain-types/contracts/mocks/utils/mpc/Arithmetic256TestsContract.ts +311 -0
- package/typechain-types/contracts/mocks/utils/mpc/Bitwise128TestsContract.ts +179 -0
- package/typechain-types/contracts/mocks/utils/mpc/Bitwise256TestsContract.ts +179 -0
- package/typechain-types/contracts/mocks/utils/mpc/CheckedArithmetic128WithOverflowBitTestsContract.ts +206 -0
- package/typechain-types/contracts/mocks/utils/mpc/CheckedArithmetic256WithOverflowBitTestsContract.ts +206 -0
- package/typechain-types/contracts/mocks/utils/mpc/Comparison128TestsContract.ts +278 -0
- package/typechain-types/contracts/mocks/utils/mpc/Comparison256TestsContract.ts +278 -0
- package/typechain-types/contracts/mocks/utils/mpc/MinMax128TestsContract.ts +142 -0
- package/typechain-types/contracts/mocks/utils/mpc/MinMax256TestsContract.ts +142 -0
- package/typechain-types/contracts/mocks/utils/mpc/MinimalImplementation.ts +259 -0
- package/typechain-types/contracts/mocks/utils/mpc/MinimalProxy.ts +90 -0
- package/typechain-types/contracts/mocks/utils/mpc/MpcOperations128TestContract.ts +388 -0
- package/typechain-types/contracts/mocks/utils/mpc/MpcOperationsTestContract.ts +455 -0
- package/typechain-types/contracts/mocks/utils/mpc/Mux128TestsContract.ts +109 -0
- package/typechain-types/contracts/mocks/utils/mpc/Mux256TestsContract.ts +109 -0
- package/typechain-types/contracts/mocks/utils/mpc/OnBoard128TestsContract.ts +166 -0
- package/typechain-types/contracts/mocks/utils/mpc/OnBoard256TestsContract.ts +194 -0
- package/typechain-types/contracts/mocks/utils/mpc/PrivacyImplementationV1.ts +385 -0
- package/typechain-types/contracts/mocks/utils/mpc/PrivacyImplementationV2.ts +441 -0
- package/typechain-types/contracts/mocks/utils/mpc/PrivacyProxy.ts +201 -0
- package/typechain-types/contracts/mocks/utils/mpc/Random128TestsContract.ts +131 -0
- package/typechain-types/contracts/mocks/utils/mpc/Random256TestsContract.ts +131 -0
- package/typechain-types/contracts/mocks/utils/mpc/Shift128TestsContract.ts +142 -0
- package/typechain-types/contracts/mocks/utils/mpc/Shift256TestsContract.ts +142 -0
- package/typechain-types/contracts/mocks/utils/mpc/Transfer128TestsContract.ts +109 -0
- package/typechain-types/contracts/mocks/utils/mpc/Transfer256TestsContract.ts +109 -0
- package/typechain-types/contracts/mocks/utils/mpc/TransferWithAllowance128TestsContract.ts +128 -0
- package/typechain-types/contracts/mocks/utils/mpc/TransferWithAllowance256TestsContract.ts +128 -0
- package/typechain-types/contracts/mocks/utils/mpc/ValidateCiphertext128TestsContract.ts +198 -0
- package/typechain-types/contracts/mocks/utils/mpc/ValidateCiphertext256TestsContract.ts +182 -0
- package/typechain-types/contracts/mocks/utils/mpc/ValidateCiphertextTestsContract.ts +257 -0
- package/typechain-types/contracts/mocks/utils/mpc/index.ts +32 -8
- package/typechain-types/contracts/token/PrivateERC20/IPrivateERC20.ts +77 -60
- package/typechain-types/contracts/token/PrivateERC20/PrivateERC20.ts +77 -60
- package/typechain-types/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations.ts +111 -10
- package/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.ts +74 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/index.ts +1 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/IERC20__factory.ts +205 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit__factory.ts +100 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/extensions/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC20/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/index.ts +1 -0
- package/typechain-types/factories/contracts/disperse/coinByRatio/FixedRatioCoinDisperser__factory.ts +759 -0
- package/typechain-types/factories/contracts/disperse/coinByRatio/index.ts +4 -0
- package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/IMintableERC20__factory.ts +43 -0
- package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/MintDisperser__factory.ts +185 -0
- package/typechain-types/factories/contracts/disperse/disperseToken/MintDisperser.sol/index.ts +5 -0
- package/typechain-types/factories/contracts/disperse/disperseToken/TokenDisperser__factory.ts +198 -0
- package/typechain-types/factories/contracts/disperse/disperseToken/index.ts +5 -0
- package/typechain-types/factories/contracts/disperse/index.ts +5 -0
- package/typechain-types/factories/contracts/index.ts +1 -0
- package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20Mock__factory.ts +179 -47
- package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic128TestsContract__factory.ts +330 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Arithmetic256TestsContract__factory.ts +330 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/ArithmeticTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise128TestsContract__factory.ts +184 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Bitwise256TestsContract__factory.ts +184 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/BitwiseTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmetic128WithOverflowBitTestsContract__factory.ts +203 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmetic256WithOverflowBitTestsContract__factory.ts +203 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/CheckedArithmeticWIthOverflowBitTestsContract.sol/CheckedArithmeticWithOverflowBitTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison128TestsContract__factory.ts +295 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison1TestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison256TestsContract__factory.ts +295 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison2TestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/MinMax128TestsContract__factory.ts +147 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/MinMax256TestsContract__factory.ts +147 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/MinMaxTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/MinimalImplementation__factory.ts +263 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/MinimalProxy__factory.ts +104 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous1TestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/MiscellaneousTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/MpcOperations128TestContract__factory.ts +723 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/MpcOperationsTestContract__factory.ts +1410 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Mux128TestsContract__factory.ts +115 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Mux256TestsContract__factory.ts +115 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/OffboardToUserKeyTestContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/OnBoard128TestsContract__factory.ts +175 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/OnBoard256TestsContract__factory.ts +205 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyImplementationV1__factory.ts +521 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyImplementationV2__factory.ts +648 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/PrivacyProxy__factory.ts +179 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Random128TestsContract__factory.ts +131 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Random256TestsContract__factory.ts +131 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Shift128TestsContract__factory.ts +147 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Shift256TestsContract__factory.ts +147 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/ShiftTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/StringTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/Transfer128TestsContract__factory.ts +135 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Transfer256TestsContract__factory.ts +135 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferScalarTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance128TestsContract__factory.ts +154 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance256TestsContract__factory.ts +154 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_16TestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_32TestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_64TestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowance64_8TestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowanceScalarTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferWithAllowanceTestsContract__factory.ts +1 -1
- package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertext128TestsContract__factory.ts +190 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertext256TestsContract__factory.ts +210 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/ValidateCiphertextTestsContract__factory.ts +260 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/index.ts +32 -8
- package/typechain-types/factories/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock__factory.ts +7 -7
- package/typechain-types/factories/contracts/token/PrivateERC20/IPrivateERC20__factory.ts +174 -42
- package/typechain-types/factories/contracts/token/PrivateERC20/PrivateERC20__factory.ts +174 -42
- package/typechain-types/factories/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations__factory.ts +126 -0
- package/typechain-types/hardhat.d.ts +638 -80
- package/typechain-types/index.ts +78 -16
- package/contracts/mocks/utils/mpc/Arithmetic128BitTestsContract.sol +0 -260
- package/contracts/mocks/utils/mpc/Arithmetic256BitTestsContract.sol +0 -264
- package/contracts/mocks/utils/mpc/Bitwise128BitTestsContract.sol +0 -91
- package/contracts/mocks/utils/mpc/Bitwise256BitTestsContract.sol +0 -91
- package/contracts/mocks/utils/mpc/Comparison128BitTestsContract.sol +0 -158
- package/contracts/mocks/utils/mpc/Comparison256BitTestsContract.sol +0 -158
- package/contracts/mocks/utils/mpc/Miscellaneous128BitTestsContract.sol +0 -185
- package/contracts/mocks/utils/mpc/Miscellaneous256BitTestsContract.sol +0 -190
- package/contracts/mocks/utils/mpc/README.md +0 -486
- package/test/utils/mpc/Unsigned128BitIntegers.test.ts +0 -945
- package/test/utils/mpc/Unsigned256BitIntegers.test.ts +0 -1124
- package/test/utils/mpc/helpers.ts +0 -77
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
|
|
5
|
+
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
6
|
+
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
7
|
+
|
|
8
|
+
abstract contract ReentrancyGuard {
|
|
9
|
+
uint256 private constant _NOT_ENTERED = 1;
|
|
10
|
+
uint256 private constant _ENTERED = 2;
|
|
11
|
+
uint256 private _status = _NOT_ENTERED;
|
|
12
|
+
modifier nonReentrant() {
|
|
13
|
+
require(_status != _ENTERED, "REENTRANCY");
|
|
14
|
+
_status = _ENTERED;
|
|
15
|
+
_;
|
|
16
|
+
_status = _NOT_ENTERED;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @title FixedRatioCoinDisperserLeftoverS1
|
|
22
|
+
* @notice Redeem ERC20 "points" for native ETH payout pool
|
|
23
|
+
* - Order-independent fixed-index redemption
|
|
24
|
+
* - Pull-based withdrawals (DoS safe)
|
|
25
|
+
* - Optional push for EOAs only
|
|
26
|
+
* - Native ETH payouts
|
|
27
|
+
*/
|
|
28
|
+
contract FixedRatioCoinDisperserLeftoverS1 is ReentrancyGuard {
|
|
29
|
+
using SafeERC20 for IERC20;
|
|
30
|
+
|
|
31
|
+
// --- Custom Errors ---
|
|
32
|
+
error TokenZeroAddress();
|
|
33
|
+
error OwnerZeroAddress();
|
|
34
|
+
error InvalidBlockRange();
|
|
35
|
+
error NotOwner();
|
|
36
|
+
error AlreadyFinalized();
|
|
37
|
+
error PoolZero();
|
|
38
|
+
error SupplyZero();
|
|
39
|
+
error NotFinalized();
|
|
40
|
+
error NoExcess();
|
|
41
|
+
error WindowActive();
|
|
42
|
+
error NoDust();
|
|
43
|
+
error WithdrawFailed();
|
|
44
|
+
error ContractMustPull();
|
|
45
|
+
error NothingToWithdraw();
|
|
46
|
+
error ContractPaused();
|
|
47
|
+
error OutOfWindow();
|
|
48
|
+
error AmountZero();
|
|
49
|
+
error SnapshotZero();
|
|
50
|
+
error NoPointsLeft();
|
|
51
|
+
error OverCapacity();
|
|
52
|
+
error BalanceManipulation();
|
|
53
|
+
error PayoutZero();
|
|
54
|
+
error RedemptionNotClosed();
|
|
55
|
+
error InvalidAddress();
|
|
56
|
+
error InsufficientBalance();
|
|
57
|
+
error InsufficientEthBalance();
|
|
58
|
+
error EthTransferFailed();
|
|
59
|
+
|
|
60
|
+
// --- Events ---
|
|
61
|
+
event Funded(address indexed from, uint256 amount);
|
|
62
|
+
event Finalized(uint256 totalPayoutPool, uint256 totalRedeemablePoints, uint256 accPayoutPerPoint);
|
|
63
|
+
event Redeemed(address indexed user, uint256 pointsRequested, uint256 pointsReceived, uint256 payout, bool pushed);
|
|
64
|
+
event Paused(bool isPaused);
|
|
65
|
+
event DustWithdrawn(uint256 amount);
|
|
66
|
+
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
|
|
67
|
+
event Withdrawal(address indexed user, uint256 amount);
|
|
68
|
+
|
|
69
|
+
/// @notice Emitted when the payout index is updated via external source sync.
|
|
70
|
+
event AccPayoutPerPointUpdated(uint256 previousAccPayoutPerPoint, uint256 newAccPayoutPerPoint);
|
|
71
|
+
|
|
72
|
+
// --- Config ---
|
|
73
|
+
IERC20 public immutable POINTS_TOKEN;
|
|
74
|
+
address public owner;
|
|
75
|
+
|
|
76
|
+
// --- Redemption window ---
|
|
77
|
+
uint256 public immutable START_BLOCK;
|
|
78
|
+
uint256 public immutable END_BLOCK;
|
|
79
|
+
|
|
80
|
+
// NOTE:
|
|
81
|
+
// START_BLOCK / END_BLOCK are retained for ABI compatibility, but are no longer enforced.
|
|
82
|
+
|
|
83
|
+
// --- Lifecycle ---
|
|
84
|
+
bool public finalized;
|
|
85
|
+
bool public paused;
|
|
86
|
+
|
|
87
|
+
// --- Accounting ---
|
|
88
|
+
uint256 public totalPayoutPool; // ETH reserved for redemptions (snapshot)
|
|
89
|
+
uint256 public totalRedeemablePoints; // points supply snapshot at finalize
|
|
90
|
+
uint256 public accPayoutPerPoint; // index = totalPayoutPool * 1e18 / totalRedeemablePoints
|
|
91
|
+
uint256 public totalPointsRedeemed; // cumulative points locked
|
|
92
|
+
uint256 public totalPayoutSent; // cumulative ETH sent
|
|
93
|
+
|
|
94
|
+
// --- Pull ledger ---
|
|
95
|
+
mapping(address => uint256) public pendingWithdrawals;
|
|
96
|
+
uint256 public pendingTotal;
|
|
97
|
+
|
|
98
|
+
uint256 private constant ONE = 1e18;
|
|
99
|
+
|
|
100
|
+
modifier onlyOwner() {
|
|
101
|
+
if (msg.sender != owner) revert NotOwner();
|
|
102
|
+
_;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @dev Constructor to initialize the FixedRatioCoinDisperser contract
|
|
107
|
+
* @param _pointsToken Address of the ERC20 points token that can be redeemed
|
|
108
|
+
* @param _owner Address that will have admin privileges (can pause, finalize, etc.)
|
|
109
|
+
* @param _startBlock Block number when redemption window opens (retained for ABI compatibility)
|
|
110
|
+
* @param _endBlock Block number when redemption window closes (retained for ABI compatibility)
|
|
111
|
+
*/
|
|
112
|
+
constructor(
|
|
113
|
+
address _pointsToken,
|
|
114
|
+
address _owner,
|
|
115
|
+
uint256 _startBlock,
|
|
116
|
+
uint256 _endBlock
|
|
117
|
+
) {
|
|
118
|
+
if (_pointsToken == address(0)) revert TokenZeroAddress();
|
|
119
|
+
if (_owner == address(0)) revert OwnerZeroAddress();
|
|
120
|
+
if (_endBlock <= _startBlock) revert InvalidBlockRange();
|
|
121
|
+
|
|
122
|
+
POINTS_TOKEN = IERC20(_pointsToken);
|
|
123
|
+
owner = _owner;
|
|
124
|
+
START_BLOCK = _startBlock;
|
|
125
|
+
END_BLOCK = _endBlock;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// --- Admin ---
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @dev Pause or unpause the redemption system
|
|
132
|
+
* @param _paused True to pause redemptions, false to unpause
|
|
133
|
+
* @notice Only the owner can call this function
|
|
134
|
+
* @notice When paused, users cannot redeem points but can still withdraw pending amounts
|
|
135
|
+
*/
|
|
136
|
+
function setPaused(bool _paused) external onlyOwner {
|
|
137
|
+
paused = _paused;
|
|
138
|
+
emit Paused(_paused);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @dev Fund the contract with ETH for redemptions
|
|
143
|
+
* @notice Only the owner can call this function
|
|
144
|
+
* @notice The ETH sent will be used to pay out redemptions
|
|
145
|
+
* @notice Can be called multiple times to add more ETH
|
|
146
|
+
* @notice Cannot be called after finalization.
|
|
147
|
+
*/
|
|
148
|
+
function fundEth() external payable onlyOwner {
|
|
149
|
+
if (finalized) revert AlreadyFinalized();
|
|
150
|
+
if (msg.value == 0) revert AmountZero();
|
|
151
|
+
totalPayoutPool += msg.value;
|
|
152
|
+
emit Funded(msg.sender, msg.value);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @dev Move existing contract balance to the payout pool
|
|
157
|
+
* @notice Only owner can call this function
|
|
158
|
+
* @notice Can only be called before finalization
|
|
159
|
+
* @notice Moves all ETH currently in contract balance to totalPayoutPool
|
|
160
|
+
*/
|
|
161
|
+
function moveBalanceToPool() external onlyOwner {
|
|
162
|
+
if (finalized) revert AlreadyFinalized();
|
|
163
|
+
uint256 balance = address(this).balance;
|
|
164
|
+
if (balance == 0) revert PoolZero();
|
|
165
|
+
|
|
166
|
+
// Only add the difference to avoid double-counting
|
|
167
|
+
uint256 currentPool = totalPayoutPool;
|
|
168
|
+
if (balance > currentPool) {
|
|
169
|
+
uint256 difference = balance - currentPool;
|
|
170
|
+
totalPayoutPool += difference;
|
|
171
|
+
emit Funded(msg.sender, difference);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @dev Finalize the redemption system and calculate payout rates
|
|
177
|
+
* @notice Only the owner can call this function
|
|
178
|
+
* @notice Can only be called once
|
|
179
|
+
* @notice Snapshot the current ETH balance and points token supply
|
|
180
|
+
* @notice Calculate the payout rate per point (ETH per point)
|
|
181
|
+
* @notice After finalization, redemptions can begin (window no longer enforced)
|
|
182
|
+
*/
|
|
183
|
+
function finalize() external onlyOwner {
|
|
184
|
+
if (finalized) revert AlreadyFinalized();
|
|
185
|
+
|
|
186
|
+
uint256 pool = address(this).balance;
|
|
187
|
+
uint256 supply = POINTS_TOKEN.totalSupply();
|
|
188
|
+
if (pool == 0) revert PoolZero();
|
|
189
|
+
if (supply == 0) revert SupplyZero();
|
|
190
|
+
|
|
191
|
+
uint256 index = Math.mulDiv(pool, ONE, supply);
|
|
192
|
+
|
|
193
|
+
totalPayoutPool = pool;
|
|
194
|
+
totalRedeemablePoints = supply;
|
|
195
|
+
accPayoutPerPoint = index;
|
|
196
|
+
finalized = true;
|
|
197
|
+
|
|
198
|
+
emit Finalized(pool, supply, index);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// --- Owner utilities ---
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @dev Withdraw excess ETH that is not needed for redemptions
|
|
205
|
+
* @notice Only the owner can call this function
|
|
206
|
+
* @notice Can only be called after finalization and redemption window closes
|
|
207
|
+
* @notice Withdraws ETH in excess of what's needed for pending withdrawals
|
|
208
|
+
* @notice ETH is sent to the owner address
|
|
209
|
+
*
|
|
210
|
+
* @dev NOTE: Redemption window is no longer enforced; this can be called any time after finalization.
|
|
211
|
+
*/
|
|
212
|
+
function withdrawDust() external onlyOwner nonReentrant {
|
|
213
|
+
if (!finalized) revert NotFinalized();
|
|
214
|
+
// NOTE: redemption window no longer enforced
|
|
215
|
+
|
|
216
|
+
uint256 requiredReserve = pendingTotal;
|
|
217
|
+
uint256 bal = address(this).balance;
|
|
218
|
+
if (bal <= requiredReserve) revert NoDust();
|
|
219
|
+
|
|
220
|
+
uint256 amount = bal - requiredReserve;
|
|
221
|
+
(bool success,) = owner.call{value: amount}("");
|
|
222
|
+
if (!success) revert EthTransferFailed();
|
|
223
|
+
emit DustWithdrawn(amount);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// --- Redeem API ---
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @dev Redeem points for ETH using pull pattern (user must call withdraw later)
|
|
230
|
+
* @param amount Amount of points to redeem
|
|
231
|
+
* @notice User must have approved the contract to spend their points
|
|
232
|
+
* @notice ETH payout is added to user's pending withdrawals
|
|
233
|
+
* @notice User must call withdraw() later to receive the ETH
|
|
234
|
+
* @notice Can only be called when finalized and not paused (window no longer enforced)
|
|
235
|
+
*/
|
|
236
|
+
function redeemPull(uint256 amount) external nonReentrant {
|
|
237
|
+
(uint256 payout, uint256 received) = _redeemCore(msg.sender, amount);
|
|
238
|
+
pendingWithdrawals[msg.sender] += payout;
|
|
239
|
+
pendingTotal += payout;
|
|
240
|
+
emit Redeemed(msg.sender, amount, received, payout, false);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @dev Redeem points for ETH using push pattern (immediate ETH transfer)
|
|
245
|
+
* @param amount Amount of points to redeem
|
|
246
|
+
* @notice User must have approved the contract to spend their points
|
|
247
|
+
* @notice ETH is sent directly to the user's address
|
|
248
|
+
* @notice Only works for EOA (externally owned accounts), not contracts
|
|
249
|
+
* @notice Can only be called when finalized and not paused (window no longer enforced)
|
|
250
|
+
*/
|
|
251
|
+
function redeemPush(uint256 amount) external nonReentrant {
|
|
252
|
+
if (!_isEoa(msg.sender)) revert ContractMustPull();
|
|
253
|
+
(uint256 payout, uint256 received) = _redeemCore(msg.sender, amount);
|
|
254
|
+
|
|
255
|
+
(bool success,) = msg.sender.call{value: payout}("");
|
|
256
|
+
if (!success) revert EthTransferFailed();
|
|
257
|
+
emit Redeemed(msg.sender, amount, received, payout, true);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* @dev Withdraw pending ETH from pull redemptions
|
|
262
|
+
* @notice Withdraws all pending ETH for the caller
|
|
263
|
+
* @notice ETH is sent directly to the caller's address
|
|
264
|
+
* @notice Can be called anytime after a pull redemption
|
|
265
|
+
* @notice Sets caller's pending balance to zero after withdrawal
|
|
266
|
+
*/
|
|
267
|
+
function withdraw() external nonReentrant {
|
|
268
|
+
uint256 amount = pendingWithdrawals[msg.sender];
|
|
269
|
+
if (amount == 0) revert NothingToWithdraw();
|
|
270
|
+
pendingWithdrawals[msg.sender] = 0;
|
|
271
|
+
pendingTotal -= amount;
|
|
272
|
+
|
|
273
|
+
(bool success,) = msg.sender.call{value: amount}("");
|
|
274
|
+
if (!success) revert EthTransferFailed();
|
|
275
|
+
emit Withdrawal(msg.sender, amount);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// --- Core math ---
|
|
279
|
+
/**
|
|
280
|
+
* @dev Internal function that handles the core redemption logic
|
|
281
|
+
* @param user Address of the user redeeming points
|
|
282
|
+
* @param amount Amount of points to redeem
|
|
283
|
+
* @return payout Amount of ETH to be paid out
|
|
284
|
+
* @return received Actual amount of points received (transferred to contract)
|
|
285
|
+
* @notice Handles all validation, point transfer, and payout calculation
|
|
286
|
+
* @notice Points are transferred from user to contract and locked forever
|
|
287
|
+
* @notice Updates global accounting (totalPointsRedeemed, totalPayoutSent)
|
|
288
|
+
*/
|
|
289
|
+
function _redeemCore(address user, uint256 amount)
|
|
290
|
+
internal
|
|
291
|
+
returns (uint256 payout, uint256 received)
|
|
292
|
+
{
|
|
293
|
+
if (!finalized) revert NotFinalized();
|
|
294
|
+
if (paused) revert ContractPaused();
|
|
295
|
+
// NOTE: block window validation removed to allow redemption anytime after finalize.
|
|
296
|
+
if (amount == 0) revert AmountZero();
|
|
297
|
+
|
|
298
|
+
uint256 trp = totalRedeemablePoints;
|
|
299
|
+
uint256 tpr = totalPointsRedeemed;
|
|
300
|
+
if (trp == 0) revert SnapshotZero();
|
|
301
|
+
|
|
302
|
+
uint256 remaining = trp - tpr;
|
|
303
|
+
if (remaining == 0) revert NoPointsLeft();
|
|
304
|
+
|
|
305
|
+
// --- Pull points token (requires allowance from user)
|
|
306
|
+
uint256 beforeBal = POINTS_TOKEN.balanceOf(address(this));
|
|
307
|
+
POINTS_TOKEN.safeTransferFrom(user, address(this), amount);
|
|
308
|
+
uint256 afterBal = POINTS_TOKEN.balanceOf(address(this));
|
|
309
|
+
received = afterBal - beforeBal;
|
|
310
|
+
|
|
311
|
+
if (received == 0) revert PayoutZero();
|
|
312
|
+
if (received > amount) revert BalanceManipulation();
|
|
313
|
+
if (received > remaining) revert OverCapacity();
|
|
314
|
+
|
|
315
|
+
payout = Math.mulDiv(received, accPayoutPerPoint, ONE);
|
|
316
|
+
|
|
317
|
+
uint256 reserve = _safeRemainingReserve();
|
|
318
|
+
if (payout > reserve) payout = reserve;
|
|
319
|
+
if (payout == 0) revert PayoutZero();
|
|
320
|
+
|
|
321
|
+
// Check if contract has enough ETH (defensive; reserve already caps by balance)
|
|
322
|
+
if (payout > address(this).balance) revert InsufficientEthBalance();
|
|
323
|
+
|
|
324
|
+
unchecked {
|
|
325
|
+
totalPointsRedeemed = tpr + received;
|
|
326
|
+
totalPayoutSent += payout;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// --- Views ---
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* @dev Check if redemptions are currently open
|
|
334
|
+
* @return True if redemptions are open (finalized and not paused)
|
|
335
|
+
*/
|
|
336
|
+
function isRedemptionOpen() public view returns (bool) {
|
|
337
|
+
return finalized && !paused;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* @dev Get the remaining ETH reserve available for redemptions
|
|
342
|
+
* @return Amount of ETH still available for redemptions
|
|
343
|
+
* @notice Returns 0 if not finalized or if all ETH has been paid out
|
|
344
|
+
*/
|
|
345
|
+
function remainingReserve() public view returns (uint256) {
|
|
346
|
+
if (!finalized) return 0;
|
|
347
|
+
if (totalPayoutSent >= totalPayoutPool) return 0;
|
|
348
|
+
return totalPayoutPool - totalPayoutSent;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* @dev Internal function to get the safe remaining reserve
|
|
353
|
+
* @return The minimum of theoretical reserve and actual ETH balance
|
|
354
|
+
* @notice Ensures we don't try to pay out more ETH than we actually have
|
|
355
|
+
*/
|
|
356
|
+
function _safeRemainingReserve() internal view returns (uint256) {
|
|
357
|
+
if (!finalized) return 0;
|
|
358
|
+
uint256 theoreticalReserve = totalPayoutSent >= totalPayoutPool ? 0 : (totalPayoutPool - totalPayoutSent);
|
|
359
|
+
uint256 actualBalance = address(this).balance;
|
|
360
|
+
return theoreticalReserve > actualBalance ? actualBalance : theoreticalReserve;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* @dev Preview the ETH payout for a given amount of points
|
|
365
|
+
* @param amount Amount of points to redeem
|
|
366
|
+
* @return Expected ETH payout amount
|
|
367
|
+
* @notice This is an estimate and actual payout may be lower due to reserve limits
|
|
368
|
+
* @notice Returns 0 if not finalized, no points left, or amount exceeds remaining points
|
|
369
|
+
*/
|
|
370
|
+
function previewPayout(uint256 amount) external view returns (uint256) {
|
|
371
|
+
if (!finalized || amount == 0) return 0;
|
|
372
|
+
|
|
373
|
+
uint256 trp = totalRedeemablePoints;
|
|
374
|
+
if (trp == 0) return 0;
|
|
375
|
+
uint256 tpr = totalPointsRedeemed;
|
|
376
|
+
if (tpr >= trp) return 0;
|
|
377
|
+
|
|
378
|
+
uint256 remaining = trp - tpr;
|
|
379
|
+
if (amount > remaining) return 0;
|
|
380
|
+
|
|
381
|
+
uint256 est = Math.mulDiv(amount, accPayoutPerPoint, ONE);
|
|
382
|
+
uint256 reserve = remainingReserve();
|
|
383
|
+
return est > reserve ? reserve : est;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// --- Governance / Admin override ---
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* @dev Owner can update the payout rate per point by reading it from an already-deployed contract.
|
|
390
|
+
* @param source Address of the deployed contract exposing accPayoutPerPoint()
|
|
391
|
+
* @notice Only callable after finalization.
|
|
392
|
+
* @notice Reads value via staticcall (no compile-time ABI dependency).
|
|
393
|
+
* @notice Does NOT retroactively adjust past payouts; only affects future redemptions.
|
|
394
|
+
*/
|
|
395
|
+
function setAccPayoutPerPointFromSource(address source) external onlyOwner {
|
|
396
|
+
if (!finalized) revert NotFinalized();
|
|
397
|
+
if (source == address(0) || source.code.length == 0) revert InvalidAddress();
|
|
398
|
+
|
|
399
|
+
(bool success, bytes memory data) =
|
|
400
|
+
source.staticcall(abi.encodeWithSignature("accPayoutPerPoint()"));
|
|
401
|
+
|
|
402
|
+
if (!success || data.length < 32) revert PayoutZero();
|
|
403
|
+
|
|
404
|
+
uint256 newValue = abi.decode(data, (uint256));
|
|
405
|
+
if (newValue == 0) revert PayoutZero();
|
|
406
|
+
|
|
407
|
+
uint256 prev = accPayoutPerPoint;
|
|
408
|
+
accPayoutPerPoint = newValue;
|
|
409
|
+
|
|
410
|
+
emit AccPayoutPerPointUpdated(prev, newValue);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// --- Ownership ---
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* @dev Transfer ownership of the contract to a new address
|
|
417
|
+
* @param newOwner Address of the new owner
|
|
418
|
+
* @notice Only the current owner can call this function
|
|
419
|
+
* @notice New owner cannot be zero address
|
|
420
|
+
* @notice Emits OwnershipTransferred event
|
|
421
|
+
*/
|
|
422
|
+
function transferOwnership(address newOwner) external onlyOwner {
|
|
423
|
+
if (newOwner == address(0)) revert OwnerZeroAddress();
|
|
424
|
+
address prev = owner;
|
|
425
|
+
owner = newOwner;
|
|
426
|
+
emit OwnershipTransferred(prev, newOwner);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Rescue (window no longer enforced)
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* @dev Rescue ERC20 tokens sent to the contract after redemption window closes
|
|
433
|
+
* @param tokenAddr Address of the ERC20 token to rescue
|
|
434
|
+
* @param to Address to send the tokens to
|
|
435
|
+
* @param amount Amount of tokens to rescue
|
|
436
|
+
* @notice Only the owner can call this function
|
|
437
|
+
* @notice Can only be called after finalization and redemption window closes
|
|
438
|
+
* @notice Used to recover accidentally sent tokens
|
|
439
|
+
*
|
|
440
|
+
* @dev NOTE: Redemption window is no longer enforced; this can be called any time after finalization.
|
|
441
|
+
*/
|
|
442
|
+
function rescueTokens(address tokenAddr, address to, uint256 amount) external onlyOwner {
|
|
443
|
+
if (!finalized) revert NotFinalized();
|
|
444
|
+
if (to == address(0)) revert InvalidAddress();
|
|
445
|
+
if (amount == 0) revert AmountZero();
|
|
446
|
+
IERC20(tokenAddr).safeTransfer(to, amount);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* @dev Rescue ETH sent to the contract after redemption window closes
|
|
451
|
+
* @param to Address to send the ETH to
|
|
452
|
+
* @param amount Amount of ETH to rescue
|
|
453
|
+
* @notice Only the owner can call this function
|
|
454
|
+
* @notice Can only be called after finalization and redemption window closes
|
|
455
|
+
* @notice Used to recover accidentally sent ETH
|
|
456
|
+
*
|
|
457
|
+
* @dev NOTE: Redemption window is no longer enforced; this can be called any time after finalization.
|
|
458
|
+
*/
|
|
459
|
+
function rescueEth(address to, uint256 amount) external onlyOwner {
|
|
460
|
+
if (!finalized) revert NotFinalized();
|
|
461
|
+
if (to == address(0)) revert InvalidAddress();
|
|
462
|
+
if (amount == 0) revert AmountZero();
|
|
463
|
+
if (amount > address(this).balance) revert InsufficientEthBalance();
|
|
464
|
+
|
|
465
|
+
(bool success,) = to.call{value: amount}("");
|
|
466
|
+
if (!success) revert EthTransferFailed();
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// --- Utils ---
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* @dev Check if an address is an externally owned account (EOA)
|
|
473
|
+
* @param a Address to check
|
|
474
|
+
* @return True if the address is an EOA (no code), false if it's a contract
|
|
475
|
+
* @notice Used to determine if push redemptions are allowed
|
|
476
|
+
*/
|
|
477
|
+
function _isEoa(address a) internal view returns (bool) {
|
|
478
|
+
return a.code.length == 0;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* @dev Allow the contract to receive ETH from any sender.
|
|
483
|
+
* @notice This is triggered automatically when ETH is sent directly (no data).
|
|
484
|
+
* @notice The ETH is NOT automatically added to the redemption pool.
|
|
485
|
+
* @notice Use fundEth() or moveBalanceToPool() to add ETH to the pool.
|
|
486
|
+
*/
|
|
487
|
+
receive() external payable {
|
|
488
|
+
if (msg.value == 0) return; // ignore zero-value sends to save gas
|
|
489
|
+
}
|
|
490
|
+
}
|