Skip to content

Commit 961da85

Browse files
committed
prefer fuzzing where possible
1 parent 42ecd7b commit 961da85

File tree

5 files changed

+111
-64
lines changed

5 files changed

+111
-64
lines changed

test/EIP7702Proxy/coinbaseImplementation.t.sol

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,12 @@ contract CoinbaseImplementationTest is Test {
134134
);
135135
}
136136

137-
function test_isValidSignature_succeeds_withValidOwnerSignature() public {
138-
bytes32 testHash = keccak256("test message");
137+
function test_isValidSignature_succeeds_withValidOwnerSignature(
138+
bytes32 message
139+
) public {
139140
assertTrue(
140141
wallet.isOwnerAddress(_newOwner),
141-
"New owner should be set after initialization"
142+
"New owner should be owner after initialization"
142143
);
143144
assertEq(
144145
wallet.ownerAtIndex(0),
@@ -147,23 +148,28 @@ contract CoinbaseImplementationTest is Test {
147148
);
148149

149150
bytes memory signature = _createOwnerSignature(
150-
testHash,
151+
message,
151152
address(wallet),
152153
_NEW_OWNER_PRIVATE_KEY,
153154
0 // First owner
154155
);
155156

156-
bytes4 result = wallet.isValidSignature(testHash, signature);
157+
bytes4 result = wallet.isValidSignature(message, signature);
157158
assertEq(
158159
result,
159160
ERC1271_MAGIC_VALUE,
160161
"Should accept valid contract owner signature"
161162
);
162163
}
163164

164-
function test_execute_transfersEth_whenCalledByOwner() public {
165-
address recipient = address(0xBEEF);
166-
uint256 amount = 1 ether;
165+
function test_execute_transfersEth_whenCalledByOwner(
166+
address recipient,
167+
uint256 amount
168+
) public {
169+
vm.assume(recipient != address(0));
170+
assumeNotPrecompile(recipient);
171+
assumePayable(recipient);
172+
vm.assume(amount > 0 && amount <= 100 ether);
167173

168174
vm.deal(address(_eoa), amount);
169175

@@ -181,10 +187,15 @@ contract CoinbaseImplementationTest is Test {
181187
);
182188
}
183189

184-
function test_upgradeToAndCall_reverts_whenCalledByNonOwner() public {
190+
function test_upgradeToAndCall_reverts_whenCalledByNonOwner(
191+
address nonOwner
192+
) public {
193+
vm.assume(nonOwner != address(0));
194+
vm.assume(nonOwner != _newOwner); // Ensure caller isn't the actual owner
195+
185196
address newImpl = address(new CoinbaseSmartWallet());
186197

187-
vm.prank(address(0xBAD));
198+
vm.prank(nonOwner);
188199
vm.expectRevert(); // Coinbase wallet specific access control
189200
wallet.upgradeToAndCall(newImpl, "");
190201
}

test/EIP7702Proxy/delegate.t.sol

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ contract DelegateTest is EIP7702ProxyBase {
2828
MockImplementation(payable(_eoa)).mockFunction();
2929
}
3030

31-
function test_preservesReturnData_whenReturningBytes() public {
32-
bytes memory testData = hex"deadbeef";
31+
function test_preservesReturnData_whenReturningBytes(
32+
bytes memory testData
33+
) public {
3334
bytes memory returnedData = MockImplementation(payable(_eoa))
3435
.returnBytesData(testData);
3536

@@ -40,11 +41,10 @@ contract DelegateTest is EIP7702ProxyBase {
4041
);
4142
}
4243

43-
function test_guardedInitializer_reverts_whenCalledDirectly() public {
44-
bytes memory initData = abi.encodeWithSelector(
45-
MockImplementation.initialize.selector,
46-
_newOwner
47-
);
44+
function test_guardedInitializer_reverts_whenCalledDirectly(
45+
bytes memory initData
46+
) public {
47+
vm.assume(initData.length >= 4); // At least a function selector
4848

4949
vm.expectRevert(EIP7702Proxy.InvalidInitializer.selector);
5050
address(_eoa).call(initData);
@@ -55,8 +55,11 @@ contract DelegateTest is EIP7702ProxyBase {
5555
MockImplementation(payable(_eoa)).revertingFunction();
5656
}
5757

58-
function test_reverts_whenWriteReverts() public {
59-
vm.prank(address(0xBAD));
58+
function test_reverts_whenWriteReverts(address unauthorized) public {
59+
vm.assume(unauthorized != address(0));
60+
vm.assume(unauthorized != _newOwner); // Not the owner
61+
62+
vm.prank(unauthorized);
6063
vm.expectRevert(MockImplementation.Unauthorized.selector);
6164
MockImplementation(payable(_eoa)).mockFunction();
6265

test/EIP7702Proxy/initialize.t.sol

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,27 @@ import {MockImplementation, RevertingInitializerMockImplementation} from "../moc
77
import {ECDSA} from "openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol";
88

99
contract InitializeTest is EIP7702ProxyBase {
10-
function test_succeeds_withValidSignatureAndArgs() public {
11-
bytes memory initArgs = _createInitArgs(_newOwner);
10+
function test_succeeds_withValidSignatureAndArgs(address newOwner) public {
11+
vm.assume(newOwner != address(0));
12+
assumeNotPrecompile(newOwner);
13+
14+
bytes memory initArgs = _createInitArgs(newOwner);
1215
bytes memory signature = _signInitData(_EOA_PRIVATE_KEY, initArgs);
1316

1417
EIP7702Proxy(_eoa).initialize(initArgs, signature);
1518

16-
// Verify implementation was set
17-
assertEq(
18-
_getERC1967Implementation(address(_eoa)),
19-
address(_implementation),
20-
"Implementation should be set after initialization"
19+
// Verify owner was set correctly
20+
assertTrue(
21+
MockImplementation(payable(_eoa)).owner() == newOwner,
22+
"Owner should be set to fuzzed address"
2123
);
2224
}
2325

24-
function test_setsERC1967ImplementationSlot() public {
25-
bytes memory initArgs = _createInitArgs(_newOwner);
26+
function test_setsERC1967ImplementationSlot(address newOwner) public {
27+
vm.assume(newOwner != address(0));
28+
assumeNotPrecompile(newOwner);
29+
30+
bytes memory initArgs = _createInitArgs(newOwner);
2631
bytes memory signature = _signInitData(_EOA_PRIVATE_KEY, initArgs);
2732

2833
EIP7702Proxy(_eoa).initialize(initArgs, signature);
@@ -44,8 +49,8 @@ contract InitializeTest is EIP7702ProxyBase {
4449
EIP7702Proxy(_eoa).initialize(initArgs, signature);
4550
}
4651

47-
function test_reverts_whenSignatureLengthInvalid() public {
48-
bytes memory initArgs = _createInitArgs(_newOwner);
52+
function test_reverts_whenSignatureLengthInvalid(address newOwner) public {
53+
bytes memory initArgs = _createInitArgs(newOwner);
4954
bytes memory signature = hex"deadbeef"; // Too short to be valid ECDSA signature
5055

5156
vm.expectRevert(
@@ -54,17 +59,19 @@ contract InitializeTest is EIP7702ProxyBase {
5459
EIP7702Proxy(_eoa).initialize(initArgs, signature);
5560
}
5661

57-
function test_reverts_whenSignatureInvalid() public {
58-
bytes memory initArgs = _createInitArgs(_newOwner);
62+
function test_reverts_whenSignatureInvalid(address newOwner) public {
63+
bytes memory initArgs = _createInitArgs(newOwner);
5964
// 65 bytes of invalid signature data
6065
bytes memory signature = new bytes(65);
6166

6267
vm.expectRevert(abi.encodeWithSignature("ECDSAInvalidSignature()"));
6368
EIP7702Proxy(_eoa).initialize(initArgs, signature);
6469
}
6570

66-
function test_reverts_whenSignerWrong() public {
67-
uint256 wrongPk = 0xC0FFEE;
71+
function test_reverts_whenSignerWrong(uint128 wrongPk) public {
72+
vm.assume(wrongPk != 0);
73+
vm.assume(wrongPk != _EOA_PRIVATE_KEY); // Not the valid signer
74+
6875
bytes memory initArgs = _createInitArgs(_newOwner);
6976
bytes32 initHash = keccak256(abi.encode(_eoa, initArgs));
7077
(uint8 v, bytes32 r, bytes32 s) = vm.sign(wrongPk, initHash);
@@ -74,7 +81,10 @@ contract InitializeTest is EIP7702ProxyBase {
7481
EIP7702Proxy(_eoa).initialize(initArgs, signature);
7582
}
7683

77-
function test_reverts_whenDelegatecallFails() public {
84+
function test_reverts_whenDelegatecallFails(address newOwner) public {
85+
vm.assume(newOwner != address(0));
86+
assumeNotPrecompile(newOwner);
87+
7888
// Deploy reverting implementation
7989
_implementation = new RevertingInitializerMockImplementation();
8090
_initSelector = RevertingInitializerMockImplementation
@@ -91,34 +101,49 @@ contract InitializeTest is EIP7702ProxyBase {
91101
vm.etch(_eoa, proxyCode);
92102

93103
// Try to initialize with valid signature but reverting implementation
94-
bytes memory initArgs = _createInitArgs(_newOwner);
104+
bytes memory initArgs = _createInitArgs(newOwner);
95105
bytes memory signature = _signInitData(_EOA_PRIVATE_KEY, initArgs);
96106

97107
vm.expectRevert("InitializerReverted");
98108
EIP7702Proxy(_eoa).initialize(initArgs, signature);
99109
}
100110

101-
function test_reverts_whenSignatureReplayedWithDifferentProxy() public {
111+
function test_reverts_whenSignatureReplayedWithDifferentProxy(
112+
address payable secondProxy,
113+
address newOwner
114+
) public {
115+
vm.assume(address(secondProxy) != address(0));
116+
vm.assume(address(secondProxy) != address(_eoa));
117+
assumeNotPrecompile(address(secondProxy));
118+
assumeNotPrecompile(newOwner);
119+
102120
// Get signature for first proxy
103-
bytes memory initArgs = _createInitArgs(_newOwner);
121+
bytes memory initArgs = _createInitArgs(newOwner);
104122
bytes memory signature = _signInitData(_EOA_PRIVATE_KEY, initArgs);
105123

106124
// Deploy a second proxy with same implementation
107-
address payable secondProxy = payable(address(0xBEEF));
108125
_deployProxy(secondProxy);
109126

110127
// Try to use same signature with different proxy
111128
vm.expectRevert(EIP7702Proxy.InvalidSignature.selector);
112129
EIP7702Proxy(secondProxy).initialize(initArgs, signature);
113130
}
114131

115-
function test_reverts_whenSignatureReplayedWithDifferentArgs() public {
132+
function test_reverts_whenSignatureReplayedWithDifferentArgs(
133+
address differentOwner,
134+
address newOwner
135+
) public {
136+
vm.assume(differentOwner != address(0));
137+
vm.assume(differentOwner != newOwner);
138+
assumeNotPrecompile(differentOwner);
139+
assumeNotPrecompile(newOwner);
140+
116141
// Get signature for first initialization args
117-
bytes memory initArgs = _createInitArgs(_newOwner);
142+
bytes memory initArgs = _createInitArgs(newOwner);
118143
bytes memory signature = _signInitData(_EOA_PRIVATE_KEY, initArgs);
119144

120145
// Try to use same signature with different args
121-
bytes memory differentArgs = _createInitArgs(address(0xBEEF));
146+
bytes memory differentArgs = _createInitArgs(differentOwner);
122147
vm.expectRevert(EIP7702Proxy.InvalidSignature.selector);
123148
EIP7702Proxy(_eoa).initialize(differentArgs, signature);
124149
}

test/EIP7702Proxy/isValidSignature.t.sol

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ abstract contract IsValidSignatureTestBase is EIP7702ProxyBase {
2222
wallet = _eoa;
2323
}
2424

25-
function test_succeeds_withValidEOASignature() public virtual {
26-
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_EOA_PRIVATE_KEY, testHash);
25+
function test_succeeds_withValidEOASignature(
26+
bytes32 message
27+
) public virtual {
28+
(uint8 v, bytes32 r, bytes32 s) = vm.sign(_EOA_PRIVATE_KEY, message);
2729
bytes memory signature = abi.encodePacked(r, s, v);
2830

2931
bytes4 result = MockImplementation(payable(wallet)).isValidSignature(
30-
testHash,
32+
message,
3133
signature
3234
);
3335
assertEq(
@@ -37,16 +39,18 @@ abstract contract IsValidSignatureTestBase is EIP7702ProxyBase {
3739
);
3840
}
3941

40-
function test_returnsExpectedValue_withInvalidEOASignature()
41-
public
42-
virtual
43-
{
44-
uint256 wrongPk = 0xB0B;
42+
function test_returnsExpectedValue_withInvalidEOASignature(
43+
uint128 wrongPk,
44+
bytes32 message
45+
) public virtual {
46+
vm.assume(wrongPk != 0);
47+
vm.assume(wrongPk != _EOA_PRIVATE_KEY);
48+
4549
(uint8 v, bytes32 r, bytes32 s) = vm.sign(wrongPk, testHash);
4650
bytes memory signature = abi.encodePacked(r, s, v);
4751

4852
bytes4 result = MockImplementation(payable(wallet)).isValidSignature(
49-
testHash,
53+
message,
5054
signature
5155
);
5256
assertEq(
@@ -101,12 +105,12 @@ contract FailingImplementationTest is IsValidSignatureTestBase {
101105
return ERC1271_FAIL_VALUE;
102106
}
103107

104-
function test_returnsFailureValue_withEmptySignature() public {
105-
bytes memory emptySignature = "";
106-
108+
function test_returnsFailureValue_withEmptySignature(
109+
bytes32 message
110+
) public {
107111
bytes4 result = MockImplementation(payable(wallet)).isValidSignature(
108-
testHash,
109-
emptySignature
112+
message,
113+
""
110114
);
111115
assertEq(result, ERC1271_FAIL_VALUE, "Should reject empty signature");
112116
}
@@ -146,17 +150,17 @@ contract SucceedingImplementationTest is IsValidSignatureTestBase {
146150
return ERC1271_MAGIC_VALUE; // Implementation always returns success
147151
}
148152

149-
function test_returnsSuccessValue_withEmptySignature() public {
150-
bytes memory emptySignature = "";
151-
153+
function test_returnsSuccessValue_withEmptySignature(
154+
bytes32 message
155+
) public {
152156
bytes4 result = MockImplementation(payable(wallet)).isValidSignature(
153-
testHash,
154-
emptySignature
157+
message,
158+
""
155159
);
156160
assertEq(
157161
result,
158162
ERC1271_MAGIC_VALUE,
159-
"Should return success for any EOA signature if implementation since `isValidSignature` always succeeds"
163+
"Should return success for any EOA signature"
160164
);
161165
}
162166
}

test/EIP7702Proxy/upgradeToAndCall.t.sol

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,12 @@ contract UpgradeToAndCallTest is EIP7702ProxyBase {
6060
);
6161
}
6262

63-
function test_reverts_whenCalledByNonOwner() public {
64-
vm.prank(address(0xBAD));
63+
function test_reverts_whenCalledByNonOwner(address nonOwner) public {
64+
vm.assume(nonOwner != address(0));
65+
vm.assume(nonOwner != _newOwner);
66+
assumeNotPrecompile(nonOwner);
67+
68+
vm.prank(nonOwner);
6569
vm.expectRevert(MockImplementation.Unauthorized.selector); // From MockImplementation
6670
MockImplementation(payable(_eoa)).upgradeToAndCall(
6771
address(newImplementation),

0 commit comments

Comments
 (0)