-
Notifications
You must be signed in to change notification settings - Fork 337
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
feat: forge-std v1.0.0 #184
Conversation
* 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 <94782988+ZeroEkkusu@users.noreply.github.com> * 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 <94782988+ZeroEkkusu@users.noreply.github.com> * 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 <94782988+ZeroEkkusu@users.noreply.github.com>
* feat: rebrand components Rename to Std<Component> * fix: StdErrors -> StdError * chore: remove `.DS_Store`
Just tested locally in a big project I had, all went smoothly! Going to ask a few others to test in their projects and will report back |
Tested on my largest project. Works fine. |
This reverts commit f21ef1a.
@ZeroEkkusu I tried moving test dir to the root in f21ef1a to match the convention of |
It's as if Edit: |
Ah makes sense. There is now a |
@ZeroEkkusu wdyt of also running |
Sure @mds1. |
I think all that's left before merge is some more testing. Just tested the latest commit on this branch in some repos and it worked great. Would love for @nventuro to test since he has an 0.7.6 repo |
@nventuro Had some time on a flight without wifi so figured this was a good offline debug task. Here's what I found: testUpdateCachedRatiosBelow is a concrete test that will pass with forge-std on master but fail with v0.3 (well, v1.0.0 technically but calling it v0.3 since that's this branch name). The difference is in the
If I change the upper bound for function testUpdateCachedRatiosFailure() public {
// Hardcode inputs from the failure case found by the fuzzer on the v0.3 branch.
uint256 bptPrice = 0;
uint256 referenceWeight = 0;
uint256 newWeight = type(uint256).max;
uint256 lowerBound = 0;
uint256 upperBound = 0;
// Pass them through bound.
bptPrice = bound(bptPrice, _MIN_BPT_PRICE, _MAX_BPT_PRICE);
lowerBound = bound(lowerBound, _MINIMUM_BOUND_PERCENTAGE, FixedPoint.ONE);
upperBound = bound(upperBound, lowerBound, _MAX_BOUND_PERCENTAGE);
referenceWeight = bound(referenceWeight, _MINIMUM_TOKEN_WEIGHT, _MAXIMUM_TOKEN_WEIGHT);
newWeight = bound(newWeight, _MINIMUM_BOUND_PERCENTAGE, FixedPoint.ONE);
// Log them for convenience.
console2.log("bptPrice", bptPrice);
console2.log("lowerBound", lowerBound);
console2.log("upperBound", upperBound);
console2.log("referenceWeight", referenceWeight);
console2.log("newWeight", newWeight);
// Convert the bound statements in the fuzz test to assumes as a sanity check that
// the bound outputs are valid.
vm.assume(bptPrice >= _MIN_BPT_PRICE && bptPrice <= _MAX_BPT_PRICE);
vm.assume(lowerBound >= _MINIMUM_BOUND_PERCENTAGE && lowerBound <= FixedPoint.ONE);
vm.assume(upperBound >= lowerBound && upperBound <= _MAX_BOUND_PERCENTAGE);
vm.assume(referenceWeight >= _MINIMUM_TOKEN_WEIGHT && referenceWeight <= _MAXIMUM_TOKEN_WEIGHT);
vm.assume(newWeight >= _MINIMUM_BOUND_PERCENTAGE && newWeight <= FixedPoint.ONE);
// Call the fuzz test with our parameters.
testUpdateCachedRatios(bptPrice, referenceWeight, newWeight, lowerBound, upperBound);
} testExitSwapsSimilar to above, the new On average I get around 70% of the way through the 10k runs before erroring with too many rejects. (The 60k reject limit you currently have is slightly less than the default of 65536). So one solution is to simply bump the max rejects limit and deal with longer test times. I tried setting An alternative idea is that you may be able to get a bit more clever with how you use amountOut = bound(amountOut, 0, balances[tokenIndex]);
bptTotalSupply = bound(bptTotalSupply, _DEFAULT_MINIMUM_BPT, type(uint112).max);
swapFeePercentage = bound(swapFeePercentage, 0, 0.99e18);
// This exit type is special in that fees are charged on the amount out. This creates scenarios in which the
// total amount out (including fees) exceeds the Pool's balance, which will lead to reverts. We reject any runs
// that result in this edge case.
bool isValid = amountOut.divUp(FixedPoint.ONE - swapFeePercentage) <= balances[tokenIndex];
if (!isValid) {
// To speed up tests by minimizing rejections, modify the swapFeePercentage to ensure
// the validity check holds.
swapFeePercentage = balances[tokenIndex] - amountOut - 1;
isValid = amountOut.divUp(FixedPoint.ONE - swapFeePercentage) <= balances[tokenIndex];
}
vm.assume(isValid); TLDRI think the branch is behaving as expected and some tests need to be updated to account for the new behavior |
Just dropped a new For Previously
Now
We should test it more in practice to make sure there are no errors. |
I'll check this out and put a simple script together to test the distributions before and after to make sure things are good / the new complexity (new conditionals) are worth it. Going forward let's make these changes as PRs into this branch instead of committing directly to it—I think the separation is cleaner and makes it easier to discuss changes without resulting in one giant PR, plus if we decide to not implement a change we just close the PR instead of force pushing or adding commits to revert something |
Ok @ZeroEkkusu I think this implementation looks good.
Did you plan on writing these? Wondering what additional tests we should add. A bit tedious, but perhaps we hardcode an array of |
Good idea, I'll add one. Thoughts on the merge after #195? |
Awesome, thanks. Once we get #195 merged I want to do one more quick round of testing by pinging a few people again (since we made some additional changes), then good to merge if that goes smoothly |
* 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
Ok just tested in two repos:
|
Just tested on one of our larger repos. Works fine. |
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.
Left one suggestion, otherwise LGTM (Let's Get This Merged)!
* ♻️ update ds-test Signed-off-by: Pascal Marco Caversaccio <pascal.caversaccio@hotmail.ch> * ♻️ use relative path for ds-test imports Signed-off-by: Pascal Marco Caversaccio <pascal.caversaccio@hotmail.ch> Signed-off-by: Pascal Marco Caversaccio <pascal.caversaccio@hotmail.ch>
Forge Standard Library V1
Forge-Std is now modular - enabling composability, and paving the way for new libraries for testing in Solidity.
Features
createCompute2Address
and standards)bound
StdChains
andassumeNoPrecompiles
#195Breaking changes
>=0.6.2 <0.9.0
tip
std-cheat,lowLevelError
std-error)Script
safer #147using stdStorage for StdStorage
will break in scripts and will need to be changed tostdStorageSafe
(or will require a manual import ofstdStorage
)Before merging
0.6.2
feat: makeScript
safer #147 (comment)internal virtual
)