Skip to content

Commit

Permalink
feat: forge-std v1.0.0 (#184)
Browse files Browse the repository at this point in the history
* Modularize forge-std (#126)

* refactor: unbundle cheats from assertions

refactor: new category StdUtils
refactor: unbundle Test from Script

* Rename "vm" to "vm_cheats" in "Cheats.sol"

Mark "vm_cheats" as "private"
Instantiate a "vm" in "Test.sol"

* refactor: remove deprecated "lowLevelError"

refactor: rename "vm_cheats" to just "vm"
refactor: rename "vm_std_store" to just "vm"
refactor: delete "INT256_MAX" and "UINT256_MAX"
revert: redeclare "stdstore" in "Test"

* refactor: move "stdErrors" to "Errors.sol"

refactor: move "stdMath" to "Math.sol"

* Add note about versions in "Errors.sol|

Co-authored-by: Zero Ekkusu <[email protected]>

* chore: delete stale delineators in Errors and Math

chore: delete stale "using stdStorage for StdStorage"

* refactor: modularize assertions and utils

docs: add NatSpec tag @dev in "console2"
refactor: delete log from "bound" function
refactor: move "addressFromLast20Bytes" to "Utils.sol"
refactor: move "bound" to "Utils.sol"
refactor: move "computeCreateAddress" to "Utils.sol"
style: move brackets on same line with "if" and "else" in "bound"

* Log bound result with static call to `console.log`

Co-authored-by: Zero Ekkusu <[email protected]>

* fix: reintroduce "vm" in "Script.sol"

chore: silence compiler warning in "bound"
refactor: define console2.log address as constant in "Utils.sol"

* test: move "testGenerateCorrectAddress" to "StdUtils.t.sol"

* Nit: remove unnecessary "bytes20" casts

* style: add white-spaces in "deal"

* fix: readd "deployCode" functions with "val"

* Add "computeCreate2Address" utility

Rename "testGenerateCorrectAddress" to "testGenerateCreateAddress"

* refactor: use "console2" in "Utils.sol"

* style: end lines and white spaces

* test: drop pragma to ">=0.8.0" in "StdError.t.sol"

chore: remove comment about "v0.8.10" in "Errors.sol"

* refactor: define "vm" and "stdStorage" in "TestBase"

feat: add "Components.sol" file which re-exports everything

* fix: inherit from DSTest in Test

* feat: ScriptBase

refactor: delete "TestBase.sol"
refactor: move TestBase in "Test.sol"

* ♻️ Make assertions virtual

* ♻️ Make deployCode virtual

* ✨ (Components) Export consoles

* ♻️ (Script) Import Vm

* ♻️ Import from Components

* ♻️ Make bound view

Co-authored-by: Zero Ekkusu <[email protected]>

* feat: make `Script` safer (#147)

* feat: add `stdStorageSafe`

* test(cheats): fix tests
`deployCode` tests started failing after 01c60f9

* refactor: make components `abstract`

* feat: add `CheatsSafe`

* feat: add `VmSafe`

* refactor: update `Script`

* docs: add license info (#156)

* feat: rebrand components (#157)

* feat: rebrand components
Rename to Std<Component>

* fix: StdErrors -> StdError

* chore: remove `.DS_Store`

* fix: use `ABIEncoderV2`

* test: correct test name

* fix: add `CommonBase`

* refactor: move test dir to root

* Revert "refactor: move test dir to root"

This reverts commit f21ef1a.

* refactor: move test dir to root, update ci accordingly

* style: configure and run forge fmt

* ci: split into jobs and add fmt job

* ci: update name and triggers

* ci: remove name field

* feat: better bound, ref #188

* fix: bound logs + remove unneeded line

* fix: update require strings

* refactor: clean up `Test` and `Script`
- do not forge fmt Components import
- do not import Safe Components in `Test`

* fix: udpate bound to match forge's uint edge bias strategy

* feat: add interfaces (#193)

* chore: update function visibility

* feat: add interfaces

* fix: fix import

* style: consistent spec style

* chore: fix find/replace issue

Co-authored-by: Zero Ekkusu <[email protected]>

* chore: update comments

Co-authored-by: Zero Ekkusu <[email protected]>

Co-authored-by: Zero Ekkusu <[email protected]>

* feat: reimplement `bound` w/ even distribution

* build: rename step

* Add memory-safe notation so that compiling via-ir can optimize effectively (#196)

* test(bound): add even distribution test (#197)

* feat: add `assumeNoPrecompiles` (#195)

* refactor: use fully-qualified paths instead of relative paths

* chore: fix typo

* feat: start adding StdChains

* feat: start adding assumeNoPrecompiles

* feat: add chains

* feat: add precompiles/predeploys

* Revert "refactor: use fully-qualified paths instead of relative paths"

This reverts commit bb2579e.

* refactor: use relative paths for compatibility with solc <0.6.9 (no --base-path flag)

* refactor: make assumeNoPrecompiles virtual

* refactor: no more constructor warning from StdChains

* fix: move stdChains into StdCheats, fix constructor initalization order, move cheats into VmSafe that can be safely used

* ♻️ update ds-test (#200)

* ♻️ update ds-test

Signed-off-by: Pascal Marco Caversaccio <[email protected]>

* ♻️  use relative path for ds-test imports

Signed-off-by: Pascal Marco Caversaccio <[email protected]>

Signed-off-by: Pascal Marco Caversaccio <[email protected]>

* refactor: move `UINT256_MAX` to `CommonBase`

Signed-off-by: Pascal Marco Caversaccio <[email protected]>
Co-authored-by: Paul Razvan Berg <[email protected]>
Co-authored-by: Matt Solomon <[email protected]>
Co-authored-by: Drake Evans <[email protected]>
Co-authored-by: Pascal Marco Caversaccio <[email protected]>
  • Loading branch information
5 people authored Oct 31, 2022
1 parent 2a2ce36 commit 17656a2
Show file tree
Hide file tree
Showing 36 changed files with 2,553 additions and 1,870 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: CI

on:
workflow_dispatch:
pull_request:
push:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Install Foundry
uses: onbjerg/foundry-toolchain@v1
with:
version: nightly

- name: Install dependencies
run: forge install

- name: Check backward compatibility
run: |
forge build --skip test --use solc:0.8.0
forge build --skip test --use solc:0.7.6
forge build --skip test --use solc:0.7.0
forge build --skip test --use solc:0.6.2
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Install Foundry
uses: onbjerg/foundry-toolchain@v1
with:
version: nightly

- name: Install dependencies
run: forge install

- name: Run tests
run: forge test -vvv

fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Install Foundry
uses: onbjerg/foundry-toolchain@v1
with:
version: nightly

- name: Check formatting
run: forge fmt --check
27 changes: 0 additions & 27 deletions .github/workflows/tests.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cache/
out/
.vscode
.idea
.idea
2 changes: 1 addition & 1 deletion LICENSE-APACHE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright Contributors to forge-std
Copyright Contributors to Forge Standard Library

Apache License
Version 2.0, January 2004
Expand Down
2 changes: 1 addition & 1 deletion LICENSE-MIT
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright Contributors to forge-std
Copyright Contributors to Forge Standard Library

Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Forge Standard Library • [![tests](https://github.com/brockelmore/forge-std/actions/workflows/tests.yml/badge.svg)](https://github.com/brockelmore/forge-std/actions/workflows/tests.yml)

Forge Standard Library is a collection of helpful contracts for use with [`forge` and `foundry`](https://github.com/foundry-rs/foundry). It leverages `forge`'s cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes.
Forge Standard Library is a collection of helpful contracts and libraries for use with [Forge and Foundry](https://github.com/foundry-rs/foundry). It leverages Forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes.

**Learn how to use Forge Std with the [📖 Foundry Book (Forge Std Guide)](https://book.getfoundry.sh/forge/forge-std.html).**
**Learn how to use Forge-Std with the [📖 Foundry Book (Forge-Std Guide)](https://book.getfoundry.sh/forge/forge-std.html).**

## Install

Expand All @@ -13,7 +13,7 @@ forge install foundry-rs/forge-std
## Contracts
### stdError

This is a helper contract for errors and reverts. In `forge`, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler builtin errors.
This is a helper contract for errors and reverts. In Forge, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler builtin errors.

See the contract itself for all error codes.

Expand Down Expand Up @@ -244,3 +244,7 @@ import "forge-std/console.sol";
...
console.log(someValue);
```

## License

Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license.
19 changes: 19 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,21 @@
[profile.default]
fs_permissions = [{ access = "read-write", path = "./"}]

[rpc_endpoints]
# We intentionally use both dashes and underscores in the key names to ensure both are supported.
# The RPC URLs below match the StdChains URLs but append a trailing slash for testing.
mainnet = "https://api.mycryptoapi.com/eth/"
optimism_goerli = "https://goerli.optimism.io/"
arbitrum-one-goerli = "https://goerli-rollup.arbitrum.io/rpc/"

[fmt]
# These are all the `forge fmt` defaults.
line_length = 120
tab_width = 4
bracket_spacing = false
int_types = 'long'
multiline_func_header = 'attributes_first'
quote_style = 'double'
number_underscore = 'preserve'
single_line_statement_blocks = 'preserve'
ignore = ["src/console.sol", "src/console2.sol"]
2 changes: 1 addition & 1 deletion lib/ds-test
Submodule ds-test updated 1 files
+15 −0 package.json
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "forge-std",
"version": "0.1.0",
"description": "Forge Standard Library is a collection of helpful contracts for use with forge and foundry",
"version": "1.0.0",
"description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.",
"homepage": "https://book.getfoundry.sh/forge/forge-std",
"bugs": "https://github.com/foundry-rs/forge-std/issues",
"license": "(Apache-2.0 OR MIT)",
"author": "Contributors to forge-std",
"author": "Contributors to Forge Standard Library",
"files": [
"src/*"
],
Expand Down
13 changes: 13 additions & 0 deletions src/Common.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.9.0;

import {StdStorage, Vm} from "./Components.sol";

abstract contract CommonBase {
address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code"))));
uint256 internal constant UINT256_MAX =
115792089237316195423570985008687907853269984665640564039457584007913129639935;

StdStorage internal stdstore;
Vm internal constant vm = Vm(VM_ADDRESS);
}
13 changes: 13 additions & 0 deletions src/Components.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.9.0;

import "./console.sol";
import "./console2.sol";
import "./StdAssertions.sol";
import "./StdCheats.sol";
import "./StdError.sol";
import "./StdJson.sol";
import "./StdMath.sol";
import "./StdStorage.sol";
import "./StdUtils.sol";
import "./Vm.sol";
48 changes: 9 additions & 39 deletions src/Script.sol
Original file line number Diff line number Diff line change
@@ -1,44 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.9.0;
pragma solidity >=0.6.2 <0.9.0;

import "./console.sol";
import "./console2.sol";
import "./StdJson.sol";
import {CommonBase} from "./Common.sol";
// forgefmt: disable-next-line
import {console, console2, StdCheatsSafe, stdJson, stdMath, StdStorage, stdStorageSafe, StdUtils, VmSafe} from "./Components.sol";

abstract contract Script {
bool public IS_SCRIPT = true;
address constant private VM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));

Vm public constant vm = Vm(VM_ADDRESS);

/// @dev Compute the address a contract will be deployed at for a given deployer address and nonce
/// @notice adapated from Solmate implementation (https://github.com/transmissions11/solmate/blob/main/src/utils/LibRLP.sol)
function computeCreateAddress(address deployer, uint256 nonce) internal pure returns (address) {
// The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0.
// A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it.
if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))));
if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce))));

// Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length.
if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce))));
if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce))));
if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce))));

// More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp
// 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce)
// 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)
// 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex)
// We assume nobody can have a nonce large enough to require more than 32 bytes.
return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))));
}

function addressFromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {
return address(uint160(uint256(bytesValue)));
}
abstract contract ScriptBase is CommonBase {
VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);
}

function deriveRememberKey(string memory mnemonic, uint32 index) internal returns (address who, uint256 privateKey) {
privateKey = vm.deriveKey(mnemonic, index);
who = vm.rememberKey(privateKey);
}
abstract contract Script is ScriptBase, StdCheatsSafe, StdUtils {
bool public IS_SCRIPT = true;
}
Loading

0 comments on commit 17656a2

Please sign in to comment.