From 240249fda754017d8f9265276abcc3231046bbfa Mon Sep 17 00:00:00 2001 From: 0age <37939117+0age@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:03:11 -0700 Subject: [PATCH] memory-safe and minor bool optimizations --- src/TheCompact.sol | 8 ++--- src/lib/FunctionCastLib.sol | 68 ++++++++++++++++++------------------- src/lib/IdLib.sol | 36 ++++++++++---------- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/TheCompact.sol b/src/TheCompact.sol index 019c85a..4021aaa 100644 --- a/src/TheCompact.sol +++ b/src/TheCompact.sol @@ -243,7 +243,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { bool firstUnderlyingTokenIsNative; uint256 id; - assembly { + assembly ("memory-safe") { let idsAndAmountsOffset := idsAndAmounts.offset id := calldataload(idsAndAmountsOffset) firstUnderlyingTokenIsNative := iszero(shr(96, shl(96, id))) @@ -343,7 +343,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { ) external payable returns (uint256[] memory) { uint256 totalTokens = permitted.length; bool firstUnderlyingTokenIsNative; - assembly { + assembly ("memory-safe") { let permittedOffset := permitted.offset firstUnderlyingTokenIsNative := iszero(shr(96, shl(96, add(permittedOffset, 0x20)))) @@ -1171,7 +1171,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { } function _emitClaim(address sponsor, bytes32 messageHash, address allocator) internal { - assembly { + assembly ("memory-safe") { mstore(0, messageHash) log4( 0, @@ -1702,7 +1702,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { IAllocator(allocator).attest(msg.sender, from, to, id, amount) != IAllocator.attest.selector ) { - assembly { + assembly ("memory-safe") { // revert UnallocatedTransfer(msg.sender, from, to, id, amount) mstore(0, 0x014c9310) mstore(0x20, caller()) diff --git a/src/lib/FunctionCastLib.sol b/src/lib/FunctionCastLib.sol index 39a11ee..92d2e42 100644 --- a/src/lib/FunctionCastLib.sol +++ b/src/lib/FunctionCastLib.sol @@ -44,7 +44,7 @@ library FunctionCastLib { pure returns (function (bytes32, address, SplitTransfer calldata) internal view fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -56,7 +56,7 @@ library FunctionCastLib { pure returns (function (bytes32, address, BatchTransfer calldata) internal view fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -68,7 +68,7 @@ library FunctionCastLib { pure returns (function (bytes32, address, SplitBatchTransfer calldata) internal view fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -82,7 +82,7 @@ library FunctionCastLib { function(SplitBatchTransfer calldata, bytes32) internal view returns (bytes32) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -96,7 +96,7 @@ library FunctionCastLib { function(QualifiedSplitClaim calldata) internal view returns (bytes32, bytes32) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -110,7 +110,7 @@ library FunctionCastLib { function(QualifiedClaimWithWitness calldata, uint256) internal view returns (bytes32) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -127,7 +127,7 @@ library FunctionCastLib { returns (bytes32) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -144,7 +144,7 @@ library FunctionCastLib { returns (bytes32) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -161,7 +161,7 @@ library FunctionCastLib { returns (bytes32) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -178,7 +178,7 @@ library FunctionCastLib { returns (bytes32) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -195,7 +195,7 @@ library FunctionCastLib { returns (bytes32) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -210,7 +210,7 @@ library FunctionCastLib { fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -226,7 +226,7 @@ library FunctionCastLib { fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -242,7 +242,7 @@ library FunctionCastLib { fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -258,7 +258,7 @@ library FunctionCastLib { fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -274,7 +274,7 @@ library FunctionCastLib { fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -284,7 +284,7 @@ library FunctionCastLib { pure returns (function (SplitClaim calldata) internal view returns (bytes32) fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -298,7 +298,7 @@ library FunctionCastLib { function (SplitClaimWithWitness calldata, uint256) internal view returns (bytes32) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -311,7 +311,7 @@ library FunctionCastLib { pure returns (function (SplitByIdComponent[] memory, uint256) internal returns (address) fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -323,7 +323,7 @@ library FunctionCastLib { pure returns (function (bytes32, ClaimWithWitness calldata, address) internal view fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -335,7 +335,7 @@ library FunctionCastLib { pure returns (function(bytes32, SplitClaimWithWitness calldata, address) internal view fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -345,7 +345,7 @@ library FunctionCastLib { pure returns (function(bytes32, SplitClaim calldata, address) internal view fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -355,7 +355,7 @@ library FunctionCastLib { pure returns (function(bytes32, BatchClaim calldata, address) internal view fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -367,7 +367,7 @@ library FunctionCastLib { pure returns (function(bytes32, SplitBatchClaim calldata, address) internal view fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -381,7 +381,7 @@ library FunctionCastLib { function(bytes32, SplitBatchClaimWithWitness calldata, address) internal view fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -393,7 +393,7 @@ library FunctionCastLib { pure returns (function(bytes32, BatchClaimWithWitness calldata, address) internal view fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -405,7 +405,7 @@ library FunctionCastLib { pure returns (function(QualifiedSplitClaim calldata) internal returns (bytes32, address) fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -419,7 +419,7 @@ library FunctionCastLib { function (bytes32, bytes32, QualifiedClaimWithWitness calldata, address) internal view fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -433,7 +433,7 @@ library FunctionCastLib { function (bytes32, bytes32, QualifiedBatchClaim calldata, address) internal view fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -447,7 +447,7 @@ library FunctionCastLib { function (bytes32, bytes32, QualifiedSplitBatchClaim calldata, address) internal view fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -462,7 +462,7 @@ library FunctionCastLib { fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -477,7 +477,7 @@ library FunctionCastLib { fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -491,7 +491,7 @@ library FunctionCastLib { function(QualifiedSplitClaimWithWitness calldata) internal returns (bytes32, address) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -503,7 +503,7 @@ library FunctionCastLib { pure returns (function(bytes32, MultichainClaim calldata, address) internal view fnOut) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } diff --git a/src/lib/IdLib.sol b/src/lib/IdLib.sol index c32c052..57e960f 100644 --- a/src/lib/IdLib.sol +++ b/src/lib/IdLib.sol @@ -13,6 +13,7 @@ library IdLib { using IdLib for uint256; using IdLib for address; using MetadataLib for Lock; + using EfficiencyLib for bool; using EfficiencyLib for uint8; using EfficiencyLib for uint96; using EfficiencyLib for uint256; @@ -40,34 +41,34 @@ library IdLib { pure returns (uint256 updatedId) { - assembly { + assembly ("memory-safe") { updatedId := or(shl(160, shr(160, id)), shr(96, shl(96, token))) } } function toScope(uint256 id) internal pure returns (Scope scope) { - assembly { + assembly ("memory-safe") { // extract uppermost bit scope := shr(255, id) } } function toResetPeriod(uint256 id) internal pure returns (ResetPeriod resetPeriod) { - assembly { + assembly ("memory-safe") { // extract 2nd, 3rd & 4th uppermost bits resetPeriod := and(shr(252, id), 7) } } function toCompactFlag(uint256 id) internal pure returns (uint8 compactFlag) { - assembly { + assembly ("memory-safe") { // extract 5th, 6th, 7th & 8th uppermost bits compactFlag := and(shr(248, id), 15) } } function toAllocatorId(uint256 id) internal pure returns (uint96 allocatorId) { - assembly { + assembly ("memory-safe") { // extract bits 5-96 allocatorId := shr(164, shl(4, id)) } @@ -76,7 +77,7 @@ library IdLib { // TODO: add a bit of extra time to pad 1 hour and 1 day values function toSeconds(ResetPeriod resetPeriod) internal pure returns (uint256 duration) { // note: no bounds check performed; ensure that the enum is in range - assembly { + assembly ("memory-safe") { // 278d00 093a80 015180 000e10 000258 00003c 00000f 000001 // 30 days 7 days 1 day 1 hour 10 min 1 min 15 sec 1 sec let bitpacked := 0x278d00093a80015180000e1000025800003c00000f000001 @@ -102,7 +103,7 @@ library IdLib { // * 17 leading zero nibbles: 14 // * 18+ leading zero nibbles: 15 function toCompactFlag(address allocator) internal pure returns (uint8 compactFlag) { - assembly { + assembly ("memory-safe") { // extract the uppermost 72 bits of the address let x := shr(168, shl(96, allocator)) @@ -132,7 +133,7 @@ library IdLib { function usingAllocatorId(address allocator) internal pure returns (uint96 allocatorId) { uint8 compactFlag = allocator.toCompactFlag(); - assembly { + assembly ("memory-safe") { allocatorId := or(shl(88, compactFlag), shr(168, shl(168, allocator))) } } @@ -179,7 +180,7 @@ library IdLib { } function toRegisteredAllocator(uint96 allocatorId) internal view returns (address allocator) { - assembly { + assembly ("memory-safe") { // NOTE: consider an SLOAD bypass for a fully compact allocator allocator := sload(or(_ALLOCATOR_BY_ALLOCATOR_ID_SLOT_SEED, allocatorId)) @@ -198,7 +199,7 @@ library IdLib { } function mustHaveARegisteredAllocator(uint96 allocatorId) internal view { - assembly { + assembly ("memory-safe") { // NOTE: consider an SLOAD bypass for a fully compact allocator if iszero(sload(or(_ALLOCATOR_BY_ALLOCATOR_ID_SLOT_SEED, allocatorId))) { mstore(0, _NO_ALLOCATOR_REGISTERED_ERROR_SIGNATURE) @@ -213,14 +214,13 @@ library IdLib { view returns (bool) { - // TODO: optimize - return (msg.sender == allocator) + uint256 proofLength = proof.length; + return (msg.sender == allocator).or( + proofLength == 86 + && (proof[0] == 0xff).and(allocator == address(uint160(uint256(keccak256(proof))))) + ) || ( - proof.length == 86 && proof[0] == 0xff - && allocator == address(uint160(uint256(keccak256(proof)))) - ) - || ( - proof.length > 31 + proofLength > 31 && allocator.isValidSignatureNow(abi.decode(proof[0:32], (bytes32)), proof[32:]) ); } @@ -228,7 +228,7 @@ library IdLib { function register(address allocator) internal returns (uint96 allocatorId) { allocatorId = allocator.usingAllocatorId(); - assembly { + assembly ("memory-safe") { let allocatorSlot := or(_ALLOCATOR_BY_ALLOCATOR_ID_SLOT_SEED, allocatorId) let registeredAllocator := sload(allocatorSlot)