|
2 | 2 | pragma solidity ^0.8.28; |
3 | 3 |
|
4 | 4 | import {ERC20Mock} from "@openzeppelin/contracts/mocks/token/ERC20Mock.sol"; |
5 | | -import {IERC20} from "forge-std/interfaces/IERC20.sol"; |
| 5 | +import {ERC20NoReturnMock} from "@openzeppelin/contracts/mocks/token/ERC20NoReturnMock.sol"; |
| 6 | +import {ERC20ReturnFalseMock} from "@openzeppelin/contracts/mocks/token/ERC20ReturnFalseMock.sol"; |
| 7 | +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; |
| 8 | +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; |
| 9 | +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; |
6 | 10 | import {Test} from "forge-std/Test.sol"; |
7 | 11 |
|
8 | 12 | import {ForwardingAddress} from "../src/ForwardingAddress.sol"; |
9 | 13 | import {ForwardingAddressFactory} from "../src/ForwardingAddressFactory.sol"; |
10 | 14 |
|
11 | 15 | contract NonPayableReceiver {} |
12 | 16 |
|
| 17 | +contract ERC20NoReturn is ERC20NoReturnMock { |
| 18 | + constructor() ERC20("ERC20Mock", "E20M") {} |
| 19 | + |
| 20 | + function mint(address account, uint256 amount) external { |
| 21 | + _mint(account, amount); |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +contract ERC20ReturnFalse is ERC20ReturnFalseMock { |
| 26 | + constructor() ERC20("ERC20Mock", "E20M") {} |
| 27 | + |
| 28 | + function mint(address account, uint256 amount) external { |
| 29 | + _mint(account, amount); |
| 30 | + } |
| 31 | +} |
| 32 | + |
13 | 33 | contract ForwardingAddressFactoryTest is Test { |
14 | 34 | ForwardingAddressFactory public factory; |
15 | 35 | ERC20Mock public erc20Mock; |
| 36 | + ERC20NoReturn public erc20NoReturn; |
| 37 | + ERC20ReturnFalse public erc20ReturnFalse; |
16 | 38 |
|
17 | 39 | function setUp() public { |
18 | 40 | factory = new ForwardingAddressFactory(); |
19 | 41 | erc20Mock = new ERC20Mock(); |
| 42 | + erc20NoReturn = new ERC20NoReturn(); |
| 43 | + erc20ReturnFalse = new ERC20ReturnFalse(); |
20 | 44 | } |
21 | 45 |
|
22 | 46 | function testFuzz_createForwardingAddress(bytes32 salt) public { |
@@ -108,6 +132,37 @@ contract ForwardingAddressFactoryTest is Test { |
108 | 132 | assertEq(IERC20(address(erc20Mock)).balanceOf(forwarder), 0); |
109 | 133 | } |
110 | 134 |
|
| 135 | + function testFuzz_sweepForERC20NoReturn(bytes32 salt, uint256 amount) public { |
| 136 | + (address receiver,) = makeAddrAndKey("receiver"); |
| 137 | + |
| 138 | + address forwarder = factory.getAddress(receiver, salt); |
| 139 | + erc20NoReturn.mint(forwarder, amount); |
| 140 | + assertEq(IERC20(address(erc20NoReturn)).balanceOf(receiver), 0); |
| 141 | + assertEq(IERC20(address(erc20NoReturn)).balanceOf(forwarder), amount); |
| 142 | + |
| 143 | + address[] memory tokens = new address[](1); |
| 144 | + tokens[0] = address(erc20NoReturn); |
| 145 | + factory.sweepFor(payable(receiver), salt, tokens); |
| 146 | + assertEq(IERC20(address(erc20NoReturn)).balanceOf(receiver), amount); |
| 147 | + assertEq(IERC20(address(erc20NoReturn)).balanceOf(forwarder), 0); |
| 148 | + } |
| 149 | + |
| 150 | + function testFuzz_sweepForERC20ReturnFalse(bytes32 salt, uint256 amount) public { |
| 151 | + (address receiver,) = makeAddrAndKey("receiver"); |
| 152 | + |
| 153 | + address forwarder = factory.getAddress(receiver, salt); |
| 154 | + erc20ReturnFalse.mint(forwarder, amount); |
| 155 | + assertEq(IERC20(address(erc20ReturnFalse)).balanceOf(receiver), 0); |
| 156 | + assertEq(IERC20(address(erc20ReturnFalse)).balanceOf(forwarder), amount); |
| 157 | + |
| 158 | + address[] memory tokens = new address[](1); |
| 159 | + tokens[0] = address(erc20ReturnFalse); |
| 160 | + vm.expectRevert(abi.encodeWithSelector(SafeERC20.SafeERC20FailedOperation.selector, tokens[0])); |
| 161 | + factory.sweepFor(payable(receiver), salt, tokens); |
| 162 | + assertEq(IERC20(address(erc20ReturnFalse)).balanceOf(receiver), 0); |
| 163 | + assertEq(IERC20(address(erc20ReturnFalse)).balanceOf(forwarder), amount); |
| 164 | + } |
| 165 | + |
111 | 166 | function testFuzz_sweepForMulti(bytes32 salt, uint256 amount) public { |
112 | 167 | (address receiver,) = makeAddrAndKey("receiver"); |
113 | 168 |
|
|
0 commit comments