From c7d68ed39e801b9ba865d2bbd9d027aaaf3658cf Mon Sep 17 00:00:00 2001 From: 0age <37939117+0age@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:38:04 -0500 Subject: [PATCH 1/3] Make ERC20 preapproval check branchless --- .../erc20/ERC20ConduitPreapproved_Solady.sol | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/tokens/erc20/ERC20ConduitPreapproved_Solady.sol b/src/tokens/erc20/ERC20ConduitPreapproved_Solady.sol index 9f4a993..5d1d993 100644 --- a/src/tokens/erc20/ERC20ConduitPreapproved_Solady.sol +++ b/src/tokens/erc20/ERC20ConduitPreapproved_Solady.sol @@ -61,16 +61,18 @@ abstract contract ERC20ConduitPreapproved_Solady is ERC20, IPreapprovalForAll { mstore(0x0c, or(from_, SOLADY_ERC20_ALLOWANCE_SLOT_SEED)) let allowanceSlot := keccak256(0x0c, 0x34) let allowance_ := sload(allowanceSlot) - // If the caller is the conduit and allowance is 0, set to type(uint256).max. If the allowance is type(uint256).max, set to 0. - let isConduit := eq(caller(), CONDUIT) - if isConduit { - let conduitAllowance_ := allowance_ - if eq(allowance_, 0) { conduitAllowance_ := not(0) } - if eq(allowance_, not(0)) { conduitAllowance_ := 0 } - if iszero(eq(allowance_, conduitAllowance_)) { allowance_ := conduitAllowance_ } - } - // If the allowance is not the maximum uint256 value. - if add(allowance_, 1) { + + // "flip" allowance if caller is CONDUIT and if allowance_ is 0 or type(uint256).max. + allowance_ := xor( + allowance_, + mul( + and(eq(caller(), CONDUIT), iszero(and(allowance_, not(allowance_)))), + not(0) + ) + ) + + // If the allowance is not the maximum uint256 value: + if not(allowance_) { // Revert if the amount to be transferred exceeds the allowance. if gt(amount, allowance_) { mstore(0x00, 0x13be252b) // `InsufficientAllowance()`. @@ -79,6 +81,7 @@ abstract contract ERC20ConduitPreapproved_Solady is ERC20, IPreapprovalForAll { // Subtract and store the updated allowance. sstore(allowanceSlot, sub(allowance_, amount)) } + // Compute the balance slot and load its value. mstore(0x0c, or(from_, SOLADY_ERC20_BALANCE_SLOT_SEED)) let fromBalanceSlot := keccak256(0x0c, 0x20) From 3458423c8716bdcd3875cde4597dcae377a16620 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Wed, 29 Nov 2023 20:39:15 +0000 Subject: [PATCH 2/3] Github Actions automatically updated formatting with forge fmt --- src/tokens/erc20/ERC20ConduitPreapproved_Solady.sol | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/tokens/erc20/ERC20ConduitPreapproved_Solady.sol b/src/tokens/erc20/ERC20ConduitPreapproved_Solady.sol index 5d1d993..425b63e 100644 --- a/src/tokens/erc20/ERC20ConduitPreapproved_Solady.sol +++ b/src/tokens/erc20/ERC20ConduitPreapproved_Solady.sol @@ -63,13 +63,8 @@ abstract contract ERC20ConduitPreapproved_Solady is ERC20, IPreapprovalForAll { let allowance_ := sload(allowanceSlot) // "flip" allowance if caller is CONDUIT and if allowance_ is 0 or type(uint256).max. - allowance_ := xor( - allowance_, - mul( - and(eq(caller(), CONDUIT), iszero(and(allowance_, not(allowance_)))), - not(0) - ) - ) + allowance_ := + xor(allowance_, mul(and(eq(caller(), CONDUIT), iszero(and(allowance_, not(allowance_)))), not(0))) // If the allowance is not the maximum uint256 value: if not(allowance_) { From e321e659946904289ddf2889b26f66efe922baa6 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Wed, 29 Nov 2023 20:39:15 +0000 Subject: [PATCH 3/3] Updated .git-blame-ignore-revs with commit 3458423c8716bdcd3875cde4597dcae377a16620 --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index da5fe98..924ff41 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -2,3 +2,4 @@ # Github Actions automatically updated formatting with forge fmt\n3b40d0f5cfd25b67a335ee2c8d7c9660d5bfd7f5 # Github Actions automatically updated formatting with forge fmt\n2d96311b29055c5b9a0b632176ce3b8d78a23a89 # Github Actions automatically updated formatting with forge fmt\ne2d336bbb0331c7716c16fed64f51be6c270ad02 +# Github Actions automatically updated formatting with forge fmt\n3458423c8716bdcd3875cde4597dcae377a16620