fix: close the re-audit findings - #16
Merged
Merged
Conversation
MinterControl: the appointment checks also refuse a Minter that has its own appointment pending as a Controller (PendingAppointment), so a cycle cannot be announced in two calls and left to whoever executes first. The same checks run at scheduling and at execution; the one shape scheduling cannot see -- an appointment pending over a Minter -- fails at execution. Docs that said 'refused at scheduling' now say exactly that. foundry.toml pins evm_version alongside solc: forge otherwise passes its own default, so creation code -- and every CREATE2 address -- depended on the forge release. Bytecode is unchanged by the pin (cancun was already the effective target). CHANGELOG and docs/deploying.md now say that addresses are bound to a repository revision and that v0.1.0 predictions no longer match. npm run lock:check (scripts/check-foundry-lock.mjs) compares foundry.lock with the submodule checkout and is part of npm run check, so the lock is enforced locally and in CI without a CI-only step. package.json carries the two OpenZeppelin packages at the submodules' release as an advisory canary: GitHub alerts and Dependabot release bumps fire for them, and a bump is the signal to move the submodules. Nothing compiles against the npm copies. Tests: the EIP-form receiveWithAuthorization payee refusal, the two-call cycle, the chain through a pending Minter. security-review.md no longer overstates the ERC-1822 guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 21, 2026
Merged
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.
Why
Re-audit of main after the audit fixes (
a0bcad0) found no regression but raised R-1…R-8 (Low 4 · Info 4). This closes R-1 through R-7; R-8 (IEip2612) is left as optional.What
MinterControl—_requireAppointablealso refuses a Minter that has its own appointment pending as a Controller (PendingAppointment), soschedule(A,B)+schedule(B,A)can no longer be announced and left for a third party to resolve via permissionlessexecuteController. The same checks run at scheduling and execution; the one shape scheduling cannot see (an appointment pending over a Minter) fails at execution — ADR-003, CHANGELOG and the review doc now say exactly that. Tests: two-call cycle; chain through a pending Minter.docs/deploying.md: CREATE2 addresses are bound to a repository revision; v0.1.0 predictions no longer match the current tree.foundry.tomlpinsevm_version = "cancun"next tosolc; verified bytecode unchanged (it was already the effective target).ci.ymlcomment corrected.package.jsoncarries@openzeppelin/contractsand@openzeppelin/contracts-upgradeableat 5.1.0 as an advisory canary (alerts + Dependabot release bumps fire; a bump is the signal to move the submodules). Nothing compiles against them — explicit remappings, andnode_modulesis outside the Foundry root. Documented in CONTRIBUTING.receiveWithAuthorization(v,r,s)form refuses a non-payee.npm run lock:check(scripts/check-foundry-lock.mjs) comparesfoundry.lockwith the submodule checkout; part ofnpm run check, so no CI-only step and the header's "package.json owns the gates" stays true.Checks
npm run check— fmt · lint · lock:check · 139 tests (8 suites); Slither 0 locally; Halmos in CI🤖 Generated with Claude Code