fix(foundry): VerifyAll supports linked libs; enable optimizer#414
Open
fix(foundry): VerifyAll supports linked libs; enable optimizer#414
Conversation
4 tasks
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.
Follow-up to #411
Summary
VerifyAll.s.solsilently underflowed on any contract that links an external library, abortingyarn verifywithPanic(0x11).foundry.tomlships without optimizer settings, so large generated contracts (e.g., ZK verifiers) can't deploy — they're rejected by EIP-170's 24,576-byte runtime limit.Problem
1.
VerifyAll.s.solbreaks on linked contractsFor contracts that use external libraries, solc leaves
__$<17-byte-hash>$__placeholders inbytecode.object. The current script does:Two bugs chained:
parseJson/abi.decode(..., (bytes))cannot hex-decode a string containing_/$, so it silently falls back to the JSON string-encoding path. The returned length is the charactercount (~2× the real byte length).
--libraries <path>:<name>:<addr>toforge verify-contract, so Etherscan has no way to link.Result:
deployedBytecode.length - compiledBytecode.lengthunderflows → verification aborts for every linked contract (Semaphore, LeanIMT, PoseidonT3, OZ libs compiled standalone,etc.).
Stock
packages/foundry/foundry.tomlhas no optimizer profile. Unoptimized bytecode from Barretenberg's Noir→Solidity verifier is ~30 KB runtime, over the 24,576-byte limit.yarn deploy --network sepoliafails before we ever reach yarn verify.Reproduction
Anyone can reproduce both issues end-to-end with the SpeedRunEthereum ZK-voting challenge:
Then fill in the contracts one of three ways:
After the contracts are written:
yarn deploy --network sepolia# fails: HonkVerifier > 24,576 bytes (bug 2)With optimizer enabled, deploy succeeds, then:
yarn verify --network sepolia# Voting panics with arithmetic underflow (bug 1)Fix
Two changes, same file ownership (Foundry package), no new deps.
packages/foundry/script/VerifyAll.s.soland resolved address are both 20 bytes, so length is placeholder-agnostic.
recompute solc's placeholder — "
satisfies the link.
--libraries <path>:<name>:<address>pairs to the existingforge verify-contractinvocation, one pair per discovered library.Verifier.solexportsHonkVerifier).No Python/jq/external tools; everything is in-script.
packages/foundry/foundry.tomlReasonable defaults for any foundry-based project and unblocks large generated contracts. (Also tried
via_ir = truefor further savings — it blew up on Yul stack-too-deep insidethe Barretenberg-generated assembly, so leaving it off.)
Test plan
yarn deploy+yarn verifyon Sepolia, both succeed--librariesflags added)--librariesflagpackages/foundry/test/*suite passes with optimizer enabled