Skip to content

Commit

Permalink
fix tests + include initial implementation in hash
Browse files Browse the repository at this point in the history
  • Loading branch information
wilsoncusack committed Apr 10, 2024
1 parent a87beb2 commit a1bb2e6
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 66 deletions.
18 changes: 10 additions & 8 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ AddOwnerPublicKeyTest:testRevertsIfAlreadyOwner() (gas: 116355)
AddOwnerPublicKeyTest:testRevertsIfCalledByNonOwner() (gas: 11754)
AddOwnerPublicKeyTest:testSetsIsOwner() (gas: 113769)
AddOwnerPublicKeyTest:testSetsOwnerAtIndex() (gas: 128616)
CoinbaseSmartWalletFactoryTest:testDeployDeterministicPassValues() (gas: 277752)
CoinbaseSmartWalletFactoryTest:test_CreateAccount_ReturnsPredeterminedAddress_WhenAccountAlreadyExists() (gas: 298114)
CoinbaseSmartWalletFactoryTest:test_RevertsIfLength32ButLargerThanAddress() (gas: 309390)
CoinbaseSmartWalletFactoryTest:test_createAccountDeploysToPredeterminedAddress() (gas: 279250)
CoinbaseSmartWalletFactoryTest:test_createAccountSetsOwnersCorrectly() (gas: 283767)
CoinbaseSmartWalletFactoryTest:test_exitIfAccountIsAlreadyInitialized() (gas: 278647)
CoinbaseSmartWallet1271InputGeneratorTest:testGetReplaySafeHashForDeployedAccount() (gas: 318694)
CoinbaseSmartWallet1271InputGeneratorTest:testGetReplaySafeHashForUndeployedAccount() (gas: 302399)
CoinbaseSmartWalletFactoryTest:testDeployDeterministicPassValues() (gas: 277765)
CoinbaseSmartWalletFactoryTest:test_CreateAccount_ReturnsPredeterminedAddress_WhenAccountAlreadyExists() (gas: 298380)
CoinbaseSmartWalletFactoryTest:test_RevertsIfLength32ButLargerThanAddress() (gas: 309404)
CoinbaseSmartWalletFactoryTest:test_createAccountDeploysToPredeterminedAddress() (gas: 279503)
CoinbaseSmartWalletFactoryTest:test_createAccountSetsOwnersCorrectly() (gas: 283780)
CoinbaseSmartWalletFactoryTest:test_exitIfAccountIsAlreadyInitialized() (gas: 278673)
CoinbaseSmartWalletFactoryTest:test_initCodeHash() (gas: 8795)
CoinbaseSmartWalletFactoryTest:test_revertsIfNoOwners() (gas: 31068)
CoinbaseSmartWalletFactoryTest:test_revertsIfNoOwners() (gas: 31029)
ERC1271Test:test_returnsExpectedDomainHashWhenProxy() (gas: 29198)
ERC1271Test:test_static() (gas: 3243921)
MultiOwnableInitializeTest:testRevertsIfLength32ButLargerThanAddress() (gas: 81111)
Expand All @@ -41,7 +43,7 @@ TestCanSkipChainIdValidation:test_approvedSelectorsReturnTrue() (gas: 15845)
TestCanSkipChainIdValidation:test_otherSelectorsReturnFalse() (gas: 12469)
TestExecuteWithoutChainIdValidation:testExecute() (gas: 424837)
TestExecuteWithoutChainIdValidation:testExecuteBatch() (gas: 728897)
TestExecuteWithoutChainIdValidation:testExecuteBatch(uint256) (runs: 256, μ: 3626898, ~: 3472813)
TestExecuteWithoutChainIdValidation:testExecuteBatch(uint256) (runs: 256, μ: 3612753, ~: 3472828)
TestExecuteWithoutChainIdValidation:test__codesize() (gas: 49960)
TestExecuteWithoutChainIdValidation:test__codesize() (gas: 50195)
TestExecuteWithoutChainIdValidation:test_revertsWithReservedNonce() (gas: 82347)
Expand Down
19 changes: 14 additions & 5 deletions src/CoinbaseSmartWalletFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ contract CoinbaseSmartWalletFactory {
}

(bool alreadyDeployed, address accountAddress) =
LibClone.createDeterministicERC1967(msg.value, emptyImplementation, _getSalt(owners, nonce));
LibClone.createDeterministicERC1967(msg.value, emptyImplementation, _getSalt(owners, nonce, implementation));

account = CoinbaseSmartWallet(payable(accountAddress));

Expand All @@ -58,8 +58,13 @@ contract CoinbaseSmartWalletFactory {
/// @param nonce The nonce provided to `createAccount()`.
///
/// @return predicted The predicted account deployment address.
function getAddress(bytes[] calldata owners, uint256 nonce) external view returns (address predicted) {
predicted = LibClone.predictDeterministicAddress(initCodeHash(), _getSalt(owners, nonce), address(this));
function getAddress(bytes[] calldata owners, uint256 nonce, address implementation)
external
view
returns (address predicted)
{
predicted =
LibClone.predictDeterministicAddress(initCodeHash(), _getSalt(owners, nonce, implementation), address(this));
}

/// @notice Returns the initialization code hash of the account (a minimal ERC1967 proxy).
Expand All @@ -75,7 +80,11 @@ contract CoinbaseSmartWalletFactory {
/// @param nonce The nonce provided to `createAccount()`.
///
/// @return salt The computed salt.
function _getSalt(bytes[] calldata owners, uint256 nonce) internal pure returns (bytes32 salt) {
salt = keccak256(abi.encode(owners, nonce));
function _getSalt(bytes[] calldata owners, uint256 nonce, address implementation)
internal
pure
returns (bytes32 salt)
{
salt = keccak256(abi.encode(owners, nonce, implementation));
}
}
8 changes: 4 additions & 4 deletions test/CoinbaseSmartWallet/IsValidSignature.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ contract TestIsValidSignature is SmartWalletTestBase {
r: uint256(r),
s: uint256(s)
})
)
)
})
);

Expand Down Expand Up @@ -78,7 +78,7 @@ contract TestIsValidSignature is SmartWalletTestBase {
r: uint256(r),
s: uint256(s)
})
)
)
})
);

Expand Down Expand Up @@ -106,7 +106,7 @@ contract TestIsValidSignature is SmartWalletTestBase {
r: uint256(r) - 1,
s: uint256(s)
})
)
)
})
);

Expand Down Expand Up @@ -153,7 +153,7 @@ contract TestIsValidSignature is SmartWalletTestBase {
r: uint256(r) - 1,
s: uint256(s)
})
)
)
})
);

Expand Down
2 changes: 1 addition & 1 deletion test/CoinbaseSmartWallet/ValidateUserOp.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ contract TestValidateUserOp is SmartWalletTestBase {
r: uint256(r),
s: uint256(s)
})
)
)
})
);

Expand Down
4 changes: 2 additions & 2 deletions test/CoinbaseSmartWalletFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ contract CoinbaseSmartWalletFactoryTest is Test {
}

function test_createAccountDeploysToPredeterminedAddress() public {
address p = factory.getAddress(owners, 0);
address p = factory.getAddress(owners, 0, address(account));
CoinbaseSmartWallet a = factory.createAccount{value: 1e18}(owners, 0, address(account));
assertEq(address(a), p);
}

function test_CreateAccount_ReturnsPredeterminedAddress_WhenAccountAlreadyExists() public {
address p = factory.getAddress(owners, 0);
address p = factory.getAddress(owners, 0, address(account));
CoinbaseSmartWallet a = factory.createAccount{value: 1e18}(owners, 0, address(account));
CoinbaseSmartWallet b = factory.createAccount{value: 1e18}(owners, 0, address(account));
assertEq(address(a), p);
Expand Down
95 changes: 49 additions & 46 deletions test/ERC1271InputGenerator.t.sol
Original file line number Diff line number Diff line change
@@ -1,46 +1,49 @@
// SPDX-License-Identifier: UNLICENSED
// pragma solidity ^0.8.0;

// import {Test, console2} from "forge-std/Test.sol";
// import {CoinbaseSmartWallet} from "../src/CoinbaseSmartWallet.sol";
// import {CoinbaseSmartWalletFactory} from "../src/CoinbaseSmartWalletFactory.sol";
// import {ERC1271InputGenerator} from "../src/utils/ERC1271InputGenerator.sol";

// contract CoinbaseSmartWallet1271InputGeneratorTest is Test {
// CoinbaseSmartWalletFactory factory;
// CoinbaseSmartWallet implementation;
// CoinbaseSmartWallet deployedAccount;
// bytes[] owners;

// function setUp() public {
// implementation = new CoinbaseSmartWallet();
// factory = new CoinbaseSmartWalletFactory(address(implementation));
// }

// function testGetReplaySafeHashForDeployedAccount() public {
// owners.push(abi.encode(address(1)));
// deployedAccount = CoinbaseSmartWallet(payable(factory.createAccount(owners, 0)));

// bytes32 hash = 0x15fa6f8c855db1dccbb8a42eef3a7b83f11d29758e84aed37312527165d5eec5;
// bytes32 replaySafeHash = deployedAccount.replaySafeHash(hash);
// ERC1271InputGenerator generator = new ERC1271InputGenerator(deployedAccount, hash, address(0), "");
// assertEq(bytes32(address(generator).code), replaySafeHash);
// }

// function testGetReplaySafeHashForUndeployedAccount() public {
// owners.push(abi.encode(address(1)));
// CoinbaseSmartWallet undeployedAccount = CoinbaseSmartWallet(payable(factory.getAddress(owners, 0)));
// bytes32 hash = 0x15fa6f8c855db1dccbb8a42eef3a7b83f11d29758e84aed37312527165d5eec5;
// ERC1271InputGenerator generator = new ERC1271InputGenerator(
// undeployedAccount,
// hash,
// address(factory),
// abi.encodeWithSignature("createAccount(bytes[],uint256)", owners, 0)
// );

// // This is now deployed.
// bytes32 replaySafeHash = undeployedAccount.replaySafeHash(hash);

// assertEq(bytes32(address(generator).code), replaySafeHash);
// }
// }
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Test, console2} from "forge-std/Test.sol";
import {CoinbaseSmartWallet} from "../src/CoinbaseSmartWallet.sol";
import {CoinbaseSmartWalletFactory} from "../src/CoinbaseSmartWalletFactory.sol";
import {ERC1271InputGenerator} from "../src/utils/ERC1271InputGenerator.sol";

contract CoinbaseSmartWallet1271InputGeneratorTest is Test {
CoinbaseSmartWalletFactory factory;
CoinbaseSmartWallet implementation;
CoinbaseSmartWallet deployedAccount;
bytes[] owners;

function setUp() public {
implementation = new CoinbaseSmartWallet();
factory = new CoinbaseSmartWalletFactory();
}

function testGetReplaySafeHashForDeployedAccount() public {
owners.push(abi.encode(address(1)));
deployedAccount = CoinbaseSmartWallet(payable(factory.createAccount(owners, 0, address(implementation))));

bytes32 hash = 0x15fa6f8c855db1dccbb8a42eef3a7b83f11d29758e84aed37312527165d5eec5;
bytes32 replaySafeHash = deployedAccount.replaySafeHash(hash);
ERC1271InputGenerator generator = new ERC1271InputGenerator(deployedAccount, hash, address(0), "");
assertEq(bytes32(address(generator).code), replaySafeHash);
}

function testGetReplaySafeHashForUndeployedAccount() public {
owners.push(abi.encode(address(1)));
CoinbaseSmartWallet undeployedAccount =
CoinbaseSmartWallet(payable(factory.getAddress(owners, 0, address(implementation))));
bytes32 hash = 0x15fa6f8c855db1dccbb8a42eef3a7b83f11d29758e84aed37312527165d5eec5;
ERC1271InputGenerator generator = new ERC1271InputGenerator(
undeployedAccount,
hash,
address(factory),
abi.encodeWithSelector(
CoinbaseSmartWalletFactory.createAccount.selector, owners, 0, address(implementation)
)
);

// This is now deployed.
bytes32 replaySafeHash = undeployedAccount.replaySafeHash(hash);

assertEq(bytes32(address(generator).code), replaySafeHash);
}
}

0 comments on commit a1bb2e6

Please sign in to comment.