Espresso 1: Contracts (re-hosted)#455
Conversation
a6a2298 to
d5ff5d1
Compare
Adds the Espresso-introduced contracts and the minimum supporting changes
required for them to compile, test, and pass the contract checks.
New contracts and scripts:
- src/L1/BatchAuthenticator.sol and interfaces/L1/IBatchAuthenticator.sol
(upgradeable contract that authenticates batch transactions, with switching
between Espresso and fallback batchers)
- scripts/deploy/DeployBatchAuthenticator.s.sol and
scripts/deploy/DeployEspresso.s.sol
- test/L1/BatchAuthenticator.t.sol and test/mocks/MockEspressoTEEVerifiers.sol
- snapshots/{abi,storageLayout}/BatchAuthenticator.json
- snapshots/semver-lock.json entry for BatchAuthenticator
New submodules:
- lib/espresso-tee-contracts (interfaces required by BatchAuthenticator)
- lib/openzeppelin-contracts-upgradeable-v5 (OZ v5 used by BatchAuthenticator
via OwnableUpgradeable)
Supporting changes (Espresso-driven):
- foundry.toml: remappings for OZ v5 and espresso-tee-contracts; ignored
warning codes for vendored libs; OOM-safe jobs settings; via-ir profile.
- justfile: fix-proxy-artifact recipe to handle OZ v5 shadowing Proxy/ProxyAdmin
artifacts; build/coverage hooks.
- src/universal/Proxy.sol, src/universal/ProxyAdmin.sol: pin pragma to exact
0.8.15 so they stay in their own compilation group and never emit PUSH0.
- src/universal/ReinitializableBase.sol: loosen pragma to ^0.8.15 so
BatchAuthenticator (compiled with OZ v5) can import it.
- scripts/* and test/*: disambiguate Proxy artifact lookups to
src/universal/Proxy.sol:Proxy (avoids OZ v5 proxy/Proxy.sol shadow).
- scripts/checks: bypass interface checks for artifacts originating from lib/;
add Espresso-related contract names to exclude lists; pragma exclusions for
Proxy/ProxyAdmin/BatchAuthenticator.
- test/vendor/Initializable.t.sol: exclude BatchAuthenticator (deployed by a
separate Espresso script).
Co-authored-by: OpenCode <noreply@opencode.ai>
Co-authored-by: piersy <pierspowlesland@gmail.com>
- strict-pragma: remove unneeded exclusions for src/universal/Proxy.sol and src/universal/ProxyAdmin.sol — both already use strict 'pragma solidity 0.8.15;', so the entries (and their misleading comment claiming '^') were dead. - interfaces: move the Espresso excludeContracts block out of the upstream-shared area and down next to the Celo block, with one entry per line to match the surrounding style. Localizes future rebase deltas. Co-authored-by: OpenCode <noreply@opencode.ai>
Inline the EspressoTEEVerifier deployment in DeployEspresso.s.sol so it
no longer imports lib/espresso-tee-contracts/scripts/DeployTEEVerifier.s.sol
or DeployNitroTEEVerifier.s.sol. The upstream scripts pulled OZ v5's
TransparentUpgradeableProxy (and its auto-deployed ProxyAdmin) into the
OP artifact tree, shadowing src/universal/ProxyAdmin.sol and forcing a
~90-line fix-proxy-artifact justfile recipe.
The TEEVerifier is now deployed behind src/universal/Proxy.sol +
src/universal/ProxyAdmin.sol, matching how BatchAuthenticator is
deployed in the same script. ERC-1967 slots are unchanged, so external
callers see no difference.
The raw vm.getCode("ProxyAdmin") lookups in the deploy scripts and
BatchAuthenticator tests are switched to the explicit artifact path
vm.getCode("forge-artifacts/ProxyAdmin.sol/ProxyAdmin.json") to
deterministically resolve the default compilation profile's bytecode
(the dispute profile transitively compiles ProxyAdmin at optimizer_runs=5000,
creating a second artifact that broke unqualified lookups).
The fix-proxy-artifact recipe and its 5 callsites are removed.
Cherry-picked from piersy's commit 5d0a803 on PR #443. Walks the dual-batcher state machine: Espresso path → switchBatcher → fallback path → switchBatcher → Espresso path. Asserts every transition emits the expected event, that signer registration survives the round-trip, and that re-issuing the same call after a mode flip changes the outcome (the previously-valid Espresso signature is no longer consulted on the fallback path). Co-authored-by: Piers Powlesland <pierspowlesland@gmail.com> Co-authored-by: OpenCode <noreply@opencode.ai>
Replace the hand-rolled `EspressoBatcherEntry[]` history + binary search with OpenZeppelin's `Checkpoints.Trace160` (`(uint96 key, uint160 value)`). `uint160` is exactly an address with no waste, and `uint96` easily covers L1 block numbers. `upperLookupRecent` replaces the custom binary search and the same-block-overwrite branch is now handled inside `_insert`. Co-authored-by: OpenCode <noreply@opencode.ai>
…sed warning codes Drop the two impl imports (EspressoTEEVerifier, EspressoNitroTEEVerifier) from DeployEspresso.s.sol and replace direct instantiation with vm.getCode + assembly create, reading bytecode from the submodule's own out/ directory. This removes the impl closure (TEEHelper, JournalValidation, and the aws-nitro-enclave-attestation chain) from OP's solc invocations. The impls are still parsed/ABI-checked by forge via libs=['lib'], but they no longer require bytecode emission or the optimizer backend. Since OP's build no longer compiles the submodule's impl files, the three error codes those files triggered (6321 unnamed return, 5667 unused param, 1878 missing SPDX) can be removed from ignored_error_codes. OP's own code does not trigger any of them. The lint_on_build=false workaround is also removed for the same reason — with the impl closure gone, forge lint reports 283 warnings (all from OP's own code), none of which cause a build failure. Adds fs_permissions read access for lib/espresso-tee-contracts/out/ so vm.getCode can locate the pre-built artifacts. The submodule must be built (forge build --root lib/espresso-tee-contracts) before OP's main build. Co-authored-by: OpenCode <noreply@opencode.ai>
Deploy the BatchAuthenticator and TEEVerifier proxies behind the existing OP Stack ProxyAdmin instead of dedicated ones (#443). Both proxies use the deployer as a transient admin to initialize directly, then changeAdmin to the shared ProxyAdmin (DeployAltDA/DeployFeesDepositor pattern). Reorder TEE deploy so the Nitro verifier is wired via initialize, removing the post-init onlyOwner call and ownership-transfer dance. Rename inputs to espressoOwner/sharedProxyAdmin and drop the teeVerifierProxyAdmin output. Co-authored-by: OpenCode <noreply@opencode.ai>
Co-authored-by: OpenCode <noreply@opencode.ai>
The Go script host's getArtifact translated a fully-qualified Foundry
name like "src/universal/Proxy.sol:Proxy" into the artifact path
"src/universal/Proxy.sol/Proxy.json", which does not exist because the
artifacts FS is keyed by the source-file basename. Reduce any
directory-qualified path to its basename before ReadArtifact so that
both "File.sol:Contract" and "path/to/File.sol:Contract" resolve to the
same artifact.
This unblocks the deploy scripts that use
getCode("src/universal/Proxy.sol:Proxy") to disambiguate from the
OpenZeppelin v5 proxy/Proxy.sol artifact, fixing TestNewDeployAltDAScript,
TestNewDeployImplementationsScript, TestNewDeploySuperchainScript and the
op-e2e proofs actions that hit the same DeploySuperchain code path.
Co-authored-by: OpenCode <noreply@opencode.ai>
Resolve the 16 findings flagged by the contracts-bedrock-checks-fast semgrep job: - sol-safety-use-deployutils-getcode: replace vm.getCode(...) with DeployUtils.getCode(...) in DeployBatchAuthenticator, DeployEspresso, DeployPeriphery, BatchAuthenticator.t, and FeesDepositor.t (add the DeployUtils import where missing). - sol-style-use-abi-encodecall: add a justified nosemgrep on the EspressoTEEVerifier initialize encoding in DeployEspresso; encodeCall would pull the EspressoTEEVerifier impl closure into OP's compile group, which deploying from the submodule artifact is meant to avoid. - sol-style-input-arg-fmt / sol-style-return-arg-fmt: rename interface and contract args (index -> _index, l1Block -> _l1Block) and name returns (batcher_, fromBlock_) on BatchAuthenticator and IBatchAuthenticator. forge build, the semgrep scan (0 blocking findings), and the BatchAuthenticator/FeesDepositor test suites all pass. Co-authored-by: OpenCode <noreply@opencode.ai>
The espressoBatcher history is an OZ Checkpoints.Trace160 keyed by block number. OZ's push overwrites (not appends) when the key equals the latest entry's key, so two setEspressoBatcher calls in the same block — or one in the same block as the initialize seed — silently destroyed the prior record. setEspressoBatcher now reverts with BatcherChangedThisBlock if a history entry already exists for the current block. Co-authored-by: OpenCode <noreply@opencode.ai>
d5ff5d1 to
27f75a7
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 27f75a7b6c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| address fallbackBatcher = address(uint160(uint256(systemConfig.batcherHash()))); | ||
| if (msg.sender != fallbackBatcher) revert UnauthorizedFallbackBatcher(msg.sender, fallbackBatcher); |
There was a problem hiding this comment.
Compare the full batcher hash in fallback mode
When SystemConfig.batcherHash() is set through the bytes32 overload with non-zero high 96 bits, this truncates the value and authorizes address(uint160(hash)) even though the configured batcher hash is not the canonical encoding of that address. The derivation code parses batcher updates as an ABI address and rejects non-zero address padding, so fallback authentication can accept a caller that the SystemConfig batcher hash does not actually represent; compare bytes32(uint256(uint160(msg.sender))) to the full hash (or reject non-canonical hashes) instead of truncating the expected value.
Useful? React with 👍 / 👎.
This PR pulls in the
BatchAuthenticatorpart of Espresso integration atpackages/contracts-bedrock/src/L1/BatchAuthenticator.sol. All other changes are deployment scripts, tests, and other wiring.BatchAuthenticatoris the contract that the batchers will have to authenticate their batches with; corresponding changes for the derivation pipeline and batchers forthcoming as subsequent PRs.This is #443, re-hosted from in-repo branch.