Skip to content

Commit f93b713

Browse files
authored
Merge pull request #24 from base-org/amie/add-receive
Add `receive` function
2 parents 9c0c9e6 + e7045ad commit f93b713

File tree

2 files changed

+40
-25
lines changed

2 files changed

+40
-25
lines changed

src/EIP7702Proxy.sol

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,7 @@ contract EIP7702Proxy is Proxy {
144144
function _implementation() internal view override returns (address) {
145145
return ERC1967Utils.getImplementation();
146146
}
147+
148+
/// @notice Allow the account to receive ETH under any circumstances
149+
receive() external payable {}
147150
}

test/EIP7702Proxy/delegate.t.sol

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {EIP7702Proxy} from "../../src/EIP7702Proxy.sol";
66
import {MockImplementation} from "../mocks/MockImplementation.sol";
77

88
contract DelegateTest is EIP7702ProxyBase {
9+
bytes4 constant INITIALIZER = MockImplementation.initialize.selector;
10+
911
function setUp() public override {
1012
super.setUp();
1113

@@ -69,31 +71,6 @@ contract DelegateTest is EIP7702ProxyBase {
6971
);
7072
}
7173

72-
function test_reverts_whenCallingBeforeInitialization() public {
73-
// Deploy a fresh proxy without initializing it
74-
address payable uninitProxy = payable(makeAddr("uninitProxy"));
75-
_deployProxy(uninitProxy);
76-
77-
vm.expectRevert(EIP7702Proxy.ProxyNotInitialized.selector);
78-
MockImplementation(payable(uninitProxy)).owner();
79-
}
80-
81-
function test_reverts_whenCallingWithArbitraryDataBeforeInitialization(
82-
bytes memory arbitraryCalldata
83-
) public {
84-
// Deploy a fresh proxy without initializing it
85-
address payable uninitProxy = payable(makeAddr("uninitProxy"));
86-
_deployProxy(uninitProxy);
87-
88-
// Test that it reverts with the correct error
89-
vm.expectRevert(EIP7702Proxy.ProxyNotInitialized.selector);
90-
address(uninitProxy).call(arbitraryCalldata);
91-
92-
// Also verify the low-level call fails
93-
(bool success, ) = address(uninitProxy).call(arbitraryCalldata);
94-
assertFalse(success, "Low-level call should fail");
95-
}
96-
9774
function test_continues_delegating_afterUpgrade() public {
9875
// Setup will have already initialized the proxy with initial implementation and an owner
9976

@@ -124,4 +101,39 @@ contract DelegateTest is EIP7702ProxyBase {
124101
"Should be able to call through proxy after upgrade"
125102
);
126103
}
104+
105+
// Add a specific test for ETH transfers
106+
function test_allows_ethTransfersBeforeInitialization() public {
107+
// Deploy a fresh proxy without initializing it
108+
address payable uninitProxy = payable(makeAddr("uninitProxy"));
109+
_deployProxy(uninitProxy);
110+
111+
// Should succeed with empty calldata and ETH value
112+
(bool success, ) = uninitProxy.call{value: 1 ether}("");
113+
assertTrue(success, "ETH transfer should succeed");
114+
assertEq(address(uninitProxy).balance, 1 ether);
115+
}
116+
117+
function test_reverts_whenCallingWithArbitraryDataBeforeInitialization(
118+
bytes calldata data
119+
) public {
120+
// Skip empty calls or pure ETH transfers
121+
vm.assume(data.length > 0);
122+
123+
// Deploy a fresh proxy without initializing it
124+
address payable uninitProxy = payable(makeAddr("uninitProxy"));
125+
_deployProxy(uninitProxy);
126+
127+
vm.expectRevert(EIP7702Proxy.ProxyNotInitialized.selector);
128+
uninitProxy.call(data);
129+
}
130+
131+
function test_reverts_whenCallingBeforeInitialization() public {
132+
// Deploy a fresh proxy without initializing it
133+
address payable uninitProxy = payable(makeAddr("uninitProxy"));
134+
_deployProxy(uninitProxy);
135+
136+
vm.expectRevert(EIP7702Proxy.ProxyNotInitialized.selector);
137+
MockImplementation(payable(uninitProxy)).owner();
138+
}
127139
}

0 commit comments

Comments
 (0)