Skip to content

Commit

Permalink
♻️ Tidy SSTORE2 (#571)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectorized authored Aug 31, 2023
1 parent a3ba516 commit 161481d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 32 deletions.
38 changes: 19 additions & 19 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -233,33 +233,33 @@ ERC4626Test:test__codesize() (gas: 41477)
ERC6909Test:testApprove() (gas: 36639)
ERC6909Test:testApprove(address,uint256,uint256) (runs: 256, μ: 36315, ~: 37248)
ERC6909Test:testBurn() (gas: 63262)
ERC6909Test:testBurn(address,uint256,uint256,uint256) (runs: 256, μ: 60734, ~: 63883)
ERC6909Test:testBurnInsufficientBalanceReverts(address,uint256,uint256,uint256) (runs: 256, μ: 56394, ~: 57598)
ERC6909Test:testBurn(address,uint256,uint256,uint256) (runs: 256, μ: 60723, ~: 63883)
ERC6909Test:testBurnInsufficientBalanceReverts(address,uint256,uint256,uint256) (runs: 256, μ: 56553, ~: 57630)
ERC6909Test:testDecimals() (gas: 5610)
ERC6909Test:testDirectApprove() (gas: 36578)
ERC6909Test:testDirectFunctions(uint256) (runs: 256, μ: 247962, ~: 248483)
ERC6909Test:testDirectFunctions(uint256) (runs: 256, μ: 247063, ~: 248457)
ERC6909Test:testDirectSetOperator() (gas: 35947)
ERC6909Test:testInfiniteApproveTransferFrom() (gas: 100267)
ERC6909Test:testMetadata() (gas: 9310)
ERC6909Test:testMint() (gas: 59540)
ERC6909Test:testMint(address,uint256,uint256) (runs: 256, μ: 57928, ~: 59794)
ERC6909Test:testMintOverMaxUintReverts() (gas: 56350)
ERC6909Test:testMintTotalSupplyOverFlowReverts(address,uint256,uint256,uint256) (runs: 256, μ: 53081, ~: 53659)
ERC6909Test:testMintTotalSupplyOverFlowReverts(address,uint256,uint256,uint256) (runs: 256, μ: 52910, ~: 53659)
ERC6909Test:testOperatorTransferFrom() (gas: 96103)
ERC6909Test:testSetOperator() (gas: 37185)
ERC6909Test:testSetOperator(address,address,bool) (runs: 256, μ: 22773, ~: 16788)
ERC6909Test:testSetOperator(address,address,bool) (runs: 256, μ: 22618, ~: 16788)
ERC6909Test:testTokenURI() (gas: 55211)
ERC6909Test:testTransfer() (gas: 67712)
ERC6909Test:testTransfer(address,uint256,uint256) (runs: 256, μ: 65020, ~: 66886)
ERC6909Test:testTransferFrom() (gas: 92062)
ERC6909Test:testTransferFrom(address,address,address,uint256,uint256,uint256) (runs: 256, μ: 96932, ~: 102792)
ERC6909Test:testTransferFrom(address,address,address,uint256,uint256,uint256) (runs: 256, μ: 96900, ~: 102792)
ERC6909Test:testTransferFromCallerIsNotOperator(address,uint256,uint256) (runs: 256, μ: 61832, ~: 61829)
ERC6909Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256,uint256) (runs: 256, μ: 88007, ~: 89857)
ERC6909Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256,uint256) (runs: 256, μ: 87921, ~: 89793)
ERC6909Test:testTransferFromInsufficientBalanceReverts() (gas: 69669)
ERC6909Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256,uint256) (runs: 256, μ: 71858, ~: 70196)
ERC6909Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256,uint256) (runs: 256, μ: 71860, ~: 70196)
ERC6909Test:testTransferFromInsufficientPermission() (gas: 89223)
ERC6909Test:testTransferInsufficientBalanceReverts() (gas: 57067)
ERC6909Test:testTransferInsufficientBalanceReverts(address,uint256,uint256,uint256) (runs: 256, μ: 56055, ~: 57596)
ERC6909Test:testTransferInsufficientBalanceReverts(address,uint256,uint256,uint256) (runs: 256, μ: 56051, ~: 57532)
ERC6909Test:test__codesize() (gas: 24193)
ERC721HooksTest:testERC721Hooks() (gas: 2881104)
ERC721HooksTest:test__codesize() (gas: 9721)
Expand Down Expand Up @@ -805,28 +805,28 @@ RedBlackTreeLibTest:testRedBlackTreeTreeFullReverts() (gas: 50293)
RedBlackTreeLibTest:testRedBlackTreeTryInsertAndRemove() (gas: 56127)
RedBlackTreeLibTest:test__codesize() (gas: 13237)
SSTORE2Test:testReadInvalidPointerCustomBoundsReverts() (gas: 3242)
SSTORE2Test:testReadInvalidPointerCustomBoundsReverts(address,uint256,uint256) (runs: 256, μ: 748036, ~: 637611)
SSTORE2Test:testReadInvalidPointerCustomBoundsReverts(address,uint256,uint256) (runs: 256, μ: 680900, ~: 637343)
SSTORE2Test:testReadInvalidPointerCustomStartBoundReverts() (gas: 3241)
SSTORE2Test:testReadInvalidPointerCustomStartBoundReverts(address,uint256) (runs: 256, μ: 739789, ~: 637730)
SSTORE2Test:testReadInvalidPointerRevert(address) (runs: 256, μ: 741871, ~: 637456)
SSTORE2Test:testReadInvalidPointerCustomStartBoundReverts(address,uint256) (runs: 256, μ: 749154, ~: 637512)
SSTORE2Test:testReadInvalidPointerRevert(address) (runs: 256, μ: 757051, ~: 637322)
SSTORE2Test:testReadInvalidPointerReverts() (gas: 3215)
SSTORE2Test:testWriteRead() (gas: 76118)
SSTORE2Test:testWriteRead(bytes) (runs: 256, μ: 841055, ~: 681781)
SSTORE2Test:testWriteRead(bytes) (runs: 256, μ: 779965, ~: 681344)
SSTORE2Test:testWriteReadCustomBounds() (gas: 34599)
SSTORE2Test:testWriteReadCustomBounds(bytes,uint256,uint256) (runs: 256, μ: 701733, ~: 669703)
SSTORE2Test:testWriteReadCustomBoundsOutOfRangeReverts(bytes,uint256,uint256) (runs: 256, μ: 837470, ~: 675326)
SSTORE2Test:testWriteReadCustomBounds(bytes,uint256,uint256) (runs: 256, μ: 694885, ~: 669569)
SSTORE2Test:testWriteReadCustomBoundsOutOfRangeReverts(bytes,uint256,uint256) (runs: 256, μ: 821319, ~: 675410)
SSTORE2Test:testWriteReadCustomStartBound() (gas: 34855)
SSTORE2Test:testWriteReadCustomStartBound(bytes,uint256) (runs: 256, μ: 773262, ~: 678912)
SSTORE2Test:testWriteReadCustomStartBoundOutOfRangeReverts(bytes,uint256) (runs: 256, μ: 781433, ~: 675343)
SSTORE2Test:testWriteReadDeterministic(bytes) (runs: 256, μ: 858077, ~: 755308)
SSTORE2Test:testWriteReadCustomStartBound(bytes,uint256) (runs: 256, μ: 765379, ~: 678649)
SSTORE2Test:testWriteReadCustomStartBoundOutOfRangeReverts(bytes,uint256) (runs: 256, μ: 831117, ~: 675258)
SSTORE2Test:testWriteReadDeterministic(bytes) (runs: 256, μ: 892985, ~: 755527)
SSTORE2Test:testWriteReadEmptyBound() (gas: 33825)
SSTORE2Test:testWriteReadEmptyOutOfBoundsReverts() (gas: 36485)
SSTORE2Test:testWriteReadFullBoundedRead() (gas: 76158)
SSTORE2Test:testWriteReadFullStartBound() (gas: 35087)
SSTORE2Test:testWriteReadOutOfBoundsReverts() (gas: 36463)
SSTORE2Test:testWriteReadOutOfStartBoundReverts() (gas: 36467)
SSTORE2Test:testWriteWithTooBigDataReverts() (gas: 97800390)
SSTORE2Test:test__codesize() (gas: 9669)
SSTORE2Test:test__codesize() (gas: 9668)
SafeCastLibTest:testSafeCastToInt(int256) (runs: 256, μ: 4384, ~: 3415)
SafeCastLibTest:testSafeCastToInt256(uint256) (runs: 256, μ: 931, ~: 390)
SafeCastLibTest:testSafeCastToIntBench() (gas: 383456)
Expand Down
24 changes: 11 additions & 13 deletions src/utils/SSTORE2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ library SSTORE2 {
* ------------------------------------------------------------------------------+
* Opcode | Mnemonic | Stack | Memory |
* ------------------------------------------------------------------------------|
* 61 codeSize | PUSH2 codeSize | codeSize | |
* 80 | DUP1 | codeSize codeSize | |
* 60 0xa | PUSH1 0xa | 0xa codeSize codeSize | |
* 3D | RETURNDATASIZE | 0 0xa codeSize codeSize | |
* 39 | CODECOPY | codeSize | [0..codeSize): code |
* 3D | RETURNDATASIZE | 0 codeSize | [0..codeSize): code |
* F3 | RETURN | | [0..codeSize): code |
* 61 dataSize | PUSH2 dataSize | dataSize | |
* 80 | DUP1 | dataSize dataSize | |
* 60 0xa | PUSH1 0xa | 0xa dataSize dataSize | |
* 3D | RETURNDATASIZE | 0 0xa dataSize dataSize | |
* 39 | CODECOPY | dataSize | [0..dataSize): code |
* 3D | RETURNDATASIZE | 0 dataSize | [0..dataSize): code |
* F3 | RETURN | | [0..dataSize): code |
* 00 | STOP | | |
* ------------------------------------------------------------------------------+
* @dev Prefix the bytecode with a STOP opcode to ensure it cannot be called.
Expand All @@ -61,11 +61,8 @@ library SSTORE2 {
// Do a out-of-gas revert if `dataSize` is more than 2 bytes.
// The actual EVM limit may be smaller and may change over time.
add(data, gt(dataSize, 0xffff)),
or(
0xfd61000080600a3d393df300,
// Left shift `dataSize` by 64 so that it lines up with the 0000 after PUSH2.
shl(0x40, dataSize)
)
// Left shift `dataSize` by 64 so that it lines up with the 0000 after PUSH2.
or(0xfd61000080600a3d393df300, shl(0x40, dataSize))
)

// Deploy a new contract with the generated creation code.
Expand Down Expand Up @@ -99,6 +96,7 @@ library SSTORE2 {
// Do a out-of-gas revert if `dataSize` is more than 2 bytes.
// The actual EVM limit may be smaller and may change over time.
add(data, gt(dataSize, 0xffff)),
// Left shift `dataSize` by 64 so that it lines up with the 0000 after PUSH2.
or(0xfd61000080600a3d393df300, shl(0x40, dataSize))
)

Expand Down Expand Up @@ -128,7 +126,7 @@ library SSTORE2 {

// Do a out-of-gas revert if `dataSize` is more than 2 bytes.
// The actual EVM limit may be smaller and may change over time.
returndatacopy(returndatasize(), returndatasize(), gt(dataSize, 0xffff))
returndatacopy(returndatasize(), returndatasize(), shr(16, dataSize))

mstore(data, or(0x61000080600a3d393df300, shl(0x40, dataSize)))

Expand Down

0 comments on commit 161481d

Please sign in to comment.