-
Hi, I'm trying to figure out why I've been unable to transfer ETH to proxies in tests in some cases. Here's a repo reproducing my issue: https://github.com/mono-koto/foundry-repro-test-transfer-gas-issue I expect all tests to pass, but only the first test contract passes (see the CI run for specifics). Here's the specific test file: // SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "forge-std/Test.sol";
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import "@openzeppelin/contracts/proxy/Clones.sol";
contract Foo {
receive() external payable {}
fallback() external payable {}
}
/// These are passing
contract ProxyEthReceiveLocalOnlyTest is Test {
function testTransferToProxy() public {
address payable proxy = payable(new ERC1967Proxy(address(new Foo()), ""));
proxy.transfer(1 ether);
assertEq(address(proxy).balance, 1 ether);
}
function testTransferToClone() public {
address payable clone = payable(Clones.clone(address(new Foo())));
clone.transfer(1 ether);
}
}
/// These are failing
contract ProxyEthReceiveSetupTest is Test {
address payable proxy;
address payable clone;
function setUp() public {
proxy = payable(new ERC1967Proxy(address(new Foo()), ""));
clone = payable(Clones.clone(address(new Foo())));
}
function testTransferToProxy() public {
proxy.transfer(1 ether);
assertEq(address(proxy).balance, 1 ether);
}
function testTransferToClone() public {
clone.transfer(1 ether);
}
}
Thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
As mentioned in #3744,
The most robust way to transfer ETH is not to use |
Beta Was this translation helpful? Give feedback.
As mentioned in #3744,
.transfer
only sends along 2300 gas. Because you are sending ETH to a proxy, you delegatecall to the implementation address, which costs 2600 gas when the address is cold (first access during tx) or 100 gas when the address is warm (subsequent accesses). See https://evm.codes for more info on gas costs. Therefore:ProxyEthReceiveLocalOnlyTest
tests, because you transfer the ETH immediately after creating the proxy, so all addresses are warm.ProxyEthReceiveSetupTest
tests be…