Skip to content

Commit 7eb67ae

Browse files
committed
refactor: add conditional to handle ETH transfers
1 parent c3758d7 commit 7eb67ae

2 files changed

Lines changed: 39 additions & 49 deletions

File tree

contracts/contracts/core/GasTankDepositor.sol

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ import {Errors} from "../utils/Errors.sol";
99
contract GasTankDepositor {
1010
address public immutable RPC_SERVICE;
1111
uint256 public immutable MAXIMUM_DEPOSIT;
12+
address public immutable GAS_TANK_ADDRESS;
1213

13-
event FundsRecovered(address indexed owner, uint256 indexed amount);
1414
event GasTankFunded(address indexed smartAccount, address indexed caller, uint256 indexed amount);
1515

16-
error FailedToRecoverFunds(address owner, uint256 amount);
1716
error FailedToFundGasTank(address rpcProvider, uint256 transferAmount);
1817
error RPCServiceNotSet(address provider);
1918
error NotRPCService(address caller);
@@ -38,24 +37,19 @@ contract GasTankDepositor {
3837
require(_maxDeposit > 0, MaximumDepositNotMet(0, _maxDeposit));
3938
RPC_SERVICE = rpcService;
4039
MAXIMUM_DEPOSIT = _maxDeposit;
40+
GAS_TANK_ADDRESS = address(this);
4141
}
4242

43-
receive() external payable { /* ETH transfers allowed. */ }
43+
receive() external payable {
44+
if (address(this) == GAS_TANK_ADDRESS) {
45+
revert Errors.InvalidReceive();
46+
}
47+
}
4448

4549
fallback() external payable {
4650
revert Errors.InvalidFallback();
4751
}
4852

49-
/// @notice Recovers funds inadvertently sent to this contract directly.
50-
function recoverFunds() external onlyRPCService {
51-
uint256 balance = address(this).balance;
52-
53-
(bool success,) = RPC_SERVICE.call{value: balance}("");
54-
require(success, FailedToRecoverFunds(RPC_SERVICE, balance));
55-
56-
emit FundsRecovered(RPC_SERVICE, balance);
57-
}
58-
5953
/// @notice Transfers ETH from the EOA's balance to the Gas RPC Service.
6054
/// @param _amount The amount to fund the gas tank with.
6155
/// @dev Only the EOA can call this function.
@@ -69,7 +63,6 @@ contract GasTankDepositor {
6963
_fundGasTank(MAXIMUM_DEPOSIT);
7064
}
7165

72-
/// @dev `fundGasTank` Internal function to fund the gas tank.
7366
function _fundGasTank(uint256 _amountToTransfer) internal {
7467
require(address(this).balance >= _amountToTransfer, InsufficientFunds(address(this).balance, _amountToTransfer));
7568

contracts/test/core/GasTankDepositorTest.sol

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pragma solidity 0.8.26;
33

44
import "forge-std/Test.sol";
55
import {GasTankDepositor} from "../../contracts/core/GasTankDepositor.sol";
6+
import {Errors} from "../../contracts/utils/Errors.sol";
67

78
contract GasTankDepositorTest is Test {
89
uint256 public constant ALICE_PK = uint256(0xA11CE);
@@ -50,17 +51,11 @@ contract GasTankDepositorTest is Test {
5051
assertEq(alice.code.length, 0);
5152
}
5253

53-
//=======================TESTS FOR IMPROPER CALLS TO THE GAS TANK MANAGER=======================
54+
//=======================TESTS FOR RECEIVING FUNDS=======================
5455

55-
function testFallbackRevert() public {
56-
bytes memory badData =
57-
abi.encodeWithSelector(GasTankDepositor.recoverFunds.selector, address(0x55555), 1 ether, 1 ether, 1 ether);
58-
vm.prank(alice);
59-
(bool success,) = address(_gasTankDepositorImpl).call{value: 1 ether}(badData);
60-
assertFalse(success);
61-
}
56+
function testReceivesFunds() public {
57+
_delegate();
6258

63-
function testReceiveNoRevert() public {
6459
uint256 beforeBalance = alice.balance;
6560
vm.prank(bob);
6661
(bool success,) = address(alice).call{value: 1 ether}("");
@@ -69,43 +64,45 @@ contract GasTankDepositorTest is Test {
6964
assertEq(afterBalance, beforeBalance + 1 ether, "balance not increased");
7065
}
7166

72-
function testFundsSentDirectlyToDelegateAddress() public {
73-
uint256 beforeBalance = address(_gasTankDepositorImpl).balance;
67+
//=======================TESTS FOR RECEIVE AND FALLBACK=======================
7468

75-
vm.prank(bob);
76-
(bool success,) = address(_gasTankDepositorImpl).call{value: 1 ether}("");
77-
assertTrue(success);
69+
function testFallbackRevert() public {
70+
bytes memory badData = abi.encodeWithSelector(bytes4(keccak256("invalidFunction()")));
71+
vm.prank(alice);
72+
(bool success,) = address(_gasTankDepositorImpl).call{value: 1 ether}(badData);
73+
assertFalse(success);
74+
}
7875

79-
uint256 afterBalance = address(_gasTankDepositorImpl).balance;
80-
assertEq(afterBalance, beforeBalance + 1 ether, "balance not increased");
76+
function testFundsSentDirectlyToDelegateAddress() public {
77+
vm.prank(bob);
78+
(bool success, bytes memory data) = address(_gasTankDepositorImpl).call{value: 1 ether}("");
79+
assertFalse(success);
80+
bytes4 selector;
81+
assembly {
82+
selector := mload(add(data, 0x20))
83+
}
84+
assertEq(selector, Errors.InvalidReceive.selector);
8185
}
8286

83-
function testWithdrawsFundsDirectlyFromDelegateAddress() public {
84-
uint256 gasTankBeforeBalance = address(_gasTankDepositorImpl).balance;
85-
uint256 depositAmount = 1 ether;
87+
function testFundsSentDirectlyToEOAAddressWithDelegation() public {
88+
_delegate();
8689

90+
uint256 beforeBalance = alice.balance;
8791
vm.prank(bob);
88-
(bool success,) = address(_gasTankDepositorImpl).call{value: depositAmount}("");
92+
(bool success,) = alice.call{value: 1 ether}("");
8993
assertTrue(success);
90-
91-
uint256 gasTankAfterBalance = address(_gasTankDepositorImpl).balance;
92-
assertEq(gasTankAfterBalance, gasTankBeforeBalance + depositAmount, "balance not increased");
93-
94-
vm.prank(rpcService);
95-
uint256 rpcServiceBeforeBalance = rpcService.balance;
96-
_gasTankDepositorImpl.recoverFunds();
97-
uint256 rpcServiceAfterBalance = rpcService.balance;
98-
99-
assertEq(address(_gasTankDepositorImpl).balance, 0, "funds not drained");
100-
assertEq(rpcServiceAfterBalance, rpcServiceBeforeBalance + depositAmount, "balance not recovered");
94+
uint256 afterBalance = alice.balance;
95+
assertEq(afterBalance, beforeBalance + 1 ether, "balance not increased");
10196
}
10297

103-
function testRevertsWhenRecoverFundsIsCalledByUnknownCaller() public {
98+
function testFundsSentDirectlyToEOAAddressWithoutDelegation() public {
99+
uint256 beforeBalance = alice.balance;
104100
vm.prank(bob);
105-
vm.expectRevert(abi.encodeWithSelector(GasTankDepositor.NotRPCService.selector, bob));
106-
_gasTankDepositorImpl.recoverFunds();
101+
(bool success,) = address(alice).call{value: 1 ether}("");
102+
assertTrue(success);
103+
uint256 afterBalance = alice.balance;
104+
assertEq(afterBalance, beforeBalance + 1 ether, "balance not increased");
107105
}
108-
109106
//=======================TESTS FOR FUNDING THE GAS TANK=======================
110107

111108
function testRpcServiceFundsMaximumDeposit() public {

0 commit comments

Comments
 (0)