Skip to content

Commit 86754e6

Browse files
committed
Passage Fuzz
1 parent ec01b61 commit 86754e6

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

test/fuzz-host/PassageFuzz.t.sol

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
pragma solidity 0.8.26;
3+
4+
// test contracts
5+
import {Passage} from "../../src/passage/Passage.sol";
6+
import {RollupPassage} from "../../src/passage/RollupPassage.sol";
7+
// utils
8+
import {TestERC20} from "../Helpers.t.sol";
9+
import {SignetStdTest} from "../SignetStdTest.t.sol";
10+
import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
11+
import {ERC20Burnable} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol";
12+
import {Address} from "openzeppelin-contracts/contracts/utils/Address.sol";
13+
import {Test, console2} from "forge-std/Test.sol";
14+
import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
15+
16+
contract PassageFuzzTest is SignetStdTest {
17+
using Address for address payable;
18+
19+
Passage public target;
20+
address configuredToken;
21+
22+
event Enter(uint256 indexed rollupChainId, address indexed rollupRecipient, uint256 amount);
23+
24+
event EnterToken(
25+
uint256 indexed rollupChainId, address indexed rollupRecipient, address indexed token, uint256 amount
26+
);
27+
28+
event EnterConfigured(address indexed token, bool indexed canEnter);
29+
30+
event Withdrawal(address indexed token, address indexed recipient, uint256 amount);
31+
32+
function setUp() public virtual {
33+
// deploy target
34+
target = HOST_PASSAGE;
35+
36+
// setup token
37+
configuredToken = address(HOST_WETH);
38+
// mint WETH by sending ETH
39+
payable(configuredToken).sendValue(10000 ether);
40+
TestERC20(configuredToken).approve(address(target), 10000 ether);
41+
42+
// // deploy new token that's not configured on Passage
43+
// newToken = address(new TestERC20("bye", "BYE", 18));
44+
// TestERC20(newToken).mint(address(this), amount * 10000);
45+
// TestERC20(newToken).approve(address(target), amount * 10000);
46+
}
47+
48+
// only the token admin can add or remove new tokens from Passage
49+
function test_onlyTokenAdmin(address caller, address token, bool canEnter, address recipient, uint256 amount)
50+
public
51+
{
52+
vm.assume(caller != TOKEN_ADMIN);
53+
vm.startPrank(caller);
54+
55+
vm.expectRevert(Passage.OnlyTokenAdmin.selector);
56+
target.configureEnter(token, canEnter);
57+
58+
vm.expectRevert(Passage.OnlyTokenAdmin.selector);
59+
target.withdraw(token, recipient, amount);
60+
}
61+
62+
// function test_disallowedEnter(address recipient, address newToken, uint256 amount) public {
63+
// vm.assume(target.canEnter(newToken) == false);
64+
// vm.expectRevert(abi.encodeWithSelector(Passage.DisallowedEnter.selector, newToken));
65+
// target.enterToken(recipient, newToken, amount);
66+
// }
67+
68+
function test_receive(uint256 amount) public {
69+
vm.assume(amount > 0 && amount < payable(address(this)).balance);
70+
vm.expectEmit();
71+
emit Enter(target.defaultRollupChainId(), address(this), amount);
72+
payable(address(target)).sendValue(amount);
73+
}
74+
75+
function test_fallback(uint256 amount, bytes memory data) public {
76+
vm.assume(amount > 0 && amount < payable(address(this)).balance);
77+
vm.expectEmit();
78+
emit Enter(target.defaultRollupChainId(), address(this), amount);
79+
payable(address(target)).functionCallWithValue(data, amount);
80+
}
81+
82+
function test_enter(uint256 rollupChainId, address recipient, uint256 amount) public {
83+
vm.assume(amount > 0 && amount < payable(address(this)).balance);
84+
vm.expectEmit();
85+
emit Enter(rollupChainId, recipient, amount);
86+
target.enter{value: amount}(rollupChainId, recipient);
87+
}
88+
89+
function test_enter_defaultChain(address recipient, uint56 amount) public {
90+
vm.assume(amount > 0 && amount < payable(address(this)).balance);
91+
vm.expectEmit();
92+
emit Enter(target.defaultRollupChainId(), recipient, amount);
93+
target.enter{value: amount}(recipient);
94+
}
95+
96+
function test_enterToken(uint256 rollupChainId, address recipient, uint256 amount) public {
97+
vm.assume(amount > 0 && amount < payable(address(this)).balance);
98+
// mint WETH of the amount
99+
payable(configuredToken).sendValue(amount);
100+
TestERC20(configuredToken).approve(address(target), amount);
101+
102+
vm.expectEmit();
103+
emit EnterToken(rollupChainId, recipient, configuredToken, amount);
104+
vm.expectCall(
105+
configuredToken, abi.encodeWithSelector(ERC20.transferFrom.selector, address(this), address(target), amount)
106+
);
107+
target.enterToken(rollupChainId, recipient, configuredToken, amount);
108+
}
109+
110+
function test_enterToken_defaultChain(address recipient, uint256 amount) public {
111+
vm.assume(amount > 0 && amount < payable(address(this)).balance);
112+
// mint WETH of the amount
113+
payable(configuredToken).sendValue(amount);
114+
TestERC20(configuredToken).approve(address(target), amount);
115+
116+
vm.expectEmit();
117+
emit EnterToken(target.defaultRollupChainId(), recipient, configuredToken, amount);
118+
vm.expectCall(
119+
configuredToken, abi.encodeWithSelector(ERC20.transferFrom.selector, address(this), address(target), amount)
120+
);
121+
target.enterToken(recipient, configuredToken, amount);
122+
}
123+
124+
function test_withdraw(address recipient, uint256 amount) public {
125+
vm.assume(amount > 0 && amount < payable(address(this)).balance);
126+
payable(configuredToken).sendValue(amount);
127+
IERC20(configuredToken).transfer(address(target), amount);
128+
129+
vm.startPrank(TOKEN_ADMIN);
130+
vm.expectEmit();
131+
emit Withdrawal(configuredToken, recipient, amount);
132+
vm.expectCall(configuredToken, abi.encodeWithSelector(ERC20.transfer.selector, recipient, amount));
133+
target.withdraw(configuredToken, recipient, amount);
134+
}
135+
}

0 commit comments

Comments
 (0)