arnaucube
arnaucube/poseidon-solidity-examplePublic Self-hosted repository
poseidon-solidity-example/lib/forge-std/test/StdCheats.t.sol
lib/forge-std/test/StdCheats.t.solRaw
  1// SPDX-License-Identifier: MIT
  2pragma solidity >=0.7.0 <0.9.0;
  3
  4import "../src/StdCheats.sol";
  5import "../src/Test.sol";
  6import "../src/StdJson.sol";
  7
  8contract StdCheatsTest is Test {
  9    Bar test;
 10
 11    using stdJson for string;
 12
 13    function setUp() public {
 14        test = new Bar();
 15    }
 16
 17    function testSkip() public {
 18        vm.warp(100);
 19        skip(25);
 20        assertEq(block.timestamp, 125);
 21    }
 22
 23    function testRewind() public {
 24        vm.warp(100);
 25        rewind(25);
 26        assertEq(block.timestamp, 75);
 27    }
 28
 29    function testHoax() public {
 30        hoax(address(1337));
 31        test.bar{value: 100}(address(1337));
 32    }
 33
 34    function testHoaxOrigin() public {
 35        hoax(address(1337), address(1337));
 36        test.origin{value: 100}(address(1337));
 37    }
 38
 39    function testHoaxDifferentAddresses() public {
 40        hoax(address(1337), address(7331));
 41        test.origin{value: 100}(address(1337), address(7331));
 42    }
 43
 44    function testStartHoax() public {
 45        startHoax(address(1337));
 46        test.bar{value: 100}(address(1337));
 47        test.bar{value: 100}(address(1337));
 48        vm.stopPrank();
 49        test.bar(address(this));
 50    }
 51
 52    function testStartHoaxOrigin() public {
 53        startHoax(address(1337), address(1337));
 54        test.origin{value: 100}(address(1337));
 55        test.origin{value: 100}(address(1337));
 56        vm.stopPrank();
 57        test.bar(address(this));
 58    }
 59
 60    function testChangePrank() public {
 61        vm.startPrank(address(1337));
 62        test.bar(address(1337));
 63        changePrank(address(0xdead));
 64        test.bar(address(0xdead));
 65        changePrank(address(1337));
 66        test.bar(address(1337));
 67        vm.stopPrank();
 68    }
 69
 70    function testMakeAddrEquivalence() public {
 71        (address addr,) = makeAddrAndKey("1337");
 72        assertEq(makeAddr("1337"), addr);
 73    }
 74
 75    function testMakeAddrSigning() public {
 76        (address addr, uint256 key) = makeAddrAndKey("1337");
 77        bytes32 hash = keccak256("some_message");
 78
 79        (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash);
 80        assertEq(ecrecover(hash, v, r, s), addr);
 81    }
 82
 83    function testDeal() public {
 84        deal(address(this), 1 ether);
 85        assertEq(address(this).balance, 1 ether);
 86    }
 87
 88    function testDealToken() public {
 89        Bar barToken = new Bar();
 90        address bar = address(barToken);
 91        deal(bar, address(this), 10000e18);
 92        assertEq(barToken.balanceOf(address(this)), 10000e18);
 93    }
 94
 95    function testDealTokenAdjustTS() public {
 96        Bar barToken = new Bar();
 97        address bar = address(barToken);
 98        deal(bar, address(this), 10000e18, true);
 99        assertEq(barToken.balanceOf(address(this)), 10000e18);
100        assertEq(barToken.totalSupply(), 20000e18);
101        deal(bar, address(this), 0, true);
102        assertEq(barToken.balanceOf(address(this)), 0);
103        assertEq(barToken.totalSupply(), 10000e18);
104    }
105
106    function testDeployCode() public {
107        address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""));
108        assertEq(string(getCode(deployed)), string(getCode(address(test))));
109    }
110
111    function testDeployCodeNoArgs() public {
112        address deployed = deployCode("StdCheats.t.sol:Bar");
113        assertEq(string(getCode(deployed)), string(getCode(address(test))));
114    }
115
116    function testDeployCodeVal() public {
117        address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether);
118        assertEq(string(getCode(deployed)), string(getCode(address(test))));
119        assertEq(deployed.balance, 1 ether);
120    }
121
122    function testDeployCodeValNoArgs() public {
123        address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether);
124        assertEq(string(getCode(deployed)), string(getCode(address(test))));
125        assertEq(deployed.balance, 1 ether);
126    }
127
128    // We need this so we can call "this.deployCode" rather than "deployCode" directly
129    function deployCodeHelper(string memory what) external {
130        deployCode(what);
131    }
132
133    function testDeployCodeFail() public {
134        vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed."));
135        this.deployCodeHelper("StdCheats.t.sol:RevertingContract");
136    }
137
138    function getCode(address who) internal view returns (bytes memory o_code) {
139        /// @solidity memory-safe-assembly
140        assembly {
141            // retrieve the size of the code, this needs assembly
142            let size := extcodesize(who)
143            // allocate output byte array - this could also be done without assembly
144            // by using o_code = new bytes(size)
145            o_code := mload(0x40)
146            // new "memory end" including padding
147            mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
148            // store length in memory
149            mstore(o_code, size)
150            // actually retrieve the code, this needs assembly
151            extcodecopy(who, add(o_code, 0x20), 0, size)
152        }
153    }
154
155    function testDeriveRememberKey() public {
156        string memory mnemonic = "test test test test test test test test test test test junk";
157
158        (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0);
159        assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266);
160        assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80);
161    }
162
163    function testBytesToUint() public {
164        assertEq(3, bytesToUint_test(hex"03"));
165        assertEq(2, bytesToUint_test(hex"02"));
166        assertEq(255, bytesToUint_test(hex"ff"));
167        assertEq(29625, bytesToUint_test(hex"73b9"));
168    }
169
170    function testParseJsonTxDetail() public {
171        string memory root = vm.projectRoot();
172        string memory path = string.concat(root, "/test/fixtures/broadcast.log.json");
173        string memory json = vm.readFile(path);
174        bytes memory transactionDetails = json.parseRaw(".transactions[0].tx");
175        RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail));
176        Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail);
177        assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266);
178        assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512);
179        assertEq(
180            txDetail.data,
181            hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004"
182        );
183        assertEq(txDetail.nonce, 3);
184        assertEq(txDetail.txType, 2);
185        assertEq(txDetail.gas, 29625);
186        assertEq(txDetail.value, 0);
187    }
188
189    function testReadEIP1559Transaction() public view {
190        string memory root = vm.projectRoot();
191        string memory path = string.concat(root, "/test/fixtures/broadcast.log.json");
192        uint256 index = 0;
193        Tx1559 memory transaction = readTx1559(path, index);
194        transaction;
195    }
196
197    function testReadEIP1559Transactions() public view {
198        string memory root = vm.projectRoot();
199        string memory path = string.concat(root, "/test/fixtures/broadcast.log.json");
200        Tx1559[] memory transactions = readTx1559s(path);
201        transactions;
202    }
203
204    function testReadReceipt() public {
205        string memory root = vm.projectRoot();
206        string memory path = string.concat(root, "/test/fixtures/broadcast.log.json");
207        uint256 index = 5;
208        Receipt memory receipt = readReceipt(path, index);
209        assertEq(
210            receipt.logsBloom,
211            hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100"
212        );
213    }
214
215    function testReadReceipts() public view {
216        string memory root = vm.projectRoot();
217        string memory path = string.concat(root, "/test/fixtures/broadcast.log.json");
218        Receipt[] memory receipts = readReceipts(path);
219        receipts;
220    }
221
222    function testGasMeteringModifier() public {
223        uint256 gas_start_normal = gasleft();
224        addInLoop();
225        uint256 gas_used_normal = gas_start_normal - gasleft();
226
227        uint256 gas_start_single = gasleft();
228        addInLoopNoGas();
229        uint256 gas_used_single = gas_start_single - gasleft();
230
231        uint256 gas_start_double = gasleft();
232        addInLoopNoGasNoGas();
233        uint256 gas_used_double = gas_start_double - gasleft();
234
235        emit log_named_uint("Normal gas", gas_used_normal);
236        emit log_named_uint("Single modifier gas", gas_used_single);
237        emit log_named_uint("Double modifier  gas", gas_used_double);
238        assertTrue(gas_used_double + gas_used_single < gas_used_normal);
239    }
240
241    function addInLoop() internal pure returns (uint256) {
242        uint256 b;
243        for (uint256 i; i < 10000; i++) {
244            b += i;
245        }
246        return b;
247    }
248
249    function addInLoopNoGas() internal noGasMetering returns (uint256) {
250        return addInLoop();
251    }
252
253    function addInLoopNoGasNoGas() internal noGasMetering returns (uint256) {
254        return addInLoopNoGas();
255    }
256
257    function bytesToUint_test(bytes memory b) private pure returns (uint256) {
258        uint256 number;
259        for (uint256 i = 0; i < b.length; i++) {
260            number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1))));
261        }
262        return number;
263    }
264
265    function testAssumeNoPrecompiles(address addr) external {
266        assumeNoPrecompiles(addr, getChain("optimism_goerli").chainId);
267        assertTrue(
268            addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000))
269                || addr > address(0x4200000000000000000000000000000000000800)
270        );
271    }
272
273    function testAssumePayable() external {
274        // all should revert since these addresses are not payable
275
276        // VM address
277        vm.expectRevert();
278        assumePayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
279
280        // Console address
281        vm.expectRevert();
282        assumePayable(0x000000000000000000636F6e736F6c652e6c6f67);
283
284        // Create2Deployer
285        vm.expectRevert();
286        assumePayable(0x4e59b44847b379578588920cA78FbF26c0B4956C);
287    }
288
289    function testAssumePayable(address addr) external {
290        assumePayable(addr);
291        assertTrue(
292            addr != 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D && addr != 0x000000000000000000636F6e736F6c652e6c6f67
293                && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C
294        );
295    }
296}
297
298contract Bar {
299    constructor() payable {
300        /// `DEAL` STDCHEAT
301        totalSupply = 10000e18;
302        balanceOf[address(this)] = totalSupply;
303    }
304
305    /// `HOAX` STDCHEATS
306    function bar(address expectedSender) public payable {
307        require(msg.sender == expectedSender, "!prank");
308    }
309
310    function origin(address expectedSender) public payable {
311        require(msg.sender == expectedSender, "!prank");
312        require(tx.origin == expectedSender, "!prank");
313    }
314
315    function origin(address expectedSender, address expectedOrigin) public payable {
316        require(msg.sender == expectedSender, "!prank");
317        require(tx.origin == expectedOrigin, "!prank");
318    }
319
320    /// `DEAL` STDCHEAT
321    mapping(address => uint256) public balanceOf;
322    uint256 public totalSupply;
323}
324
325contract RevertingContract {
326    constructor() {
327        revert();
328    }
329}