-
Notifications
You must be signed in to change notification settings - Fork 514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Seaport bulk sig support for smart accounts: AccountSeaportBulkSigSupport #633
Conversation
|
||
// Read consideration item typehash from runtime code & place on stack. | ||
typeHash = _CONSIDERATION_ITEM_TYPEHASH; | ||
|
||
// Utilize assembly so that memory regions can be reused across hashes. | ||
assembly { | ||
// Retrieve the free memory pointer and place on the stack. | ||
let hashArrPtr := mload(FreeMemoryPointerSlot) | ||
|
||
// Get the pointer to the consideration array. | ||
let considerationArrPtr := add( | ||
mload(add(orderParameters, OrderParameters_consideration_head_offset)), | ||
OneWord | ||
) | ||
|
||
// Iterate over the consideration items (not including tips). | ||
for { | ||
let i := 0 | ||
} lt(i, originalConsiderationLength) { | ||
i := add(i, 1) | ||
} { | ||
// Read the pointer to the consideration data and subtract one | ||
// word to get typeHash pointer. | ||
let ptr := sub(mload(considerationArrPtr), OneWord) | ||
|
||
// Read the current value before the consideration data. | ||
let value := mload(ptr) | ||
|
||
// Write the type hash to the previous word. | ||
mstore(ptr, typeHash) | ||
|
||
// Take the EIP712 hash and store it in the hash array. | ||
mstore(hashArrPtr, keccak256(ptr, EIP712_ConsiderationItem_size)) | ||
|
||
// Restore the previous word. | ||
mstore(ptr, value) | ||
|
||
// Increment the array pointers by one word. | ||
considerationArrPtr := add(considerationArrPtr, OneWord) | ||
hashArrPtr := add(hashArrPtr, OneWord) | ||
} | ||
|
||
// Derive the consideration hash using the hashes of each item. | ||
considerationHash := keccak256(mload(FreeMemoryPointerSlot), shl(OneWordShift, originalConsiderationLength)) | ||
} | ||
|
||
// Read order item EIP-712 typehash from runtime code & place on stack. | ||
typeHash = _ORDER_TYPEHASH; | ||
|
||
// Utilize assembly to access derived hashes & other arguments directly. | ||
assembly { | ||
// Retrieve pointer to the region located just behind parameters. | ||
let typeHashPtr := sub(orderParameters, OneWord) | ||
|
||
// Store the value at that pointer location to restore later. | ||
let previousValue := mload(typeHashPtr) | ||
|
||
// Store the order item EIP-712 typehash at the typehash location. | ||
mstore(typeHashPtr, typeHash) | ||
|
||
// Retrieve the pointer for the offer array head. | ||
let offerHeadPtr := add(orderParameters, OrderParameters_offer_head_offset) | ||
|
||
// Retrieve the data pointer referenced by the offer head. | ||
let offerDataPtr := mload(offerHeadPtr) | ||
|
||
// Store the offer hash at the retrieved memory location. | ||
mstore(offerHeadPtr, offerHash) | ||
|
||
// Retrieve the pointer for the consideration array head. | ||
let considerationHeadPtr := add(orderParameters, OrderParameters_consideration_head_offset) | ||
|
||
// Retrieve the data pointer referenced by the consideration head. | ||
let considerationDataPtr := mload(considerationHeadPtr) | ||
|
||
// Store the consideration hash at the retrieved memory location. | ||
mstore(considerationHeadPtr, considerationHash) | ||
|
||
// Retrieve the pointer for the counter. | ||
let counterPtr := add(orderParameters, OrderParameters_counter_offset) | ||
|
||
// Store the counter at the retrieved memory location. | ||
mstore(counterPtr, counter) | ||
|
||
// Derive the order hash using the full range of order parameters. | ||
orderHash := keccak256(typeHashPtr, EIP712_Order_size) | ||
|
||
// Restore the value previously held at typehash pointer location. | ||
mstore(typeHashPtr, previousValue) | ||
|
||
// Restore offer data pointer at the offer head pointer location. | ||
mstore(offerHeadPtr, offerDataPtr) | ||
|
||
// Restore consideration data pointer at the consideration head ptr. | ||
mstore(considerationHeadPtr, considerationDataPtr) | ||
|
||
// Restore consideration item length at the counter pointer. | ||
mstore(counterPtr, originalConsiderationLength) | ||
} | ||
} |
Check warning
Code scanning / Slither
Assembly usage Warning
- INLINE ASM
- INLINE ASM
- INLINE ASM
function _computeBulkOrderProof( | ||
bytes memory proofAndSignature, | ||
bytes32 leaf | ||
) internal pure returns (bytes32 bulkOrderHash) { | ||
// Declare arguments for the root hash and the height of the proof. | ||
bytes32 root; | ||
uint256 height; | ||
|
||
// Utilize assembly to efficiently derive the root hash using the proof. | ||
assembly { | ||
// Retrieve the length of the proof, key, and signature combined. | ||
let fullLength := mload(proofAndSignature) | ||
|
||
// If proofAndSignature has odd length, it is a compact signature | ||
// with 64 bytes. | ||
let signatureLength := sub(ECDSA_MaxLength, and(fullLength, 1)) | ||
|
||
// Derive height (or depth of tree) with signature and proof length. | ||
height := shr(OneWordShift, sub(fullLength, signatureLength)) | ||
|
||
// Update the length in memory to only include the signature. | ||
mstore(proofAndSignature, signatureLength) | ||
|
||
// Derive the pointer for the key using the signature length. | ||
let keyPtr := add(proofAndSignature, add(OneWord, signatureLength)) | ||
|
||
// Retrieve the three-byte key using the derived pointer. | ||
let key := shr(BulkOrderProof_keyShift, mload(keyPtr)) | ||
|
||
/// Retrieve pointer to first proof element by applying a constant | ||
// for the key size to the derived key pointer. | ||
let proof := add(keyPtr, BulkOrderProof_keySize) | ||
|
||
// Compute level 1. | ||
let scratchPtr1 := shl(OneWordShift, and(key, 1)) | ||
mstore(scratchPtr1, leaf) | ||
mstore(xor(scratchPtr1, OneWord), mload(proof)) | ||
|
||
// Compute remaining proofs. | ||
for { | ||
let i := 1 | ||
} lt(i, height) { | ||
i := add(i, 1) | ||
} { | ||
proof := add(proof, OneWord) | ||
let scratchPtr := shl(OneWordShift, and(shr(i, key), 1)) | ||
mstore(scratchPtr, keccak256(0, TwoWords)) | ||
mstore(xor(scratchPtr, OneWord), mload(proof)) | ||
} | ||
|
||
// Compute root hash. | ||
root := keccak256(0, TwoWords) | ||
} | ||
|
||
// Retrieve appropriate typehash constant based on height. | ||
bytes32 rootTypeHash = _lookupBulkOrderTypehash(height); | ||
|
||
// Use the typehash and the root hash to derive final bulk order hash. | ||
assembly { | ||
mstore(0, rootTypeHash) | ||
mstore(OneWord, root) | ||
bulkOrderHash := keccak256(0, TwoWords) | ||
} | ||
} |
Check warning
Code scanning / Slither
Assembly usage Warning
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #633 +/- ##
==========================================
- Coverage 65.26% 64.69% -0.58%
==========================================
Files 217 220 +3
Lines 6847 6908 +61
==========================================
Hits 4469 4469
- Misses 2378 2439 +61 ☔ View full report in Codecov by Sentry. |
No description provided.