Skip to content

Espresso 1: Contracts (re-hosted)#455

Merged
piersy merged 31 commits into
celo-rebase-18from
espresso/contracts
Jun 18, 2026
Merged

Espresso 1: Contracts (re-hosted)#455
piersy merged 31 commits into
celo-rebase-18from
espresso/contracts

Conversation

@QuentinI

@QuentinI QuentinI commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

This PR pulls in the BatchAuthenticator part of Espresso integration at packages/contracts-bedrock/src/L1/BatchAuthenticator.sol. All other changes are deployment scripts, tests, and other wiring.

BatchAuthenticator is 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.

@QuentinI QuentinI closed this Jun 12, 2026
@QuentinI QuentinI reopened this Jun 12, 2026
@QuentinI QuentinI changed the title Espresso 1: Contracts Espresso 1: Contracts (re-hosted) Jun 12, 2026
@QuentinI QuentinI force-pushed the espresso/contracts branch 4 times, most recently from a6a2298 to d5ff5d1 Compare June 17, 2026 17:10
QuentinI and others added 21 commits June 18, 2026 18:38
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>
QuentinI and others added 10 commits June 18, 2026 18:38
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>
@QuentinI QuentinI force-pushed the espresso/contracts branch from d5ff5d1 to 27f75a7 Compare June 18, 2026 16:40
@piersy piersy marked this pull request as ready for review June 18, 2026 17:43

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +174 to +175
address fallbackBatcher = address(uint160(uint256(systemConfig.batcherHash())));
if (msg.sender != fallbackBatcher) revert UnauthorizedFallbackBatcher(msg.sender, fallbackBatcher);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@piersy piersy left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good @QuentinI!

@piersy piersy merged commit efaaff6 into celo-rebase-18 Jun 18, 2026
63 checks passed
@piersy piersy deleted the espresso/contracts branch June 18, 2026 21:42
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.

4 participants