Skip to content

Commit

Permalink
⚡️ Optimize initCodeERC1967 (#805)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectorized committed Jan 23, 2024
1 parent dcdddfd commit 7593af5
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 46 deletions.
65 changes: 31 additions & 34 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -221,21 +221,21 @@ ERC2981Test:testRoyaltyOverflowCheckDifferential(uint256,uint256) (runs: 256, μ
ERC2981Test:testSetAndGetRoyaltyInfo(uint256) (runs: 256, μ: 107960, ~: 104831)
ERC2981Test:test__codesize() (gas: 8419)
ERC4337FactoryTest:testCreateAccountRepeatedDeployment() (gas: 149757)
ERC4337FactoryTest:testCreateAccountRepeatedDeployment(uint256) (runs: 256, μ: 171766, ~: 171754)
ERC4337FactoryTest:testDeployDeterministic(uint256) (runs: 256, μ: 134010, ~: 139899)
ERC4337FactoryTest:testCreateAccountRepeatedDeployment(uint256) (runs: 256, μ: 171769, ~: 171755)
ERC4337FactoryTest:testDeployDeterministic(uint256) (runs: 256, μ: 134037, ~: 139900)
ERC4337FactoryTest:test__codesize() (gas: 13520)
ERC4337Test:testCdFallback() (gas: 443989)
ERC4337Test:testCdFallback2() (gas: 1140699)
ERC4337Test:testDelegateExecute() (gas: 369570)
ERC4337Test:testDelegateExecute(uint256) (runs: 256, μ: 357884, ~: 344555)
ERC4337Test:testDelegateExecute(uint256) (runs: 256, μ: 353327, ~: 344555)
ERC4337Test:testDelegateExecuteRevertsIfOwnerSlotValueChanged() (gas: 319282)
ERC4337Test:testDepositFunctions() (gas: 502955)
ERC4337Test:testDirectStorage() (gas: 70413)
ERC4337Test:testDisableInitializerForImplementation() (gas: 1177324)
ERC4337Test:testETHReceived() (gas: 16584)
ERC4337Test:testExecute() (gas: 382786)
ERC4337Test:testExecuteBatch() (gas: 692605)
ERC4337Test:testExecuteBatch(uint256) (runs: 256, μ: 496893, ~: 368308)
ERC4337Test:testExecuteBatch(uint256) (runs: 256, μ: 515118, ~: 368207)
ERC4337Test:testInitializer() (gas: 285192)
ERC4337Test:testIsValidSignature() (gas: 111663)
ERC4337Test:testIsValidSignaturePersonalSign() (gas: 96270)
Expand Down Expand Up @@ -270,7 +270,7 @@ ERC6551Test:testDeployERC6551(uint256) (runs: 256, μ: 171228, ~: 168767)
ERC6551Test:testDeployERC6551Proxy() (gas: 80751)
ERC6551Test:testExecute() (gas: 507949)
ERC6551Test:testExecuteBatch() (gas: 817049)
ERC6551Test:testExecuteBatch(uint256) (runs: 256, μ: 619121, ~: 483224)
ERC6551Test:testExecuteBatch(uint256) (runs: 256, μ: 612404, ~: 495821)
ERC6551Test:testInitializeERC6551ProxyImplementation() (gas: 189807)
ERC6551Test:testIsValidSignature() (gas: 187653)
ERC6551Test:testOnERC1155BatchReceived() (gas: 1526548)
Expand Down Expand Up @@ -586,27 +586,24 @@ LibBitmapTest:testBitmapUnsetBatch() (gas: 3086142)
LibBitmapTest:testBitmapUnsetBatchAcrossMultipleBuckets() (gas: 453362)
LibBitmapTest:testBitmapUnsetBatchWithinSingleBucket() (gas: 446762)
LibBitmapTest:test__codesize() (gas: 8132)
LibCloneTest:testClone() (gas: 72992)
LibCloneTest:testClone(uint256) (runs: 256, μ: 73021, ~: 73021)
LibCloneTest:testCloneDeteministicWithImmutableArgs() (gas: 193070)
LibCloneTest:testCloneDeteministicWithImmutableArgs(address,uint256,uint256[],bytes,uint64,uint8,uint256) (runs: 256, μ: 1055183, ~: 996334)
LibCloneTest:testCloneDeterministic() (gas: 96790)
LibCloneTest:testCloneDeterministic(uint256,bytes32) (runs: 256, μ: 96860, ~: 96860)
LibCloneTest:testCloneDeterministicRevertsIfAddressAlreadyUsed() (gas: 96882833)
LibCloneTest:testCloneWithImmutableArgs() (gas: 120835)
LibCloneTest:testCloneWithImmutableArgs(uint256,address,uint256,uint256[],uint64,uint8) (runs: 256, μ: 987603, ~: 1012323)
LibCloneTest:testCloneWithImmutableArgsRevertsIfDataTooBig() (gas: 97305791)
LibCloneTest:testDeployDeterministicERC1967() (gas: 123158)
LibCloneTest:testDeployDeterministicERC1967(uint256,bytes32) (runs: 256, μ: 123186, ~: 123186)
LibCloneTest:testDeployERC1967() (gas: 99238)
LibCloneTest:testDeployERC1967(uint256) (runs: 256, μ: 99311, ~: 99311)
LibCloneTest:testInitCode(address) (runs: 256, μ: 717905, ~: 612555)
LibCloneTest:testInitCode(address,uint256) (runs: 256, μ: 748894, ~: 613952)
LibCloneTest:testInitCodeERC1967(address) (runs: 256, μ: 701433, ~: 612630)
LibCloneTest:testInitCode_PUSH0(address) (runs: 256, μ: 735957, ~: 612591)
LibCloneTest:testInitialDeposit() (gas: 323906)
LibCloneTest:testStartsWith(uint256) (runs: 256, μ: 29047, ~: 29048)
LibCloneTest:test__codesize() (gas: 19462)
LibCloneTest:testClone() (gas: 72879)
LibCloneTest:testClone(uint256) (runs: 256, μ: 72952, ~: 72952)
LibCloneTest:testCloneDeteministicWithImmutableArgs() (gas: 192934)
LibCloneTest:testCloneDeteministicWithImmutableArgs(address,uint256,uint256[],bytes,uint64,uint8,uint256) (runs: 256, μ: 1055024, ~: 996175)
LibCloneTest:testCloneDeterministic() (gas: 96722)
LibCloneTest:testCloneDeterministic(uint256,bytes32) (runs: 256, μ: 96792, ~: 96792)
LibCloneTest:testCloneDeterministicRevertsIfAddressAlreadyUsed() (gas: 96882832)
LibCloneTest:testCloneWithImmutableArgs() (gas: 120744)
LibCloneTest:testCloneWithImmutableArgs(uint256,address,uint256,uint256[],uint64,uint8) (runs: 256, μ: 987490, ~: 1012210)
LibCloneTest:testCloneWithImmutableArgsRevertsIfDataTooBig() (gas: 97305788)
LibCloneTest:testDeployDeterministicERC1967() (gas: 123067)
LibCloneTest:testDeployDeterministicERC1967(uint256,bytes32) (runs: 256, μ: 123072, ~: 123072)
LibCloneTest:testDeployERC1967() (gas: 99147)
LibCloneTest:testDeployERC1967(uint256) (runs: 256, μ: 99220, ~: 99220)
LibCloneTest:testInitCode(address,uint256,uint256) (runs: 256, μ: 861851, ~: 768483)
LibCloneTest:testInitialDeposit() (gas: 323883)
LibCloneTest:testStartsWith(uint256) (runs: 256, μ: 29028, ~: 29026)
LibCloneTest:test__codesize() (gas: 19418)
LibMapTest:testFoundStatementDifferential(uint256,uint256,uint256) (runs: 256, μ: 499, ~: 499)
LibMapTest:testGeneralMapFunctionsGas() (gas: 3304775)
LibMapTest:testGeneralMapFunctionsWithSmallBitWidths(uint256) (runs: 256, μ: 78995, ~: 81602)
Expand Down Expand Up @@ -814,17 +811,17 @@ LibStringTest:testToStringZeroBrutalized() (gas: 591165)
LibStringTest:testToStringZeroRightPadded(uint256) (runs: 256, μ: 733933, ~: 591557)
LibStringTest:test__codesize() (gas: 42685)
LibZipTest:testCdCompress() (gas: 156007)
LibZipTest:testCdCompressDecompress(bytes) (runs: 256, μ: 749384, ~: 645943)
LibZipTest:testCdCompressDecompress(uint256) (runs: 256, μ: 784717, ~: 696279)
LibZipTest:testCdCompressDecompress(bytes) (runs: 256, μ: 751424, ~: 648337)
LibZipTest:testCdCompressDecompress(uint256) (runs: 256, μ: 798327, ~: 695927)
LibZipTest:testCdDecompressOnInvalidInput() (gas: 26080)
LibZipTest:testCdFallback() (gas: 5674556)
LibZipTest:testCdFallback(bytes,uint256) (runs: 256, μ: 1164427, ~: 1038880)
LibZipTest:testCdFallbackDecompressor(bytes) (runs: 256, μ: 121289, ~: 117627)
LibZipTest:testCdFallbackDecompressor(uint256) (runs: 256, μ: 167160, ~: 155248)
LibZipTest:testCdFallbackMaskTrick(uint256,uint256) (runs: 256, μ: 689, ~: 663)
LibZipTest:testDecompressWontRevert(bytes) (runs: 256, μ: 752845, ~: 626175)
LibZipTest:testCdFallback(bytes,uint256) (runs: 256, μ: 1190615, ~: 1039536)
LibZipTest:testCdFallbackDecompressor(bytes) (runs: 256, μ: 121292, ~: 117358)
LibZipTest:testCdFallbackDecompressor(uint256) (runs: 256, μ: 167124, ~: 155698)
LibZipTest:testCdFallbackMaskTrick(uint256,uint256) (runs: 256, μ: 690, ~: 663)
LibZipTest:testDecompressWontRevert(bytes) (runs: 256, μ: 720256, ~: 625418)
LibZipTest:testFlzCompressDecompress() (gas: 1911942)
LibZipTest:testFlzCompressDecompress(bytes) (runs: 256, μ: 843372, ~: 678002)
LibZipTest:testFlzCompressDecompress(bytes) (runs: 256, μ: 885200, ~: 678355)
LibZipTest:testFlzCompressDecompress2() (gas: 941136)
LibZipTest:test__codesize() (gas: 21701)
MerkleProofLibTest:testEmptyCalldataHelpers() (gas: 1086)
Expand Down
12 changes: 5 additions & 7 deletions src/utils/LibClone.sol
Original file line number Diff line number Diff line change
Expand Up @@ -855,17 +855,15 @@ library LibClone {
/// @solidity memory-safe-assembly
assembly {
result := mload(0x40)
mstore(add(result, 0x60), 0)
mstore(
add(result, 0x5f),
0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3
add(result, 0x60),
0x3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f300
)
mstore(
add(result, 0x3f),
0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076
add(result, 0x40),
0x55f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc
)
mstore(add(result, 0x1f), 0x6009)
mstore(add(result, 0x1d), implementation)
mstore(add(result, 0x20), or(shl(24, implementation), 0x600951))
mstore(add(result, 0x09), 0x603d3d8160223d3973)
mstore(result, 0x5f) // Store the length.
mstore(0x40, add(result, 0x80)) // Allocate memory.
Expand Down
24 changes: 19 additions & 5 deletions test/LibClone.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -420,36 +420,50 @@ contract LibCloneTest is SoladyTest, Clone {
}
}

function testInitCode(address implementation) public brutalizeMemory {
function testInitCode(address implementation, uint256 r, uint256 c) public {
if (c & (1 << 0) == 0) _testInitCode(implementation);
if (c & (1 << 1) == 0) _testInitCode_PUSH0(implementation);
if (c & (1 << 2) == 0) _testInitCode(implementation, r);
if (c & (1 << 3) == 0) _testInitCodeERC1967(implementation);
}

function _testInitCode(address implementation) internal {
_brutalizeMemory();
bytes memory initCode = LibClone.initCode(_brutalized(implementation));
_checkMemory(initCode);
_brutalizeMemory();
bytes32 expected = LibClone.initCodeHash(_brutalized(implementation));
_checkMemory(initCode);
assertEq(keccak256(initCode), expected);
}

function testInitCode_PUSH0(address implementation) public brutalizeMemory {
function _testInitCode_PUSH0(address implementation) internal {
_brutalizeMemory();
bytes memory initCode = LibClone.initCode_PUSH0(_brutalized(implementation));
_checkMemory(initCode);
_brutalizeMemory();
bytes32 expected = LibClone.initCodeHash_PUSH0(_brutalized(implementation));
_checkMemory(initCode);
assertEq(keccak256(initCode), expected);
}

function testInitCode(address implementation, uint256 n) public brutalizeMemory {
function _testInitCode(address implementation, uint256 n) internal {
_brutalizeMemory();
bytes memory data;
if ((n >> 32) & 31 > 0) data = _dummyData((n >> 128) & 0xff);
bytes memory initCode = LibClone.initCode(implementation, data);
_checkMemory(initCode);
if ((n >> 64) & 31 > 0) _brutalizeMemory();
_brutalizeMemory();
bytes32 expected = LibClone.initCodeHash(implementation, data);
_checkMemory(initCode);
assertEq(keccak256(initCode), expected);
}

function testInitCodeERC1967(address implementation) public brutalizeMemory {
function _testInitCodeERC1967(address implementation) internal {
_brutalizeMemory();
bytes memory initCode = LibClone.initCodeERC1967(_brutalized(implementation));
_checkMemory(initCode);
_brutalizeMemory();
bytes32 expected = LibClone.initCodeHashERC1967(_brutalized(implementation));
_checkMemory(initCode);
assertEq(keccak256(initCode), expected);
Expand Down

0 comments on commit 7593af5

Please sign in to comment.