Skip to content

Commit

Permalink
perf: assembly optimisations (Finding 8) (#43)
Browse files Browse the repository at this point in the history
* perf: write `Create2` revert data to the beginning of memory

* perf: assembly for all of `ERC721TransferLib._transfer()` with reusable data
  • Loading branch information
ARR4N authored Aug 4, 2024
1 parent fb56fb7 commit 8f51558
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 20 deletions.
12 changes: 6 additions & 6 deletions src/Create2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ library Create2 {
}

assembly ("memory-safe") {
let free := mload(0x40)

if iszero(returndatasize()) {
mstore(free, 0x33d2bae4) // Create2EmptyRevert()
revert(add(free, 28), 4)
mstore(0, 0x33d2bae4) // Create2EmptyRevert()
revert(28, 4)
}

returndatacopy(free, 0, returndatasize())
revert(free, returndatasize())
// Even though this may extend beyond scratch space, we revert the current context immediately so it's still
// memory-safe.
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
23 changes: 9 additions & 14 deletions src/ERC721TransferLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,19 @@ library ERC721TransferLib {
}
uint256[] memory ids = token.ids;

uint256 idSrc;
uint256 idDst;
assembly ("memory-safe") {
idSrc := add(ids, 0x20)
idDst := add(reusableCallData, 0x64)
}
let idSrc := add(ids, 0x20)
let idDst := add(reusableCallData, 0x64)
let dataPtr := add(reusableCallData, 0x20)

for (uint256 end = idSrc + ids.length * 0x20; idSrc < end; idSrc += 0x20) {
assembly ("memory-safe") {
for { let end := add(idSrc, mul(mload(ids), 0x20)) } lt(idSrc, end) { idSrc := add(idSrc, 0x20) } {
mcopy(idDst, idSrc, 0x20)
}
(bool success,) = addr.call(reusableCallData);

if (!success) {
assembly ("memory-safe") {
let free := mload(0x40)
returndatacopy(free, 0, returndatasize())
revert(free, returndatasize())
if iszero(call(gas(), addr, 0, dataPtr, reusableCallData, 0, 0)) {
// Even though this may extend beyond scratch space, we revert the current context immediately so
// it's still memory-safe.
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
Expand Down

0 comments on commit 8f51558

Please sign in to comment.