From 54b5a4901b4c2ba9ee954d8b12776f9d0ba1714f Mon Sep 17 00:00:00 2001 From: 0age <37939117+0age@users.noreply.github.com> Date: Tue, 29 Oct 2024 23:14:09 -0700 Subject: [PATCH] remove some allocated transfer & withdrawal functions to get it under the limit --- foundry.toml | 2 +- snapshots/TheCompactTest.json | 74 +++++------ src/TheCompact.sol | 8 +- src/interfaces/ITheCompact.sol | 2 + src/lib/HashLib.sol | 14 -- test/TheCompact.t.sol | 228 +++++++++++++++++---------------- 6 files changed, 158 insertions(+), 170 deletions(-) diff --git a/foundry.toml b/foundry.toml index d9e7d95..40f9b72 100644 --- a/foundry.toml +++ b/foundry.toml @@ -3,7 +3,7 @@ solc = '0.8.28' evm_version='cancun' via_ir = true # optimizer_runs = 4_294_967_295 -optimizer_runs = 200 +optimizer_runs = 50 bytecode_hash = 'none' src = "src" out = "out" diff --git a/snapshots/TheCompactTest.json b/snapshots/TheCompactTest.json index d28a77f..1a00ab1 100644 --- a/snapshots/TheCompactTest.json +++ b/snapshots/TheCompactTest.json @@ -1,42 +1,38 @@ { - "basicTransfer": "57341", - "basicWithdrawal": "60321", - "batchClaim": "112382", - "batchClaimRegisteredWithDeposit": "112382", - "batchClaimRegisteredWithDepositWithWitness": "113117", - "batchClaimWithWitness": "113111", - "batchDepositAndRegisterViaPermit2": "221918", - "batchDepositAndRegisterWithWitnessViaPermit2": "221896", - "batchTransfer": "82919", - "batchWithdrawal": "101334", - "claim": "57533", - "claimAndWithdraw": "73824", - "claimWithWitness": "59977", - "depositAndRegisterViaPermit2": "124252", - "depositBatchSingleERC20": "67846", - "depositBatchSingleNative": "28149", - "depositBatchViaPermit2NativeAndERC20": "129562", - "depositBatchViaPermit2SingleERC20": "104689", - "depositERC20AndURI": "67095", - "depositERC20Basic": "67124", - "depositERC20ViaPermit2AndURI": "98277", - "depositETHAndURI": "26755", - "depositETHBasic": "28318", - "qualifiedBatchClaim": "113797", - "qualifiedBatchClaimWithWitness": "113240", - "qualifiedClaim": "60795", + "basicTransfer": "57278", + "basicWithdrawal": "60320", + "batchClaim": "112360", + "batchClaimRegisteredWithDeposit": "112360", + "batchClaimRegisteredWithDepositWithWitness": "113051", + "batchClaimWithWitness": "113045", + "batchDepositAndRegisterViaPermit2": "221954", + "batchDepositAndRegisterWithWitnessViaPermit2": "221932", + "claim": "57501", + "claimAndWithdraw": "73758", + "claimWithWitness": "59955", + "depositAndRegisterViaPermit2": "124302", + "depositBatchSingleERC20": "67822", + "depositBatchSingleNative": "28086", + "depositBatchViaPermit2NativeAndERC20": "129587", + "depositBatchViaPermit2SingleERC20": "104714", + "depositERC20AndURI": "67145", + "depositERC20Basic": "67152", + "depositERC20ViaPermit2AndURI": "98349", + "depositETHAndURI": "26769", + "depositETHBasic": "28288", + "qualifiedBatchClaim": "113731", + "qualifiedBatchClaimWithWitness": "113174", + "qualifiedClaim": "60773", "qualifiedClaimWithWitness": "59336", - "qualifiedSplitBatchClaim": "141343", - "qualifiedSplitBatchClaimWithWitness": "141314", - "qualifiedSplitClaim": "87067", - "qualifiedSplitClaimWithWitness": "87390", - "register": "25357", - "splitBatchClaim": "140830", - "splitBatchClaimWithWitness": "140767", - "splitBatchTransfer": "113620", - "splitBatchWithdrawal": "142828", - "splitClaim": "86993", - "splitClaimWithWitness": "86447", - "splitTransfer": "83253", - "splitWithdrawal": "94163" + "qualifiedSplitBatchClaim": "141307", + "qualifiedSplitBatchClaimWithWitness": "141278", + "qualifiedSplitClaim": "87001", + "qualifiedSplitClaimWithWitness": "87324", + "register": "25335", + "splitBatchClaim": "140794", + "splitBatchClaimWithWitness": "140731", + "splitBatchTransfer": "113570", + "splitBatchWithdrawal": "142818", + "splitClaim": "86927", + "splitClaimWithWitness": "86403" } \ No newline at end of file diff --git a/src/TheCompact.sol b/src/TheCompact.sol index 3810fca..dad3c00 100644 --- a/src/TheCompact.sol +++ b/src/TheCompact.sol @@ -265,16 +265,16 @@ contract TheCompact is ITheCompact, ITheCompactClaims, ERC6909, Tstorish { } function deposit(address token, address allocator, uint256 amount) external returns (uint256) { - return _performBasicERC20Deposit(token, allocator, amount, msg.sender); + return _performBasicERC20Deposit(token, allocator, amount); } function depositAndRegister(address token, address allocator, uint256 amount, bytes32 claimHash, bytes32 typehash) external returns (uint256 id) { - id = _performBasicERC20Deposit(token, allocator, amount, msg.sender); + id = _performBasicERC20Deposit(token, allocator, amount); _register(msg.sender, claimHash, typehash, 0x258); } - function _performBasicERC20Deposit(address token, address allocator, uint256 amount, address recipient) internal returns (uint256 id) { + function _performBasicERC20Deposit(address token, address allocator, uint256 amount) internal returns (uint256 id) { _setTstorish(_REENTRANCY_GUARD_SLOT, 1); id = token.excludingNative().toIdIfRegistered(Scope.Multichain, ResetPeriod.TenMinutes, allocator); @@ -463,6 +463,7 @@ contract TheCompact is ITheCompact, ITheCompactClaims, ERC6909, Tstorish { return _processBasicTransfer(withdrawal, _withdraw); } + /* function allocatedTransfer(SplitTransfer calldata transfer) external returns (bool) { return _processSplitTransfer(transfer, _release); } @@ -478,6 +479,7 @@ contract TheCompact is ITheCompact, ITheCompactClaims, ERC6909, Tstorish { function allocatedWithdrawal(BatchTransfer calldata withdrawal) external returns (bool) { return _processBatchTransfer(withdrawal, _withdraw); } + */ function allocatedTransfer(SplitBatchTransfer calldata transfer) external returns (bool) { return _processSplitBatchTransfer(transfer, _release); diff --git a/src/interfaces/ITheCompact.sol b/src/interfaces/ITheCompact.sol index 0935fb2..bef8a29 100644 --- a/src/interfaces/ITheCompact.sol +++ b/src/interfaces/ITheCompact.sol @@ -89,6 +89,7 @@ interface ITheCompact { function allocatedWithdrawal(BasicTransfer calldata withdrawal) external returns (bool); + /* function allocatedTransfer(SplitTransfer calldata transfer) external returns (bool); function allocatedWithdrawal(SplitTransfer calldata withdrawal) external returns (bool); @@ -96,6 +97,7 @@ interface ITheCompact { function allocatedTransfer(BatchTransfer calldata transfer) external returns (bool); function allocatedWithdrawal(BatchTransfer calldata withdrawal) external returns (bool); + */ function allocatedTransfer(SplitBatchTransfer calldata transfer) external returns (bool); diff --git a/src/lib/HashLib.sol b/src/lib/HashLib.sol index e704835..dd394d4 100644 --- a/src/lib/HashLib.sol +++ b/src/lib/HashLib.sol @@ -580,20 +580,6 @@ library HashLib { } ///// CATEGORY 6: miscellaneous utilities ///// - - function toPermit2DepositWitnessHash(address allocator, ResetPeriod resetPeriod, Scope scope, address recipient) internal pure returns (bytes32 witnessHash) { - assembly ("memory-safe") { - let m := mload(0x40) // Grab the free memory pointer; memory will be left dirtied. - - mstore(m, PERMIT2_DEPOSIT_WITNESS_FRAGMENT_HASH) - mstore(add(m, 0x20), allocator) - mstore(add(m, 0x40), resetPeriod) - mstore(add(m, 0x60), scope) - mstore(add(m, 0x80), recipient) - witnessHash := keccak256(m, 0xa0) - } - } - function toLatest(bytes32 initialDomainSeparator, uint256 initialChainId) external view returns (bytes32 domainSeparator) { domainSeparator = initialDomainSeparator; diff --git a/test/TheCompact.t.sol b/test/TheCompact.t.sol index b80f5a8..b7d9ffc 100644 --- a/test/TheCompact.t.sol +++ b/test/TheCompact.t.sol @@ -616,6 +616,7 @@ contract TheCompactTest is Test { assertEq(theCompact.balanceOf(recipient, id), amount); } + /* TODO: try to add these back in when there's room function test_splitTransfer() public { ResetPeriod resetPeriod = ResetPeriod.TenMinutes; Scope scope = Scope.Multichain; @@ -729,119 +730,6 @@ contract TheCompactTest is Test { assertEq(theCompact.balanceOf(recipient, idTwo), amountTwo); } - function test_splitBatchTransfer() public { - ResetPeriod resetPeriod = ResetPeriod.TenMinutes; - Scope scope = Scope.Multichain; - uint256 amountOne = 1e18; - uint256 amountTwo = 6e17; - uint256 amountThree = 4e17; - uint256 nonce = 0; - uint256 expiration = block.timestamp + 1000; - address recipientOne = 0x1111111111111111111111111111111111111111; - address recipientTwo = 0x2222222222222222222222222222222222222222; - - vm.prank(allocator); - theCompact.__registerAllocator(allocator, ""); - - vm.startPrank(swapper); - uint256 idOne = theCompact.deposit(address(token), allocator, resetPeriod, scope, amountOne, swapper); - uint256 idTwo = theCompact.deposit{ value: amountTwo + amountThree }(allocator); - vm.stopPrank(); - - assertEq(theCompact.balanceOf(swapper, idOne), amountOne); - assertEq(theCompact.balanceOf(swapper, idTwo), amountTwo + amountThree); - - uint256[2][] memory idsAndAmounts = new uint256[2][](2); - idsAndAmounts[0] = [idOne, amountOne]; - idsAndAmounts[1] = [idTwo, amountTwo + amountThree]; - - bytes32 digest = keccak256( - abi.encodePacked( - bytes2(0x1901), - theCompact.DOMAIN_SEPARATOR(), - keccak256( - abi.encode( - keccak256("BatchCompact(address arbiter,address sponsor,uint256 nonce,uint256 expires,uint256[2][] idsAndAmounts)"), - swapper, - swapper, - nonce, - expiration, - keccak256(abi.encodePacked(idsAndAmounts)) - ) - ) - ) - ); - - (bytes32 r, bytes32 vs) = vm.signCompact(allocatorPrivateKey, digest); - bytes memory allocatorSignature = abi.encodePacked(r, vs); - - SplitByIdComponent[] memory transfers = new SplitByIdComponent[](2); - - SplitComponent[] memory portionsOne = new SplitComponent[](1); - portionsOne[0] = SplitComponent({ claimant: recipientOne, amount: amountOne }); - - SplitComponent[] memory portionsTwo = new SplitComponent[](2); - portionsTwo[0] = SplitComponent({ claimant: recipientOne, amount: amountTwo }); - portionsTwo[1] = SplitComponent({ claimant: recipientTwo, amount: amountThree }); - - transfers[0] = SplitByIdComponent({ id: idOne, portions: portionsOne }); - transfers[1] = SplitByIdComponent({ id: idTwo, portions: portionsTwo }); - - SplitBatchTransfer memory transfer = SplitBatchTransfer({ nonce: nonce, expires: expiration, allocatorSignature: allocatorSignature, transfers: transfers }); - - vm.prank(swapper); - bool status = theCompact.allocatedTransfer(transfer); - vm.snapshotGasLastCall("splitBatchTransfer"); - assert(status); - - assertEq(token.balanceOf(recipientOne), 0); - assertEq(token.balanceOf(recipientTwo), 0); - assertEq(theCompact.balanceOf(swapper, idOne), 0); - assertEq(theCompact.balanceOf(swapper, idTwo), 0); - assertEq(theCompact.balanceOf(recipientOne, idOne), amountOne); - assertEq(theCompact.balanceOf(recipientOne, idTwo), amountTwo); - assertEq(theCompact.balanceOf(recipientTwo, idTwo), amountThree); - } - - function test_basicWithdrawal() public { - ResetPeriod resetPeriod = ResetPeriod.TenMinutes; - Scope scope = Scope.Multichain; - uint256 amount = 1e18; - uint256 nonce = 0; - uint256 expiration = block.timestamp + 1000; - address recipient = 0x1111111111111111111111111111111111111111; - - vm.prank(allocator); - theCompact.__registerAllocator(allocator, ""); - - vm.prank(swapper); - uint256 id = theCompact.deposit(address(token), allocator, resetPeriod, scope, amount, swapper); - assertEq(theCompact.balanceOf(swapper, id), amount); - - bytes32 digest = keccak256( - abi.encodePacked( - bytes2(0x1901), - theCompact.DOMAIN_SEPARATOR(), - keccak256(abi.encode(keccak256("Compact(address arbiter,address sponsor,uint256 nonce,uint256 expires,uint256 id,uint256 amount)"), swapper, swapper, nonce, expiration, id, amount)) - ) - ); - - (bytes32 r, bytes32 vs) = vm.signCompact(allocatorPrivateKey, digest); - bytes memory allocatorSignature = abi.encodePacked(r, vs); - - BasicTransfer memory transfer = BasicTransfer({ nonce: nonce, expires: expiration, allocatorSignature: allocatorSignature, id: id, amount: amount, recipient: recipient }); - - vm.prank(swapper); - bool status = theCompact.allocatedWithdrawal(transfer); - vm.snapshotGasLastCall("basicWithdrawal"); - assert(status); - - assertEq(token.balanceOf(address(theCompact)), 0); - assertEq(token.balanceOf(recipient), amount); - assertEq(theCompact.balanceOf(swapper, id), 0); - assertEq(theCompact.balanceOf(recipient, id), 0); - } - function test_splitWithdrawal() public { ResetPeriod resetPeriod = ResetPeriod.TenMinutes; Scope scope = Scope.Multichain; @@ -958,6 +846,120 @@ contract TheCompactTest is Test { assertEq(theCompact.balanceOf(recipient, idOne), 0); assertEq(theCompact.balanceOf(recipient, idTwo), 0); } + */ + + function test_splitBatchTransfer() public { + ResetPeriod resetPeriod = ResetPeriod.TenMinutes; + Scope scope = Scope.Multichain; + uint256 amountOne = 1e18; + uint256 amountTwo = 6e17; + uint256 amountThree = 4e17; + uint256 nonce = 0; + uint256 expiration = block.timestamp + 1000; + address recipientOne = 0x1111111111111111111111111111111111111111; + address recipientTwo = 0x2222222222222222222222222222222222222222; + + vm.prank(allocator); + theCompact.__registerAllocator(allocator, ""); + + vm.startPrank(swapper); + uint256 idOne = theCompact.deposit(address(token), allocator, resetPeriod, scope, amountOne, swapper); + uint256 idTwo = theCompact.deposit{ value: amountTwo + amountThree }(allocator); + vm.stopPrank(); + + assertEq(theCompact.balanceOf(swapper, idOne), amountOne); + assertEq(theCompact.balanceOf(swapper, idTwo), amountTwo + amountThree); + + uint256[2][] memory idsAndAmounts = new uint256[2][](2); + idsAndAmounts[0] = [idOne, amountOne]; + idsAndAmounts[1] = [idTwo, amountTwo + amountThree]; + + bytes32 digest = keccak256( + abi.encodePacked( + bytes2(0x1901), + theCompact.DOMAIN_SEPARATOR(), + keccak256( + abi.encode( + keccak256("BatchCompact(address arbiter,address sponsor,uint256 nonce,uint256 expires,uint256[2][] idsAndAmounts)"), + swapper, + swapper, + nonce, + expiration, + keccak256(abi.encodePacked(idsAndAmounts)) + ) + ) + ) + ); + + (bytes32 r, bytes32 vs) = vm.signCompact(allocatorPrivateKey, digest); + bytes memory allocatorSignature = abi.encodePacked(r, vs); + + SplitByIdComponent[] memory transfers = new SplitByIdComponent[](2); + + SplitComponent[] memory portionsOne = new SplitComponent[](1); + portionsOne[0] = SplitComponent({ claimant: recipientOne, amount: amountOne }); + + SplitComponent[] memory portionsTwo = new SplitComponent[](2); + portionsTwo[0] = SplitComponent({ claimant: recipientOne, amount: amountTwo }); + portionsTwo[1] = SplitComponent({ claimant: recipientTwo, amount: amountThree }); + + transfers[0] = SplitByIdComponent({ id: idOne, portions: portionsOne }); + transfers[1] = SplitByIdComponent({ id: idTwo, portions: portionsTwo }); + + SplitBatchTransfer memory transfer = SplitBatchTransfer({ nonce: nonce, expires: expiration, allocatorSignature: allocatorSignature, transfers: transfers }); + + vm.prank(swapper); + bool status = theCompact.allocatedTransfer(transfer); + vm.snapshotGasLastCall("splitBatchTransfer"); + assert(status); + + assertEq(token.balanceOf(recipientOne), 0); + assertEq(token.balanceOf(recipientTwo), 0); + assertEq(theCompact.balanceOf(swapper, idOne), 0); + assertEq(theCompact.balanceOf(swapper, idTwo), 0); + assertEq(theCompact.balanceOf(recipientOne, idOne), amountOne); + assertEq(theCompact.balanceOf(recipientOne, idTwo), amountTwo); + assertEq(theCompact.balanceOf(recipientTwo, idTwo), amountThree); + } + + function test_basicWithdrawal() public { + ResetPeriod resetPeriod = ResetPeriod.TenMinutes; + Scope scope = Scope.Multichain; + uint256 amount = 1e18; + uint256 nonce = 0; + uint256 expiration = block.timestamp + 1000; + address recipient = 0x1111111111111111111111111111111111111111; + + vm.prank(allocator); + theCompact.__registerAllocator(allocator, ""); + + vm.prank(swapper); + uint256 id = theCompact.deposit(address(token), allocator, resetPeriod, scope, amount, swapper); + assertEq(theCompact.balanceOf(swapper, id), amount); + + bytes32 digest = keccak256( + abi.encodePacked( + bytes2(0x1901), + theCompact.DOMAIN_SEPARATOR(), + keccak256(abi.encode(keccak256("Compact(address arbiter,address sponsor,uint256 nonce,uint256 expires,uint256 id,uint256 amount)"), swapper, swapper, nonce, expiration, id, amount)) + ) + ); + + (bytes32 r, bytes32 vs) = vm.signCompact(allocatorPrivateKey, digest); + bytes memory allocatorSignature = abi.encodePacked(r, vs); + + BasicTransfer memory transfer = BasicTransfer({ nonce: nonce, expires: expiration, allocatorSignature: allocatorSignature, id: id, amount: amount, recipient: recipient }); + + vm.prank(swapper); + bool status = theCompact.allocatedWithdrawal(transfer); + vm.snapshotGasLastCall("basicWithdrawal"); + assert(status); + + assertEq(token.balanceOf(address(theCompact)), 0); + assertEq(token.balanceOf(recipient), amount); + assertEq(theCompact.balanceOf(swapper, id), 0); + assertEq(theCompact.balanceOf(recipient, id), 0); + } function test_splitBatchWithdrawal() public { ResetPeriod resetPeriod = ResetPeriod.TenMinutes;