Skip to content

feat: latticeTest, read the authority, existence and address params off the book - #3

Merged
0xrajath merged 3 commits into
mainfrom
feat/env-authority-and-existence
Oct 4, 2026
Merged

0xrajath merged 3 commits into
mainfrom
feat/env-authority-and-existence

Conversation

@0xrajath

@0xrajath 0xrajath commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

A release's pre- and post-checks read the book lattice materializes at .lattice/env.json, and Env had 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, and parseJson* reverts on a missing key), and a param that holds an address without vm.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 SafeSimBase share 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 readers addr_, int256_, bytes32_, bytes_ and the range-checked uint8_ … uint128_ (a cast would truncate silently). LatticeVm gains 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; and callAs / tryCallAs / callAsAuthority / proposeAs / executeAs / applyAsAuthority to apply a plan under prank. Readers and helpers only, no assertions, cheatcodes declared inline as cheats so a test inheriting forge-std's Test sees 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 and Env reads 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 (every Env reader 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() in setUp, implementationSane(staged) == "", sameAnswers(proxy, staged, getters), governedAsDeclared(proxy), reverts(proxy, initializeCalldata); a narrow param that does not fit its type reverts instead of truncating.

@0xrajath 0xrajath changed the title feat: read the authority, existence and address params off the book feat: latticeTest, read the authority, existence and address params off the book Oct 4, 2026
@0xrajath
0xrajath merged commit bbd0640 into main Oct 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant