Repository navigation
feat: latticeTest, read the authority, existence and address params off the book - #3
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
A release's pre- and post-checks read the book lattice materializes at
.lattice/env.json, andEnvhad no accessor for three things they need: the governing account (the Safe or the EOA), whether a key exists (a test placed before the deploy step asserts nothing is staged yet, andparseJson*reverts on a missing key), and a param that holds an address withoutvm.parseAddress(Env.str(k))at every call site. Safe-administration releases also need the owner set and threshold the book expects.The first release's test base (polymarket-v2 #369) and safe-sim's
SafeSimBaseshare most of their helpers, and safe-sim's conventions name the checklist every governance simulation runs: the operation not yet filed, ownership and roles as declared, the new implementation sane (code, UUPS, initializers disabled) with its immutables matching the live ones, raw storage byte-equal after the upgrade, the proxy not re-initializable. That belongs here, once, so every release's checks and every simulation reuse it.Modifications
src/Lattice.sol:Env.authority(),authorityOwners(),authorityThreshold()(empty and zero when the book records none),has(name),hasStaged(name),chainId(); the scalar readersaddr_,int256_,bytes32_,bytes_and the range-checkeduint8_…uint128_(a cast would truncate silently).LatticeVmgains the cheatcodes they use.src/LatticeTest.sol:LatticeTest, an abstract base —materialized()/skipUnlessMaterialized();liveImplementation(name)/liveImplementationOf/liveBeaconOf;timelock(),operationState(id),operationId(...);governedAsDeclared(target),holdsNoRoles,soladyRole(n); the initializer readers for Solady and OpenZeppelin (*InitializedVersion,*Initializing,*InitializersDisabled,initializersDisabled),isUUPS,implementationSane(impl);answer,reverts,sameAnswers(a, b, getters),snapshot/firstSlots/firstChangedSlot; andcallAs/tryCallAs/callAsAuthority/proposeAs/executeAs/applyAsAuthorityto apply a plan underprank. Readers and helpers only, no assertions, cheatcodes declared inline ascheatsso a test inheriting forge-std'sTestsees no clash: the library still depends on nothing.test/Lattice.t.sol,test/LatticeTest.t.sol: both books in one test (forge runs test functions in parallel andEnvreads one fixed path); fakes for the timelock, a target, a governed contract, UUPS and non-UUPS implementations and constant holders; the skip exercised from a test's own frame, the only place forge allows it. Both files at 100/100 in the gate.docs/:README.md(what to reach for when),scripts.md(the entry points and their return shapes),env.md(everyEnvreader and when to use it),encoders.md(the three libraries and why a release script does not need them),testing.md(the checklist mapped to helpers, applying a plan yourself, what stays with the test). Linked from the README.Result
Release tests read everything they assert from the book and inherit the shared checklist:
contract PreUpgrade is Test, LatticeTest,skipUnlessMaterialized()insetUp,implementationSane(staged) == "",sameAnswers(proxy, staged, getters),governedAsDeclared(proxy),reverts(proxy, initializeCalldata); a narrow param that does not fit its type reverts instead of truncating.