feat(protocol): Proposal0020 — move SGX legs onto a PCCS-backed DCAP entrypoint - #21964
Draft
davidtaikocha wants to merge 4 commits into
Draft
feat(protocol): Proposal0020 — move SGX legs onto a PCCS-backed DCAP entrypoint#21964davidtaikocha wants to merge 4 commits into
davidtaikocha wants to merge 4 commits into
Conversation
…entrypoint Retires the Proposal0017 SGX verifiers, which attest through Taiko's legacy stripped AutomataDcapV3Attestation proxies, in favour of two fresh SecureSgxVerifiers attesting through a Taiko-owned upstream AutomataDcapAttestationFee entrypoint backed by Automata's on-chain PCCS (router 0xE2Cd5aA4, provisioned by Automata on 2026-07-10). The RISC0 and SP1 verifiers are reused unchanged, so the raiko2 v0.6.0 image IDs and program keys that Proposal0019 trusts carry over. Because ComposeVerifier holds its sub-verifiers as immutables and Inbox._proofVerifier is immutable, swapping the SGX legs requires both a new ZkRequiredVerifier and a new MainnetInbox impl; the latter is identical to Proposal0019's impl in every Config field except proofVerifier. Stacks on Proposal0019, which must execute first. Also adds the deploy script that produced the addresses, so the proposal is reproducible: DeploySgxSwapProofStack asserts at deploy time that the new inbox impl differs from the reference impl only in proofVerifier. The ATTRIBUTES pin is deliberately unset — buildL1Actions reverts with AttributePolicyNotSet() until it is filled from a real raiko2 v0.6.0 quote, so the proposal cannot emit executable action data with an unset pin. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sets ENCLAVE_ATTRIBUTE_MASK / ENCLAVE_ATTRIBUTE_EXPECTED to Profile A (the "strict FLAGS pin" from enclave-attribute-policies.md): mask checks all 8 FLAGS bytes and leaves XFRM unchecked, expected requires INIT|MODE64BIT and forces every other FLAGS bit — including CET, KSS and AEX_NOTIFY — to zero. Both v0.6.0 enclaves attest with FLAGS = 0x05, established from their builds rather than assumed. They use different TEE frameworks: raiko2's SGX-reth is Gramine (manifest sets sgx.debug=false, enables no KSS/CET/AEX-Notify; EDMM sets no FLAGS bit so both reth measurements share the pin), while gaiko2's SGX-geth is EGo v1.9 / Open Enclave (enclave.json "debug": false, and the schema exposes no knob for those bits). This clears the AttributePolicyNotSet guard, so Proposal0020.action.md is now generated. Fork-simulating the bundle against mainnet executes all 9 actions cleanly (280,336 gas): the pin is accepted on-chain (EnclaveAttributePolicySet version 1) and the inbox upgradeTo passes the UUPS proxiableUUID check. The pin still wants reconciling against a real v0.6.0 quote before submission — re-pinning later revokes instances registered under the old pin — and the SGX-geth/EGo side has no on-chain precedent to cross-check against. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Removes script/layer1/verifiers/deploy_sgx_swap.sh. It was only a convenience wrapper around two forge broadcasts, and the deployment it automated has already run; DeploySgxSwapProofStack.s.sol remains as the substantive, reproducible artifact behind the proposal's addresses. Repoints the two references that named it (the Proposal0020 constant block and the deployed-addresses section) at the underlying scripts instead: DeployAutomataDcapAttestation (profile layer1o) for the entrypoint, then DeploySgxSwapProofStack (profile layer1) with DCAP_ATTESTATION set to it. Comment-only change to the proposal, so the generated action data is unaffected — re-running `P=0020 pnpm proposal` reproduces byte-identical calldata. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
Moves Taiko's two SGX proof legs off the legacy stripped
AutomataDcapV3Attestationproxies and onto a Taiko-owned upstreamAutomataDcapAttestationFeeentrypoint backed by Automata's on-chain PCCS. RISC0 and SP1 are reused unchanged; the Inbox is re-pointed at a newZkRequiredVerifiercomposing the new SGX verifiers with them.The proof policy is unchanged — at least one ZK proof per batch; SGX-GETH + SGX-RETH alone still can never finalize.
Important
Stacks on #21935 / Proposal0019, which must execute first. 0020 assumes 0019 has already rotated the RISC0/SP1 trusted IDs to raiko2 v0.6.0 on the reused ZK verifiers, run
init3, and upgraded the Inbox.Why now
The upstream Automata entrypoint resolves quotes against PCCS router
0xE2Cd5aA4…, which was unprovisioned on mainnet until 2026-07-10, when Automata deployed a V2 async-upsert DAO stack behind it and upserted the collateral.getStandardTcbEvaluationDataNumber(SGX)now returns19and the full read path resolves — which is what unblocked this migration.Why a new verifier and a new inbox impl
ComposeVerifierholds its sub-verifiers as immutables andInbox._proofVerifieris immutable. So changing the SGX legs cascades: new SGX verifiers → newZkRequiredVerifier→ newMainnetInboximpl → upgrade. The existing0x7284aaC0…cannot be re-pointed.The new impl is identical to Proposal0019's (
0x5253D4C9…) in every Config field exceptproofVerifier— verified against both deployments on-chain, and asserted at deploy time byDeploySgxSwapProofStack._assertOnlyProofVerifierChanged.Deployed addresses (mainnet block 25543404, verified on-chain)
AutomataDcapAttestationFee0x49216ad7d4DbafbE2F14525a863E621e2041ECB6V3QuoteVerifier0x560bd80fa0C0109954f0a8EFacb06779df397072SecureSgxVerifier(geth)0xA8A78d008b5745dd8487A8E912cD3d5A8618b496SecureSgxVerifier(reth)0x4bFaB16Bd9DA86bF6498a640B4d076eF4Ef5dfaAZkRequiredVerifier0x0676334976D6578229829fAf92fb72Bd9378995bMainnetInbox(new impl)0x05C9620F9cc7154Ab1a47029014960e673586138Reused: RISC0
0x059dAF31…, SP10x73A0Db39…. Entrypoint is DAO-owned withgetBp() == 0.9 actions
0–2 establish SGX-geth trust (
setMrSigner/setMrEnclave/setEnclaveAttributePolicy), 3–7 the same for SGX-reth (two measurements: non-EDMM + EDMM), 8 upgrades the Inbox. Note the trust surface moved: on the new stack these areonlyOwneron the verifier itself, whereas 0019 rotates measurements on the legacy attester proxies.ATTRIBUTES pin — Profile A ✅
Profile A ("strict FLAGS pin") from
enclave-attribute-policies.md— the documented default for both prover enclaves and the exact pinSgxVerifier.t.solexercises (STRICT_MASK/STRICT_EXPECTED). Mask checks all 8 FLAGS bytes, leaves XFRM unchecked (so provers with XFRM0x03/0x07/0xE7all pass); expected requiresINIT|MODE64BITand forces every other FLAGS bit — forbidden floor,CET,KSS,AEX_NOTIFY, reserved — to zero.FLAGS =
0x05established from the builds, not assumed. The two enclaves use different TEE frameworks:sgx.debug = false, no KSS/CET/AEX-Notify.sgx.edmm_enableis templated and EDMM sets no FLAGS bit → both reth measurements share the pin.ego/enclave.json:"debug": false; EGo's schema exposes no knob for KSS/CET/AEX-Notify.Important
Reconcile against a real v0.6.0 quote before submission — re-pinning bumps the policy version and revokes every instance registered under the old pin.
ATTRIBUTES= bytes[96:112]of a raw quote (raiko2-sgx-prover bootstrapemits one; it's also persisted on any running prover). The SGX-geth/EGo side has no on-chain precedent: the live0x41e79EB4/0x9D3C595Bare the pre-#21827SgxVerifierand carry no attribute policy at all — I verifiedenclaveAttributePolicy/instanceValidityDelaydon't even exist on them. Neither project's build metadata exposes the attributes (both scripts drop them), so usegramine-sgx-sigstruct-viewor a quote.Post-execution (operational, not DAO)
The registrar
0x9CBeE534…callsregisterInstanceon both new verifiers with fresh v0.6.0 quotes. It cannot run earlier — registration fail-closes until the DAO sets the pin. Until then no SGX leg verifies and finalization runs onRISC0 + SP1, whichZkRequiredVerifieraccepts.Testing
FOUNDRY_PROFILE=layer1 forge build— clean.P=0020 pnpm proposalgeneratesProposal0020.action.md; decoded calldata = 9 actions (2setMrSigner, 3setMrEnclave, 3setEnclaveAttributePolicy, 1upgradeTo; 3 hits on sgxGeth, 5 on sgxReth, 1 on INBOX). TheAttributePolicyNotSet()guard was verified to fire while the pin was unset.MODE=l1dryrun, no--broadcast) →DryrunSucceeded(), 280,336 gas: the pin is accepted on-chain (EnclaveAttributePolicySet(..., version: 1)) andupgradeTopasses the UUPSproxiableUUID()check.DeploySgxSwapProofStackfork-simulated against mainnet before the real run; its drift assertion passed against the live0x5253d4c9.Notes
DeploySgxSwapProofStack.s.solso the proposal's addresses are reproducible — it exists in no other PR, and it asserts at deploy time that the new inbox impl differs from the reference impl only inproofVerifier. The entrypoint comes from the existingDeployAutomataDcapAttestation(profilelayer1o); this script (profilelayer1) takes it viaDCAP_ATTESTATION.0x55862381…, SGX-geth0xe78129f8…, P2560x03Fad3a6…, V30xFf269552…. Nothing references them; the live set is the table above. Documented inProposal0020.mdso reviewers aren't confused by two entrypoints on Etherscan.🤖 Generated with Claude Code