Skip to content

Commit 27035c8

Browse files
ZeroEkkusumds1
andauthored
fix: improve DX (#398)
* fix: dx, warnings, cleanup * feat(cheats): etchify * chore: forge fmt * fix: ABIEncoderV2 * revert: `safeconsole` -> `consoleSafe` * revert: add `etchify` * chore: forge fmt * docs: improve comment * ci: add back 0.6.12 backwards compatibility check * fix: add assumeNotBlacklisted alias * chore: add comment explaining _viewChainId/_pureChainId --------- Co-authored-by: Matt Solomon <[email protected]>
1 parent 7b0c65a commit 27035c8

File tree

10 files changed

+69
-37
lines changed

10 files changed

+69
-37
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ jobs:
2121
- name: Print forge version
2222
run: forge --version
2323

24-
# Backwards compatibility checks.
24+
# Backwards compatibility checks:
25+
# - the oldest and newest version of each supported minor version
26+
# - versions with specific issues
2527
- name: Check compatibility with latest
2628
if: always()
2729
run: |
@@ -72,6 +74,10 @@ jobs:
7274
exit 1
7375
fi
7476
77+
- name: Check compatibility with 0.6.12
78+
if: always()
79+
run: forge build --skip test --use solc:0.6.12
80+
7581
- name: Check compatibility with 0.6.2
7682
if: always()
7783
run: |

src/Script.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22
pragma solidity >=0.6.2 <0.9.0;
33

44
// 💬 ABOUT
5-
// Standard Library's default Script.
5+
// Forge Std's default Script.
66

77
// 🧩 MODULES
8-
import {ScriptBase} from "./Base.sol";
98
import {console} from "./console.sol";
109
import {console2} from "./console2.sol";
10+
import {safeconsole} from "./safeconsole.sol";
1111
import {StdChains} from "./StdChains.sol";
1212
import {StdCheatsSafe} from "./StdCheats.sol";
1313
import {stdJson} from "./StdJson.sol";
1414
import {stdMath} from "./StdMath.sol";
1515
import {StdStorage, stdStorageSafe} from "./StdStorage.sol";
16+
import {StdStyle} from "./StdStyle.sol";
1617
import {StdUtils} from "./StdUtils.sol";
1718
import {VmSafe} from "./Vm.sol";
1819

src/StdChains.sol

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity >=0.6.2 <0.9.0;
33

4-
pragma experimental ABIEncoderV2;
5-
64
import {VmSafe} from "./Vm.sol";
75

86
/**

src/StdCheats.sol

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,13 @@ abstract contract StdCheatsSafe {
194194
}
195195

196196
// Checks that `addr` is not blacklisted by token contracts that have a blacklist.
197-
function assumeNoBlacklisted(address token, address addr) internal virtual {
197+
function assumeNotBlacklisted(address token, address addr) internal view virtual {
198198
// Nothing to check if `token` is not a contract.
199199
uint256 tokenCodeSize;
200200
assembly {
201201
tokenCodeSize := extcodesize(token)
202202
}
203-
require(tokenCodeSize > 0, "StdCheats assumeNoBlacklisted(address,address): Token address is not a contract.");
203+
require(tokenCodeSize > 0, "StdCheats assumeNotBlacklisted(address,address): Token address is not a contract.");
204204

205205
bool success;
206206
bytes memory returnData;
@@ -214,13 +214,16 @@ abstract contract StdCheatsSafe {
214214
vm.assume(!success || abi.decode(returnData, (bool)) == false);
215215
}
216216

217-
function assumeNoPrecompiles(address addr) internal virtual {
218-
// Assembly required since `block.chainid` was introduced in 0.8.0.
219-
uint256 chainId;
220-
assembly {
221-
chainId := chainid()
222-
}
223-
assumeNoPrecompiles(addr, chainId);
217+
// Checks that `addr` is not blacklisted by token contracts that have a blacklist.
218+
// This is identical to `assumeNotBlacklisted(address,address)` but with a different name, for
219+
// backwards compatibility, since this name was used in the original PR which has already has
220+
// a release. This function can be removed in a future release once we want a breaking change.
221+
function assumeNoBlacklisted(address token, address addr) internal view virtual {
222+
assumeNotBlacklisted(token, addr);
223+
}
224+
225+
function assumeNoPrecompiles(address addr) internal pure virtual {
226+
assumeNoPrecompiles(addr, _pureChainId());
224227
}
225228

226229
function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual {
@@ -515,6 +518,28 @@ abstract contract StdCheatsSafe {
515518
(bool success,) = payable(addr).call{value: 0}("");
516519
vm.assume(success);
517520
}
521+
522+
// We use this complex approach of `_viewChainId` and `_pureChainId` to ensure there are no
523+
// compiler warnings when accessing chain ID in any solidity version supported by forge-std. We
524+
// can't simply access the chain ID in a normal view or pure function because the solc View Pure
525+
// Checker changed `chainid` from pure to view in 0.8.0.
526+
function _viewChainId() private view returns (uint256 chainId) {
527+
// Assembly required since `block.chainid` was introduced in 0.8.0.
528+
assembly {
529+
chainId := chainid()
530+
}
531+
532+
address(this); // Silence warnings in older Solc versions.
533+
}
534+
535+
function _pureChainId() private pure returns (uint256 chainId) {
536+
function() internal view returns (uint256) fnIn = _viewChainId;
537+
function() internal pure returns (uint256) pureChainId;
538+
assembly {
539+
pureChainId := fnIn
540+
}
541+
chainId = pureChainId();
542+
}
518543
}
519544

520545
// Wrappers around cheatcodes to avoid footguns

src/StdInvariant.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pragma solidity >=0.6.2 <0.9.0;
33

44
pragma experimental ABIEncoderV2;
55

6-
contract StdInvariant {
6+
abstract contract StdInvariant {
77
struct FuzzSelector {
88
address addr;
99
bytes4[] selectors;

src/StdStyle.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity >=0.4.22 <0.9.0;
33

4-
import {Vm} from "./Vm.sol";
4+
import {VmSafe} from "./Vm.sol";
55

66
library StdStyle {
7-
Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
7+
VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code")))));
88

99
string constant RED = "\u001b[91m";
1010
string constant GREEN = "\u001b[92m";

src/StdUtils.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ abstract contract StdUtils {
8585
console2_log("Bound result", vm.toString(result));
8686
}
8787

88-
function boundPrivateKey(uint256 privateKey) internal view virtual returns (uint256 result) {
88+
function boundPrivateKey(uint256 privateKey) internal pure virtual returns (uint256 result) {
8989
result = _bound(privateKey, 1, SECP256K1_ORDER - 1);
9090
}
9191

src/Test.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ pragma solidity >=0.6.2 <0.9.0;
44
pragma experimental ABIEncoderV2;
55

66
// 💬 ABOUT
7-
// Standard Library's default Test
7+
// Forge Std's default Test.
88

99
// 🧩 MODULES
1010
import {console} from "./console.sol";
1111
import {console2} from "./console2.sol";
12+
import {safeconsole} from "./safeconsole.sol";
1213
import {StdAssertions} from "./StdAssertions.sol";
1314
import {StdChains} from "./StdChains.sol";
1415
import {StdCheats} from "./StdCheats.sol";
@@ -17,15 +18,16 @@ import {StdInvariant} from "./StdInvariant.sol";
1718
import {stdJson} from "./StdJson.sol";
1819
import {stdMath} from "./StdMath.sol";
1920
import {StdStorage, stdStorage} from "./StdStorage.sol";
21+
import {StdStyle} from "./StdStyle.sol";
2022
import {StdUtils} from "./StdUtils.sol";
2123
import {Vm} from "./Vm.sol";
22-
import {StdStyle} from "./StdStyle.sol";
2324

2425
// 📦 BOILERPLATE
2526
import {TestBase} from "./Base.sol";
2627
import {DSTest} from "ds-test/test.sol";
2728

2829
// ⭐️ TEST
30+
// Note: DSTest and any contracts that inherit it must be inherited first, https://github.com/foundry-rs/forge-std/pull/241
2931
abstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase {
3032
// Note: IS_TEST() must return true.
3133
// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76.

src/Vm.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ interface VmSafe {
116116
// Labels an address in call traces
117117
function label(address account, string calldata newLabel) external;
118118
// Gets the label for the specified address
119-
function getLabel(address account) external returns (string memory label);
119+
function getLabel(address account) external returns (string memory currentLabel);
120120
// Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain
121121
function broadcast() external;
122122
// Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain

test/StdCheats.t.sol

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,8 @@ contract StdCheatsTest is Test {
370370

371371
contract StdCheatsMock is StdCheats {
372372
// We deploy a mock version so we can properly test expected reverts.
373-
function assumeNoBlacklisted_(address token, address addr) external {
374-
return assumeNoBlacklisted(token, addr);
373+
function assumeNotBlacklisted_(address token, address addr) external view {
374+
return assumeNotBlacklisted(token, addr);
375375
}
376376
}
377377

@@ -386,38 +386,38 @@ contract StdCheatsForkTest is Test {
386386
StdCheatsMock private stdCheats = new StdCheatsMock();
387387

388388
function setUp() public {
389-
// All tests of the `assumeNoBlacklisted` method are fork tests using live contracts.
389+
// All tests of the `assumeNotBlacklisted` method are fork tests using live contracts.
390390
vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900});
391391
}
392392

393-
function testCannotAssumeNoBlacklisted_EOA() external {
393+
function testCannotAssumeNotBlacklisted_EOA() external {
394394
address eoa = vm.addr({privateKey: 1});
395-
vm.expectRevert("StdCheats assumeNoBlacklisted(address,address): Token address is not a contract.");
396-
assumeNoBlacklisted(eoa, address(0));
395+
vm.expectRevert("StdCheats assumeNotBlacklisted(address,address): Token address is not a contract.");
396+
assumeNotBlacklisted(eoa, address(0));
397397
}
398398

399-
function testAssumeNoBlacklisted_TokenWithoutBlacklist(address addr) external {
400-
assumeNoBlacklisted(SHIB, addr);
399+
function testAssumeNotBlacklisted_TokenWithoutBlacklist(address addr) external {
400+
assumeNotBlacklisted(SHIB, addr);
401401
assertTrue(true);
402402
}
403403

404-
function testAssumeNoBlacklisted_USDC() external {
404+
function testAssumeNotBlacklisted_USDC() external {
405405
vm.expectRevert();
406-
stdCheats.assumeNoBlacklisted_(USDC, USDC_BLACKLISTED_USER);
406+
stdCheats.assumeNotBlacklisted_(USDC, USDC_BLACKLISTED_USER);
407407
}
408408

409-
function testAssumeNoBlacklisted_USDC(address addr) external {
410-
assumeNoBlacklisted(USDC, addr);
409+
function testAssumeNotBlacklisted_USDC(address addr) external {
410+
assumeNotBlacklisted(USDC, addr);
411411
assertFalse(USDCLike(USDC).isBlacklisted(addr));
412412
}
413413

414-
function testAssumeNoBlacklisted_USDT() external {
414+
function testAssumeNotBlacklisted_USDT() external {
415415
vm.expectRevert();
416-
stdCheats.assumeNoBlacklisted_(USDT, USDT_BLACKLISTED_USER);
416+
stdCheats.assumeNotBlacklisted_(USDT, USDT_BLACKLISTED_USER);
417417
}
418418

419-
function testAssumeNoBlacklisted_USDT(address addr) external {
420-
assumeNoBlacklisted(USDT, addr);
419+
function testAssumeNotBlacklisted_USDT(address addr) external {
420+
assumeNotBlacklisted(USDT, addr);
421421
assertFalse(USDTLike(USDT).isBlackListed(addr));
422422
}
423423
}

0 commit comments

Comments
 (0)