From 2563ede879fbb063d2652602a08520508bac3832 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 10 Oct 2024 13:01:12 -0400 Subject: [PATCH 01/29] Golf AllowanceHolder calldata decoding --- src/allowanceholder/AllowanceHolderBase.sol | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index b90fe7584..ee11a639b 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -21,9 +21,14 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // (e.g. tokens with blacklists), we choose to copy the first argument // out of `data` and mask it as an address. If there isn't enough // `data`, we use 0xdead instead. - address target; - if (data.length > 0x10) { - target = address(uint160(bytes20(data[0x10:]))); + address target; // = address(uint160(bytes20(data[0x10:]))); + assembly ("memory-safe") { + target := calldataload(data.offset) + // `shl(0x08, data.length)` can't overflow because we're going to + // `calldatacopy(..., data.length)` later. It would OOG. + let mask := shr(shl(0x08, data.length), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + // Zero the low bits of `target` if `data` is short + target := and(not(mask), target) } // EIP-1352 (not adopted) specifies 0xffff as the maximum precompile if (target <= address(0xffff)) { From 927c216a3e797ffb42900362d0988c1420e07ccb Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 10 Oct 2024 14:34:59 -0400 Subject: [PATCH 02/29] Add comment about technically not-memory-safe code (but it is actually safe) --- src/allowanceholder/AllowanceHolderBase.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index ee11a639b..750f6cb05 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -179,6 +179,8 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // return result; assembly ("memory-safe") { let returndata := sub(result, 0x20) + // This is technically not "memory-safe", but manual examination + // of the compiled bytecode shows that it's OK mstore(returndata, 0x20) return(returndata, add(0x40, mload(result))) } From 71113e7d8b9153c3787e0303d321a353870a29d1 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 10 Oct 2024 14:35:28 -0400 Subject: [PATCH 03/29] Use `return` instead of `revert` inside `balanceOf` to make transactions prettier in block explorers --- src/allowanceholder/AllowanceHolderBase.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 750f6cb05..8ceda9cba 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -188,7 +188,7 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // balanceOf(address) reverts with a single byte of returndata, // making it more gas efficient to pass the `_rejectERC20` check assembly ("memory-safe") { - revert(0x00, 0x01) + return(0x00, 0x01) } } else { // emulate standard Solidity behavior From 271df28e08aaa61c87c4baba9a3e8a2d9b7ef4b5 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 10 Oct 2024 14:36:19 -0400 Subject: [PATCH 04/29] Remove EIP-3074 (EIP-7702) footgun from AllowanceHolder (homogenizes Cancun and non-Cancun versions) --- src/allowanceholder/AllowanceHolder.sol | 14 ------------ src/allowanceholder/AllowanceHolderBase.sol | 25 ++++++++------------- src/allowanceholder/AllowanceHolderOld.sol | 11 --------- 3 files changed, 9 insertions(+), 41 deletions(-) diff --git a/src/allowanceholder/AllowanceHolder.sol b/src/allowanceholder/AllowanceHolder.sol index a0c6c0ba3..355f431bc 100644 --- a/src/allowanceholder/AllowanceHolder.sol +++ b/src/allowanceholder/AllowanceHolder.sol @@ -9,18 +9,4 @@ contract AllowanceHolder is TransientStorage, AllowanceHolderBase { constructor() { require(address(this) == 0x0000000000001fF3684f28c67538d4D072C22734 || block.chainid == 31337); } - - /// @inheritdoc AllowanceHolderBase - function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data) - internal - override - returns (bytes memory) - { - (bytes memory result, address sender, TSlot allowance) = _exec(operator, token, amount, target, data); - // EIP-3074 seems unlikely - if (sender != tx.origin) { - _set(allowance, 0); - } - return result; - } } diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 8ceda9cba..870783021 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -47,18 +47,9 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { } } - /// @dev This virtual function provides the implementation for the function - /// of the same name in `IAllowanceHolder`. It is unimplemented in this - /// base contract to accommodate the customization required to support - /// both chains that have EIP-1153 (transient storage) and those that - /// don't. - function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data) - internal - virtual - returns (bytes memory result); - - /// @dev This is the majority of the implementation of IAllowanceHolder.exec - /// . The arguments have the same meaning as documented there. + /// @dev This function provides the implementation for the function of the + /// same name in `IAllowanceHolder`. The arguments have the same + /// meaning as documented there. /// @return result /// @return sender The (possibly forwarded) message sender that is /// requesting the allowance be set. Provided to avoid @@ -66,9 +57,9 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { /// @return allowance The slot where the ephemeral allowance is /// stored. Provided to avoid duplicated computation in /// customized `exec` - function _exec(address operator, address token, uint256 amount, address payable target, bytes calldata data) + function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data) internal - returns (bytes memory result, address sender, TSlot allowance) + returns (bytes memory result) { // This contract has no special privileges, except for the allowances it // holds. In order to prevent abusing those allowances, we prohibit @@ -76,8 +67,8 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // contract that might be an ERC20. _rejectIfERC20(target, data); - sender = _msgSender(); - allowance = _ephemeralAllowance(operator, sender, token); + address sender = _msgSender(); + TSlot allowance = _ephemeralAllowance(operator, sender, token); _set(allowance, amount); // For gas efficiency we're omitting a bunch of checks here. Notably, @@ -99,6 +90,8 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { mstore(0x40, add(ptr, returndatasize())) } } + + _set(allowance, 0); } /// @dev This provides the implementation of the function of the same name diff --git a/src/allowanceholder/AllowanceHolderOld.sol b/src/allowanceholder/AllowanceHolderOld.sol index 9762f2fdd..55618809e 100644 --- a/src/allowanceholder/AllowanceHolderOld.sol +++ b/src/allowanceholder/AllowanceHolderOld.sol @@ -6,17 +6,6 @@ import {TransientStorageMock} from "./TransientStorageMock.sol"; /// @custom:security-contact security@0x.org contract AllowanceHolder is TransientStorageMock, AllowanceHolderBase { - /// @inheritdoc AllowanceHolderBase - function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data) - internal - override - returns (bytes memory) - { - (bytes memory result,, TSlot allowance) = _exec(operator, token, amount, target, data); - _set(allowance, 0); - return result; - } - // This is here as a deploy-time check that AllowanceHolder doesn't have any // state. If it did, it would interfere with TransientStorageMock. bytes32 private _sentinel; From 6fc2989e8ecebcff656619a0afb80175c9b86661 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 10 Oct 2024 15:25:52 -0400 Subject: [PATCH 05/29] Comments --- src/allowanceholder/AllowanceHolderBase.sol | 41 ++++++++++----------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 870783021..cd29f05d8 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -27,14 +27,17 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // `shl(0x08, data.length)` can't overflow because we're going to // `calldatacopy(..., data.length)` later. It would OOG. let mask := shr(shl(0x08, data.length), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - // Zero the low bits of `target` if `data` is short + // Zero the low bits of `target` if `data` is short. Dirty low bits + // are only ever possible with nonstandard encodings, like ERC-2771. target := and(not(mask), target) } + // EIP-1352 (not adopted) specifies 0xffff as the maximum precompile if (target <= address(0xffff)) { // 0xdead is a conventional burn address; we assume that it is not treated specially target = address(0xdead); } + bytes memory testData = abi.encodeCall(IERC20.balanceOf, target); if (maybeERC20.checkCall(testData, 0x20)) revert ConfusedDeputy(); } @@ -48,15 +51,8 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { } /// @dev This function provides the implementation for the function of the - /// same name in `IAllowanceHolder`. The arguments have the same - /// meaning as documented there. - /// @return result - /// @return sender The (possibly forwarded) message sender that is - /// requesting the allowance be set. Provided to avoid - /// duplicated computation in customized `exec` - /// @return allowance The slot where the ephemeral allowance is - /// stored. Provided to avoid duplicated computation in - /// customized `exec` + /// same name in `IAllowanceHolder`. The arguments and return value + /// have the same meaning as documented there. function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data) internal returns (bytes memory result) @@ -95,15 +91,17 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { } /// @dev This provides the implementation of the function of the same name - /// in `IAllowanceHolder`. + /// in `IAllowanceHolder`. The arguments have the same meaning as + /// documented there. function transferFrom(address token, address owner, address recipient, uint256 amount) internal { - // msg.sender is the assumed and later validated operator + // `msg.sender` is the assumed and later validated `operator`. TSlot allowance = _ephemeralAllowance(msg.sender, owner, token); - // validation of the ephemeral allowance for operator, owner, token via - // uint underflow + // We validate the ephemeral allowance for the 3-tuple of `operator` + // (`msg.sender`), `owner`, and `token` by reverting on unsigned integer + // underflow (built in to Solidity 0.8). _set(allowance, _get(allowance) - amount); // `safeTransferFrom` does not check that `token` actually contains - // code. It is the responsibility of integrating code to check for that + // code. It is the responsibility of integrating code to check for that, // if vacuous success is a security concern. IERC20(token).safeTransferFrom(owner, recipient, amount); } @@ -134,7 +132,7 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { transferFrom(token, owner, recipient, amount); - // return true; + // `return true;` assembly ("memory-safe") { mstore(0x00, 0x01) return(0x00, 0x20) @@ -169,22 +167,23 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { bytes memory result = exec(operator, token, amount, target, data); - // return result; + // `return result;` assembly ("memory-safe") { let returndata := sub(result, 0x20) // This is technically not "memory-safe", but manual examination - // of the compiled bytecode shows that it's OK + // of the compiled bytecode shows that it's OK. mstore(returndata, 0x20) return(returndata, add(0x40, mload(result))) } } else if (selector == uint256(uint32(IERC20.balanceOf.selector))) { - // balanceOf(address) reverts with a single byte of returndata, - // making it more gas efficient to pass the `_rejectERC20` check + // `balanceOf(address)` returns a single byte of returndata, making + // it more gas efficient to pass the `_rejectERC20` check during + // recursive/reentrant calls. assembly ("memory-safe") { return(0x00, 0x01) } } else { - // emulate standard Solidity behavior + // Emulate standard Solidity behavior. assembly ("memory-safe") { revert(0x00, 0x00) } From 65d50881e6628f371eb2b30cdea1c2ecffa40313 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 10 Oct 2024 15:26:02 -0400 Subject: [PATCH 06/29] Function visibility --- src/allowanceholder/AllowanceHolderBase.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index cd29f05d8..33807a725 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -54,7 +54,7 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { /// same name in `IAllowanceHolder`. The arguments and return value /// have the same meaning as documented there. function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data) - internal + private returns (bytes memory result) { // This contract has no special privileges, except for the allowances it @@ -93,7 +93,7 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { /// @dev This provides the implementation of the function of the same name /// in `IAllowanceHolder`. The arguments have the same meaning as /// documented there. - function transferFrom(address token, address owner, address recipient, uint256 amount) internal { + function transferFrom(address token, address owner, address recipient, uint256 amount) private { // `msg.sender` is the assumed and later validated `operator`. TSlot allowance = _ephemeralAllowance(msg.sender, owner, token); // We validate the ephemeral allowance for the 3-tuple of `operator` From e68e4a71341e48741b79c7b56efe954dbc7ad70f Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 10 Oct 2024 15:29:18 -0400 Subject: [PATCH 07/29] Reorder constant arguments in Yul --- src/allowanceholder/AllowanceHolderBase.sol | 6 +++--- src/utils/CheckCall.sol | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 33807a725..f76c3a939 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -76,14 +76,14 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { calldatacopy(result, data.offset, data.length) // ERC-2771 style msgSender forwarding https://eips.ethereum.org/EIPS/eip-2771 mstore(add(result, data.length), shl(0x60, sender)) - let success := call(gas(), target, callvalue(), result, add(data.length, 0x14), 0x00, 0x00) - let ptr := add(result, 0x20) + let success := call(gas(), target, callvalue(), result, add(0x14, data.length), 0x00, 0x00) + let ptr := add(0x20, result) returndatacopy(ptr, 0x00, returndatasize()) switch success case 0 { revert(ptr, returndatasize()) } default { mstore(result, returndatasize()) - mstore(0x40, add(ptr, returndatasize())) + mstore(0x40, add(returndatasize(), ptr)) } } diff --git a/src/utils/CheckCall.sol b/src/utils/CheckCall.sol index bda31190c..26ee5181e 100644 --- a/src/utils/CheckCall.sol +++ b/src/utils/CheckCall.sol @@ -21,7 +21,7 @@ library CheckCall { assembly ("memory-safe") { let beforeGas { - let offset := add(data, 0x20) + let offset := add(0x20, data) let length := mload(data) beforeGas := gas() success := staticcall(gas(), target, offset, length, 0x00, 0x00) @@ -51,8 +51,8 @@ library CheckCall { // We apply the "all but one 64th" rule twice because `target` could // plausibly be a proxy. We apply it only twice because we assume only a // single level of indirection. - let remainingGas := shr(6, beforeGas) - remainingGas := add(remainingGas, shr(6, sub(beforeGas, remainingGas))) + let remainingGas := shr(0x06, beforeGas) + remainingGas := add(remainingGas, shr(0x06, sub(beforeGas, remainingGas))) if iszero(lt(remainingGas, afterGas)) { // The call failed due to not enough gas left. We deliberately consume // all remaining gas with `invalid` (instead of `revert`) to make this From e8ab2898a3e1c7d3d81dc27480a7189aeee7a148 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 10 Oct 2024 15:29:50 -0400 Subject: [PATCH 08/29] Apply the all-but-one-64th rule 3 times (not 2) --- src/utils/CheckCall.sol | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/utils/CheckCall.sol b/src/utils/CheckCall.sol index 26ee5181e..0dcfb060f 100644 --- a/src/utils/CheckCall.sol +++ b/src/utils/CheckCall.sol @@ -48,11 +48,12 @@ library CheckCall { // Check whether the call reverted due to out-of-gas. // https://eips.ethereum.org/EIPS/eip-150 // https://ronan.eth.limo/blog/ethereum-gas-dangers/ - // We apply the "all but one 64th" rule twice because `target` could - // plausibly be a proxy. We apply it only twice because we assume only a - // single level of indirection. + // We apply the "all but one 64th" rule three times because `target` could + // plausibly be a proxy. We apply it only three because we assume only two + // levels of indirection. let remainingGas := shr(0x06, beforeGas) remainingGas := add(remainingGas, shr(0x06, sub(beforeGas, remainingGas))) + remainingGas := add(remainingGas, shr(0x06, sub(beforeGas, remainingGas))) if iszero(lt(remainingGas, afterGas)) { // The call failed due to not enough gas left. We deliberately consume // all remaining gas with `invalid` (instead of `revert`) to make this From 9b606236ab3ed67fed6ce29184efa6eacfefbb48 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Sun, 13 Oct 2024 14:51:05 -0400 Subject: [PATCH 09/29] Bug! The first argument word is the 4 bytes into calldata --- src/allowanceholder/AllowanceHolderBase.sol | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index f76c3a939..e36ad3a97 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -22,14 +22,17 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // out of `data` and mask it as an address. If there isn't enough // `data`, we use 0xdead instead. address target; // = address(uint160(bytes20(data[0x10:]))); - assembly ("memory-safe") { - target := calldataload(data.offset) - // `shl(0x08, data.length)` can't overflow because we're going to - // `calldatacopy(..., data.length)` later. It would OOG. - let mask := shr(shl(0x08, data.length), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - // Zero the low bits of `target` if `data` is short. Dirty low bits - // are only ever possible with nonstandard encodings, like ERC-2771. - target := and(not(mask), target) + if (data.length >= 4) { + assembly ("memory-safe") { + target := calldataload(add(0x04, data.offset)) + // `shl(0x08, data.length)` can't overflow because we're going to + // `calldatacopy(..., data.length)` later. It would OOG. + let mask := shr(shl(0x08, sub(data.length, 0x04)), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + // Zero the low bits of `target` if `data` is short. Dirty low + // bits are only ever possible with nonstandard encodings, like + // ERC-2771. + target := and(not(mask), target) + } } // EIP-1352 (not adopted) specifies 0xffff as the maximum precompile From d349d181873ec0a81c75ae39ae4691bdb2041e61 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Sun, 13 Oct 2024 14:55:48 -0400 Subject: [PATCH 10/29] Typo --- src/utils/CheckCall.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/CheckCall.sol b/src/utils/CheckCall.sol index 0dcfb060f..eb86e5489 100644 --- a/src/utils/CheckCall.sol +++ b/src/utils/CheckCall.sol @@ -49,8 +49,8 @@ library CheckCall { // https://eips.ethereum.org/EIPS/eip-150 // https://ronan.eth.limo/blog/ethereum-gas-dangers/ // We apply the "all but one 64th" rule three times because `target` could - // plausibly be a proxy. We apply it only three because we assume only two - // levels of indirection. + // plausibly be a proxy. We apply it only three times because we assume only + // two levels of indirection. let remainingGas := shr(0x06, beforeGas) remainingGas := add(remainingGas, shr(0x06, sub(beforeGas, remainingGas))) remainingGas := add(remainingGas, shr(0x06, sub(beforeGas, remainingGas))) From ecb00c99d685529b8b2f3136488548dd7fefae21 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Tue, 15 Oct 2024 03:54:08 -0400 Subject: [PATCH 11/29] Implement ABIEncoding in assembly --- src/allowanceholder/AllowanceHolderBase.sol | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index e36ad3a97..96be0010f 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -21,6 +21,7 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // (e.g. tokens with blacklists), we choose to copy the first argument // out of `data` and mask it as an address. If there isn't enough // `data`, we use 0xdead instead. + address target; // = address(uint160(bytes20(data[0x10:]))); if (data.length >= 4) { assembly ("memory-safe") { @@ -41,7 +42,15 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { target = address(0xdead); } - bytes memory testData = abi.encodeCall(IERC20.balanceOf, target); + bytes memory testData; // = abi.encodeCall(IERC20.balanceOf, target); + assembly ("memory-safe") { + testData := mload(0x40) + mstore(add(0x04, testData), 0x70a08231) + mstore(add(0x24, testData), and(0xffffffffffffffffffffffffffffffffffffffff, target)) + mstore(testData, 0x24) + mstore(0x40, add(0x60, testData)) + } + if (maybeERC20.checkCall(testData, 0x20)) revert ConfusedDeputy(); } @@ -77,7 +86,7 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { assembly ("memory-safe") { result := mload(0x40) calldatacopy(result, data.offset, data.length) - // ERC-2771 style msgSender forwarding https://eips.ethereum.org/EIPS/eip-2771 + // ERC-2771 style `msgSender` forwarding https://eips.ethereum.org/EIPS/eip-2771 mstore(add(result, data.length), shl(0x60, sender)) let success := call(gas(), target, callvalue(), result, add(0x14, data.length), 0x00, 0x00) let ptr := add(0x20, result) From 12c438889fa752ebd4dd348ef55364507ea15d11 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Tue, 15 Oct 2024 04:18:29 -0400 Subject: [PATCH 12/29] Implement reverting in assembly --- src/allowanceholder/AllowanceHolderBase.sol | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 96be0010f..9b45e3782 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -51,7 +51,12 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { mstore(0x40, add(0x60, testData)) } - if (maybeERC20.checkCall(testData, 0x20)) revert ConfusedDeputy(); + if (maybeERC20.checkCall(testData, 0x20)) { + assembly ("memory-safe") { + mstore(0x00, 0xe758b8d5) // Selector for `ConfusedDeputy()` + revert(0x1c, 0x04) + } + } } function _msgSender() private view returns (address sender) { From 39e522444fe929b3828368d1b0393a0be60555f8 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Tue, 15 Oct 2024 07:05:20 -0400 Subject: [PATCH 13/29] Return strict ABIEncoding of `result` --- src/allowanceholder/AllowanceHolderBase.sol | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 9b45e3782..8e5e5159b 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -190,7 +190,17 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // This is technically not "memory-safe", but manual examination // of the compiled bytecode shows that it's OK. mstore(returndata, 0x20) - return(returndata, add(0x40, mload(result))) + + // Pad `returndata` to a multiple of 32 bytes. + let len := mload(result) + let m := and(0x1f, len) + if m { + mstore(add(len, add(0x20, result)), 0x00) + len := add(sub(0x20, m), len) + } + + // Return the ABIEncoding of `result`. + return(returndata, add(0x40, len)) } } else if (selector == uint256(uint32(IERC20.balanceOf.selector))) { // `balanceOf(address)` returns a single byte of returndata, making From 1444d8c135b3d358d6aa4d6f360c273accdf9f29 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Wed, 16 Oct 2024 06:44:35 -0400 Subject: [PATCH 14/29] Update snaps --- .../allowanceHolder_empty_DAI-WETH.snap | 2 +- .../allowanceHolder_empty_USDC-WETH.snap | 2 +- .../allowanceHolder_empty_USDT-WETH.snap | 2 +- ...owanceHolder_maverickV2_VIP_USDC-WETH.snap | 2 +- .../allowanceHolder_rfq_DAI-WETH.snap | 2 +- .../allowanceHolder_rfq_USDC-WETH.snap | 2 +- .../allowanceHolder_rfq_USDT-WETH.snap | 2 +- ...older_rfq_fixedFee_sellToken_DAI-WETH.snap | 2 +- ...lder_rfq_fixedFee_sellToken_USDC-WETH.snap | 2 +- ...lder_rfq_fixedFee_sellToken_USDT-WETH.snap | 2 +- ...fq_proportionalFee_sellToken_DAI-WETH.snap | 2 +- ...q_proportionalFee_sellToken_USDC-WETH.snap | 2 +- ...q_proportionalFee_sellToken_USDT-WETH.snap | 2 +- ...older_uniswapV2_single_chain_DAI-WETH.snap | 2 +- ...lder_uniswapV2_single_chain_USDC-WETH.snap | 2 +- ...lder_uniswapV2_single_chain_USDT-WETH.snap | 2 +- ...allowanceHolder_uniswapV3VIP_DAI-WETH.snap | 2 +- ...llowanceHolder_uniswapV3VIP_USDC-WETH.snap | 2 +- ...llowanceHolder_uniswapV3VIP_USDT-WETH.snap | 2 +- ...Holder_uniswapV3VIP_contract_DAI-WETH.snap | 2 +- ...older_uniswapV3VIP_contract_USDC-WETH.snap | 2 +- ...older_uniswapV3VIP_contract_USDT-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_DAI-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_USDC-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_USDT-WETH.snap | 2 +- README.md | 54 +++++++++---------- 26 files changed, 52 insertions(+), 52 deletions(-) diff --git a/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap index 6648708cf..5472eff09 100644 --- a/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap @@ -1 +1 @@ -8646 \ No newline at end of file +8685 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap index 6648708cf..5472eff09 100644 --- a/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap @@ -1 +1 @@ -8646 \ No newline at end of file +8685 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap index 6648708cf..5472eff09 100644 --- a/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap @@ -1 +1 @@ -8646 \ No newline at end of file +8685 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap index f4183d682..6694dcfef 100644 --- a/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap @@ -1 +1 @@ -123658 \ No newline at end of file +123697 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap index 7df7442f9..69dc09026 100644 --- a/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap @@ -1 +1 @@ -87028 \ No newline at end of file +87067 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap index 677988d8b..141a36846 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap @@ -1 +1 @@ -106502 \ No newline at end of file +106541 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap index bbd2c2031..6e14ab74d 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap @@ -1 +1 @@ -98140 \ No newline at end of file +98179 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap index a6238f1dd..f98bd458f 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap @@ -1 +1 @@ -99127 \ No newline at end of file +99166 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap index d84cd0077..776643221 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap @@ -1 +1 @@ -122775 \ No newline at end of file +122814 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap index 7796668f4..63a8f8ab5 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap @@ -1 +1 @@ -111351 \ No newline at end of file +111390 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap index 4acc97482..abac617d9 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap @@ -1 +1 @@ -126873 \ No newline at end of file +126912 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap index bda7f204e..73afe119b 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap @@ -1 +1 @@ -154459 \ No newline at end of file +154498 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap index e2cdbee0c..0391d30de 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap @@ -1 +1 @@ -143617 \ No newline at end of file +143656 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap index 85a5501b4..5478da142 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap @@ -1 +1 @@ -104263 \ No newline at end of file +104183 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap index 9f402300f..1bc5ca08e 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap @@ -1 +1 @@ -114361 \ No newline at end of file +114281 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap index 4463b72a2..4e6771c9d 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap @@ -1 +1 @@ -105431 \ No newline at end of file +105351 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap index e0a891d12..368986a22 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap @@ -1 +1 @@ -113154 \ No newline at end of file +113193 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap index 9723c0497..2e4ab1631 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap @@ -1 +1 @@ -125720 \ No newline at end of file +125759 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap index d3f68dfa0..923cd951a 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap @@ -1 +1 @@ -115970 \ No newline at end of file +116009 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap index 59bebe8f2..368986a22 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap @@ -1 +1 @@ -113273 \ No newline at end of file +113193 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap index 7020d6626..2e4ab1631 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap @@ -1 +1 @@ -125839 \ No newline at end of file +125759 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap index d41546743..923cd951a 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap @@ -1 +1 @@ -116089 \ No newline at end of file +116009 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap index ebf61e421..d9c7d7966 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap @@ -1 +1 @@ -139883 \ No newline at end of file +139922 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap index cf7ba921b..78873d63a 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap @@ -1 +1 @@ -156505 \ No newline at end of file +156544 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap index d2363a531..71c535b07 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap @@ -1 +1 @@ -146556 \ No newline at end of file +146595 \ No newline at end of file diff --git a/README.md b/README.md index 3f8255edb..61e1fc6ce 100644 --- a/README.md +++ b/README.md @@ -560,19 +560,19 @@ comparison. | 0x V4 VIP | Uniswap V3 | USDC/WETH | 124669 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | USDC/WETH | 138525 | 11.11% | | Settler VIP (warm) | Uniswap V3 | USDC/WETH | 136237 | 9.28% | -| AllowanceHolder VIP | Uniswap V3 | USDC/WETH | 125720 | 0.84% | +| AllowanceHolder VIP | Uniswap V3 | USDC/WETH | 125759 | 0.87% | | UniswapRouter V3 | Uniswap V3 | USDC/WETH | 120978 | -2.96% | | | | | | | | 0x V4 VIP | Uniswap V3 | DAI/WETH | 112103 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | DAI/WETH | 125959 | 12.36% | | Settler VIP (warm) | Uniswap V3 | DAI/WETH | 123671 | 10.32% | -| AllowanceHolder VIP | Uniswap V3 | DAI/WETH | 113154 | 0.94% | +| AllowanceHolder VIP | Uniswap V3 | DAI/WETH | 113193 | 0.97% | | UniswapRouter V3 | Uniswap V3 | DAI/WETH | 108412 | -3.29% | | | | | | | | 0x V4 VIP | Uniswap V3 | USDT/WETH | 114910 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | USDT/WETH | 128766 | 12.06% | | Settler VIP (warm) | Uniswap V3 | USDT/WETH | 126487 | 10.07% | -| AllowanceHolder VIP | Uniswap V3 | USDT/WETH | 115970 | 0.92% | +| AllowanceHolder VIP | Uniswap V3 | USDT/WETH | 116009 | 0.96% | | UniswapRouter V3 | Uniswap V3 | USDT/WETH | 111091 | -3.32% | | | | | | | @@ -580,15 +580,15 @@ comparison. | -------------------- | ---------- | --------- | ------ | ------- | | 0x V4 TransformERC20 | Uniswap V3 | USDC/WETH | 244603 | 0.00% | | Settler | Uniswap V3 | USDC/WETH | 166872 | -31.78% | -| AllowanceHolder | Uniswap V3 | USDC/WETH | 156505 | -36.02% | +| AllowanceHolder | Uniswap V3 | USDC/WETH | 156544 | -36.00% | | | | | | | | 0x V4 TransformERC20 | Uniswap V3 | DAI/WETH | 221601 | 0.00% | | Settler | Uniswap V3 | DAI/WETH | 150250 | -32.20% | -| AllowanceHolder | Uniswap V3 | DAI/WETH | 139883 | -36.88% | +| AllowanceHolder | Uniswap V3 | DAI/WETH | 139922 | -36.86% | | | | | | | | 0x V4 TransformERC20 | Uniswap V3 | USDT/WETH | 228500 | 0.00% | | Settler | Uniswap V3 | USDT/WETH | 156923 | -31.32% | -| AllowanceHolder | Uniswap V3 | USDT/WETH | 146556 | -35.86% | +| AllowanceHolder | Uniswap V3 | USDT/WETH | 146595 | -35.84% | | | | | | | | MetaTransactions | DEX | Pair | Gas | % | @@ -608,17 +608,17 @@ comparison. | 0x V4 | 0x V4 | USDC/WETH | 97972 | 0.00% | | Settler | Settler | USDC/WETH | 114370 | 16.74% | | Settler | 0x V4 | USDC/WETH | 206545 | 110.82% | -| AllowanceHolder | Settler | USDC/WETH | 106502 | 8.71% | +| AllowanceHolder | Settler | USDC/WETH | 106541 | 8.75% | | | | | | | | 0x V4 | 0x V4 | DAI/WETH | 78498 | 0.00% | | Settler | Settler | DAI/WETH | 94896 | 20.89% | | Settler | 0x V4 | DAI/WETH | 176635 | 125.02% | -| AllowanceHolder | Settler | DAI/WETH | 87028 | 10.87% | +| AllowanceHolder | Settler | DAI/WETH | 87067 | 10.92% | | | | | | | | 0x V4 | 0x V4 | USDT/WETH | 89610 | 0.00% | | Settler | Settler | USDT/WETH | 106008 | 18.30% | | Settler | 0x V4 | USDT/WETH | 191967 | 114.22% | -| AllowanceHolder | Settler | USDT/WETH | 98140 | 9.52% | +| AllowanceHolder | Settler | USDT/WETH | 98179 | 9.56% | | | | | | | | Curve | DEX | Pair | Gas | % | @@ -661,32 +661,32 @@ comparison. | AllowanceHolder | DEX | Pair | Gas | % | | ------------------------------------ | -------------- | --------- | ------ | ------- | -| execute | Uniswap V3 VIP | USDC/WETH | 125720 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140372 | 11.65% | -| execute | RFQ | USDC/WETH | 106502 | -15.29% | +| execute | Uniswap V3 VIP | USDC/WETH | 125759 | 0.00% | +| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140372 | 11.62% | +| execute | RFQ | USDC/WETH | 106541 | -15.28% | | | | | | | -| execute | Uniswap V3 VIP | DAI/WETH | 113154 | 0.00% | -| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129381 | 14.34% | -| execute | RFQ | DAI/WETH | 87028 | -23.09% | +| execute | Uniswap V3 VIP | DAI/WETH | 113193 | 0.00% | +| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129381 | 14.30% | +| execute | RFQ | DAI/WETH | 87067 | -23.08% | | | | | | | -| execute | Uniswap V3 VIP | USDT/WETH | 115970 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136369 | 17.59% | -| execute | RFQ | USDT/WETH | 98140 | -15.37% | +| execute | Uniswap V3 VIP | USDT/WETH | 116009 | 0.00% | +| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136369 | 17.55% | +| execute | RFQ | USDT/WETH | 98179 | -15.37% | | | | | | | | AllowanceHolder sell token fees | DEX | Pair | Gas | % | | ------------------------------- | --- | --------- | ------ | ------ | -| no fee | RFQ | USDC/WETH | 106502 | 0.00% | -| proportional fee | RFQ | USDC/WETH | 154459 | 45.03% | -| fixed fee | RFQ | USDC/WETH | 122775 | 15.28% | +| no fee | RFQ | USDC/WETH | 106541 | 0.00% | +| proportional fee | RFQ | USDC/WETH | 154498 | 45.01% | +| fixed fee | RFQ | USDC/WETH | 122814 | 15.27% | | | | | | | -| no fee | RFQ | DAI/WETH | 87028 | 0.00% | -| proportional fee | RFQ | DAI/WETH | 126873 | 45.78% | -| fixed fee | RFQ | DAI/WETH | 99127 | 13.90% | +| no fee | RFQ | DAI/WETH | 87067 | 0.00% | +| proportional fee | RFQ | DAI/WETH | 126912 | 45.76% | +| fixed fee | RFQ | DAI/WETH | 99166 | 13.90% | | | | | | | -| no fee | RFQ | USDT/WETH | 98140 | 0.00% | -| proportional fee | RFQ | USDT/WETH | 143617 | 46.34% | -| fixed fee | RFQ | USDT/WETH | 111351 | 13.46% | +| no fee | RFQ | USDT/WETH | 98179 | 0.00% | +| proportional fee | RFQ | USDT/WETH | 143656 | 46.32% | +| fixed fee | RFQ | USDT/WETH | 111390 | 13.46% | | | | | | | [//]: # "END TABLES" From 635baa0653251629dde1d8c48868d550c1103ec4 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 17 Oct 2024 06:28:29 -0400 Subject: [PATCH 15/29] Remove Solmate `SafeTransferLib`; port AllowanceHolder to the Solady version --- src/allowanceholder/AllowanceHolderBase.sol | 2 +- src/vendor/SafeTransferLib_Solmate.sol | 119 -------------------- 2 files changed, 1 insertion(+), 120 deletions(-) delete mode 100644 src/vendor/SafeTransferLib_Solmate.sol diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 8e5e5159b..4af7aa326 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.25; import {IAllowanceHolder} from "./IAllowanceHolder.sol"; import {IERC20} from "@forge-std/interfaces/IERC20.sol"; -import {SafeTransferLib} from "../vendor/SafeTransferLib_Solmate.sol"; +import {SafeTransferLib} from "../vendor/SafeTransferLib.sol"; import {CheckCall} from "../utils/CheckCall.sol"; import {FreeMemory} from "../utils/FreeMemory.sol"; import {TransientStorageLayout} from "./TransientStorageLayout.sol"; diff --git a/src/vendor/SafeTransferLib_Solmate.sol b/src/vendor/SafeTransferLib_Solmate.sol deleted file mode 100644 index 6aebad031..000000000 --- a/src/vendor/SafeTransferLib_Solmate.sol +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.25; - -import {IERC20} from "@forge-std/interfaces/IERC20.sol"; - -/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) -/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. -/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. -library SafeTransferLib { - uint32 private constant _TRANSFER_FROM_FAILED_SELECTOR = 0x7939f424; // bytes4(keccak256("TransferFromFailed()")) - uint32 private constant _TRANSFER_FAILED_SELECTOR = 0x90b8ec18; // bytes4(keccak256("TransferFailed()")) - uint32 private constant _APPROVE_FAILED_SELECTOR = 0x3e3f8f73; // bytes4(keccak256("ApproveFailed()")) - - /*////////////////////////////////////////////////////////////// - ETH OPERATIONS - //////////////////////////////////////////////////////////////*/ - - function safeTransferETH(address payable to, uint256 amount) internal { - assembly ("memory-safe") { - // Transfer the ETH and store if it succeeded or not. - if iszero(call(gas(), to, amount, 0, 0, 0, 0)) { - let freeMemoryPointer := mload(0x40) - returndatacopy(freeMemoryPointer, 0, returndatasize()) - revert(freeMemoryPointer, returndatasize()) - } - } - } - - /*////////////////////////////////////////////////////////////// - ERC20 OPERATIONS - //////////////////////////////////////////////////////////////*/ - - function safeTransferFrom(IERC20 token, address from, address to, uint256 amount) internal { - assembly ("memory-safe") { - // Get a pointer to some free memory. - let freeMemoryPointer := mload(0x40) - - // Write the abi-encoded calldata into memory, beginning with the function selector. - mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument. - mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. - mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. - - // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. - // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. - if iszero(call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)) { - returndatacopy(freeMemoryPointer, 0, returndatasize()) - revert(freeMemoryPointer, returndatasize()) - } - // We check that the call either returned exactly 1 (can't just be non-zero data), or had no - // return data. - if iszero(or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize()))) { - mstore(0, _TRANSFER_FROM_FAILED_SELECTOR) - revert(0x1c, 0x04) - } - } - } - - function safeTransfer(IERC20 token, address to, uint256 amount) internal { - assembly ("memory-safe") { - // Get a pointer to some free memory. - let freeMemoryPointer := mload(0x40) - - // Write the abi-encoded calldata into memory, beginning with the function selector. - mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. - mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. - - // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. - // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. - if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)) { - returndatacopy(freeMemoryPointer, 0, returndatasize()) - revert(freeMemoryPointer, returndatasize()) - } - // We check that the call either returned exactly 1 (can't just be non-zero data), or had no - // return data. - if iszero(or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize()))) { - mstore(0, _TRANSFER_FAILED_SELECTOR) - revert(0x1c, 0x04) - } - } - } - - function safeApprove(IERC20 token, address to, uint256 amount) internal { - assembly ("memory-safe") { - // Get a pointer to some free memory. - let freeMemoryPointer := mload(0x40) - - // Write the abi-encoded calldata into memory, beginning with the function selector. - mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. - mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. - - // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. - // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. - if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)) { - returndatacopy(freeMemoryPointer, 0, returndatasize()) - revert(freeMemoryPointer, returndatasize()) - } - // We check that the call either returned exactly 1 (can't just be non-zero data), or had no - // return data. - if iszero(or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize()))) { - mstore(0, _APPROVE_FAILED_SELECTOR) - revert(0x1c, 0x04) - } - } - } - - function safeApproveIfBelow(IERC20 token, address spender, uint256 amount) internal { - uint256 allowance = token.allowance(address(this), spender); - if (allowance < amount) { - if (allowance != 0) { - safeApprove(token, spender, 0); - } - safeApprove(token, spender, type(uint256).max); - } - } -} From 2beee668b5abedb26a7075f52b7b0786b87eb483 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 17 Oct 2024 06:29:09 -0400 Subject: [PATCH 16/29] Update snaps --- ...owanceHolder_maverickV2_VIP_USDC-WETH.snap | 2 +- .../allowanceHolder_rfq_DAI-WETH.snap | 2 +- .../allowanceHolder_rfq_USDC-WETH.snap | 2 +- .../allowanceHolder_rfq_USDT-WETH.snap | 2 +- ...older_rfq_fixedFee_sellToken_DAI-WETH.snap | 2 +- ...lder_rfq_fixedFee_sellToken_USDC-WETH.snap | 2 +- ...lder_rfq_fixedFee_sellToken_USDT-WETH.snap | 2 +- ...fq_proportionalFee_sellToken_DAI-WETH.snap | 2 +- ...q_proportionalFee_sellToken_USDC-WETH.snap | 2 +- ...q_proportionalFee_sellToken_USDT-WETH.snap | 2 +- ...older_uniswapV2_single_chain_DAI-WETH.snap | 2 +- ...lder_uniswapV2_single_chain_USDC-WETH.snap | 2 +- ...lder_uniswapV2_single_chain_USDT-WETH.snap | 2 +- ...allowanceHolder_uniswapV3VIP_DAI-WETH.snap | 2 +- ...llowanceHolder_uniswapV3VIP_USDC-WETH.snap | 2 +- ...llowanceHolder_uniswapV3VIP_USDT-WETH.snap | 2 +- ...Holder_uniswapV3VIP_contract_DAI-WETH.snap | 2 +- ...older_uniswapV3VIP_contract_USDC-WETH.snap | 2 +- ...older_uniswapV3VIP_contract_USDT-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_DAI-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_USDC-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_USDT-WETH.snap | 2 +- .../settler_dodoV1_USDC-WETH.snap | 2 +- README.md | 56 +++++++++---------- 24 files changed, 51 insertions(+), 51 deletions(-) diff --git a/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap index 6694dcfef..1f5e5aba5 100644 --- a/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap @@ -1 +1 @@ -123697 \ No newline at end of file +123655 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap index 69dc09026..5832a8bd7 100644 --- a/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap @@ -1 +1 @@ -87067 \ No newline at end of file +87025 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap index 141a36846..09a11d4b6 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap @@ -1 +1 @@ -106541 \ No newline at end of file +106499 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap index 6e14ab74d..5508b7b5e 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap @@ -1 +1 @@ -98179 \ No newline at end of file +98137 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap index f98bd458f..8d2d1d04a 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap @@ -1 +1 @@ -99166 \ No newline at end of file +99082 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap index 776643221..a1321366c 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap @@ -1 +1 @@ -122814 \ No newline at end of file +122730 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap index 63a8f8ab5..2ea4f40e4 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap @@ -1 +1 @@ -111390 \ No newline at end of file +111306 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap index abac617d9..df889b462 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap @@ -1 +1 @@ -126912 \ No newline at end of file +126870 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap index 73afe119b..430457542 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap @@ -1 +1 @@ -154498 \ No newline at end of file +154456 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap index 0391d30de..7ebecb1f8 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap @@ -1 +1 @@ -143656 \ No newline at end of file +143614 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap index 5478da142..97bba8acd 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap @@ -1 +1 @@ -104183 \ No newline at end of file +104141 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap index 1bc5ca08e..7c1916897 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap @@ -1 +1 @@ -114281 \ No newline at end of file +114239 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap index 4e6771c9d..4ba05846c 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap @@ -1 +1 @@ -105351 \ No newline at end of file +105309 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap index 368986a22..d7dd53f3f 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap @@ -1 +1 @@ -113193 \ No newline at end of file +113151 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap index 2e4ab1631..eeead3751 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap @@ -1 +1 @@ -125759 \ No newline at end of file +125717 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap index 923cd951a..ec676b12f 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap @@ -1 +1 @@ -116009 \ No newline at end of file +115967 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap index 368986a22..d7dd53f3f 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap @@ -1 +1 @@ -113193 \ No newline at end of file +113151 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap index 2e4ab1631..eeead3751 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap @@ -1 +1 @@ -125759 \ No newline at end of file +125717 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap index 923cd951a..ec676b12f 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap @@ -1 +1 @@ -116009 \ No newline at end of file +115967 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap index d9c7d7966..0e5acb1ff 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap @@ -1 +1 @@ -139922 \ No newline at end of file +139880 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap index 78873d63a..2792c6610 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap @@ -1 +1 @@ -156544 \ No newline at end of file +156502 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap index 71c535b07..dafbfede1 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap @@ -1 +1 @@ -146595 \ No newline at end of file +146553 \ No newline at end of file diff --git a/.forge-snapshots/settler_dodoV1_USDC-WETH.snap b/.forge-snapshots/settler_dodoV1_USDC-WETH.snap index d8bde7e24..cd14c8e88 100644 --- a/.forge-snapshots/settler_dodoV1_USDC-WETH.snap +++ b/.forge-snapshots/settler_dodoV1_USDC-WETH.snap @@ -1 +1 @@ -308591 \ No newline at end of file +308996 \ No newline at end of file diff --git a/README.md b/README.md index 61e1fc6ce..59aae9d26 100644 --- a/README.md +++ b/README.md @@ -560,19 +560,19 @@ comparison. | 0x V4 VIP | Uniswap V3 | USDC/WETH | 124669 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | USDC/WETH | 138525 | 11.11% | | Settler VIP (warm) | Uniswap V3 | USDC/WETH | 136237 | 9.28% | -| AllowanceHolder VIP | Uniswap V3 | USDC/WETH | 125759 | 0.87% | +| AllowanceHolder VIP | Uniswap V3 | USDC/WETH | 125717 | 0.84% | | UniswapRouter V3 | Uniswap V3 | USDC/WETH | 120978 | -2.96% | | | | | | | | 0x V4 VIP | Uniswap V3 | DAI/WETH | 112103 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | DAI/WETH | 125959 | 12.36% | | Settler VIP (warm) | Uniswap V3 | DAI/WETH | 123671 | 10.32% | -| AllowanceHolder VIP | Uniswap V3 | DAI/WETH | 113193 | 0.97% | +| AllowanceHolder VIP | Uniswap V3 | DAI/WETH | 113151 | 0.93% | | UniswapRouter V3 | Uniswap V3 | DAI/WETH | 108412 | -3.29% | | | | | | | | 0x V4 VIP | Uniswap V3 | USDT/WETH | 114910 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | USDT/WETH | 128766 | 12.06% | | Settler VIP (warm) | Uniswap V3 | USDT/WETH | 126487 | 10.07% | -| AllowanceHolder VIP | Uniswap V3 | USDT/WETH | 116009 | 0.96% | +| AllowanceHolder VIP | Uniswap V3 | USDT/WETH | 115967 | 0.92% | | UniswapRouter V3 | Uniswap V3 | USDT/WETH | 111091 | -3.32% | | | | | | | @@ -580,15 +580,15 @@ comparison. | -------------------- | ---------- | --------- | ------ | ------- | | 0x V4 TransformERC20 | Uniswap V3 | USDC/WETH | 244603 | 0.00% | | Settler | Uniswap V3 | USDC/WETH | 166872 | -31.78% | -| AllowanceHolder | Uniswap V3 | USDC/WETH | 156544 | -36.00% | +| AllowanceHolder | Uniswap V3 | USDC/WETH | 156502 | -36.02% | | | | | | | | 0x V4 TransformERC20 | Uniswap V3 | DAI/WETH | 221601 | 0.00% | | Settler | Uniswap V3 | DAI/WETH | 150250 | -32.20% | -| AllowanceHolder | Uniswap V3 | DAI/WETH | 139922 | -36.86% | +| AllowanceHolder | Uniswap V3 | DAI/WETH | 139880 | -36.88% | | | | | | | | 0x V4 TransformERC20 | Uniswap V3 | USDT/WETH | 228500 | 0.00% | | Settler | Uniswap V3 | USDT/WETH | 156923 | -31.32% | -| AllowanceHolder | Uniswap V3 | USDT/WETH | 146595 | -35.84% | +| AllowanceHolder | Uniswap V3 | USDT/WETH | 146553 | -35.86% | | | | | | | | MetaTransactions | DEX | Pair | Gas | % | @@ -608,17 +608,17 @@ comparison. | 0x V4 | 0x V4 | USDC/WETH | 97972 | 0.00% | | Settler | Settler | USDC/WETH | 114370 | 16.74% | | Settler | 0x V4 | USDC/WETH | 206545 | 110.82% | -| AllowanceHolder | Settler | USDC/WETH | 106541 | 8.75% | +| AllowanceHolder | Settler | USDC/WETH | 106499 | 8.70% | | | | | | | | 0x V4 | 0x V4 | DAI/WETH | 78498 | 0.00% | | Settler | Settler | DAI/WETH | 94896 | 20.89% | | Settler | 0x V4 | DAI/WETH | 176635 | 125.02% | -| AllowanceHolder | Settler | DAI/WETH | 87067 | 10.92% | +| AllowanceHolder | Settler | DAI/WETH | 87025 | 10.86% | | | | | | | | 0x V4 | 0x V4 | USDT/WETH | 89610 | 0.00% | | Settler | Settler | USDT/WETH | 106008 | 18.30% | | Settler | 0x V4 | USDT/WETH | 191967 | 114.22% | -| AllowanceHolder | Settler | USDT/WETH | 98179 | 9.56% | +| AllowanceHolder | Settler | USDT/WETH | 98137 | 9.52% | | | | | | | | Curve | DEX | Pair | Gas | % | @@ -635,7 +635,7 @@ comparison. | DODO V1 | DEX | Pair | Gas | % | | ------- | ------- | --------- | ------ | ----- | -| Settler | DODO V1 | USDC/WETH | 308591 | 0.00% | +| Settler | DODO V1 | USDC/WETH | 308996 | 0.00% | | | | | | | | | | | | | | | | | | | @@ -661,32 +661,32 @@ comparison. | AllowanceHolder | DEX | Pair | Gas | % | | ------------------------------------ | -------------- | --------- | ------ | ------- | -| execute | Uniswap V3 VIP | USDC/WETH | 125759 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140372 | 11.62% | -| execute | RFQ | USDC/WETH | 106541 | -15.28% | +| execute | Uniswap V3 VIP | USDC/WETH | 125717 | 0.00% | +| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140372 | 11.66% | +| execute | RFQ | USDC/WETH | 106499 | -15.29% | | | | | | | -| execute | Uniswap V3 VIP | DAI/WETH | 113193 | 0.00% | -| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129381 | 14.30% | -| execute | RFQ | DAI/WETH | 87067 | -23.08% | +| execute | Uniswap V3 VIP | DAI/WETH | 113151 | 0.00% | +| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129381 | 14.34% | +| execute | RFQ | DAI/WETH | 87025 | -23.09% | | | | | | | -| execute | Uniswap V3 VIP | USDT/WETH | 116009 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136369 | 17.55% | -| execute | RFQ | USDT/WETH | 98179 | -15.37% | +| execute | Uniswap V3 VIP | USDT/WETH | 115967 | 0.00% | +| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136369 | 17.59% | +| execute | RFQ | USDT/WETH | 98137 | -15.38% | | | | | | | | AllowanceHolder sell token fees | DEX | Pair | Gas | % | | ------------------------------- | --- | --------- | ------ | ------ | -| no fee | RFQ | USDC/WETH | 106541 | 0.00% | -| proportional fee | RFQ | USDC/WETH | 154498 | 45.01% | -| fixed fee | RFQ | USDC/WETH | 122814 | 15.27% | +| no fee | RFQ | USDC/WETH | 106499 | 0.00% | +| proportional fee | RFQ | USDC/WETH | 154456 | 45.03% | +| fixed fee | RFQ | USDC/WETH | 122730 | 15.24% | | | | | | | -| no fee | RFQ | DAI/WETH | 87067 | 0.00% | -| proportional fee | RFQ | DAI/WETH | 126912 | 45.76% | -| fixed fee | RFQ | DAI/WETH | 99166 | 13.90% | +| no fee | RFQ | DAI/WETH | 87025 | 0.00% | +| proportional fee | RFQ | DAI/WETH | 126870 | 45.79% | +| fixed fee | RFQ | DAI/WETH | 99082 | 13.85% | | | | | | | -| no fee | RFQ | USDT/WETH | 98179 | 0.00% | -| proportional fee | RFQ | USDT/WETH | 143656 | 46.32% | -| fixed fee | RFQ | USDT/WETH | 111390 | 13.46% | +| no fee | RFQ | USDT/WETH | 98137 | 0.00% | +| proportional fee | RFQ | USDT/WETH | 143614 | 46.34% | +| fixed fee | RFQ | USDT/WETH | 111306 | 13.42% | | | | | | | [//]: # "END TABLES" From 7d63a4f50e6371cec87e325b8b023c9e143008c5 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Wed, 30 Oct 2024 03:44:12 -0400 Subject: [PATCH 17/29] Use technique from `fastBalanceOf` in `AllowanceHolderBase`'s `_rejectIfERC20` --- src/allowanceholder/AllowanceHolderBase.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 4af7aa326..a68736f68 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -45,8 +45,8 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { bytes memory testData; // = abi.encodeCall(IERC20.balanceOf, target); assembly ("memory-safe") { testData := mload(0x40) - mstore(add(0x04, testData), 0x70a08231) - mstore(add(0x24, testData), and(0xffffffffffffffffffffffffffffffffffffffff, target)) + mstore(add(0x24, testData), target) + mstore(add(0x10, testData), 0x70a08231000000000000000000000000) mstore(testData, 0x24) mstore(0x40, add(0x60, testData)) } From ce5c565a4cd1345fb722080460f99d489332c502 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Wed, 30 Oct 2024 04:00:30 -0400 Subject: [PATCH 18/29] Update snaps --- .../allowanceHolder_empty_DAI-WETH.snap | 2 +- .../allowanceHolder_empty_USDC-WETH.snap | 2 +- .../allowanceHolder_empty_USDT-WETH.snap | 2 +- ...owanceHolder_maverickV2_VIP_USDC-WETH.snap | 2 +- .../allowanceHolder_rfq_DAI-WETH.snap | 2 +- .../allowanceHolder_rfq_USDC-WETH.snap | 2 +- .../allowanceHolder_rfq_USDT-WETH.snap | 2 +- ...older_rfq_fixedFee_sellToken_DAI-WETH.snap | 2 +- ...lder_rfq_fixedFee_sellToken_USDC-WETH.snap | 2 +- ...lder_rfq_fixedFee_sellToken_USDT-WETH.snap | 2 +- ...fq_proportionalFee_sellToken_DAI-WETH.snap | 2 +- ...q_proportionalFee_sellToken_USDC-WETH.snap | 2 +- ...q_proportionalFee_sellToken_USDT-WETH.snap | 2 +- ...older_uniswapV2_single_chain_DAI-WETH.snap | 2 +- ...lder_uniswapV2_single_chain_USDC-WETH.snap | 2 +- ...lder_uniswapV2_single_chain_USDT-WETH.snap | 2 +- ...allowanceHolder_uniswapV3VIP_DAI-WETH.snap | 2 +- ...llowanceHolder_uniswapV3VIP_USDC-WETH.snap | 2 +- ...llowanceHolder_uniswapV3VIP_USDT-WETH.snap | 2 +- ...Holder_uniswapV3VIP_contract_DAI-WETH.snap | 2 +- ...older_uniswapV3VIP_contract_USDC-WETH.snap | 2 +- ...older_uniswapV3VIP_contract_USDT-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_DAI-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_USDC-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_USDT-WETH.snap | 2 +- README.md | 54 +++++++++---------- 26 files changed, 52 insertions(+), 52 deletions(-) diff --git a/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap index e04a388c7..9c8bba4a5 100644 --- a/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap @@ -1 +1 @@ -8677 \ No newline at end of file +8671 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap index e04a388c7..9c8bba4a5 100644 --- a/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap @@ -1 +1 @@ -8677 \ No newline at end of file +8671 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap index e04a388c7..9c8bba4a5 100644 --- a/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap @@ -1 +1 @@ -8677 \ No newline at end of file +8671 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap index 127a22b30..77c95047d 100644 --- a/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap @@ -1 +1 @@ -123647 \ No newline at end of file +123641 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap index 08670e729..7c8e6e102 100644 --- a/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap @@ -1 +1 @@ -87017 \ No newline at end of file +87011 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap index a9ca3274d..f337b2a22 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap @@ -1 +1 @@ -106491 \ No newline at end of file +106485 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap index 50d251501..a19bb26b1 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap @@ -1 +1 @@ -98129 \ No newline at end of file +98123 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap index ce5564ef7..80e9922b1 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap @@ -1 +1 @@ -99073 \ No newline at end of file +99067 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap index 732e0d72a..c8e6a35c7 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap @@ -1 +1 @@ -122721 \ No newline at end of file +122715 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap index d7d9bdd6b..7cfa3d6d0 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap @@ -1 +1 @@ -111297 \ No newline at end of file +111291 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap index a61754de2..bfd575b31 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap @@ -1 +1 @@ -126413 \ No newline at end of file +126407 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap index ea2c3dbe6..c95306291 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap @@ -1 +1 @@ -153999 \ No newline at end of file +153993 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap index d15662fd3..bd3a22992 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap @@ -1 +1 @@ -143157 \ No newline at end of file +143151 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap index ffed8e005..88b90e127 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap @@ -1 +1 @@ -104128 \ No newline at end of file +104122 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap index 09c1d0a24..b96c5b285 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap @@ -1 +1 @@ -114226 \ No newline at end of file +114220 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap index a9a924189..f6cba9193 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap @@ -1 +1 @@ -105296 \ No newline at end of file +105290 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap index a6cda2640..9e9e5b84a 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap @@ -1 +1 @@ -113143 \ No newline at end of file +113137 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap index 95adbd0bb..14366c205 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap @@ -1 +1 @@ -125709 \ No newline at end of file +125703 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap index 479e5dff0..a5b2d8fa7 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap @@ -1 +1 @@ -115959 \ No newline at end of file +115953 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap index a6cda2640..9e9e5b84a 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap @@ -1 +1 @@ -113143 \ No newline at end of file +113137 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap index 95adbd0bb..14366c205 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap @@ -1 +1 @@ -125709 \ No newline at end of file +125703 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap index 479e5dff0..a5b2d8fa7 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap @@ -1 +1 @@ -115959 \ No newline at end of file +115953 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap index d95601c53..cc49389ef 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap @@ -1 +1 @@ -139698 \ No newline at end of file +139692 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap index b830a2a15..1b2c65762 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap @@ -1 +1 @@ -156320 \ No newline at end of file +156314 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap index 9fa77efb0..6983b590e 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap @@ -1 +1 @@ -146371 \ No newline at end of file +146365 \ No newline at end of file diff --git a/README.md b/README.md index a33ee5a97..63a3dcdac 100644 --- a/README.md +++ b/README.md @@ -560,19 +560,19 @@ comparison. | 0x V4 VIP | Uniswap V3 | USDC/WETH | 124669 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | USDC/WETH | 138525 | 11.11% | | Settler VIP (warm) | Uniswap V3 | USDC/WETH | 136229 | 9.27% | -| AllowanceHolder VIP | Uniswap V3 | USDC/WETH | 125709 | 0.83% | +| AllowanceHolder VIP | Uniswap V3 | USDC/WETH | 125703 | 0.83% | | UniswapRouter V3 | Uniswap V3 | USDC/WETH | 120978 | -2.96% | | | | | | | | 0x V4 VIP | Uniswap V3 | DAI/WETH | 112103 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | DAI/WETH | 125959 | 12.36% | | Settler VIP (warm) | Uniswap V3 | DAI/WETH | 123663 | 10.31% | -| AllowanceHolder VIP | Uniswap V3 | DAI/WETH | 113143 | 0.93% | +| AllowanceHolder VIP | Uniswap V3 | DAI/WETH | 113137 | 0.92% | | UniswapRouter V3 | Uniswap V3 | DAI/WETH | 108412 | -3.29% | | | | | | | | 0x V4 VIP | Uniswap V3 | USDT/WETH | 114910 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | USDT/WETH | 128766 | 12.06% | | Settler VIP (warm) | Uniswap V3 | USDT/WETH | 126479 | 10.07% | -| AllowanceHolder VIP | Uniswap V3 | USDT/WETH | 115959 | 0.91% | +| AllowanceHolder VIP | Uniswap V3 | USDT/WETH | 115953 | 0.91% | | UniswapRouter V3 | Uniswap V3 | USDT/WETH | 111091 | -3.32% | | | | | | | @@ -580,15 +580,15 @@ comparison. | -------------------- | ---------- | --------- | ------ | ------- | | 0x V4 TransformERC20 | Uniswap V3 | USDC/WETH | 244603 | 0.00% | | Settler | Uniswap V3 | USDC/WETH | 166693 | -31.85% | -| AllowanceHolder | Uniswap V3 | USDC/WETH | 156320 | -36.09% | +| AllowanceHolder | Uniswap V3 | USDC/WETH | 156314 | -36.09% | | | | | | | | 0x V4 TransformERC20 | Uniswap V3 | DAI/WETH | 221601 | 0.00% | | Settler | Uniswap V3 | DAI/WETH | 150071 | -32.28% | -| AllowanceHolder | Uniswap V3 | DAI/WETH | 139698 | -36.96% | +| AllowanceHolder | Uniswap V3 | DAI/WETH | 139692 | -36.96% | | | | | | | | 0x V4 TransformERC20 | Uniswap V3 | USDT/WETH | 228500 | 0.00% | | Settler | Uniswap V3 | USDT/WETH | 156744 | -31.40% | -| AllowanceHolder | Uniswap V3 | USDT/WETH | 146371 | -35.94% | +| AllowanceHolder | Uniswap V3 | USDT/WETH | 146365 | -35.95% | | | | | | | | MetaTransactions | DEX | Pair | Gas | % | @@ -608,17 +608,17 @@ comparison. | 0x V4 | 0x V4 | USDC/WETH | 97972 | 0.00% | | Settler | Settler | USDC/WETH | 114362 | 16.73% | | Settler | 0x V4 | USDC/WETH | 206164 | 110.43% | -| AllowanceHolder | Settler | USDC/WETH | 106491 | 8.70% | +| AllowanceHolder | Settler | USDC/WETH | 106485 | 8.69% | | | | | | | | 0x V4 | 0x V4 | DAI/WETH | 78498 | 0.00% | | Settler | Settler | DAI/WETH | 94888 | 20.88% | | Settler | 0x V4 | DAI/WETH | 176254 | 124.53% | -| AllowanceHolder | Settler | DAI/WETH | 87017 | 10.85% | +| AllowanceHolder | Settler | DAI/WETH | 87011 | 10.84% | | | | | | | | 0x V4 | 0x V4 | USDT/WETH | 89610 | 0.00% | | Settler | Settler | USDT/WETH | 106000 | 18.29% | | Settler | 0x V4 | USDT/WETH | 191586 | 113.80% | -| AllowanceHolder | Settler | USDT/WETH | 98129 | 9.51% | +| AllowanceHolder | Settler | USDT/WETH | 98123 | 9.50% | | | | | | | | Curve | DEX | Pair | Gas | % | @@ -661,32 +661,32 @@ comparison. | AllowanceHolder | DEX | Pair | Gas | % | | ------------------------------------ | -------------- | --------- | ------ | ------- | -| execute | Uniswap V3 VIP | USDC/WETH | 125709 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140191 | 11.52% | -| execute | RFQ | USDC/WETH | 106491 | -15.29% | +| execute | Uniswap V3 VIP | USDC/WETH | 125703 | 0.00% | +| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140191 | 11.53% | +| execute | RFQ | USDC/WETH | 106485 | -15.29% | | | | | | | -| execute | Uniswap V3 VIP | DAI/WETH | 113143 | 0.00% | -| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129200 | 14.19% | -| execute | RFQ | DAI/WETH | 87017 | -23.09% | +| execute | Uniswap V3 VIP | DAI/WETH | 113137 | 0.00% | +| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129200 | 14.20% | +| execute | RFQ | DAI/WETH | 87011 | -23.09% | | | | | | | -| execute | Uniswap V3 VIP | USDT/WETH | 115959 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136188 | 17.44% | -| execute | RFQ | USDT/WETH | 98129 | -15.38% | +| execute | Uniswap V3 VIP | USDT/WETH | 115953 | 0.00% | +| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136188 | 17.45% | +| execute | RFQ | USDT/WETH | 98123 | -15.38% | | | | | | | | AllowanceHolder sell token fees | DEX | Pair | Gas | % | | ------------------------------- | --- | --------- | ------ | ------ | -| no fee | RFQ | USDC/WETH | 106491 | 0.00% | -| proportional fee | RFQ | USDC/WETH | 153999 | 44.61% | -| fixed fee | RFQ | USDC/WETH | 122721 | 15.24% | +| no fee | RFQ | USDC/WETH | 106485 | 0.00% | +| proportional fee | RFQ | USDC/WETH | 153993 | 44.61% | +| fixed fee | RFQ | USDC/WETH | 122715 | 15.24% | | | | | | | -| no fee | RFQ | DAI/WETH | 87017 | 0.00% | -| proportional fee | RFQ | DAI/WETH | 126413 | 45.27% | -| fixed fee | RFQ | DAI/WETH | 99073 | 13.85% | +| no fee | RFQ | DAI/WETH | 87011 | 0.00% | +| proportional fee | RFQ | DAI/WETH | 126407 | 45.28% | +| fixed fee | RFQ | DAI/WETH | 99067 | 13.86% | | | | | | | -| no fee | RFQ | USDT/WETH | 98129 | 0.00% | -| proportional fee | RFQ | USDT/WETH | 143157 | 45.89% | -| fixed fee | RFQ | USDT/WETH | 111297 | 13.42% | +| no fee | RFQ | USDT/WETH | 98123 | 0.00% | +| proportional fee | RFQ | USDT/WETH | 143151 | 45.89% | +| fixed fee | RFQ | USDT/WETH | 111291 | 13.42% | | | | | | | [//]: # "END TABLES" From 935a7c45cfc81d71a1ea5acf1a5677c1549c98e5 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 23 Jan 2025 23:59:29 -0500 Subject: [PATCH 19/29] Golf --- src/allowanceholder/TransientStorageLayout.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/allowanceholder/TransientStorageLayout.sol b/src/allowanceholder/TransientStorageLayout.sol index 5dacb94d6..6e3ab5d0c 100644 --- a/src/allowanceholder/TransientStorageLayout.sol +++ b/src/allowanceholder/TransientStorageLayout.sol @@ -7,14 +7,15 @@ abstract contract TransientStorageLayout is TransientStorageBase { /// @dev The key for this ephemeral allowance is keccak256(abi.encodePacked(operator, owner, token)). function _ephemeralAllowance(address operator, address owner, address token) internal pure returns (TSlot r) { assembly ("memory-safe") { - let ptr := mload(0x40) + // This dirties the upper 8 bytes of the free memory pointer. These bytes must always be + // zero, otherwise we would OOM. mstore(0x28, token) mstore(0x14, owner) mstore(0x00, operator) // allowance slot is keccak256(abi.encodePacked(operator, owner, token)) r := keccak256(0x0c, 0x3c) // restore dirtied free pointer - mstore(0x40, ptr) + mstore(0x28, 0x00) } } } From 38f70ddd06db3f3cb0d1c481707f66fa08c65174 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Fri, 24 Jan 2025 00:14:09 -0500 Subject: [PATCH 20/29] Update snaps --- .../allowanceHolder_empty_DAI-WETH.snap | 2 +- .../allowanceHolder_empty_USDC-WETH.snap | 2 +- .../allowanceHolder_empty_USDT-WETH.snap | 2 +- ...owanceHolder_maverickV2_VIP_USDC-WETH.snap | 2 +- .../allowanceHolder_rfq_DAI-WETH.snap | 2 +- .../allowanceHolder_rfq_USDC-WETH.snap | 2 +- .../allowanceHolder_rfq_USDT-WETH.snap | 2 +- ...older_rfq_fixedFee_sellToken_DAI-WETH.snap | 2 +- ...lder_rfq_fixedFee_sellToken_USDC-WETH.snap | 2 +- ...lder_rfq_fixedFee_sellToken_USDT-WETH.snap | 2 +- ...fq_proportionalFee_sellToken_DAI-WETH.snap | 2 +- ...q_proportionalFee_sellToken_USDC-WETH.snap | 2 +- ...q_proportionalFee_sellToken_USDT-WETH.snap | 2 +- ...older_uniswapV2_single_chain_DAI-WETH.snap | 2 +- ...lder_uniswapV2_single_chain_USDC-WETH.snap | 2 +- ...lder_uniswapV2_single_chain_USDT-WETH.snap | 2 +- ...allowanceHolder_uniswapV3VIP_DAI-WETH.snap | 2 +- ...llowanceHolder_uniswapV3VIP_USDC-WETH.snap | 2 +- ...llowanceHolder_uniswapV3VIP_USDT-WETH.snap | 2 +- ...Holder_uniswapV3VIP_contract_DAI-WETH.snap | 2 +- ...older_uniswapV3VIP_contract_USDC-WETH.snap | 2 +- ...older_uniswapV3VIP_contract_USDT-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_DAI-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_USDC-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_USDT-WETH.snap | 2 +- .../settler_dodoV1_USDC-WETH.snap | 2 +- .../settler_makerPsmLite_buyGem_DAI-USDC.snap | 2 +- ...settler_makerPsmLite_sellGem_USDC-DAI.snap | 2 +- README.md | 56 +++++++++---------- 29 files changed, 56 insertions(+), 56 deletions(-) diff --git a/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap index 9c8bba4a5..4f672858b 100644 --- a/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap @@ -1 +1 @@ -8671 \ No newline at end of file +8655 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap index 9c8bba4a5..4f672858b 100644 --- a/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap @@ -1 +1 @@ -8671 \ No newline at end of file +8655 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap index 9c8bba4a5..4f672858b 100644 --- a/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap @@ -1 +1 @@ -8671 \ No newline at end of file +8655 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap index 77c95047d..1df65133f 100644 --- a/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap @@ -1 +1 @@ -123641 \ No newline at end of file +123627 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap index 7c8e6e102..cf7665bac 100644 --- a/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap @@ -1 +1 @@ -87011 \ No newline at end of file +86997 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap index f337b2a22..c7eeaeb2f 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap @@ -1 +1 @@ -106485 \ No newline at end of file +106471 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap index a19bb26b1..ce12e31a0 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap @@ -1 +1 @@ -98123 \ No newline at end of file +98109 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap index 80e9922b1..3b1ee0d9c 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_DAI-WETH.snap @@ -1 +1 @@ -99067 \ No newline at end of file +99055 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap index c8e6a35c7..2d8e22d3c 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDC-WETH.snap @@ -1 +1 @@ -122715 \ No newline at end of file +122703 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap index 7cfa3d6d0..f900925c3 100644 --- a/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_fixedFee_sellToken_USDT-WETH.snap @@ -1 +1 @@ -111291 \ No newline at end of file +111279 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap index bfd575b31..bdd221435 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap @@ -1 +1 @@ -126407 \ No newline at end of file +126393 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap index c95306291..d7eea8b0e 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap @@ -1 +1 @@ -153993 \ No newline at end of file +153979 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap index bd3a22992..8d3db45e3 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap @@ -1 +1 @@ -143151 \ No newline at end of file +143137 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap index 88b90e127..7f7a65a2f 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap @@ -1 +1 @@ -104122 \ No newline at end of file +104108 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap index b96c5b285..4e426e3a2 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap @@ -1 +1 @@ -114220 \ No newline at end of file +114206 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap index f6cba9193..b912ef0ba 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap @@ -1 +1 @@ -105290 \ No newline at end of file +105276 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap index 9e9e5b84a..1782aa2c2 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap @@ -1 +1 @@ -113137 \ No newline at end of file +113123 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap index 14366c205..02f0571ce 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap @@ -1 +1 @@ -125703 \ No newline at end of file +125689 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap index a5b2d8fa7..937cb699f 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap @@ -1 +1 @@ -115953 \ No newline at end of file +115939 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap index 9e9e5b84a..1782aa2c2 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap @@ -1 +1 @@ -113137 \ No newline at end of file +113123 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap index 14366c205..02f0571ce 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap @@ -1 +1 @@ -125703 \ No newline at end of file +125689 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap index a5b2d8fa7..937cb699f 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap @@ -1 +1 @@ -115953 \ No newline at end of file +115939 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap index cc49389ef..18c503ab0 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap @@ -1 +1 @@ -139692 \ No newline at end of file +139678 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap index 1b2c65762..7f875a0b2 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap @@ -1 +1 @@ -156314 \ No newline at end of file +156300 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap index 6983b590e..a5ae3079e 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap @@ -1 +1 @@ -146365 \ No newline at end of file +146351 \ No newline at end of file diff --git a/.forge-snapshots/settler_dodoV1_USDC-WETH.snap b/.forge-snapshots/settler_dodoV1_USDC-WETH.snap index 50f9a2599..579c977fa 100644 --- a/.forge-snapshots/settler_dodoV1_USDC-WETH.snap +++ b/.forge-snapshots/settler_dodoV1_USDC-WETH.snap @@ -1 +1 @@ -308461 \ No newline at end of file +308077 \ No newline at end of file diff --git a/.forge-snapshots/settler_makerPsmLite_buyGem_DAI-USDC.snap b/.forge-snapshots/settler_makerPsmLite_buyGem_DAI-USDC.snap index 9656f1cc3..f901469c0 100644 --- a/.forge-snapshots/settler_makerPsmLite_buyGem_DAI-USDC.snap +++ b/.forge-snapshots/settler_makerPsmLite_buyGem_DAI-USDC.snap @@ -1 +1 @@ -171115 \ No newline at end of file +171147 \ No newline at end of file diff --git a/.forge-snapshots/settler_makerPsmLite_sellGem_USDC-DAI.snap b/.forge-snapshots/settler_makerPsmLite_sellGem_USDC-DAI.snap index 7f91c0d8a..8604b6c4f 100644 --- a/.forge-snapshots/settler_makerPsmLite_sellGem_USDC-DAI.snap +++ b/.forge-snapshots/settler_makerPsmLite_sellGem_USDC-DAI.snap @@ -1 +1 @@ -177730 \ No newline at end of file +177757 \ No newline at end of file diff --git a/README.md b/README.md index 63a3dcdac..5ae542c9e 100644 --- a/README.md +++ b/README.md @@ -560,19 +560,19 @@ comparison. | 0x V4 VIP | Uniswap V3 | USDC/WETH | 124669 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | USDC/WETH | 138525 | 11.11% | | Settler VIP (warm) | Uniswap V3 | USDC/WETH | 136229 | 9.27% | -| AllowanceHolder VIP | Uniswap V3 | USDC/WETH | 125703 | 0.83% | +| AllowanceHolder VIP | Uniswap V3 | USDC/WETH | 125689 | 0.82% | | UniswapRouter V3 | Uniswap V3 | USDC/WETH | 120978 | -2.96% | | | | | | | | 0x V4 VIP | Uniswap V3 | DAI/WETH | 112103 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | DAI/WETH | 125959 | 12.36% | | Settler VIP (warm) | Uniswap V3 | DAI/WETH | 123663 | 10.31% | -| AllowanceHolder VIP | Uniswap V3 | DAI/WETH | 113137 | 0.92% | +| AllowanceHolder VIP | Uniswap V3 | DAI/WETH | 113123 | 0.91% | | UniswapRouter V3 | Uniswap V3 | DAI/WETH | 108412 | -3.29% | | | | | | | | 0x V4 VIP | Uniswap V3 | USDT/WETH | 114910 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | USDT/WETH | 128766 | 12.06% | | Settler VIP (warm) | Uniswap V3 | USDT/WETH | 126479 | 10.07% | -| AllowanceHolder VIP | Uniswap V3 | USDT/WETH | 115953 | 0.91% | +| AllowanceHolder VIP | Uniswap V3 | USDT/WETH | 115939 | 0.90% | | UniswapRouter V3 | Uniswap V3 | USDT/WETH | 111091 | -3.32% | | | | | | | @@ -580,15 +580,15 @@ comparison. | -------------------- | ---------- | --------- | ------ | ------- | | 0x V4 TransformERC20 | Uniswap V3 | USDC/WETH | 244603 | 0.00% | | Settler | Uniswap V3 | USDC/WETH | 166693 | -31.85% | -| AllowanceHolder | Uniswap V3 | USDC/WETH | 156314 | -36.09% | +| AllowanceHolder | Uniswap V3 | USDC/WETH | 156300 | -36.10% | | | | | | | | 0x V4 TransformERC20 | Uniswap V3 | DAI/WETH | 221601 | 0.00% | | Settler | Uniswap V3 | DAI/WETH | 150071 | -32.28% | -| AllowanceHolder | Uniswap V3 | DAI/WETH | 139692 | -36.96% | +| AllowanceHolder | Uniswap V3 | DAI/WETH | 139678 | -36.97% | | | | | | | | 0x V4 TransformERC20 | Uniswap V3 | USDT/WETH | 228500 | 0.00% | | Settler | Uniswap V3 | USDT/WETH | 156744 | -31.40% | -| AllowanceHolder | Uniswap V3 | USDT/WETH | 146365 | -35.95% | +| AllowanceHolder | Uniswap V3 | USDT/WETH | 146351 | -35.95% | | | | | | | | MetaTransactions | DEX | Pair | Gas | % | @@ -608,17 +608,17 @@ comparison. | 0x V4 | 0x V4 | USDC/WETH | 97972 | 0.00% | | Settler | Settler | USDC/WETH | 114362 | 16.73% | | Settler | 0x V4 | USDC/WETH | 206164 | 110.43% | -| AllowanceHolder | Settler | USDC/WETH | 106485 | 8.69% | +| AllowanceHolder | Settler | USDC/WETH | 106471 | 8.67% | | | | | | | | 0x V4 | 0x V4 | DAI/WETH | 78498 | 0.00% | | Settler | Settler | DAI/WETH | 94888 | 20.88% | | Settler | 0x V4 | DAI/WETH | 176254 | 124.53% | -| AllowanceHolder | Settler | DAI/WETH | 87011 | 10.84% | +| AllowanceHolder | Settler | DAI/WETH | 86997 | 10.83% | | | | | | | | 0x V4 | 0x V4 | USDT/WETH | 89610 | 0.00% | | Settler | Settler | USDT/WETH | 106000 | 18.29% | | Settler | 0x V4 | USDT/WETH | 191586 | 113.80% | -| AllowanceHolder | Settler | USDT/WETH | 98123 | 9.50% | +| AllowanceHolder | Settler | USDT/WETH | 98109 | 9.48% | | | | | | | | Curve | DEX | Pair | Gas | % | @@ -635,7 +635,7 @@ comparison. | DODO V1 | DEX | Pair | Gas | % | | ------- | ------- | --------- | ------ | ----- | -| Settler | DODO V1 | USDC/WETH | 308461 | 0.00% | +| Settler | DODO V1 | USDC/WETH | 308077 | 0.00% | | | | | | | | | | | | | | | | | | | @@ -661,32 +661,32 @@ comparison. | AllowanceHolder | DEX | Pair | Gas | % | | ------------------------------------ | -------------- | --------- | ------ | ------- | -| execute | Uniswap V3 VIP | USDC/WETH | 125703 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140191 | 11.53% | -| execute | RFQ | USDC/WETH | 106485 | -15.29% | +| execute | Uniswap V3 VIP | USDC/WETH | 125689 | 0.00% | +| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140191 | 11.54% | +| execute | RFQ | USDC/WETH | 106471 | -15.29% | | | | | | | -| execute | Uniswap V3 VIP | DAI/WETH | 113137 | 0.00% | -| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129200 | 14.20% | -| execute | RFQ | DAI/WETH | 87011 | -23.09% | +| execute | Uniswap V3 VIP | DAI/WETH | 113123 | 0.00% | +| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129200 | 14.21% | +| execute | RFQ | DAI/WETH | 86997 | -23.10% | | | | | | | -| execute | Uniswap V3 VIP | USDT/WETH | 115953 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136188 | 17.45% | -| execute | RFQ | USDT/WETH | 98123 | -15.38% | +| execute | Uniswap V3 VIP | USDT/WETH | 115939 | 0.00% | +| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136188 | 17.47% | +| execute | RFQ | USDT/WETH | 98109 | -15.38% | | | | | | | | AllowanceHolder sell token fees | DEX | Pair | Gas | % | | ------------------------------- | --- | --------- | ------ | ------ | -| no fee | RFQ | USDC/WETH | 106485 | 0.00% | -| proportional fee | RFQ | USDC/WETH | 153993 | 44.61% | -| fixed fee | RFQ | USDC/WETH | 122715 | 15.24% | +| no fee | RFQ | USDC/WETH | 106471 | 0.00% | +| proportional fee | RFQ | USDC/WETH | 153979 | 44.62% | +| fixed fee | RFQ | USDC/WETH | 122703 | 15.25% | | | | | | | -| no fee | RFQ | DAI/WETH | 87011 | 0.00% | -| proportional fee | RFQ | DAI/WETH | 126407 | 45.28% | -| fixed fee | RFQ | DAI/WETH | 99067 | 13.86% | +| no fee | RFQ | DAI/WETH | 86997 | 0.00% | +| proportional fee | RFQ | DAI/WETH | 126393 | 45.28% | +| fixed fee | RFQ | DAI/WETH | 99055 | 13.86% | | | | | | | -| no fee | RFQ | USDT/WETH | 98123 | 0.00% | -| proportional fee | RFQ | USDT/WETH | 143151 | 45.89% | -| fixed fee | RFQ | USDT/WETH | 111291 | 13.42% | +| no fee | RFQ | USDT/WETH | 98109 | 0.00% | +| proportional fee | RFQ | USDT/WETH | 143137 | 45.90% | +| fixed fee | RFQ | USDT/WETH | 111279 | 13.42% | | | | | | | [//]: # "END TABLES" From f28d955b43ae1384010494976c7cb5a317643452 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Tue, 4 Mar 2025 16:45:04 -0500 Subject: [PATCH 21/29] Adopt the same pattern as in `MultiCall` where the ERC2771 forwarder is omitted if there is no selector --- src/allowanceholder/AllowanceHolder.sol | 2 +- src/allowanceholder/AllowanceHolderBase.sol | 15 ++++++++++++--- src/allowanceholder/AllowanceHolderOld.sol | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/allowanceholder/AllowanceHolder.sol b/src/allowanceholder/AllowanceHolder.sol index 355f431bc..9c8446a6d 100644 --- a/src/allowanceholder/AllowanceHolder.sol +++ b/src/allowanceholder/AllowanceHolder.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity =0.8.25; +pragma solidity =0.8.28; import {AllowanceHolderBase} from "./AllowanceHolderBase.sol"; import {TransientStorage} from "./TransientStorage.sol"; diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index a68736f68..6db1186de 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; +pragma solidity =0.8.28; import {IAllowanceHolder} from "./IAllowanceHolder.sol"; import {IERC20} from "@forge-std/interfaces/IERC20.sol"; @@ -89,16 +89,25 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // send (we know it does), and we're omitting the check that `target` // contains code (we already checked in `_rejectIfERC20`). assembly ("memory-safe") { + // Copy the payload from calldata into memory result := mload(0x40) calldatacopy(result, data.offset, data.length) + // ERC-2771 style `msgSender` forwarding https://eips.ethereum.org/EIPS/eip-2771 + // We do not append the forwarded sender if the payload has no selector mstore(add(result, data.length), shl(0x60, sender)) - let success := call(gas(), target, callvalue(), result, add(0x14, data.length), 0x00, 0x00) + let length := add(mul(0x14, lt(0x03, data.length)), data.length) + + // Perform the call + let success := call(gas(), target, callvalue(), result, length, 0x00, 0x00) + + // Copy returndata into memory; if it is a revert, bubble let ptr := add(0x20, result) returndatacopy(ptr, 0x00, returndatasize()) switch success case 0 { revert(ptr, returndatasize()) } default { + // Wrap the returndata in a level of ABIEncoding mstore(result, returndatasize()) mstore(0x40, add(returndatasize(), ptr)) } @@ -195,7 +204,7 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { let len := mload(result) let m := and(0x1f, len) if m { - mstore(add(len, add(0x20, result)), 0x00) + mstore(add(add(0x20, result), len), 0x00) len := add(sub(0x20, m), len) } diff --git a/src/allowanceholder/AllowanceHolderOld.sol b/src/allowanceholder/AllowanceHolderOld.sol index 55618809e..45c4a465c 100644 --- a/src/allowanceholder/AllowanceHolderOld.sol +++ b/src/allowanceholder/AllowanceHolderOld.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; +pragma solidity =0.8.28; import {AllowanceHolderBase} from "./AllowanceHolderBase.sol"; import {TransientStorageMock} from "./TransientStorageMock.sol"; From e3daeecfb2113fc94a110ba3d00ee7f38affcb1d Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Tue, 4 Mar 2025 18:42:40 -0500 Subject: [PATCH 22/29] Solc 0.8.28 --- ...lowanceHolder_balancerV3VIP_USDC-USDT.snap | 2 +- .../allowanceHolder_empty_DAI-WETH.snap | 2 +- .../allowanceHolder_empty_USDC-USDT.snap | 2 +- .../allowanceHolder_empty_USDC-WETH.snap | 2 +- .../allowanceHolder_empty_USDT-WETH.snap | 2 +- ...owanceHolder_maverickV2_VIP_USDC-WETH.snap | 2 +- .../allowanceHolder_rfq_DAI-WETH.snap | 2 +- .../allowanceHolder_rfq_USDC-USDT.snap | 2 +- .../allowanceHolder_rfq_USDC-WETH.snap | 2 +- .../allowanceHolder_rfq_USDT-WETH.snap | 2 +- ...fq_proportionalFee_sellToken_DAI-WETH.snap | 2 +- ...q_proportionalFee_sellToken_USDC-USDT.snap | 2 +- ...q_proportionalFee_sellToken_USDC-WETH.snap | 2 +- ...q_proportionalFee_sellToken_USDT-WETH.snap | 2 +- ...older_uniswapV2_single_chain_DAI-WETH.snap | 2 +- ...lder_uniswapV2_single_chain_USDC-WETH.snap | 2 +- ...lder_uniswapV2_single_chain_USDT-WETH.snap | 2 +- ...allowanceHolder_uniswapV3VIP_DAI-WETH.snap | 2 +- ...llowanceHolder_uniswapV3VIP_USDC-WETH.snap | 2 +- ...llowanceHolder_uniswapV3VIP_USDT-WETH.snap | 2 +- ...Holder_uniswapV3VIP_contract_DAI-WETH.snap | 2 +- ...older_uniswapV3VIP_contract_USDC-WETH.snap | 2 +- ...older_uniswapV3VIP_contract_USDT-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_DAI-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_USDC-WETH.snap | 2 +- .../allowanceHolder_uniswapV3_USDT-WETH.snap | 2 +- .../settler_balancerV3VIP_USDC-USDT.snap | 2 +- .../settler_balancerV3_USDC-USDT.snap | 2 +- .../settler_basic_curve_USDT-WETH.snap | 2 +- .../settler_curveTricrypto_USDC-WETH.snap | 2 +- .../settler_curveTricrypto_USDT-WETH.snap | 2 +- .../settler_curveV2_fee_USDT-WETH.snap | 2 +- .../settler_dodoV1_USDC-WETH.snap | 2 +- .forge-snapshots/settler_dodov2_USDT-DAI.snap | 2 +- .../settler_dodov2_custody_USDT-DAI.snap | 2 +- ...xternalMoveExecute_uniswapV3_DAI-WETH.snap | 2 +- ...ternalMoveExecute_uniswapV3_USDC-WETH.snap | 2 +- ...ternalMoveExecute_uniswapV3_USDT-WETH.snap | 2 +- .../settler_makerPsmLite_buyGem_DAI-USDC.snap | 2 +- ...settler_makerPsmLite_sellGem_USDC-DAI.snap | 2 +- .../settler_maverickV2_USDC-WETH.snap | 2 +- .../settler_maverickV2_VIP_USDC-WETH.snap | 2 +- .../settler_metaTxn_balancerV3_USDC-USDT.snap | 2 +- .../settler_metaTxn_maverickV2_USDC-WETH.snap | 2 +- .forge-snapshots/settler_rfq_DAI-USDC.snap | 2 +- .forge-snapshots/settler_rfq_DAI-WETH.snap | 2 +- .forge-snapshots/settler_rfq_USDC-DAI.snap | 2 +- .forge-snapshots/settler_rfq_USDC-USDT.snap | 2 +- .forge-snapshots/settler_rfq_USDC-WETH.snap | 2 +- .forge-snapshots/settler_rfq_USDT-WETH.snap | 2 +- ...settler_rfq_fee_full_custody_DAI-USDC.snap | 2 +- ...settler_rfq_fee_full_custody_DAI-WETH.snap | 2 +- ...settler_rfq_fee_full_custody_USDC-DAI.snap | 2 +- ...ettler_rfq_fee_full_custody_USDC-USDT.snap | 2 +- ...ettler_rfq_fee_full_custody_USDC-WETH.snap | 2 +- ...ettler_rfq_fee_full_custody_USDT-WETH.snap | 2 +- .../settler_uniswapV2_DAI-WETH.snap | 2 +- .../settler_uniswapV2_USDC-WETH.snap | 2 +- .../settler_uniswapV2_USDT-WETH.snap | 2 +- .../settler_uniswapV2_multihop_DAI-WETH.snap | 2 +- .../settler_uniswapV2_multihop_USDC-WETH.snap | 2 +- .../settler_uniswapV2_multihop_USDT-WETH.snap | 2 +- ...swapV2_multihop_single_chain_DAI-WETH.snap | 2 +- ...wapV2_multihop_single_chain_USDC-WETH.snap | 2 +- ...wapV2_multihop_single_chain_USDT-WETH.snap | 2 +- ...ttler_uniswapV2_single_chain_DAI-WETH.snap | 2 +- ...tler_uniswapV2_single_chain_USDC-WETH.snap | 2 +- ...tler_uniswapV2_single_chain_USDT-WETH.snap | 2 +- .../settler_uniswapV3VIP_DAI-WETH.snap | 2 +- .../settler_uniswapV3VIP_USDC-WETH.snap | 2 +- .../settler_uniswapV3VIP_USDT-WETH.snap | 2 +- .../settler_uniswapV3_DAI-WETH.snap | 2 +- .../settler_uniswapV3_USDC-WETH.snap | 2 +- .../settler_uniswapV3_USDT-WETH.snap | 2 +- ...V3_buyToken_fee_full_custody_DAI-WETH.snap | 2 +- ...3_buyToken_fee_full_custody_USDC-WETH.snap | 2 +- ...3_buyToken_fee_full_custody_USDT-WETH.snap | 2 +- ..._buyToken_fee_single_custody_DAI-WETH.snap | 2 +- ...buyToken_fee_single_custody_USDC-WETH.snap | 2 +- ...buyToken_fee_single_custody_USDT-WETH.snap | 2 +- ...settler_uniswapV3_multiplex2_DAI-WETH.snap | 2 +- ...ettler_uniswapV3_multiplex2_USDC-WETH.snap | 2 +- ...ettler_uniswapV3_multiplex2_USDT-WETH.snap | 2 +- ...3_sellToken_fee_full_custody_DAI-WETH.snap | 2 +- ..._sellToken_fee_full_custody_USDC-WETH.snap | 2 +- ..._sellToken_fee_full_custody_USDT-WETH.snap | 2 +- .../settler_velodrome_USDT-USDC.snap | 2 +- .../settler_zeroExOtc_DAI-WETH.snap | 2 +- .../settler_zeroExOtc_USDC-WETH.snap | 2 +- .../settler_zeroExOtc_USDT-WETH.snap | 2 +- ...ettler_zeroExOtc_partialFill_DAI-WETH.snap | 2 +- ...ttler_zeroExOtc_partialFill_USDC-WETH.snap | 2 +- ...ttler_zeroExOtc_partialFill_USDT-WETH.snap | 2 +- .forge-snapshots/wethDeposit.snap | 2 +- .forge-snapshots/wethWithdraw.snap | 2 +- README.md | 128 +++++++----------- src/allowanceholder/AllowanceHolder.sol | 5 +- src/allowanceholder/AllowanceHolderBase.sol | 7 + src/allowanceholder/AllowanceHolderOld.sol | 1 - test/integration/BasePairTest.t.sol | 5 +- test/integration/DeployAllowanceHolder.t.sol | 19 +++ test/integration/DodoV2PairTest.t.sol | 5 - test/integration/SettlerBasePairTest.t.sol | 14 +- test/integration/SettlerMetaTxnPairTest.t.sol | 1 - test/integration/UniV3CallbackPoC.t.sol | 15 +- test/integration/VelodromePairTest.t.sol | 5 - test/integration/WethWrapTest.t.sol | 1 - test/unit/AllowanceHolderUnitTest.t.sol | 2 +- 108 files changed, 193 insertions(+), 205 deletions(-) create mode 100644 test/integration/DeployAllowanceHolder.t.sol diff --git a/.forge-snapshots/allowanceHolder_balancerV3VIP_USDC-USDT.snap b/.forge-snapshots/allowanceHolder_balancerV3VIP_USDC-USDT.snap index c5bcf5509..9ab974f5f 100644 --- a/.forge-snapshots/allowanceHolder_balancerV3VIP_USDC-USDT.snap +++ b/.forge-snapshots/allowanceHolder_balancerV3VIP_USDC-USDT.snap @@ -1 +1 @@ -319009 \ No newline at end of file +319273 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap index 4f672858b..d8085367b 100644 --- a/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_DAI-WETH.snap @@ -1 +1 @@ -8655 \ No newline at end of file +8716 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_empty_USDC-USDT.snap b/.forge-snapshots/allowanceHolder_empty_USDC-USDT.snap index fd45b341c..86c8fbb2a 100644 --- a/.forge-snapshots/allowanceHolder_empty_USDC-USDT.snap +++ b/.forge-snapshots/allowanceHolder_empty_USDC-USDT.snap @@ -1 +1 @@ -30696 \ No newline at end of file +30716 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap index 4f672858b..d8085367b 100644 --- a/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_USDC-WETH.snap @@ -1 +1 @@ -8655 \ No newline at end of file +8716 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap index 4f672858b..d8085367b 100644 --- a/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_empty_USDT-WETH.snap @@ -1 +1 @@ -8655 \ No newline at end of file +8716 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap index 1df65133f..8611be4c1 100644 --- a/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_maverickV2_VIP_USDC-WETH.snap @@ -1 +1 @@ -123627 \ No newline at end of file +124077 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap index cf7665bac..4ad65978b 100644 --- a/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_DAI-WETH.snap @@ -1 +1 @@ -86997 \ No newline at end of file +87087 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDC-USDT.snap b/.forge-snapshots/allowanceHolder_rfq_USDC-USDT.snap index cc669e464..49a0efd70 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDC-USDT.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDC-USDT.snap @@ -1 +1 @@ -140080 \ No newline at end of file +140066 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap index c7eeaeb2f..7b1cd7b78 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDC-WETH.snap @@ -1 +1 @@ -106471 \ No newline at end of file +106561 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap index ce12e31a0..4428b8f9e 100644 --- a/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_USDT-WETH.snap @@ -1 +1 @@ -98109 \ No newline at end of file +98199 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap index bdd221435..4c8b19fe3 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_DAI-WETH.snap @@ -1 +1 @@ -126393 \ No newline at end of file +126131 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-USDT.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-USDT.snap index bb1f4ec4f..bb0b60c34 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-USDT.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-USDT.snap @@ -1 +1 @@ -187236 \ No newline at end of file +187222 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap index d7eea8b0e..2fec7a592 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDC-WETH.snap @@ -1 +1 @@ -153979 \ No newline at end of file +153717 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap index 8d3db45e3..ef87855a9 100644 --- a/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_rfq_proportionalFee_sellToken_USDT-WETH.snap @@ -1 +1 @@ -143137 \ No newline at end of file +142875 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap index 7f7a65a2f..f80306b3c 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_DAI-WETH.snap @@ -1 +1 @@ -104108 \ No newline at end of file +103872 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap index 4e426e3a2..13d86b750 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDC-WETH.snap @@ -1 +1 @@ -114206 \ No newline at end of file +113970 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap index b912ef0ba..c287b277b 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV2_single_chain_USDT-WETH.snap @@ -1 +1 @@ -105276 \ No newline at end of file +105040 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap index 1782aa2c2..7922276ed 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_DAI-WETH.snap @@ -1 +1 @@ -113123 \ No newline at end of file +113339 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap index 02f0571ce..a7c769368 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDC-WETH.snap @@ -1 +1 @@ -125689 \ No newline at end of file +125905 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap index 937cb699f..8a96d4782 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_USDT-WETH.snap @@ -1 +1 @@ -115939 \ No newline at end of file +116159 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap index 1782aa2c2..7922276ed 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_DAI-WETH.snap @@ -1 +1 @@ -113123 \ No newline at end of file +113339 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap index 02f0571ce..a7c769368 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDC-WETH.snap @@ -1 +1 @@ -125689 \ No newline at end of file +125905 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap index 937cb699f..8a96d4782 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3VIP_contract_USDT-WETH.snap @@ -1 +1 @@ -115939 \ No newline at end of file +116159 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap index 18c503ab0..a8642f896 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_DAI-WETH.snap @@ -1 +1 @@ -139678 \ No newline at end of file +139570 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap index 7f875a0b2..236f77a11 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_USDC-WETH.snap @@ -1 +1 @@ -156300 \ No newline at end of file +156192 \ No newline at end of file diff --git a/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap b/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap index a5ae3079e..bdd3d9738 100644 --- a/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap +++ b/.forge-snapshots/allowanceHolder_uniswapV3_USDT-WETH.snap @@ -1 +1 @@ -146351 \ No newline at end of file +146247 \ No newline at end of file diff --git a/.forge-snapshots/settler_balancerV3VIP_USDC-USDT.snap b/.forge-snapshots/settler_balancerV3VIP_USDC-USDT.snap index 7cc8a5afe..1b20e3f5d 100644 --- a/.forge-snapshots/settler_balancerV3VIP_USDC-USDT.snap +++ b/.forge-snapshots/settler_balancerV3VIP_USDC-USDT.snap @@ -1 +1 @@ -330239 \ No newline at end of file +330511 \ No newline at end of file diff --git a/.forge-snapshots/settler_balancerV3_USDC-USDT.snap b/.forge-snapshots/settler_balancerV3_USDC-USDT.snap index 66d1111d5..63a98a224 100644 --- a/.forge-snapshots/settler_balancerV3_USDC-USDT.snap +++ b/.forge-snapshots/settler_balancerV3_USDC-USDT.snap @@ -1 +1 @@ -360681 \ No newline at end of file +360934 \ No newline at end of file diff --git a/.forge-snapshots/settler_basic_curve_USDT-WETH.snap b/.forge-snapshots/settler_basic_curve_USDT-WETH.snap index 66f3e8383..fc50f320b 100644 --- a/.forge-snapshots/settler_basic_curve_USDT-WETH.snap +++ b/.forge-snapshots/settler_basic_curve_USDT-WETH.snap @@ -1 +1 @@ -422029 \ No newline at end of file +422023 \ No newline at end of file diff --git a/.forge-snapshots/settler_curveTricrypto_USDC-WETH.snap b/.forge-snapshots/settler_curveTricrypto_USDC-WETH.snap index bca353886..ed2d83703 100644 --- a/.forge-snapshots/settler_curveTricrypto_USDC-WETH.snap +++ b/.forge-snapshots/settler_curveTricrypto_USDC-WETH.snap @@ -1 +1 @@ -231504 \ No newline at end of file +231583 \ No newline at end of file diff --git a/.forge-snapshots/settler_curveTricrypto_USDT-WETH.snap b/.forge-snapshots/settler_curveTricrypto_USDT-WETH.snap index b90ca1d84..f19759120 100644 --- a/.forge-snapshots/settler_curveTricrypto_USDT-WETH.snap +++ b/.forge-snapshots/settler_curveTricrypto_USDT-WETH.snap @@ -1 +1 @@ -243871 \ No newline at end of file +243950 \ No newline at end of file diff --git a/.forge-snapshots/settler_curveV2_fee_USDT-WETH.snap b/.forge-snapshots/settler_curveV2_fee_USDT-WETH.snap index 19da19dc1..5b1bfaf45 100644 --- a/.forge-snapshots/settler_curveV2_fee_USDT-WETH.snap +++ b/.forge-snapshots/settler_curveV2_fee_USDT-WETH.snap @@ -1 +1 @@ -433165 \ No newline at end of file +433159 \ No newline at end of file diff --git a/.forge-snapshots/settler_dodoV1_USDC-WETH.snap b/.forge-snapshots/settler_dodoV1_USDC-WETH.snap index 579c977fa..39c9ef9f3 100644 --- a/.forge-snapshots/settler_dodoV1_USDC-WETH.snap +++ b/.forge-snapshots/settler_dodoV1_USDC-WETH.snap @@ -1 +1 @@ -308077 \ No newline at end of file +304507 \ No newline at end of file diff --git a/.forge-snapshots/settler_dodov2_USDT-DAI.snap b/.forge-snapshots/settler_dodov2_USDT-DAI.snap index 99e939217..d2a4584b7 100644 --- a/.forge-snapshots/settler_dodov2_USDT-DAI.snap +++ b/.forge-snapshots/settler_dodov2_USDT-DAI.snap @@ -1 +1 @@ -217229 \ No newline at end of file +217223 \ No newline at end of file diff --git a/.forge-snapshots/settler_dodov2_custody_USDT-DAI.snap b/.forge-snapshots/settler_dodov2_custody_USDT-DAI.snap index d61f1a364..cf2b712b7 100644 --- a/.forge-snapshots/settler_dodov2_custody_USDT-DAI.snap +++ b/.forge-snapshots/settler_dodov2_custody_USDT-DAI.snap @@ -1 +1 @@ -186907 \ No newline at end of file +186901 \ No newline at end of file diff --git a/.forge-snapshots/settler_externalMoveExecute_uniswapV3_DAI-WETH.snap b/.forge-snapshots/settler_externalMoveExecute_uniswapV3_DAI-WETH.snap index dc7b62c66..47281a79d 100644 --- a/.forge-snapshots/settler_externalMoveExecute_uniswapV3_DAI-WETH.snap +++ b/.forge-snapshots/settler_externalMoveExecute_uniswapV3_DAI-WETH.snap @@ -1 +1 @@ -129292 \ No newline at end of file +129373 \ No newline at end of file diff --git a/.forge-snapshots/settler_externalMoveExecute_uniswapV3_USDC-WETH.snap b/.forge-snapshots/settler_externalMoveExecute_uniswapV3_USDC-WETH.snap index 6c1b3296d..b753d9bb6 100644 --- a/.forge-snapshots/settler_externalMoveExecute_uniswapV3_USDC-WETH.snap +++ b/.forge-snapshots/settler_externalMoveExecute_uniswapV3_USDC-WETH.snap @@ -1 +1 @@ -140283 \ No newline at end of file +140364 \ No newline at end of file diff --git a/.forge-snapshots/settler_externalMoveExecute_uniswapV3_USDT-WETH.snap b/.forge-snapshots/settler_externalMoveExecute_uniswapV3_USDT-WETH.snap index 0d4e9afd3..578171111 100644 --- a/.forge-snapshots/settler_externalMoveExecute_uniswapV3_USDT-WETH.snap +++ b/.forge-snapshots/settler_externalMoveExecute_uniswapV3_USDT-WETH.snap @@ -1 +1 @@ -136280 \ No newline at end of file +136365 \ No newline at end of file diff --git a/.forge-snapshots/settler_makerPsmLite_buyGem_DAI-USDC.snap b/.forge-snapshots/settler_makerPsmLite_buyGem_DAI-USDC.snap index f901469c0..78bcd1e53 100644 --- a/.forge-snapshots/settler_makerPsmLite_buyGem_DAI-USDC.snap +++ b/.forge-snapshots/settler_makerPsmLite_buyGem_DAI-USDC.snap @@ -1 +1 @@ -171147 \ No newline at end of file +170753 \ No newline at end of file diff --git a/.forge-snapshots/settler_makerPsmLite_sellGem_USDC-DAI.snap b/.forge-snapshots/settler_makerPsmLite_sellGem_USDC-DAI.snap index 8604b6c4f..3e8ea6714 100644 --- a/.forge-snapshots/settler_makerPsmLite_sellGem_USDC-DAI.snap +++ b/.forge-snapshots/settler_makerPsmLite_sellGem_USDC-DAI.snap @@ -1 +1 @@ -177757 \ No newline at end of file +177341 \ No newline at end of file diff --git a/.forge-snapshots/settler_maverickV2_USDC-WETH.snap b/.forge-snapshots/settler_maverickV2_USDC-WETH.snap index e08153cae..91ca78a2a 100644 --- a/.forge-snapshots/settler_maverickV2_USDC-WETH.snap +++ b/.forge-snapshots/settler_maverickV2_USDC-WETH.snap @@ -1 +1 @@ -163488 \ No newline at end of file +163482 \ No newline at end of file diff --git a/.forge-snapshots/settler_maverickV2_VIP_USDC-WETH.snap b/.forge-snapshots/settler_maverickV2_VIP_USDC-WETH.snap index 126b04fb9..429ef8b0a 100644 --- a/.forge-snapshots/settler_maverickV2_VIP_USDC-WETH.snap +++ b/.forge-snapshots/settler_maverickV2_VIP_USDC-WETH.snap @@ -1 +1 @@ -135049 \ No newline at end of file +135363 \ No newline at end of file diff --git a/.forge-snapshots/settler_metaTxn_balancerV3_USDC-USDT.snap b/.forge-snapshots/settler_metaTxn_balancerV3_USDC-USDT.snap index 69315d51a..6c6f0d12a 100644 --- a/.forge-snapshots/settler_metaTxn_balancerV3_USDC-USDT.snap +++ b/.forge-snapshots/settler_metaTxn_balancerV3_USDC-USDT.snap @@ -1 +1 @@ -333632 \ No newline at end of file +333614 \ No newline at end of file diff --git a/.forge-snapshots/settler_metaTxn_maverickV2_USDC-WETH.snap b/.forge-snapshots/settler_metaTxn_maverickV2_USDC-WETH.snap index cc90c4f74..e88959348 100644 --- a/.forge-snapshots/settler_metaTxn_maverickV2_USDC-WETH.snap +++ b/.forge-snapshots/settler_metaTxn_maverickV2_USDC-WETH.snap @@ -1 +1 @@ -138406 \ No newline at end of file +138394 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_DAI-USDC.snap b/.forge-snapshots/settler_rfq_DAI-USDC.snap index 223a45b97..1083b7787 100644 --- a/.forge-snapshots/settler_rfq_DAI-USDC.snap +++ b/.forge-snapshots/settler_rfq_DAI-USDC.snap @@ -1 +1 @@ -171011 \ No newline at end of file +171005 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_DAI-WETH.snap b/.forge-snapshots/settler_rfq_DAI-WETH.snap index b0131d2e3..2d5f5d1a2 100644 --- a/.forge-snapshots/settler_rfq_DAI-WETH.snap +++ b/.forge-snapshots/settler_rfq_DAI-WETH.snap @@ -1 +1 @@ -94944 \ No newline at end of file +94938 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_USDC-DAI.snap b/.forge-snapshots/settler_rfq_USDC-DAI.snap index 223a45b97..1083b7787 100644 --- a/.forge-snapshots/settler_rfq_USDC-DAI.snap +++ b/.forge-snapshots/settler_rfq_USDC-DAI.snap @@ -1 +1 @@ -171011 \ No newline at end of file +171005 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_USDC-USDT.snap b/.forge-snapshots/settler_rfq_USDC-USDT.snap index 1f33adf38..ddc33a222 100644 --- a/.forge-snapshots/settler_rfq_USDC-USDT.snap +++ b/.forge-snapshots/settler_rfq_USDC-USDT.snap @@ -1 +1 @@ -147923 \ No newline at end of file +147917 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_USDC-WETH.snap b/.forge-snapshots/settler_rfq_USDC-WETH.snap index b713024ba..52041caac 100644 --- a/.forge-snapshots/settler_rfq_USDC-WETH.snap +++ b/.forge-snapshots/settler_rfq_USDC-WETH.snap @@ -1 +1 @@ -114418 \ No newline at end of file +114412 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_USDT-WETH.snap b/.forge-snapshots/settler_rfq_USDT-WETH.snap index 547891d33..8f96ba576 100644 --- a/.forge-snapshots/settler_rfq_USDT-WETH.snap +++ b/.forge-snapshots/settler_rfq_USDT-WETH.snap @@ -1 +1 @@ -106056 \ No newline at end of file +106050 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_fee_full_custody_DAI-USDC.snap b/.forge-snapshots/settler_rfq_fee_full_custody_DAI-USDC.snap index 8f85ba0a5..230bee0fd 100644 --- a/.forge-snapshots/settler_rfq_fee_full_custody_DAI-USDC.snap +++ b/.forge-snapshots/settler_rfq_fee_full_custody_DAI-USDC.snap @@ -1 +1 @@ -244497 \ No newline at end of file +244491 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_fee_full_custody_DAI-WETH.snap b/.forge-snapshots/settler_rfq_fee_full_custody_DAI-WETH.snap index 076c4eb2e..1d13d4211 100644 --- a/.forge-snapshots/settler_rfq_fee_full_custody_DAI-WETH.snap +++ b/.forge-snapshots/settler_rfq_fee_full_custody_DAI-WETH.snap @@ -1 +1 @@ -159741 \ No newline at end of file +159735 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_fee_full_custody_USDC-DAI.snap b/.forge-snapshots/settler_rfq_fee_full_custody_USDC-DAI.snap index 83365f1c7..9fd79e1c7 100644 --- a/.forge-snapshots/settler_rfq_fee_full_custody_USDC-DAI.snap +++ b/.forge-snapshots/settler_rfq_fee_full_custody_USDC-DAI.snap @@ -1 +1 @@ -240441 \ No newline at end of file +240435 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_fee_full_custody_USDC-USDT.snap b/.forge-snapshots/settler_rfq_fee_full_custody_USDC-USDT.snap index 2e9c019dc..26eac79c9 100644 --- a/.forge-snapshots/settler_rfq_fee_full_custody_USDC-USDT.snap +++ b/.forge-snapshots/settler_rfq_fee_full_custody_USDC-USDT.snap @@ -1 +1 @@ -222968 \ No newline at end of file +222962 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_fee_full_custody_USDC-WETH.snap b/.forge-snapshots/settler_rfq_fee_full_custody_USDC-WETH.snap index b20d33864..e03367ceb 100644 --- a/.forge-snapshots/settler_rfq_fee_full_custody_USDC-WETH.snap +++ b/.forge-snapshots/settler_rfq_fee_full_custody_USDC-WETH.snap @@ -1 +1 @@ -183271 \ No newline at end of file +183265 \ No newline at end of file diff --git a/.forge-snapshots/settler_rfq_fee_full_custody_USDT-WETH.snap b/.forge-snapshots/settler_rfq_fee_full_custody_USDT-WETH.snap index 821560f0f..4f973d58c 100644 --- a/.forge-snapshots/settler_rfq_fee_full_custody_USDT-WETH.snap +++ b/.forge-snapshots/settler_rfq_fee_full_custody_USDT-WETH.snap @@ -1 +1 @@ -174709 \ No newline at end of file +174703 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_DAI-WETH.snap b/.forge-snapshots/settler_uniswapV2_DAI-WETH.snap index 044ff3387..63a0a75cf 100644 --- a/.forge-snapshots/settler_uniswapV2_DAI-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_DAI-WETH.snap @@ -1 +1 @@ -139753 \ No newline at end of file +139747 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_USDC-WETH.snap b/.forge-snapshots/settler_uniswapV2_USDC-WETH.snap index b0c7e21a8..2f3c1bba6 100644 --- a/.forge-snapshots/settler_uniswapV2_USDC-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_USDC-WETH.snap @@ -1 +1 @@ -153194 \ No newline at end of file +153188 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_USDT-WETH.snap b/.forge-snapshots/settler_uniswapV2_USDT-WETH.snap index ceba2eec6..ef22cdd39 100644 --- a/.forge-snapshots/settler_uniswapV2_USDT-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_USDT-WETH.snap @@ -1 +1 @@ -144348 \ No newline at end of file +144342 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_multihop_DAI-WETH.snap b/.forge-snapshots/settler_uniswapV2_multihop_DAI-WETH.snap index df8fffd0b..04f2bac2d 100644 --- a/.forge-snapshots/settler_uniswapV2_multihop_DAI-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_multihop_DAI-WETH.snap @@ -1 +1 @@ -198168 \ No newline at end of file +198162 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_multihop_USDC-WETH.snap b/.forge-snapshots/settler_uniswapV2_multihop_USDC-WETH.snap index 905a70b0c..bb5ca5f2a 100644 --- a/.forge-snapshots/settler_uniswapV2_multihop_USDC-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_multihop_USDC-WETH.snap @@ -1 +1 @@ -211609 \ No newline at end of file +211603 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_multihop_USDT-WETH.snap b/.forge-snapshots/settler_uniswapV2_multihop_USDT-WETH.snap index 312af387f..35c178c53 100644 --- a/.forge-snapshots/settler_uniswapV2_multihop_USDT-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_multihop_USDT-WETH.snap @@ -1 +1 @@ -202763 \ No newline at end of file +202757 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_multihop_single_chain_DAI-WETH.snap b/.forge-snapshots/settler_uniswapV2_multihop_single_chain_DAI-WETH.snap index 41555d232..556647369 100644 --- a/.forge-snapshots/settler_uniswapV2_multihop_single_chain_DAI-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_multihop_single_chain_DAI-WETH.snap @@ -1 +1 @@ -172576 \ No newline at end of file +172561 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_multihop_single_chain_USDC-WETH.snap b/.forge-snapshots/settler_uniswapV2_multihop_single_chain_USDC-WETH.snap index 015f6dcec..5f91a52af 100644 --- a/.forge-snapshots/settler_uniswapV2_multihop_single_chain_USDC-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_multihop_single_chain_USDC-WETH.snap @@ -1 +1 @@ -182674 \ No newline at end of file +182659 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_multihop_single_chain_USDT-WETH.snap b/.forge-snapshots/settler_uniswapV2_multihop_single_chain_USDT-WETH.snap index 4a6576ed7..9095a866d 100644 --- a/.forge-snapshots/settler_uniswapV2_multihop_single_chain_USDT-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_multihop_single_chain_USDT-WETH.snap @@ -1 +1 @@ -173744 \ No newline at end of file +173729 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_single_chain_DAI-WETH.snap b/.forge-snapshots/settler_uniswapV2_single_chain_DAI-WETH.snap index a89d0e1a1..8adf11095 100644 --- a/.forge-snapshots/settler_uniswapV2_single_chain_DAI-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_single_chain_DAI-WETH.snap @@ -1 +1 @@ -114152 \ No newline at end of file +114146 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_single_chain_USDC-WETH.snap b/.forge-snapshots/settler_uniswapV2_single_chain_USDC-WETH.snap index 261cc1117..0cb529921 100644 --- a/.forge-snapshots/settler_uniswapV2_single_chain_USDC-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_single_chain_USDC-WETH.snap @@ -1 +1 @@ -124250 \ No newline at end of file +124244 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV2_single_chain_USDT-WETH.snap b/.forge-snapshots/settler_uniswapV2_single_chain_USDT-WETH.snap index 0717f25c7..f4db78537 100644 --- a/.forge-snapshots/settler_uniswapV2_single_chain_USDT-WETH.snap +++ b/.forge-snapshots/settler_uniswapV2_single_chain_USDT-WETH.snap @@ -1 +1 @@ -115320 \ No newline at end of file +115314 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3VIP_DAI-WETH.snap b/.forge-snapshots/settler_uniswapV3VIP_DAI-WETH.snap index 5bd30b172..0fa748172 100644 --- a/.forge-snapshots/settler_uniswapV3VIP_DAI-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3VIP_DAI-WETH.snap @@ -1 +1 @@ -123758 \ No newline at end of file +123839 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3VIP_USDC-WETH.snap b/.forge-snapshots/settler_uniswapV3VIP_USDC-WETH.snap index 272f14740..52163de67 100644 --- a/.forge-snapshots/settler_uniswapV3VIP_USDC-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3VIP_USDC-WETH.snap @@ -1 +1 @@ -136324 \ No newline at end of file +136405 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3VIP_USDT-WETH.snap b/.forge-snapshots/settler_uniswapV3VIP_USDT-WETH.snap index 532cac299..ac41bb4cc 100644 --- a/.forge-snapshots/settler_uniswapV3VIP_USDT-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3VIP_USDT-WETH.snap @@ -1 +1 @@ -126574 \ No newline at end of file +126659 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_DAI-WETH.snap b/.forge-snapshots/settler_uniswapV3_DAI-WETH.snap index 82470d8b4..752324329 100644 --- a/.forge-snapshots/settler_uniswapV3_DAI-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_DAI-WETH.snap @@ -1 +1 @@ -149840 \ No newline at end of file +149921 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_USDC-WETH.snap b/.forge-snapshots/settler_uniswapV3_USDC-WETH.snap index ce7d239e6..e4a5be0d5 100644 --- a/.forge-snapshots/settler_uniswapV3_USDC-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_USDC-WETH.snap @@ -1 +1 @@ -166462 \ No newline at end of file +166543 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_USDT-WETH.snap b/.forge-snapshots/settler_uniswapV3_USDT-WETH.snap index f32d505b4..ad5caf27f 100644 --- a/.forge-snapshots/settler_uniswapV3_USDT-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_USDT-WETH.snap @@ -1 +1 @@ -156513 \ No newline at end of file +156598 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_DAI-WETH.snap b/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_DAI-WETH.snap index 82d3df2d1..618cdb0ed 100644 --- a/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_DAI-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_DAI-WETH.snap @@ -1 +1 @@ -187280 \ No newline at end of file +187361 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_USDC-WETH.snap b/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_USDC-WETH.snap index acb01cb59..deb8244d6 100644 --- a/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_USDC-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_USDC-WETH.snap @@ -1 +1 @@ -203902 \ No newline at end of file +203983 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_USDT-WETH.snap b/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_USDT-WETH.snap index 4b9675c19..9dc3dbc7c 100644 --- a/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_USDT-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_buyToken_fee_full_custody_USDT-WETH.snap @@ -1 +1 @@ -193953 \ No newline at end of file +194038 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_DAI-WETH.snap b/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_DAI-WETH.snap index a25cb3fa3..652022272 100644 --- a/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_DAI-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_DAI-WETH.snap @@ -1 +1 @@ -161196 \ No newline at end of file +161277 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_USDC-WETH.snap b/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_USDC-WETH.snap index b5f438392..6b54550e4 100644 --- a/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_USDC-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_USDC-WETH.snap @@ -1 +1 @@ -173762 \ No newline at end of file +173843 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_USDT-WETH.snap b/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_USDT-WETH.snap index a11dc8ded..7240c927c 100644 --- a/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_USDT-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_buyToken_fee_single_custody_USDT-WETH.snap @@ -1 +1 @@ -164012 \ No newline at end of file +164097 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_multiplex2_DAI-WETH.snap b/.forge-snapshots/settler_uniswapV3_multiplex2_DAI-WETH.snap index 1c63aa3db..3dd2bafd8 100644 --- a/.forge-snapshots/settler_uniswapV3_multiplex2_DAI-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_multiplex2_DAI-WETH.snap @@ -1 +1 @@ -182582 \ No newline at end of file +182750 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_multiplex2_USDC-WETH.snap b/.forge-snapshots/settler_uniswapV3_multiplex2_USDC-WETH.snap index 07f581a75..c726ec538 100644 --- a/.forge-snapshots/settler_uniswapV3_multiplex2_USDC-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_multiplex2_USDC-WETH.snap @@ -1 +1 @@ -203034 \ No newline at end of file +203202 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_multiplex2_USDT-WETH.snap b/.forge-snapshots/settler_uniswapV3_multiplex2_USDT-WETH.snap index d38659fda..b2d2ba926 100644 --- a/.forge-snapshots/settler_uniswapV3_multiplex2_USDT-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_multiplex2_USDT-WETH.snap @@ -1 +1 @@ -191498 \ No newline at end of file +191674 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_DAI-WETH.snap b/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_DAI-WETH.snap index 63697e49f..d09e84921 100644 --- a/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_DAI-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_DAI-WETH.snap @@ -1 +1 @@ -161269 \ No newline at end of file +161350 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_USDC-WETH.snap b/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_USDC-WETH.snap index 52439d3eb..6117d0853 100644 --- a/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_USDC-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_USDC-WETH.snap @@ -1 +1 @@ -181947 \ No newline at end of file +182028 \ No newline at end of file diff --git a/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_USDT-WETH.snap b/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_USDT-WETH.snap index 826e92808..626468d7d 100644 --- a/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_USDT-WETH.snap +++ b/.forge-snapshots/settler_uniswapV3_sellToken_fee_full_custody_USDT-WETH.snap @@ -1 +1 @@ -169718 \ No newline at end of file +169803 \ No newline at end of file diff --git a/.forge-snapshots/settler_velodrome_USDT-USDC.snap b/.forge-snapshots/settler_velodrome_USDT-USDC.snap index ca9b80aba..4bfc86d3d 100644 --- a/.forge-snapshots/settler_velodrome_USDT-USDC.snap +++ b/.forge-snapshots/settler_velodrome_USDT-USDC.snap @@ -1 +1 @@ -308000 \ No newline at end of file +307992 \ No newline at end of file diff --git a/.forge-snapshots/settler_zeroExOtc_DAI-WETH.snap b/.forge-snapshots/settler_zeroExOtc_DAI-WETH.snap index d20f1db8e..b6b887fb0 100644 --- a/.forge-snapshots/settler_zeroExOtc_DAI-WETH.snap +++ b/.forge-snapshots/settler_zeroExOtc_DAI-WETH.snap @@ -1 +1 @@ -175928 \ No newline at end of file +175922 \ No newline at end of file diff --git a/.forge-snapshots/settler_zeroExOtc_USDC-WETH.snap b/.forge-snapshots/settler_zeroExOtc_USDC-WETH.snap index 8f626f78e..8494f0c18 100644 --- a/.forge-snapshots/settler_zeroExOtc_USDC-WETH.snap +++ b/.forge-snapshots/settler_zeroExOtc_USDC-WETH.snap @@ -1 +1 @@ -205838 \ No newline at end of file +205832 \ No newline at end of file diff --git a/.forge-snapshots/settler_zeroExOtc_USDT-WETH.snap b/.forge-snapshots/settler_zeroExOtc_USDT-WETH.snap index 0d2bcc5ed..c8292b1d1 100644 --- a/.forge-snapshots/settler_zeroExOtc_USDT-WETH.snap +++ b/.forge-snapshots/settler_zeroExOtc_USDT-WETH.snap @@ -1 +1 @@ -191260 \ No newline at end of file +191254 \ No newline at end of file diff --git a/.forge-snapshots/settler_zeroExOtc_partialFill_DAI-WETH.snap b/.forge-snapshots/settler_zeroExOtc_partialFill_DAI-WETH.snap index 82b89bb60..ba071bcbf 100644 --- a/.forge-snapshots/settler_zeroExOtc_partialFill_DAI-WETH.snap +++ b/.forge-snapshots/settler_zeroExOtc_partialFill_DAI-WETH.snap @@ -1 +1 @@ -182926 \ No newline at end of file +182920 \ No newline at end of file diff --git a/.forge-snapshots/settler_zeroExOtc_partialFill_USDC-WETH.snap b/.forge-snapshots/settler_zeroExOtc_partialFill_USDC-WETH.snap index d72bd21f8..bce51dac5 100644 --- a/.forge-snapshots/settler_zeroExOtc_partialFill_USDC-WETH.snap +++ b/.forge-snapshots/settler_zeroExOtc_partialFill_USDC-WETH.snap @@ -1 +1 @@ -214892 \ No newline at end of file +214886 \ No newline at end of file diff --git a/.forge-snapshots/settler_zeroExOtc_partialFill_USDT-WETH.snap b/.forge-snapshots/settler_zeroExOtc_partialFill_USDT-WETH.snap index 3e6fd6415..1cead6243 100644 --- a/.forge-snapshots/settler_zeroExOtc_partialFill_USDT-WETH.snap +++ b/.forge-snapshots/settler_zeroExOtc_partialFill_USDT-WETH.snap @@ -1 +1 @@ -200034 \ No newline at end of file +200028 \ No newline at end of file diff --git a/.forge-snapshots/wethDeposit.snap b/.forge-snapshots/wethDeposit.snap index 5fdba67f8..900b9b05c 100644 --- a/.forge-snapshots/wethDeposit.snap +++ b/.forge-snapshots/wethDeposit.snap @@ -1 +1 @@ -85252 \ No newline at end of file +85246 \ No newline at end of file diff --git a/.forge-snapshots/wethWithdraw.snap b/.forge-snapshots/wethWithdraw.snap index f5f89866d..dd839db21 100644 --- a/.forge-snapshots/wethWithdraw.snap +++ b/.forge-snapshots/wethWithdraw.snap @@ -1 +1 @@ -45970 \ No newline at end of file +45954 \ No newline at end of file diff --git a/README.md b/README.md index 3bbfc2f19..56f3d4a86 100644 --- a/README.md +++ b/README.md @@ -569,36 +569,36 @@ comparison. | ------------------- | ---------- | --------- | ------ | ------ | | 0x V4 VIP | Uniswap V3 | USDC/WETH | 124669 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | USDC/WETH | 138525 | 11.11% | -| Settler VIP (warm) | Uniswap V3 | USDC/WETH | 136229 | 9.27% | -| AllowanceHolder VIP | Uniswap V3 | USDC/WETH | 125689 | 0.82% | +| Settler VIP (warm) | Uniswap V3 | USDC/WETH | 136405 | 9.41% | +| AllowanceHolder VIP | Uniswap V3 | USDC/WETH | 125905 | 0.99% | | UniswapRouter V3 | Uniswap V3 | USDC/WETH | 120978 | -2.96% | | | | | | | | 0x V4 VIP | Uniswap V3 | DAI/WETH | 112103 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | DAI/WETH | 125959 | 12.36% | -| Settler VIP (warm) | Uniswap V3 | DAI/WETH | 123663 | 10.31% | -| AllowanceHolder VIP | Uniswap V3 | DAI/WETH | 113123 | 0.91% | +| Settler VIP (warm) | Uniswap V3 | DAI/WETH | 123839 | 10.47% | +| AllowanceHolder VIP | Uniswap V3 | DAI/WETH | 113339 | 1.10% | | UniswapRouter V3 | Uniswap V3 | DAI/WETH | 108412 | -3.29% | | | | | | | | 0x V4 VIP | Uniswap V3 | USDT/WETH | 114910 | 0.00% | | 0x V4 Multiplex | Uniswap V3 | USDT/WETH | 128766 | 12.06% | -| Settler VIP (warm) | Uniswap V3 | USDT/WETH | 126479 | 10.07% | -| AllowanceHolder VIP | Uniswap V3 | USDT/WETH | 115939 | 0.90% | +| Settler VIP (warm) | Uniswap V3 | USDT/WETH | 126659 | 10.22% | +| AllowanceHolder VIP | Uniswap V3 | USDT/WETH | 116159 | 1.09% | | UniswapRouter V3 | Uniswap V3 | USDT/WETH | 111091 | -3.32% | | | | | | | | Custody | DEX | Pair | Gas | % | | -------------------- | ---------- | --------- | ------ | ------- | | 0x V4 TransformERC20 | Uniswap V3 | USDC/WETH | 244603 | 0.00% | -| Settler | Uniswap V3 | USDC/WETH | 166693 | -31.85% | -| AllowanceHolder | Uniswap V3 | USDC/WETH | 156300 | -36.10% | +| Settler | Uniswap V3 | USDC/WETH | 166543 | -31.91% | +| AllowanceHolder | Uniswap V3 | USDC/WETH | 156192 | -36.14% | | | | | | | | 0x V4 TransformERC20 | Uniswap V3 | DAI/WETH | 221601 | 0.00% | -| Settler | Uniswap V3 | DAI/WETH | 150071 | -32.28% | -| AllowanceHolder | Uniswap V3 | DAI/WETH | 139678 | -36.97% | +| Settler | Uniswap V3 | DAI/WETH | 149921 | -32.35% | +| AllowanceHolder | Uniswap V3 | DAI/WETH | 139570 | -37.02% | | | | | | | | 0x V4 TransformERC20 | Uniswap V3 | USDT/WETH | 228500 | 0.00% | -| Settler | Uniswap V3 | USDT/WETH | 156744 | -31.40% | -| AllowanceHolder | Uniswap V3 | USDT/WETH | 146351 | -35.95% | +| Settler | Uniswap V3 | USDT/WETH | 156598 | -31.47% | +| AllowanceHolder | Uniswap V3 | USDT/WETH | 146247 | -36.00% | | | | | | | | MetaTransactions | DEX | Pair | Gas | % | @@ -616,115 +616,87 @@ comparison. | RFQ | DEX | Pair | Gas | % | | --------------- | ------- | --------- | ------ | ------- | | 0x V4 | 0x V4 | USDC/WETH | 97972 | 0.00% | -| Settler | Settler | USDC/WETH | 114362 | 16.73% | -| Settler | 0x V4 | USDC/WETH | 206164 | 110.43% | -| AllowanceHolder | Settler | USDC/WETH | 106471 | 8.67% | +| Settler | Settler | USDC/WETH | 114412 | 16.78% | +| Settler | 0x V4 | USDC/WETH | 205832 | 110.09% | +| AllowanceHolder | Settler | USDC/WETH | 106561 | 8.77% | | | | | | | | 0x V4 | 0x V4 | DAI/WETH | 78498 | 0.00% | -| Settler | Settler | DAI/WETH | 94888 | 20.88% | -| Settler | 0x V4 | DAI/WETH | 176254 | 124.53% | -| AllowanceHolder | Settler | DAI/WETH | 86997 | 10.83% | +| Settler | Settler | DAI/WETH | 94938 | 20.94% | +| Settler | 0x V4 | DAI/WETH | 175922 | 124.11% | +| AllowanceHolder | Settler | DAI/WETH | 87087 | 10.94% | | | | | | | | 0x V4 | 0x V4 | USDT/WETH | 89610 | 0.00% | -| Settler | Settler | USDT/WETH | 106000 | 18.29% | -| Settler | 0x V4 | USDT/WETH | 191586 | 113.80% | -| AllowanceHolder | Settler | USDT/WETH | 98109 | 9.48% | +| Settler | Settler | USDT/WETH | 106050 | 18.35% | +| Settler | 0x V4 | USDT/WETH | 191254 | 113.43% | +| AllowanceHolder | Settler | USDT/WETH | 98199 | 9.58% | | | | | | | | Curve | DEX | Pair | Gas | % | | ----------------- | --------------------- | --------- | ------ | ------- | -| Settler | CurveV2 Tricrypto VIP | USDC/WETH | 231504 | NaN% | +| Settler | CurveV2 Tricrypto VIP | USDC/WETH | 231583 | NaN% | | | | | | | | | | | | | | 0x V4 | Curve | USDT/WETH | 452672 | 0.00% | -| Settler | Curve | USDT/WETH | 422029 | -6.77% | -| Settler | CurveV2 Tricrypto VIP | USDT/WETH | 243871 | -46.13% | +| Settler | Curve | USDT/WETH | 422023 | -6.77% | +| Settler | CurveV2 Tricrypto VIP | USDT/WETH | 243950 | -46.11% | | Curve | Curve | USDT/WETH | 341799 | -24.49% | | Curve Swap Router | Curve | USDT/WETH | 412038 | -8.98% | | | | | | | | DODO V1 | DEX | Pair | Gas | % | | ------- | ------- | --------- | ------ | ----- | -| Settler | DODO V1 | USDC/WETH | 308077 | 0.00% | +| Settler | DODO V1 | USDC/WETH | 304507 | 0.00% | | | | | | | | | | | | | | | | | | | | Buy token fee | DEX | Pair | Gas | % | | ----------------- | ---------- | --------- | ------ | ----- | -| Settler - custody | Uniswap V3 | USDC/WETH | 173762 | 0.00% | +| Settler - custody | Uniswap V3 | USDC/WETH | 173843 | 0.00% | | | | | | | -| Settler - custody | Uniswap V3 | DAI/WETH | 161196 | 0.00% | +| Settler - custody | Uniswap V3 | DAI/WETH | 161277 | 0.00% | | | | | | | -| Settler - custody | Uniswap V3 | USDT/WETH | 164012 | 0.00% | +| Settler - custody | Uniswap V3 | USDT/WETH | 164097 | 0.00% | | | | | | | | Sell token fee | DEX | Pair | Gas | % | | -------------- | ---------- | --------- | ------ | ------- | -| Settler | Uniswap V3 | USDC/WETH | 181947 | 0.00% | +| Settler | Uniswap V3 | USDC/WETH | 182028 | 0.00% | | | | | | | -| Settler | Uniswap V3 | DAI/WETH | 161269 | 0.00% | +| Settler | Uniswap V3 | DAI/WETH | 161350 | 0.00% | | | | | | | -| Settler | Uniswap V3 | USDT/WETH | 169718 | 0.00% | -| Settler | Curve | USDT/WETH | 433165 | 155.23% | +| Settler | Uniswap V3 | USDT/WETH | 169803 | 0.00% | +| Settler | Curve | USDT/WETH | 433159 | 155.10% | | | | | | | | AllowanceHolder | DEX | Pair | Gas | % | | ------------------------------------ | -------------- | --------- | ------ | ------- | -<<<<<<< HEAD -| execute | Uniswap V3 VIP | USDC/WETH | 125689 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140191 | 11.54% | -| execute | RFQ | USDC/WETH | 106471 | -15.29% | +| execute | Uniswap V3 VIP | USDC/WETH | 125905 | 0.00% | +| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140364 | 11.48% | +| execute | RFQ | USDC/WETH | 106561 | -15.36% | | | | | | | -| execute | Uniswap V3 VIP | DAI/WETH | 113123 | 0.00% | -| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129200 | 14.21% | -| execute | RFQ | DAI/WETH | 86997 | -23.10% | +| execute | Uniswap V3 VIP | DAI/WETH | 113339 | 0.00% | +| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129373 | 14.15% | +| execute | RFQ | DAI/WETH | 87087 | -23.16% | | | | | | | -| execute | Uniswap V3 VIP | USDT/WETH | 115939 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136188 | 17.47% | -| execute | RFQ | USDT/WETH | 98109 | -15.38% | -======= -| execute | Uniswap V3 VIP | USDC/WETH | 125832 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDC/WETH | 140283 | 11.48% | -| execute | RFQ | USDC/WETH | 106575 | -15.30% | -| | | | | | -| execute | Uniswap V3 VIP | DAI/WETH | 113266 | 0.00% | -| Settler - external move then execute | Uniswap V3 | DAI/WETH | 129292 | 14.15% | -| execute | RFQ | DAI/WETH | 87101 | -23.10% | -| | | | | | -| execute | Uniswap V3 VIP | USDT/WETH | 116082 | 0.00% | -| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136280 | 17.40% | -| execute | RFQ | USDT/WETH | 98213 | -15.39% | ->>>>>>> master +| execute | Uniswap V3 VIP | USDT/WETH | 116159 | 0.00% | +| Settler - external move then execute | Uniswap V3 | USDT/WETH | 136365 | 17.40% | +| execute | RFQ | USDT/WETH | 98199 | -15.46% | | | | | | | | AllowanceHolder sell token fees | DEX | Pair | Gas | % | | ------------------------------- | --- | --------- | ------ | ------ | -<<<<<<< HEAD -| no fee | RFQ | USDC/WETH | 106471 | 0.00% | -| proportional fee | RFQ | USDC/WETH | 153979 | 44.62% | -| fixed fee | RFQ | USDC/WETH | 122703 | 15.25% | -| | | | | | -| no fee | RFQ | DAI/WETH | 86997 | 0.00% | -| proportional fee | RFQ | DAI/WETH | 126393 | 45.28% | -| fixed fee | RFQ | DAI/WETH | 99055 | 13.86% | -| | | | | | -| no fee | RFQ | USDT/WETH | 98109 | 0.00% | -| proportional fee | RFQ | USDT/WETH | 143137 | 45.90% | -| fixed fee | RFQ | USDT/WETH | 111279 | 13.42% | -======= -| no fee | RFQ | USDC/WETH | 106575 | 0.00% | -| proportional fee | RFQ | USDC/WETH | 153734 | 44.25% | -| fixed fee | RFQ | USDC/WETH | 122824 | 15.25% | +| no fee | RFQ | USDC/WETH | 106561 | 0.00% | +| proportional fee | RFQ | USDC/WETH | 153717 | 44.25% | +| fixed fee | RFQ | USDC/WETH | 122703 | 15.15% | | | | | | | -| no fee | RFQ | DAI/WETH | 87101 | 0.00% | -| proportional fee | RFQ | DAI/WETH | 126148 | 44.83% | -| fixed fee | RFQ | DAI/WETH | 99176 | 13.86% | +| no fee | RFQ | DAI/WETH | 87087 | 0.00% | +| proportional fee | RFQ | DAI/WETH | 126131 | 44.83% | +| fixed fee | RFQ | DAI/WETH | 99055 | 13.74% | | | | | | | -| no fee | RFQ | USDT/WETH | 98213 | 0.00% | -| proportional fee | RFQ | USDT/WETH | 142892 | 45.49% | -| fixed fee | RFQ | USDT/WETH | 111400 | 13.43% | ->>>>>>> master +| no fee | RFQ | USDT/WETH | 98199 | 0.00% | +| proportional fee | RFQ | USDT/WETH | 142875 | 45.50% | +| fixed fee | RFQ | USDT/WETH | 111279 | 13.32% | | | | | | | [//]: # "END TABLES" diff --git a/src/allowanceholder/AllowanceHolder.sol b/src/allowanceholder/AllowanceHolder.sol index 9c8446a6d..a125b7b63 100644 --- a/src/allowanceholder/AllowanceHolder.sol +++ b/src/allowanceholder/AllowanceHolder.sol @@ -7,6 +7,9 @@ import {TransientStorage} from "./TransientStorage.sol"; /// @custom:security-contact security@0x.org contract AllowanceHolder is TransientStorage, AllowanceHolderBase { constructor() { - require(address(this) == 0x0000000000001fF3684f28c67538d4D072C22734 || block.chainid == 31337); + // Check that we're on a chain with transient storage support + assembly ("memory-safe") { + tstore(0x00, 0x00) + } } } diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 6db1186de..e4bcb8da5 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -15,6 +15,13 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { using SafeTransferLib for IERC20; using CheckCall for address payable; + constructor() { + assert( + (msg.sender == 0x4e59b44847b379578588920cA78FbF26c0B4956C && uint160(address(this)) >> 104 == 0) + || block.chainid == 31337 + ); + } + function _rejectIfERC20(address payable maybeERC20, bytes calldata data) private view DANGEROUS_freeMemory { // We could just choose a random address for this check, but to make // confused deputy attacks harder for tokens that might be badly behaved diff --git a/src/allowanceholder/AllowanceHolderOld.sol b/src/allowanceholder/AllowanceHolderOld.sol index 45c4a465c..7bc372be2 100644 --- a/src/allowanceholder/AllowanceHolderOld.sol +++ b/src/allowanceholder/AllowanceHolderOld.sol @@ -11,7 +11,6 @@ contract AllowanceHolder is TransientStorageMock, AllowanceHolderBase { bytes32 private _sentinel; constructor() { - require(address(this) == 0x0000000000005E88410CcDFaDe4a5EfaE4b49562 || block.chainid == 31337); uint256 _sentinelSlot; assembly ("memory-safe") { _sentinelSlot := _sentinel.slot diff --git a/test/integration/BasePairTest.t.sol b/test/integration/BasePairTest.t.sol index 263e68637..64b3373ca 100644 --- a/test/integration/BasePairTest.t.sol +++ b/test/integration/BasePairTest.t.sol @@ -8,10 +8,11 @@ import {IERC20} from "@forge-std/interfaces/IERC20.sol"; import {ISignatureTransfer} from "@permit2/interfaces/ISignatureTransfer.sol"; import {Permit2Signature} from "../utils/Permit2Signature.sol"; +import {DeployAllowanceHolder} from "./DeployAllowanceHolder.t.sol"; import {SafeTransferLib} from "../../src/vendor/SafeTransferLib.sol"; -abstract contract BasePairTest is Test, GasSnapshot, Permit2Signature { +abstract contract BasePairTest is Test, GasSnapshot, Permit2Signature, DeployAllowanceHolder { using SafeTransferLib for IERC20; uint256 internal constant FROM_PRIVATE_KEY = 0x1337; @@ -49,6 +50,8 @@ abstract contract BasePairTest is Test, GasSnapshot, Permit2Signature { vm.label(MAKER, "MAKER"); vm.label(BURN_ADDRESS, "BURN"); + _deployAllowanceHolder(); + // Initialize addresses with non-zero balances // https://github.com/0xProject/0x-settler#gas-comparisons if (address(fromToken()).code.length != 0) { diff --git a/test/integration/DeployAllowanceHolder.t.sol b/test/integration/DeployAllowanceHolder.t.sol new file mode 100644 index 000000000..b25cc1114 --- /dev/null +++ b/test/integration/DeployAllowanceHolder.t.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import {IAllowanceHolder} from "src/allowanceholder/IAllowanceHolder.sol"; + +import {Vm} from "@forge-std/Vm.sol"; + +contract DeployAllowanceHolder { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + IAllowanceHolder internal allowanceHolder; + + function _deployAllowanceHolder() internal returns (IAllowanceHolder) { + allowanceHolder = IAllowanceHolder(0x0000000000001fF3684f28c67538d4D072C22734); + vm.etch(address(allowanceHolder), vm.getDeployedCode("AllowanceHolder.sol:AllowanceHolder")); + vm.label(address(allowanceHolder), "AllowanceHolder"); + return allowanceHolder; + } +} diff --git a/test/integration/DodoV2PairTest.t.sol b/test/integration/DodoV2PairTest.t.sol index e89549c79..6b7f98710 100644 --- a/test/integration/DodoV2PairTest.t.sol +++ b/test/integration/DodoV2PairTest.t.sol @@ -10,7 +10,6 @@ import {MainnetSettler as Settler} from "src/chains/Mainnet/TakerSubmitted.sol"; import {SettlerBase} from "src/SettlerBase.sol"; import {Shim} from "./SettlerBasePairTest.t.sol"; -import {AllowanceHolder} from "src/allowanceholder/AllowanceHolder.sol"; import {IAllowanceHolder} from "src/allowanceholder/IAllowanceHolder.sol"; contract DodoV2PairTest is BasePairTest { @@ -19,7 +18,6 @@ contract DodoV2PairTest is BasePairTest { } Settler internal settler; - IAllowanceHolder internal allowanceHolder; uint256 private _amount; function setUp() public override { @@ -31,12 +29,9 @@ contract DodoV2PairTest is BasePairTest { safeApproveIfBelow(fromToken(), FROM, address(PERMIT2), amount()); warmPermit2Nonce(FROM); - allowanceHolder = IAllowanceHolder(0x0000000000001fF3684f28c67538d4D072C22734); - uint256 forkChainId = (new Shim()).chainId(); vm.chainId(31337); settler = new Settler(bytes20(0)); - vm.etch(address(allowanceHolder), address(new AllowanceHolder()).code); vm.chainId(forkChainId); // USDT is obnoxious about throwing errors, so let's check here before diff --git a/test/integration/SettlerBasePairTest.t.sol b/test/integration/SettlerBasePairTest.t.sol index f33832de4..01ceacb53 100644 --- a/test/integration/SettlerBasePairTest.t.sol +++ b/test/integration/SettlerBasePairTest.t.sol @@ -11,7 +11,6 @@ import {IERC20} from "@forge-std/interfaces/IERC20.sol"; import {LibBytes} from "../utils/LibBytes.sol"; import {SafeTransferLib} from "src/vendor/SafeTransferLib.sol"; -import {AllowanceHolder} from "src/allowanceholder/AllowanceHolder.sol"; import {IAllowanceHolder} from "src/allowanceholder/IAllowanceHolder.sol"; import {MainnetSettler as Settler} from "src/chains/Mainnet/TakerSubmitted.sol"; @@ -35,18 +34,23 @@ abstract contract SettlerBasePairTest is BasePairTest { uint256 internal PERMIT2_MAKER_NONCE = 1; Settler internal settler; - IAllowanceHolder internal allowanceHolder; IZeroEx internal ZERO_EX = IZeroEx(0xDef1C0ded9bec7F1a1670819833240f027b25EfF); function setUp() public virtual override { super.setUp(); - allowanceHolder = IAllowanceHolder(0x0000000000001fF3684f28c67538d4D072C22734); uint256 forkChainId = (new Shim()).chainId(); vm.chainId(31337); + // Some derived tests have an indirect dependency on the nonce of the test + // contract. Previously, we deployed a mock contract here to get the code for + // AllowanceHolder, but now this is taken care of by DeployAllowanceHolder. So we use a + // dummy `CREATE` to advance the nonce. + assembly ("memory-safe") { + if iszero(create(0x00, 0x00, 0x00)) { + revert(0x00, 0x00) + } + } settler = new Settler(bytes20(0)); - vm.etch(address(allowanceHolder), address(new AllowanceHolder()).code); - vm.label(address(allowanceHolder), "AllowanceHolder"); vm.chainId(forkChainId); } diff --git a/test/integration/SettlerMetaTxnPairTest.t.sol b/test/integration/SettlerMetaTxnPairTest.t.sol index ef3e309f0..d85fef622 100644 --- a/test/integration/SettlerMetaTxnPairTest.t.sol +++ b/test/integration/SettlerMetaTxnPairTest.t.sol @@ -13,7 +13,6 @@ import {ActionDataBuilder} from "../utils/ActionDataBuilder.sol"; import {SafeTransferLib} from "src/vendor/SafeTransferLib.sol"; -import {AllowanceHolder} from "src/allowanceholder/AllowanceHolder.sol"; import {MainnetSettlerMetaTxn as SettlerMetaTxn} from "src/chains/Mainnet/MetaTxn.sol"; import {Settler} from "src/Settler.sol"; import {SettlerBase} from "src/SettlerBase.sol"; diff --git a/test/integration/UniV3CallbackPoC.t.sol b/test/integration/UniV3CallbackPoC.t.sol index fa67e68d7..c712ca476 100644 --- a/test/integration/UniV3CallbackPoC.t.sol +++ b/test/integration/UniV3CallbackPoC.t.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.25; -import {AllowanceHolder} from "src/allowanceholder/AllowanceHolderOld.sol"; import {IAllowanceHolder} from "src/allowanceholder/IAllowanceHolder.sol"; import {MainnetSettler as Settler} from "src/chains/Mainnet/TakerSubmitted.sol"; import {ISettlerActions} from "src/ISettlerActions.sol"; @@ -15,6 +14,7 @@ import {uniswapV3MainnetFactory} from "src/core/univ3forks/UniswapV3.sol"; import {Utils} from "../unit/Utils.sol"; import {Permit2Signature} from "../utils/Permit2Signature.sol"; import {ActionDataBuilder} from "../utils/ActionDataBuilder.sol"; +import {DeployAllowanceHolder} from "./DeployAllowanceHolder.t.sol"; import {Test, console} from "@forge-std/Test.sol"; import {MockERC20} from "@solmate/test/utils/mocks/MockERC20.sol"; @@ -53,11 +53,10 @@ contract Shim { } } -contract UniV3CallbackPoC is Utils, Permit2Signature { +contract UniV3CallbackPoC is Utils, Permit2Signature, DeployAllowanceHolder { ISignatureTransfer permit2 = ISignatureTransfer(0x000000000022D473030F116dDEE9F6B43aC78BA3); bytes32 internal permit2Domain; - IAllowanceHolder ah; Settler settler; address pool; @@ -84,13 +83,7 @@ contract UniV3CallbackPoC is Utils, Permit2Signature { permit2Domain = permit2.DOMAIN_SEPARATOR(); // Deploy AllowanceHolder - ah = IAllowanceHolder(0x0000000000001fF3684f28c67538d4D072C22734); - { - uint256 forkChainId = (new Shim()).chainId(); - vm.chainId(31337); - vm.etch(address(ah), address(new AllowanceHolder()).code); - vm.chainId(forkChainId); - } + _deployAllowanceHolder(); // Deploy Settler. { @@ -136,7 +129,7 @@ contract UniV3CallbackPoC is Utils, Permit2Signature { MockERC20(dai).mint(alice, 100e18); vm.prank(alice); - MockERC20(dai).approve(address(ah), type(uint256).max); + MockERC20(dai).approve(address(allowanceHolder), type(uint256).max); vm.prank(alice); MockERC20(dai).approve(address(permit2), type(uint256).max); diff --git a/test/integration/VelodromePairTest.t.sol b/test/integration/VelodromePairTest.t.sol index b9c73ae6d..fc3ea2c95 100644 --- a/test/integration/VelodromePairTest.t.sol +++ b/test/integration/VelodromePairTest.t.sol @@ -10,7 +10,6 @@ import {BaseSettler as Settler} from "src/chains/Base/TakerSubmitted.sol"; import {SettlerBase} from "src/SettlerBase.sol"; import {Shim} from "./SettlerBasePairTest.t.sol"; -import {AllowanceHolder} from "src/allowanceholder/AllowanceHolder.sol"; import {IAllowanceHolder} from "src/allowanceholder/IAllowanceHolder.sol"; contract VelodromePairTest is BasePairTest { @@ -19,7 +18,6 @@ contract VelodromePairTest is BasePairTest { } Settler internal settler; - IAllowanceHolder internal allowanceHolder; uint256 private _amount; function setUp() public override { @@ -31,12 +29,9 @@ contract VelodromePairTest is BasePairTest { safeApproveIfBelow(fromToken(), FROM, address(PERMIT2), amount()); warmPermit2Nonce(FROM); - allowanceHolder = IAllowanceHolder(0x0000000000001fF3684f28c67538d4D072C22734); - uint256 forkChainId = (new Shim()).chainId(); vm.chainId(31337); settler = new Settler(bytes20(0)); - vm.etch(address(allowanceHolder), address(new AllowanceHolder()).code); vm.chainId(forkChainId); // USDT is obnoxious about throwing errors, so let's check here before diff --git a/test/integration/WethWrapTest.t.sol b/test/integration/WethWrapTest.t.sol index dad782f59..9bfa053a4 100644 --- a/test/integration/WethWrapTest.t.sol +++ b/test/integration/WethWrapTest.t.sol @@ -5,7 +5,6 @@ import {IERC20} from "@forge-std/interfaces/IERC20.sol"; import {Test} from "@forge-std/Test.sol"; import {WETH} from "@solmate/tokens/WETH.sol"; -import {AllowanceHolder} from "src/allowanceholder/AllowanceHolder.sol"; import {MainnetSettler as Settler} from "src/chains/Mainnet/TakerSubmitted.sol"; import {SettlerBase} from "src/SettlerBase.sol"; import {ActionDataBuilder} from "../utils/ActionDataBuilder.sol"; diff --git a/test/unit/AllowanceHolderUnitTest.t.sol b/test/unit/AllowanceHolderUnitTest.t.sol index 018e547a1..ed0bb99ef 100644 --- a/test/unit/AllowanceHolderUnitTest.t.sol +++ b/test/unit/AllowanceHolderUnitTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; +pragma solidity ^0.8.28; import {AllowanceHolder} from "src/allowanceholder/AllowanceHolderOld.sol"; import {IAllowanceHolder} from "src/allowanceholder/IAllowanceHolder.sol"; From d550fb4433087519c7bfdb8c7e77d77fb945dbd1 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Mon, 24 Nov 2025 18:27:11 +0100 Subject: [PATCH 23/29] Add `MultiCallContext` to `AllowanceHolder` --- src/allowanceholder/AllowanceHolderBase.sol | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index e4bcb8da5..d81b34f40 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -7,11 +7,12 @@ import {SafeTransferLib} from "../vendor/SafeTransferLib.sol"; import {CheckCall} from "../utils/CheckCall.sol"; import {FreeMemory} from "../utils/FreeMemory.sol"; import {TransientStorageLayout} from "./TransientStorageLayout.sol"; +import {MultiCallContext} from "../multicall/MultiCallContext.sol"; /// @notice Thrown when validating the target, avoiding executing against an ERC20 directly error ConfusedDeputy(); -abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { +abstract contract AllowanceHolderBase is MultiCallContext, TransientStorageLayout, FreeMemory { using SafeTransferLib for IERC20; using CheckCall for address payable; @@ -67,10 +68,12 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { } function _msgSender() private view returns (address sender) { - if ((sender = msg.sender) == address(this)) { + if (msg.sender == address(this)) { assembly ("memory-safe") { sender := shr(0x60, calldataload(sub(calldatasize(), 0x14))) } + } else { + sender = super._msgSender(); } } From 6dbf06d8f4173f927a6addb22aa90c35f53cb5b9 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Mon, 24 Nov 2025 18:35:48 +0100 Subject: [PATCH 24/29] Golf --- src/allowanceholder/AllowanceHolderBase.sol | 22 +++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index d81b34f40..4e01b947a 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -7,15 +7,16 @@ import {SafeTransferLib} from "../vendor/SafeTransferLib.sol"; import {CheckCall} from "../utils/CheckCall.sol"; import {FreeMemory} from "../utils/FreeMemory.sol"; import {TransientStorageLayout} from "./TransientStorageLayout.sol"; -import {MultiCallContext} from "../multicall/MultiCallContext.sol"; /// @notice Thrown when validating the target, avoiding executing against an ERC20 directly error ConfusedDeputy(); -abstract contract AllowanceHolderBase is MultiCallContext, TransientStorageLayout, FreeMemory { +abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { using SafeTransferLib for IERC20; using CheckCall for address payable; + address internal constant _MULTICALL = 0x00000000000000CF9E3c5A26621af382fA17f24f; + constructor() { assert( (msg.sender == 0x4e59b44847b379578588920cA78FbF26c0B4956C && uint160(address(this)) >> 104 == 0) @@ -68,12 +69,17 @@ abstract contract AllowanceHolderBase is MultiCallContext, TransientStorageLayou } function _msgSender() private view returns (address sender) { - if (msg.sender == address(this)) { - assembly ("memory-safe") { - sender := shr(0x60, calldataload(sub(calldatasize(), 0x14))) - } - } else { - sender = super._msgSender(); + assembly ("memory-safe") { + let isSelfForwarded := eq(caller(), address()) + let isMultiCallForwarded := and(lt(0x03, calldatasize()), eq(_MULTICALL, caller())) + sender := + xor( + caller(), + mul( + xor(caller(), shr(0x60, calldataload(sub(calldatasize(), 0x14)))), + or(isMultiCallForwarded, isSelfForwarded) + ) + ) } } From 01f8003580d8af262f043edf8a593baf01db22a4 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Mon, 24 Nov 2025 20:47:55 +0100 Subject: [PATCH 25/29] Comment, formatting --- src/allowanceholder/AllowanceHolderBase.sol | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 4e01b947a..5f6b09235 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -37,7 +37,11 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { target := calldataload(add(0x04, data.offset)) // `shl(0x08, data.length)` can't overflow because we're going to // `calldatacopy(..., data.length)` later. It would OOG. - let mask := shr(shl(0x08, sub(data.length, 0x04)), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + let mask := + shr( + shl(0x08, sub(data.length, 0x04)), + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ) // Zero the low bits of `target` if `data` is short. Dirty low // bits are only ever possible with nonstandard encodings, like // ERC-2771. @@ -55,7 +59,7 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { assembly ("memory-safe") { testData := mload(0x40) mstore(add(0x24, testData), target) - mstore(add(0x10, testData), 0x70a08231000000000000000000000000) + mstore(add(0x10, testData), 0x70a08231000000000000000000000000) // `IERC20.balanceOf.selector` with `target`'s padding mstore(testData, 0x24) mstore(0x40, add(0x60, testData)) } From 270e5982e974cfa9be2a06518588fa53823051ee Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 4 Dec 2025 20:34:23 +0100 Subject: [PATCH 26/29] Golf --- src/allowanceholder/AllowanceHolderBase.sol | 23 +++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index 5f6b09235..c0f78c638 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -6,6 +6,7 @@ import {IERC20} from "@forge-std/interfaces/IERC20.sol"; import {SafeTransferLib} from "../vendor/SafeTransferLib.sol"; import {CheckCall} from "../utils/CheckCall.sol"; import {FreeMemory} from "../utils/FreeMemory.sol"; +import {Panic} from "../utils/Panic.sol"; import {TransientStorageLayout} from "./TransientStorageLayout.sol"; /// @notice Thrown when validating the target, avoiding executing against an ERC20 directly @@ -101,8 +102,8 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { _rejectIfERC20(target, data); address sender = _msgSender(); - TSlot allowance = _ephemeralAllowance(operator, sender, token); - _set(allowance, amount); + TSlot allowanceSlot = _ephemeralAllowance(operator, sender, token); + _set(allowanceSlot, amount); // For gas efficiency we're omitting a bunch of checks here. Notably, // we're omitting the check that `address(this)` has sufficient value to @@ -133,7 +134,7 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { } } - _set(allowance, 0); + _set(allowanceSlot, 0); } /// @dev This provides the implementation of the function of the same name @@ -141,11 +142,21 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { /// documented there. function transferFrom(address token, address owner, address recipient, uint256 amount) private { // `msg.sender` is the assumed and later validated `operator`. - TSlot allowance = _ephemeralAllowance(msg.sender, owner, token); + TSlot allowanceSlot = _ephemeralAllowance(msg.sender, owner, token); + uint256 allowanceValue = _get(allowanceSlot); + // We validate the ephemeral allowance for the 3-tuple of `operator` // (`msg.sender`), `owner`, and `token` by reverting on unsigned integer - // underflow (built in to Solidity 0.8). - _set(allowance, _get(allowance) - amount); + // underflow. + if (allowanceValue < amount) { + Panic.panic(Panic.ARITHMETIC_OVERFLOW); + } + + // Update the ephemeral allowance + unchecked { + _set(allowanceSlot, allowanceValue - amount); + } + // `safeTransferFrom` does not check that `token` actually contains // code. It is the responsibility of integrating code to check for that, // if vacuous success is a security concern. From 599730516e416c31580e4ba67da933c696970c67 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 4 Dec 2025 20:50:49 +0100 Subject: [PATCH 27/29] Golf --- src/allowanceholder/AllowanceHolderBase.sol | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index c0f78c638..d93bd0e3c 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -33,21 +33,21 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // `data`, we use 0xdead instead. address target; // = address(uint160(bytes20(data[0x10:]))); - if (data.length >= 4) { - assembly ("memory-safe") { - target := calldataload(add(0x04, data.offset)) - // `shl(0x08, data.length)` can't overflow because we're going to - // `calldatacopy(..., data.length)` later. It would OOG. - let mask := - shr( - shl(0x08, sub(data.length, 0x04)), - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - ) - // Zero the low bits of `target` if `data` is short. Dirty low - // bits are only ever possible with nonstandard encodings, like - // ERC-2771. - target := and(not(mask), target) - } + assembly ("memory-safe") { + target := calldataload(add(0x04, data.offset)) + // `shl(0x08, data.length)` can't overflow because we're going to + // `calldatacopy(..., data.length)` later. It would OOG. We check + // for underflow in `sub(data.length, 0x04)` later. + let mask := + shr( + shl(0x08, sub(data.length, 0x04)), + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ) + // Zero the low bits of `target` if `data` is short. Dirty low bits + // are only ever possible with nonstandard encodings, like ERC-2771. + target := and(not(mask), target) + // Zero `target` if `sub(data.length, 0x04)` underflowed. + target := mul(lt(0x03, data.length), target) } // EIP-1352 (not adopted) specifies 0xffff as the maximum precompile From a5e923dcbdd394782a672b61625374744455f9da Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 4 Dec 2025 20:53:26 +0100 Subject: [PATCH 28/29] Simplify --- src/allowanceholder/AllowanceHolderBase.sol | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index d93bd0e3c..be5647bb6 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -38,11 +38,7 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { // `shl(0x08, data.length)` can't overflow because we're going to // `calldatacopy(..., data.length)` later. It would OOG. We check // for underflow in `sub(data.length, 0x04)` later. - let mask := - shr( - shl(0x08, sub(data.length, 0x04)), - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - ) + let mask := shr(shl(0x08, sub(data.length, 0x04)), not(0x00)) // Zero the low bits of `target` if `data` is short. Dirty low bits // are only ever possible with nonstandard encodings, like ERC-2771. target := and(not(mask), target) From 79203c4d6bd5de33095fbfda9f4edc3ac0427800 Mon Sep 17 00:00:00 2001 From: Duncan Townsend Date: Thu, 4 Dec 2025 23:14:06 +0100 Subject: [PATCH 29/29] Golf --- src/allowanceholder/AllowanceHolderBase.sol | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/allowanceholder/AllowanceHolderBase.sol b/src/allowanceholder/AllowanceHolderBase.sol index be5647bb6..0c42dc629 100644 --- a/src/allowanceholder/AllowanceHolderBase.sol +++ b/src/allowanceholder/AllowanceHolderBase.sol @@ -7,6 +7,7 @@ import {SafeTransferLib} from "../vendor/SafeTransferLib.sol"; import {CheckCall} from "../utils/CheckCall.sol"; import {FreeMemory} from "../utils/FreeMemory.sol"; import {Panic} from "../utils/Panic.sol"; +import {Ternary} from "../utils/Ternary.sol"; import {TransientStorageLayout} from "./TransientStorageLayout.sol"; /// @notice Thrown when validating the target, avoiding executing against an ERC20 directly @@ -15,6 +16,7 @@ error ConfusedDeputy(); abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { using SafeTransferLib for IERC20; using CheckCall for address payable; + using Ternary for bool; address internal constant _MULTICALL = 0x00000000000000CF9E3c5A26621af382fA17f24f; @@ -46,11 +48,10 @@ abstract contract AllowanceHolderBase is TransientStorageLayout, FreeMemory { target := mul(lt(0x03, data.length), target) } - // EIP-1352 (not adopted) specifies 0xffff as the maximum precompile - if (target <= address(0xffff)) { - // 0xdead is a conventional burn address; we assume that it is not treated specially - target = address(0xdead); - } + // EIP-1352 (not adopted) specifies 0xffff as the maximum precompile. + // 0xdead is a conventional burn address; we assume that it is not + // treated specially. + target = (target > address(0xffff)).ternary(target, address(0xdead)); bytes memory testData; // = abi.encodeCall(IERC20.balanceOf, target); assembly ("memory-safe") {