diff --git a/.gas-snapshot b/.gas-snapshot index 9ae8948..27436c8 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,52 +1,53 @@ -AddOwnerAddressTest:testEmitsAddOwner() (gas: 92374) -AddOwnerAddressTest:testIncreasesOwnerIndex() (gas: 90614) -AddOwnerAddressTest:testRevertsIfAlreadyOwner() (gas: 93137) -AddOwnerAddressTest:testRevertsIfCalledByNonOwner() (gas: 11754) -AddOwnerAddressTest:testSetsIsOwner() (gas: 90476) -AddOwnerAddressTest:testSetsOwnerAtIndex() (gas: 98897) -AddOwnerPublicKeyTest:testEmitsAddOwner() (gas: 115509) -AddOwnerPublicKeyTest:testFuzzIsOwnerPublicKey(bytes32,bytes32) (runs: 256, μ: 115333, ~: 115333) -AddOwnerPublicKeyTest:testRevertsIfAlreadyOwner() (gas: 116301) -AddOwnerPublicKeyTest:testRevertsIfCalledByNonOwner() (gas: 11744) -AddOwnerPublicKeyTest:testSetsIsOwner() (gas: 113775) -AddOwnerPublicKeyTest:testSetsOwnerAtIndex() (gas: 128543) -CoinbaseSmartWallet1271InputGeneratorTest:testGetReplaySafeHashForDeployedAccount() (gas: 308664) -CoinbaseSmartWallet1271InputGeneratorTest:testGetReplaySafeHashForUndeployedAccount() (gas: 291435) +AddOwnerAddressTest:testEmitsAddOwner() (gas: 92393) +AddOwnerAddressTest:testIncreasesOwnerIndex() (gas: 90633) +AddOwnerAddressTest:testRevertsIfAlreadyOwner() (gas: 93175) +AddOwnerAddressTest:testRevertsIfCalledByNonOwner() (gas: 11764) +AddOwnerAddressTest:testSetsIsOwner() (gas: 90495) +AddOwnerAddressTest:testSetsOwnerAtIndex() (gas: 98916) +AddOwnerPublicKeyTest:testEmitsAddOwner() (gas: 115528) +AddOwnerPublicKeyTest:testFuzzIsOwnerPublicKey(bytes32,bytes32) (runs: 256, μ: 115352, ~: 115352) +AddOwnerPublicKeyTest:testRevertsIfAlreadyOwner() (gas: 116339) +AddOwnerPublicKeyTest:testRevertsIfCalledByNonOwner() (gas: 11754) +AddOwnerPublicKeyTest:testSetsIsOwner() (gas: 113794) +AddOwnerPublicKeyTest:testSetsOwnerAtIndex() (gas: 128562) +CoinbaseSmartWallet1271InputGeneratorTest:testGetReplaySafeHashForDeployedAccount() (gas: 308658) +CoinbaseSmartWallet1271InputGeneratorTest:testGetReplaySafeHashForUndeployedAccount() (gas: 291429) CoinbaseSmartWalletFactoryTest:testDeployDeterministicPassValues() (gas: 267742) CoinbaseSmartWalletFactoryTest:test_CreateAccount_ReturnsPredeterminedAddress_WhenAccountAlreadyExists() (gas: 287406) CoinbaseSmartWalletFactoryTest:test_createAccountDeploysToPredeterminedAddress() (gas: 269093) CoinbaseSmartWalletFactoryTest:test_createAccountSetsOwnersCorrectly() (gas: 277981) +CoinbaseSmartWalletFactoryTest:test_implementation_returnsExpectedAddress() (gas: 7676) CoinbaseSmartWalletFactoryTest:test_revertsIfNoOwners() (gas: 29214) ERC1271Test:test_returnsExpectedDomainHashWhenProxy() (gas: 15406) MultiOwnableInitializeTest:testRevertsIfLength32ButLargerThanAddress() (gas: 78927) MultiOwnableInitializeTest:testRevertsIfLength32NotAddress() (gas: 78908) MultiOwnableInitializeTest:testRevertsIfLengthNot32Or64() (gas: 101211) -RemoveOwnerAtIndexTest:testEmitsRemoveOwner() (gas: 33299) -RemoveOwnerAtIndexTest:testRemovesOwner() (gas: 32682) -RemoveOwnerAtIndexTest:testRemovesOwnerAtIndex() (gas: 27567) -RemoveOwnerAtIndexTest:testRevertsIfCalledByNonOwner() (gas: 11332) -RemoveOwnerAtIndexTest:testRevertsIfNoOwnerAtIndex() (gas: 16648) -TestCanSkipChainIdValidation:test_approvedSelectorsReturnTrue() (gas: 15845) -TestCanSkipChainIdValidation:test_otherSelectorsReturnFalse() (gas: 12469) -TestExecuteWithoutChainIdValidation:testExecute() (gas: 424705) -TestExecuteWithoutChainIdValidation:testExecuteBatch() (gas: 729086) -TestExecuteWithoutChainIdValidation:testExecuteBatch(uint256) (runs: 256, μ: 3409748, ~: 3278930) -TestExecuteWithoutChainIdValidation:test__codesize() (gas: 49006) -TestExecuteWithoutChainIdValidation:test__codesize() (gas: 49241) -TestExecuteWithoutChainIdValidation:test_canChangeOwnerWithoutChainId() (gas: 287917) -TestExecuteWithoutChainIdValidation:test_cannotCallExec() (gas: 220047) -TestExecuteWithoutChainIdValidation:test_revertsIfCallerNotEntryPoint() (gas: 8620) +RemoveOwnerAtIndexTest:testEmitsRemoveOwner() (gas: 33270) +RemoveOwnerAtIndexTest:testRemovesOwner() (gas: 32653) +RemoveOwnerAtIndexTest:testRemovesOwnerAtIndex() (gas: 27538) +RemoveOwnerAtIndexTest:testRevertsIfCalledByNonOwner() (gas: 11308) +RemoveOwnerAtIndexTest:testRevertsIfNoOwnerAtIndex() (gas: 16624) +TestCanSkipChainIdValidation:test_approvedSelectorsReturnTrue() (gas: 15933) +TestCanSkipChainIdValidation:test_otherSelectorsReturnFalse() (gas: 12513) +TestExecuteWithoutChainIdValidation:testExecute() (gas: 424907) +TestExecuteWithoutChainIdValidation:testExecuteBatch() (gas: 729143) +TestExecuteWithoutChainIdValidation:testExecuteBatch(uint256) (runs: 256, μ: 3422948, ~: 3288297) +TestExecuteWithoutChainIdValidation:test__codesize() (gas: 49053) +TestExecuteWithoutChainIdValidation:test__codesize() (gas: 49288) +TestExecuteWithoutChainIdValidation:test_canChangeOwnerWithoutChainId() (gas: 287727) +TestExecuteWithoutChainIdValidation:test_cannotCallExec() (gas: 220025) +TestExecuteWithoutChainIdValidation:test_revertsIfCallerNotEntryPoint() (gas: 8598) TestExecuteWithoutChainIdValidation:test_revertsIfWrongNonceKey() (gas: 62275) -TestExecuteWithoutChainIdValidation:test_revertsWithReservedNonce() (gas: 82302) -TestInitialize:testInitialize() (gas: 21122) -TestInitialize:test_cannotInitImplementation() (gas: 2708253) -TestIsValidSignature:testReturnsInvalidIfPasskeySigButWrongOwnerLength() (gas: 39497) -TestIsValidSignature:testRevertsIfEthereumSignatureButWrongOwnerLength() (gas: 24068) -TestIsValidSignature:testSmartWalletSigner() (gas: 2981137) -TestIsValidSignature:testValidateSignatureWithEOASigner() (gas: 24950) -TestIsValidSignature:testValidateSignatureWithEOASignerFailsWithWrongSigner() (gas: 23880) -TestIsValidSignature:testValidateSignatureWithPasskeySigner() (gas: 421284) -TestIsValidSignature:testValidateSignatureWithPasskeySignerFailsBadOwnerIndex() (gas: 34986) -TestIsValidSignature:testValidateSignatureWithPasskeySignerFailsWithWrongBadSignature() (gas: 428750) -TestUpgradeToAndCall:testUpgradeToAndCall() (gas: 23839) -TestValidateUserOp:testValidateUserOp() (gas: 447113) \ No newline at end of file +TestExecuteWithoutChainIdValidation:test_revertsWithReservedNonce() (gas: 82324) +TestInitialize:testInitialize() (gas: 21034) +TestInitialize:test_cannotInitImplementation() (gas: 2714468) +TestIsValidSignature:testReturnsInvalidIfPasskeySigButWrongOwnerLength() (gas: 39469) +TestIsValidSignature:testRevertsIfEthereumSignatureButWrongOwnerLength() (gas: 24040) +TestIsValidSignature:testSmartWalletSigner() (gas: 2990421) +TestIsValidSignature:testValidateSignatureWithEOASigner() (gas: 24922) +TestIsValidSignature:testValidateSignatureWithEOASignerFailsWithWrongSigner() (gas: 23877) +TestIsValidSignature:testValidateSignatureWithPasskeySigner() (gas: 421256) +TestIsValidSignature:testValidateSignatureWithPasskeySignerFailsBadOwnerIndex() (gas: 34958) +TestIsValidSignature:testValidateSignatureWithPasskeySignerFailsWithWrongBadSignature() (gas: 428722) +TestUpgradeToAndCall:testUpgradeToAndCall() (gas: 23836) +TestValidateUserOp:testValidateUserOp() (gas: 447275) \ No newline at end of file diff --git a/src/CoinbaseSmartWallet.sol b/src/CoinbaseSmartWallet.sol index f3b26f7..0c48b44 100644 --- a/src/CoinbaseSmartWallet.sol +++ b/src/CoinbaseSmartWallet.sol @@ -235,6 +235,15 @@ contract CoinbaseSmartWallet is MultiOwnable, UUPSUpgradeable, Receiver, ERC1271 return keccak256(abi.encode(UserOperationLib.hash(userOp), entryPoint())); } + /// @notice Returns the implementation of the ERC1967 proxy. + /// + /// @return $ The address of implementation contract. + function implementation() public view returns (address $) { + assembly { + $ := sload(_ERC1967_IMPLEMENTATION_SLOT) + } + } + /// @notice Check if the given function selector is whitelisted to skip the chain ID validation. /// /// @param functionSelector The function selector to check. diff --git a/test/CoinbaseSmartWallet/ExecuteWithoutChainIdValidation.t.sol b/test/CoinbaseSmartWallet/ExecuteWithoutChainIdValidation.t.sol index 3c2084d..e92e83a 100644 --- a/test/CoinbaseSmartWallet/ExecuteWithoutChainIdValidation.t.sol +++ b/test/CoinbaseSmartWallet/ExecuteWithoutChainIdValidation.t.sol @@ -42,7 +42,7 @@ contract TestExecuteWithoutChainIdValidation is SmartWalletTestBase { UserOperation memory userOp = _getUserOpWithSignature(); vm.expectEmit(true, true, true, true); emit IEntryPoint.UserOperationEvent( - entryPoint.getUserOpHash(userOp), userOp.sender, address(0), userOp.nonce, false, 0, 48027 + entryPoint.getUserOpHash(userOp), userOp.sender, address(0), userOp.nonce, false, 0, 48005 ); _sendUserOperation(userOp); } diff --git a/test/CoinbaseSmartWalletFactory.t.sol b/test/CoinbaseSmartWalletFactory.t.sol index 3cb9620..54f3514 100644 --- a/test/CoinbaseSmartWalletFactory.t.sol +++ b/test/CoinbaseSmartWalletFactory.t.sol @@ -51,4 +51,8 @@ contract CoinbaseSmartWalletFactoryTest is Test { CoinbaseSmartWallet a = factory.createAccount{value: 1e18}(owners, 0); assertEq(address(a).balance, 1e18); } + + function test_implementation_returnsExpectedAddress() public { + assertEq(factory.implementation(), address(account)); + } }