-
Notifications
You must be signed in to change notification settings - Fork 412
feat: config helper contract #715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/Base.sol
Outdated
console.log("----------"); | ||
console.log(string.concat("Loading config from '", filePath, "'")); | ||
config = new StdConfig(filePath); | ||
vm.makePersistent(address(config)); | ||
console.log("Config successfully loaded"); | ||
console.log("----------"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since the StdConfig
constructor impl uses try catch blocks and there may be several errors in the traces, i thought it would be useful to add some logs to easily identify the config loading block
…std into rusowsky/config-helper
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
optimizer = true | ||
optimizer_runs = 200 | ||
|
||
# A list of solidity error codes to ignore. | ||
# 3860 = init-code-size | ||
ignored_error_codes = [3860] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for other reviewers - this already happens in master but not showing up as no ignored_error_codes
specified
Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
# -- OPTIMISM ------------------------------------ | ||
|
||
[optimism] | ||
endpoint_url = "${OPTIMISM_RPC}" | ||
|
||
[optimism.bool] | ||
is_live = false | ||
bool_array = [false, true] | ||
|
||
[optimism.address] | ||
weth = "${WETH_OPTIMISM}" | ||
deps = [ | ||
"0x2222222222222222222222222222222222222222", | ||
"0x3333333333333333333333333333333333333333", | ||
] | ||
|
||
[optimism.uint] | ||
number = 9999 | ||
number_array = [1234, 5678] | ||
|
||
[optimism.int] | ||
signed_number = 9999 | ||
signed_number_array = [-1234, -5678] | ||
|
||
[optimism.bytes32] | ||
word = "0x000000000000000000000000000000000000000000000000000000000000270f" # 9999 | ||
word_array = [ | ||
"0x00000000000000000000000000000000000000000000000000000000000004d2", # 1234 | ||
"0x000000000000000000000000000000000000000000000000000000000000162e", # 5678 | ||
] | ||
|
||
[optimism.bytes] | ||
b = "0xdcba" | ||
b_array = ["0xc0ffee", "0xbabe"] | ||
|
||
[optimism.string] | ||
str = "alice" | ||
str_array = ["bob", "charlie"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, it may be useful to display an alternative style either here or in the documentation that TOML allows for:
dotted keys
[optimism]
endpoint_url = "${OPTIMISM_RPC}"
bool.is_live = false
bool.bool_array = [false, true]
address.weth = "${WETH_OPTIMISM}"
address.deps = [
"0x2222222222222222222222222222222222222222",
"0x3333333333333333333333333333333333333333",
]
uint.number = 9999
uint.number_array = [1234, 5678]
int.signed_number = 9999
int.signed_number_array = [-1234, -5678]
bytes32.word = "0x000000000000000000000000000000000000000000000000000000000000270f" # 9999
bytes32.word_array = [
"0x00000000000000000000000000000000000000000000000000000000000004d2", # 1234
"0x000000000000000000000000000000000000000000000000000000000000162e", # 5678
]
bytes.b = "0xdcba"
bytes.b_array = ["0xc0ffee", "0xbabe"]
string.str = "alice"
string.str_array = ["bob", "charlie"]
or as inline table
[optimism]
endpoint_url = "${OPTIMISM_RPC}"
bool = { is_live = false, bool_array = [false, true] }
address = { weth = "${WETH_OPTIMISM}", deps = [
"0x2222222222222222222222222222222222222222",
"0x3333333333333333333333333333333333333333",
] }
uint = { number = 9999, number_array = [1234, 5678] }
int = { signed_number = 9999, signed_number_array = [-1234, -5678] }
bytes32 = { word = "0x000000000000000000000000000000000000000000000000000000000000270f", word_array = [
"0x00000000000000000000000000000000000000000000000000000000000004d2",
"0x000000000000000000000000000000000000000000000000000000000000162e",
] }
bytes = { b = "0xdcba", b_array = ["0xc0ffee", "0xbabe"] }
string = { str = "alice", str_array = ["bob", "charlie"] }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's great feedback, will make sure to add it to the docs
do we have any preference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for compactness I think user may prefer the inline table style but it has some limitations (no inline comments for example) and some limitations around multiline.
Either way I think both are valid to show in documentation so users are aware.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! 👍
This PR introduces a new contract,
StdConfig
, which encapsulates all the logic to read and write from a user-defined.toml
config file that sticks to a predetermined structure (access permissions must be granted viafoundry.toml
as usual).It also introduces a new abstract contract,
Config
, which can be inherited together withTest
andScript
. Users can then tap into the new features thatConfig
andStdConfig
enable to streamline the setup of multi-chain environments.Features
Comprehensive + Easily Programmable Config File
The TOML structure must have top-level keys representing the target chains. Under each chain key, variables are organized by type in separate sub-tables like
[<chain>.<type>]
.uint
or a valid alloy-chain alias.bool
,address
,uint
,bytes32
,string
, orbytes
.Ease dev burden when dealing with Multi-Chain Setups
The new
Config
abstract contract introduces a minimal set of storage variables that expose the user config:These variables are populated with a single function that users can call when setting up their tests or scripts:
Intuitive and type-safe API with
StdConfig
andLibVariable
StdConfig
reads, resolves, and parses all variables when initialized, caching them in storage.StdConfig
exposes a genericget
method that returns aVariable
struct. This struct holds the raw data and its type information.LibVariable
library is used to safely cast theVariable
struct to a concrete Solidity type. This ensures type safety at runtime, reverting with a clear error if a variable is missing or cast incorrectly.StdConfig
supports bidirectional (read + write capabilities) configuration management:writeToFile
parameter enables automatic persistence of changes.function writeUpdatesBackToFile(bool)
to toggle write behavior at runtime.Usage example