Skip to content

RFP-021, RFP-022: Ethereum state attestation and the wrapped ERC-20 bridge - #158

Open
jzaki wants to merge 69 commits into
masterfrom
rfp-021-wrapped-erc20
Open

RFP-021, RFP-022: Ethereum state attestation and the wrapped ERC-20 bridge#158
jzaki wants to merge 69 commits into
masterfrom
rfp-021-wrapped-erc20

Conversation

@jzaki

@jzaki jzaki commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Related to logos-co/ecosystem#123

Two RFPs covering the Ethereum-to-LEZ asset path, split so that the shared,
security-critical part is specified and audited once rather than per consumer.

Both RFPs are ready for review. RFP-023 (Native Gas Token Bridge) has
moved to #169, stacked on this branch so its cross-references resolve, and is
no longer part of this diff.

RFP Title Tier What it delivers
RFP-021 Trustless Ethereum State Attestation for LEZ M The primitive that lets a LEZ program act on a fact about Ethereum state and know it is true
RFP-022 Privacy-Preserving Wrapped ERC-20 and Ether Bridge for LEZ L Ethereum vault escrows ERC-20/ETH, LEZ program mints the wrapped asset
RFP-023 → #169 Native Gas Token Bridge for LEZ M The reverse direction: LEZ is the vault, Ethereum mints a gas-token ERC-20
              RFP-021  attestation
              reads finalised Ethereum state
                   ↑              ↑
              RFP-022          RFP-023
              ETH vault        LEZ vault
              → LEZ mint       → ETH mint

RFP-021 — Ethereum State Attestation

A LEZ execution is self-contained: its correctness is established given its
inputs
, and whether an input is a true statement about the outside world is not
something the execution establishes. A program minting against "a deposit of X
occurred on Ethereum" establishes only that it minted given the claim.

An inclusion proof alone does not fix this. Anyone can construct a header and
Merkle paths internally consistent with a state they chose, so verification
passes having checked a real inclusion proof against a fabricated Ethereum. The
anchor comes from finality: sync-committee signatures over a light-client
finality update, then inclusion under that finalised header, then a predicate
over the verified state.

Output is a verified statement with no application action attached. Uniqueness
stays with the consumer, keyed on a statement identifier the primitive supplies.
The two trust assumptions it carries, honest sync-committee supermajority and
the weak-subjectivity checkpoint, are explicit documentation deliverables rather
than footnotes.

Cost, separated by execution path. BLS12-381 aggregate verification is
needed only to prove a header finalised, and a finalised header is public, so
sync-committee tracking belongs on the public path where the sequencer executes
it and the question is throughput. Inclusion is hashing rather than curve work:
SHA256 for the SSZ binding of the execution payload into the beacon body, then
keccak256 down a Merkle-Patricia path. The open question is whether that hashing
fits a private transaction proven on the user's own hardware, which decides
whether the primitive is usable privately at all. Measuring both, separated by
where the cost is paid, is a first-class deliverable; if BLS does not fit, the
measurement feeds a follow-on precompile RFP, reachable only from public
transactions.

Instances, not deployments. The program is deployed once and its code is
immutable. The checkpoint, chain binding, finality parameters and tracked
consensus state are per-instance configuration held in accounts, written at
initialisation and never rewritten; instances coexist, one per chain in normal
operation, and a stale checkpoint is repaired by initialising a fresh instance
rather than mutating an existing one. Advancing an instance is permissionless,
so the operator is a liveness role with no trust attached.

Reference consumer programs demonstrate the recommended integration pattern end
to end, for an ERC-20 transfer and for a native ether transfer to a specific
contract.

RFP-022 — Wrapped ERC-20 and Ether Bridge

Lock-and-mint bridge with unlinkability as a hard requirement on both legs: no
signal other than amount, token and timing may link an Ethereum deposit to the
LEZ mint it funded, or a LEZ burn to the Ethereum release it triggered. Fixed
denominations are the expected baseline, with hidden amounts as a soft
requirement.

Trustless throughout: no signer, validator, or federation is trusted with a key.
The RFP is candid that this addresses only one class of bridge failure, since a
comparable or larger share of historical losses came from bugs in verification
logic rather than key custody, and it treats verification correctness as a
security requirement of the same order as eliminating signer trust.
Loss-of-access is designed against rather than disclaimed: every unclaimed
deposit and unreleased burn must be recoverable from the user's existing wallet
seed alone.

Fixed verification logic, stated per chain

Both RFPs require that no party can change what the bridge or the module accepts
as a valid proof after deployment, and each states it in terms of its own chain
rather than assuming an EVM shape on both sides.

On LEZ the risk is indirection. A program may hold a ProgramId in mutable
account state and dispatch verification through it, so whoever controls that
pointer could repoint it at a verifier that accepts anything. RFP-021 forbids
reaching consensus or inclusion verification that way, and requires the consumer
documentation to extend the same rule to consumers, since a consumer holding the
module's ProgramId in mutable state reintroduces exactly the same substitution.
On Ethereum, RFP-022 targets the upgrade path, where the familiar
proxy-substitution risk is real.

Also in this PR

  • appendix/bridges-and-wrapped-tokens.md — sourced bridge-hack taxonomy with
    per-hack root causes, distinguishing key-custody failures from
    verification-logic bugs, plus the stablecoin market figures RFP-022 cites.
  • appendix/ethereum-light-client-ecosystem.md — survey of the sync-committee
    light-client implementations RFP-021 could reuse (Telepathy, SP1 Helios,
    r0vm-helios) with their audit history, plus the two-proof-system structure of
    an attestation: the SSZ generalised-index proof binding the execution payload
    into the beacon body, then Merkle-Patricia proofs against the execution roots.
    It also records that a log is not a trie leaf and has to be proven through its
    receipt, which is why RFP-021 specifies logs by position within a receipt.
  • README table and .github/ISSUE_TEMPLATE/proposal.yml dropdown updated for
    both RFPs. RFP-023's row and dropdown entry live in RFP-023: Native Gas Token Bridge for LEZ #169.

Review notes

  • RFP-022 consumes RFP-021 and says so in its Platform Dependencies rather than
    restating the verification design. Both link forward to RFP-023, which lands
    with RFP-023: Native Gas Token Bridge for LEZ #169.
  • FURPS items state conditions, not test instructions. Supportability already
    requires every hard requirement to have a corresponding test, so per-item
    "provide a test asserting..." phrasing was removed; the specific adversarial
    cases it named are kept as conditions the requirement demands.
  • RFP-021 and RFP-022 were swapped so the shared attestation primitive carries
    the lower number and its consumers follow it. Both files were renamed.
  • RFP-021 no longer specifies the runtime that proves it. The zkVM framing, the
    RISC0 platform dependency and the RISC0 skills and resources entries are gone;
    requirements now state what verification must establish. RFP-022 still carries
    its RISC0 dependency section.
  • Rebased onto master (including the RFP-008 closure), so the diff is confined
    to the two RFPs, the two appendices, and the README and proposal-template
    wiring.

🤖 Generated with Claude Code

@jzaki
jzaki requested a review from fryorcraken August 6, 2026 19:21

@fryorcraken fryorcraken left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not fully reviewed yet.

Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
@fryorcraken

Copy link
Copy Markdown
Collaborator

Related: logos-co/ecosystem#123

Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-022-wrapped-erc20.md
Comment thread RFPs/RFP-022-wrapped-erc20.md
Comment thread RFPs/RFP-022-wrapped-erc20.md
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-022-wrapped-erc20.md
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
Comment thread RFPs/RFP-021-wrapped-erc20.md Outdated
@fryorcraken fryorcraken changed the title Rfp 021 wrapped erc20 RFP-021, RFP-022, RFP-023: Ethereum bridges and the state attestation primitive Aug 17, 2026
@fryorcraken
fryorcraken force-pushed the rfp-021-wrapped-erc20 branch from f523932 to 8a2a3cd Compare August 17, 2026 05:19
@fryorcraken fryorcraken changed the title RFP-021, RFP-022, RFP-023: Ethereum bridges and the state attestation primitive RFP-021, RFP-022: Ethereum state attestation and the wrapped ERC-20 bridge Aug 19, 2026

@jzaki jzaki left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Since I'm still considered the author of this (inspite of the PR fundamentally changing while away), I can't approve it. @fryorcraken consider this approved.
I avoided minor comments and the 21/22 split makes sense. While it does dip into particular impl details in the request, I'll primarily asses the suggested impls from the proposals.
Interested in seeing how the Verified Proxy integrates with 021 as a lib/module

jzaki and others added 16 commits August 27, 2026 13:54
Project style avoids em-dashes and punctuation hyphens in prose; replace
the ones in body text with commas, colons, or parentheses depending on
the clause (title-line and Resources-list separators are an unrelated
repo-wide convention and are left as-is). Also drop the bare "Crucially,"
opener in the Overview, which asserts importance without adding
information. Reformatted with mdformat per repo convention.
The Overview stated verification "rests on RISC0 zero-knowledge proofs
of consensus and state, verified in-program on LEZ and via a native
precompile on Ethereum." This RFP should specify the required outcome
(trustless cryptographic verification) and not dictate the specific
proof system or verification mechanism teams must use to achieve it.
Both references to RFP-003 described atomic swaps as a "trustless path"
or "bridging" mechanism parallel to wrapping, which is inaccurate: atomic
swaps trade assets directly and never mint a wrapped representation on
LEZ. Rephrase both mentions (Why This Matters, Out of Scope) to describe
atomic swaps as the liquidity route for BTC/XMR/ZEC, distinct in kind
from the wrapped-token primitive this RFP defines for ETH/ERC-20.
Addresses review comment https://github.com/logos-co/rfp/pull/158/changes#r3733249831.
The previous text quoted RFP-003's unexplained claim that wrapping "is a
much simpler construction" without saying why. State the real reasons
directly: atomic swaps require an online counterparty, so wrapping is
non-interactive; wrapping needs no added infrastructure (counterparty
matching); and wrapping produces a genuine LEZ-native token, not just a
trade, which is what lets it be composed with AMMs, lending markets, and
other DeFi programs.
The opening claimed LEZ DeFi "cannot function" without external
collateral and called this RFP a "missing primitive", an overstated
framing led by a list of dependent RFPs rather than by why the bridge is
needed. Replace with the actual motivation: LEZ's separated public/private
state architecture and programmability make private DeFi possible, and
bringing in assets from non-private chains like Ethereum has to preserve
Logos' sovereignty principle, no custodian, signer, or federation trusted
along the way. The dependent-RFP list and the wrapping-vs-swaps
comparison remain as supporting detail underneath that framing.
The paragraph was structured around what other RFPs "assume" and "don't
specify", an indirect, gatekeeping way to make the point. State it
directly instead: wrapped tokens are what let users bring Ethereum
assets into LEZ's private DeFi, and list the RFPs that DeFi comprises
(DEX, lending, stablecoin, and the price feeds that collateralise them),
this RFP is the wrapping primitive that feeds all of them.
Make explicit that wrapped tokens bring not just the asset but its
already-established market value into LEZ DeFi, usable directly or
posted as collateral, since that value transfer is the actual point of
wrapping rather than just moving a token between chains.
Replace "A transparent bridge would deanonymise the whole chain" with a
section that states the actual expectation: the applicant must consider
and document a strategy for reducing linkability between Ethereum and
LEZ events, and where a specific form of linkability can't be avoided,
document why and what residual correlation remains. The prior framing
asserted unlinkability as a hard requirement "of the same standing as
solvency", which overstates what a bridge touching a public chain can
actually guarantee. Soften the matching Overview paragraph to the same
effect so the two sections don't contradict each other.
P1 and P2 previously claimed the adversary "cannot determine" the true
pairing at all, contradicted a few paragraphs later by "What cannot be
hidden", which correctly states that amount and timing are visible on
Ethereum and do correlate. The Privacy Preservation hard requirements
inherited the same overstatement ("no correlation... better than
chance"). Narrow the hard requirement to what the bridge can actually
guarantee: no information other than amount, token, and timing may link
an Ethereum event to its LEZ counterpart. Update the P1/P2 definitions
and their test requirements to match, and cross-reference the amount
mitigation already specified (fixed denominations, Soft Requirement 1).
The passage claimed LEZ "has no path" to bring stablecoin liquidity
onto the chain without a wrapped ERC-20 primitive, and that this blocks
downstream protocols. This overstates it: a healthy DeFi ecosystem
draws on native LEZ assets, wrapped assets, and synthetics together, and
wrapping is one strategy among those we want to see implemented, not
the exclusive route. Keep the concrete stablecoin market data as the
reason wrapping is a worthwhile target, without implying it's the only
way collateral reaches the lending protocol and reflexive stablecoin.
fryorcraken and others added 24 commits August 27, 2026 13:55
Stating that the vault must measure its own balance increase rather
than trust the claimed deposit amount is basic smart-contract hygiene,
not something this RFP needs to spell out as a requirement; it only
made the sentence longer without adding information. The specific,
non-obvious case that does need stating, fee-on-transfer and rebasing
tokens breaking this assumption, remains in "Token registry and decimal
normalisation".
RISC0 is a genuine, unavoidable dependency on the LEZ side, since LEZ
itself runs on RISC0, so LEZ-side proving requirements correctly keep
mentioning it. But several places also mandated RISC0-specific
constructions (a Groth16 precompile, "this RFP specifies RISC0... not a
candidate for alternative proof systems") for the Ethereum-side
verification, which is a design choice this RFP has no reason to
dictate. Generalize Functionality #3 and #8, Usability #4, the Out of
Scope RISC0 bullets, and Platform Dependencies' "RISC0 zkVM" section to
state the LEZ-side dependency as fact while leaving the Ethereum-side
proof system to the proposal.

RFP-021: support public and private LEZ accounts for both mint and burn

Functionality #4 and #7 previously mandated private-state-only minting
and burning. Change this to a choice: both flows must support a private
or a public LEZ account as the destination/source, at the user's
choice, rather than forcing private accounts exclusively. Add a new
Usability requirement that the mini-app and CLI default to inviting the
user toward the private path (pre-selected, public path needs an
explicit action), consistent with the existing Privacy Preservation
"default configuration must be private" requirement. Update the
Platform Dependencies "Private LEZ account state" section to match.

RFP-021: require deposits and burns to secretly commit to their destination

Add a new Bridge Security hard requirement: a deposit and a burn must
each secretly commit to the destination on the other chain, so a claim
can only be completed by whoever holds the originating seed, and no
information beyond that seed, however it leaks, from the transaction
itself, public state, or any party in the flow, can let someone else
construct a valid claim. This closes a gap the earlier destination-
hiding requirements (Functionality #2, #6) didn't fully cover: hiding a
destination from observers is not the same as cryptographically binding
the claim to it.
Three cleanups to Functionality:

- Removed "the design must not restrict minting/burning to private
  accounts only" from #4 and #6 (old #4/#7). These clauses only made
  sense as a diff against the previous private-only wording; stated on
  their own they're confusing, since nothing established a private-only
  restriction to argue against.
- Removed the old #5 (repeat-claim rejection) entirely, per direction.
- Removed "where a burn involves a private account, the burn must not
  thereby reveal its Ethereum destination" from burn support (old #7):
  redundant with the destination-hiding requirement on the burn path
  itself (now #5), and wrongly implied that requirement only applies
  when burning from a private account, when it applies to every burn.

Renumbered Functionality #5 through #18 down to #4 through #17
accordingly, and fixed all eight downstream cross-references across
Bridge Security, Soft Requirements, and Platform Dependencies.
Add Soft Requirement 8: an ERC-20 on Ethereum representing a Logos
zone's native gas token, where minting it is actually a release of gas
token already escrowed on the LEZ side, the inverse of this RFP's
primary deposit/mint flow. The goal is letting a user with no existing
holdings on the zone acquire gas via the bridge, so they are never
blocked from their first transaction. Since this direction has no
external market minting new supply on Ethereum (unlike a wrapped
external asset), require proposals to either treat it symmetrically to
the primary flow and document how the Ethereum-side escrow is funded
and replenished, or document why it isn't achievable and what
alternative bootstrapping mechanism would be needed instead.
Functionality:
- Simplify #7 (Ethereum release): drop the redundant "if the original
  deposit was ETH" clause and "each burn may be redeemed at most once"
  restatement.
- Delete the old #9 (funded-account / relayer-learns-nothing item);
  its substance is now folded into Bridge Security.
- #11 (registry): replace the sync/divergence language with a plain
  documentation requirement covering registration changes and delisting.
- #14 (fee): "can be charged" instead of "is charged", drop the
  redundant "no fee mandated on Ethereum" sentence, note the admin can
  set either fee to zero.
- #15/#16 (chain ID, multi-config): rewrite around a precise
  program-refers-to-contract-refers-to-zone model instead of vague
  "vault contract... Ethereum mainnet" language that didn't fit the
  LEZ side and ignored testnets. #16 now allows "same or different
  pairs" of blockchain programs.

Usability:
- #1 rewritten around a Logos core module used by multiple Logos ui
  modules, rather than an SDK.
- #2 (mini-app) trimmed to drop build/deployment detail that belongs
  in Supportability.
- CLI item removed from Usability (moved conceptually to Supportability
  doc-packet requirements).
- New #5: the three privacy correlation mitigations (amount, timing,
  fee payer) must be enabled by default, with a leak indicator and
  recommended parameters, replacing the narrower anonymity-set-warning
  item.

Supportability:
- Testnet wording corrected (LEZ testnet, not devnet/testnet).
- Doc packet items reference "the core module" instead of "the SDK".
- New deployer doc-packet item, matching the pattern of the SDK and
  CLI doc-packet items, covering how an entity stands up its own
  configured deployment.
- Figma-designs item removed.
- Audit item simplified to "the audit report must be published",
  dropping the Chainalysis justification aside.
- New item requiring the Logos Ethereum core module (with verified
  proxy features), RPC/target switching in the UI, the Lambda Prize
  wallet SDK, RFP-001/002 outputs for admin and freeze authorities,
  compatibility with the existing LEZ token program and ATA derivation,
  catalog publication, and standard Logos GitHub Actions.

Bridge Security:
- Removed the standalone "off-chain component must independently
  derive chain state" item.
- Merged the claim-theft-resistance requirement into the malicious-
  relayer item, since they covered overlapping ground.

Platform Dependencies:
- Trimmed the LP-0013, "Private LEZ account state", and "RISC0 zkVM"
  subsections to their core dependency statements.
- Moved "Event emission (LP-0012)" from Soft to Hard dependencies,
  removing the now-empty "Soft dependencies" heading.

Out of Scope: removed the BTC/XMR/ZEC, mobile/in-browser proving, and
price-feed bullets (now covered elsewhere or no longer needed as
exclusions).

Renumbered Functionality, Bridge Security, and their downstream
cross-references throughout to stay sequential and accurate.
Avoids collision with the numbered items (1., 2., ...) in the FURPS
Privacy Preservation requirements list, where "1. P1 must hold under
test" read as if P1 meant that item's own number.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
PP1/PP2 read as "Privacy Preservation 1/2", colliding with the section
name itself, on top of already colliding with that section's own item
numbering. Instead of any invented label, the inbound/outbound
unlinkability properties are now defined directly as Privacy
Preservation items #1 and #2, and every other reference cites them
the same way the doc already cites other FURPS items elsewhere
(Functionality #2, #5, Supportability #9, etc).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Credit Cryptarchia and Blend alongside LEZ architecture
- Note wrapped Bitcoin and synthetics as other strategies under consideration
- Require the UI to encourage a submission delay
- Drop the "not the only deployment model" hedge; the RFP does mandate admin curation
- Remove fee-on-transfer/rebasing rejection as an implementation choice
- Drop the RFP-017 comparison and "in the manner of RFP-004" cross-reads
- Add Design Rationale: One program pair = one chain pair
- Add admin UI to Usability #2
- Move proof-system maturity and CI-green to Reliability
- Split Supportability #11 into separate criteria; move dependencies to
  Platform Dependencies (Logos Ethereum core module, wallet SDK, ATA/token program)
- Correct LP-0013 title and mark it closed; drop the redundant private-account
  dependency section
- Soften Soft Requirement #1 phrasing; drop the batching privacy claim and the
  shared-anonymity-set question; freeze -> admin authority on the release delay
- Rewrite gas-token bootstrapping for clarity

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A proposal may commit to researching the gas-token leg and reporting findings
rather than implementing it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Extract the Ethereum consensus and state verification that RFP-021's mint
path needs into its own RFP, so the primitive is built and audited once and
shared with the other LEZ programs that need to read Ethereum state.

The attestation establishes finality (sync-committee signatures over a
light-client finality update), inclusion (Merkle-Patricia proof under the
finalised header), and a predicate over the verified state, then emits a
verified statement with no application action attached. Uniqueness stays with
the consumer, keyed on a statement identifier the primitive supplies.

RFP-021 now depends on RFP-022 for the inbound leg; the outbound leg
(verifying a LEZ burn natively on Ethereum) stays in RFP-021.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
RFP-021 carried gas-token bootstrapping as a soft requirement asking only for
research. Deliver it properly as its own RFP: the LEZ program is the vault
holding native gas token, the Ethereum contract is the minter, and the two
directions mirror RFP-021 with the chains swapped.

This closes a gap in the corpus. RFP-004, 008, 012 through 017 all fund gas by
atomic deshield from the user's own shielded balance, precisely so no external
funding source links the ephemeral account to an identity. That pattern
presupposes the user already has funds on LEZ and says nothing about how they
got there. RFP-023 is the trustless entry path for a user holding nothing.

Supply is demand-driven: the ERC-20 is minted against proof of a lock in the
LEZ vault and burned to release from it, so there is no float to seed and no
incentive mechanism to design. The invariant that makes this sound is that the
ERC-20 has no privileged minter and no pre-issued supply, which is exactly the
Meter Passport failure mode already documented in the appendix.

Privacy mirrors RFP-021 in full: each leg of each bridge has one public
endpoint and it is the Ethereum one in every case.

The one genuinely new problem is releasing native gas to a recipient who has
none. Hard requirement that this must work for a zero-balance account with no
required off-chain counterparty; mechanism left to the proposal.

RFP-021 Soft Requirement #8 becomes a pointer to RFP-023. RFP-022 gains it as
a third consumer of the attestation primitive.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The release path previously said "must work for a zero-balance recipient" and
left the mechanism open. Specify it: an off-chain paymaster is the third
component of a deployment, alongside the LEZ vault and the EVM mint/burn
contract with its dedicated ERC-20.

Eligibility is a property of the proof, never of the requester. The paymaster
sponsors a request iff it carries a valid attestation of a burn of its own
deployment's ERC-20, above a configured minimum, not already sponsored. The
nullifier that exists for double-spend protection doubles as the anti-abuse
budget, so abusing the paymaster costs what acquiring and burning real ERC-20
costs. No account, allowlist, or registration.

Reachable over Logos Delivery and over Tor, either alone sufficient. Tor is
required rather than a nicety: Delivery's RLN spam protection may itself need
LEZ gas, which the user by definition lacks, so a Delivery-only deployment
could reintroduce the circularity this component exists to break.

The paymaster must not observe requester IP addresses, by construction rather
than by logging policy. This is the point where the user has no choice but to
talk to somebody, so it is where the unlinkability of the whole design is most
easily lost.

Also require a defence against griefing. lez-proof-vault documents that fee
reservation precedes execution and failed transactions are still charged, so a
paymaster committing to pay before verifying can be drained by well-formed
garbage. Mechanism is the proposal's choice; the cost bound must be measured.

Narrows the network-anonymity out-of-scope bullet, which contradicted the new
Tor and IP requirements.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Supportability already requires every hard requirement in Functionality,
Usability, Reliability, Performance and Privacy Preservation to have at least
one corresponding test. Restating that inside individual FURPS items as
"Provide a test asserting..." was redundant.

Where a clause named specific adversarial cases (tampered headers, mint-twice
from one deposit, minting via an admin path, flooding the paymaster with
ineligible requests), those cases are kept but phrased as conditions the
requirement demands rather than as test instructions, so nothing is lost from
the spec and the coverage obligation flows from Supportability as intended.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The requirement said the verifier "must be deployed as an immutable program ...
in preference to an upgradeable contract governed by a mutable key". That is
EVM proxy language mixed with Solana upgrade-authority language, and neither
describes LEZ.

LEZ has no upgradeability at all. A ProgramId is the RISC0 image ID computed
from the bytecode, the deployed-program registry is append-only, redeploying
identical bytecode is rejected, and a deployment transaction carries no
authority or deployer identity. Changing one byte yields a different program,
not a new version of the same one. So "deploy as immutable rather than
upgradeable" was not a choice a proposal could make on the LEZ side, and the
stolen-upgrade-key attack cannot arise there.

What can arise is indirection. ChainedCall takes a ProgramId as an ordinary
runtime field, and a program may hold one in its own account state, so an
immutable bridge could still point at swappable verification logic. Whoever
controls that pointer can repoint it at a verifier that accepts anything, which
is the same fund-stealing capability relocated from the code to the pointer.

The requirement now addresses the pointer on LEZ and the upgrade path on
Ethereum, since only the Ethereum half has a genuine upgradeability question.
RFP-022 additionally notes that its consumers inherit the same discipline,
because they reference the module by image ID.

Verified against logos-execution-zone: lee/state_machine/src/program/mod.rs
(image ID derivation), validated_state_diff/mod.rs (append-only registry,
ChainedCall dispatch), program_deployment_transaction/message.rs (bytecode
only, unsigned).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The requirement is one sentence and had grown into twenty lines of platform
background, plus two rationale paragraphs explaining LEZ program identity and
ChainedCall indirection. None of it changed what an applicant builds.

Requirements now read "The verification logic cannot be swapped", followed only
by the two chain-specific bans that are the actual testable content.

The rationale states plainly that mutable verification logic is unwanted and
attributes the two risks correctly: whoever can change it can point the bridge
at a verifier that accepts anything, which has no documented cross-chain bridge
example, and an upgrade made in good faith can ship a catastrophic bug, which
caused Nomad (~$190M) and nearly caused a second Ronin incident in 2024 ($12M,
returned). Both figures and the no-stolen-upgrade-key finding are as sourced in
the appendix.

Also removes "which fixed verification logic forecloses by construction", which
was ambiguous about what forecloses what.

Net -45 lines.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The wrapped ERC-20 and Ether bridge becomes RFP-022 and the Ethereum state
attestation primitive becomes RFP-021, so the shared primitive carries the
lower number and its consumers follow it.

Renames both files and swaps every ID, title, link and cross-reference across
the three RFPs, the README table, the proposal dropdown and the bridges
appendix. README and dropdown rows reordered to stay numeric.

Also fixes references broken by the section restructure in the bridge RFP:

- Privacy Preservation #8 -> #7 (an item was removed)
- Supportability #8 (audit) -> Security #1, following the move to the new
  Security section
- Supportability #9 (privacy properties document) was deleted, so the
  out-of-scope note now points at Privacy Preservation #6, which carries the
  surviving disclosure obligation
- Soft Requirement #3 -> #2 (viewing keys, after deletions)
- Soft Requirement #4's "as per F TODO" resolved to Security #8, the rule that
  verification logic cannot be swapped

RFP-023's references into the bridge RFP updated for the same restructure:
Bridge Security #8 -> Security #9, Bridge Security #7 -> Security #8, and the
privacy-properties reference made self-contained since its target no longer
exists.

Minor: stray double space, a stray indent in a doc-packet item, and reflow of
the newly added unwrapped lines.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
FURPS items state the condition to be met; Supportability already
requires a test for every hard requirement, so embedded "provide a
test that..." instructions are redundant.

Also drops a stranded "Provide" fragment left in RFP-023 item 3 by an
earlier cleanup pass, and makes each outbound-unlinkability item
readable on its own rather than deferring to the inbound item.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The RFP required trustless Ethereum verification but never said where
the tracked sync-committee state lives, leaving applicants to guess
between a shared on-chain light client and a bring-your-own-chain design
that almost certainly cannot fit a single transaction.

Specifies the expected shape: an operator advances shared consensus
state, anyone may submit a proof-checked update, and consumers supply
only inclusion proofs. Trust is a one-off deployment-time checkpoint,
recoverable by fresh deployment rather than by a privileged party
mutating an existing one. This removes the admin surface entirely, so
the RFP-001 dependency goes with it.

Adds an appendix surveying Telepathy, SP1 Helios and r0vm-helios, plus
the Across fork that deliberately gates submission behind a role: the
clearest evidence that permissionlessness is a design choice rather than
something zk proofs confer automatically. Points applicants at
r0vm-helios as a RISC Zero reuse candidate to assess, not to assume.

Also corrects the consumption model, which described the primitive as a
library and forbade depending on any account written by a third party.
That contradicted the operator architecture. On testnet and mainnet this
is a deployed program with an interface; what must stay in the
consumer's transaction is inclusion and predicate evaluation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Cost section now splits by execution path: BLS12-381 is needed only for
headers, which are public and executed by the sequencer, while the open
question is whether hash-based inclusion verification is viable in a private
transaction proven on user hardware. Drops the secp256k1 ECDSA benchmark, which
measured a different primitive on a different question.

Replaces Ethereum-style "deployment" wording with the account model: the
program is deployed once, and the checkpoint, chain binding, finality
parameters, and tracked consensus state are per-instance configuration held in
accounts.

Adds reference consumer programs covering an ERC-20 transfer and a native ether
transfer to a specific contract.

Appendix records that an attestation spans two proof systems, the SSZ binding
of the execution payload over SHA256 and the Merkle-Patricia path over
keccak256, and that a log is proven through its receipt.

Renumbers Supportability after dropping the per-item test and README items, and
fixes the cross-references that pointed at the old numbering.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Extracted so the gas token bridge can be reviewed separately from RFP-021 and
RFP-022. The cross-links from RFP-021 and RFP-022 stay, and resolve once the
RFP-023 branch merges back into this one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Moves with the RFP to its own branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
LEZ execution is already proven, so wrapping the sync-committee check in
a second proof for LEZ to verify adds a translation step and its own
audit surface without strengthening the guarantee. Verify the aggregate
in the program instead, and reframe the operator as a submitter that
supplies update material rather than one that proves anything.

Merge the light-client requirements into one item and leave the
verification path to the applicant. Switch performance terminology to
cycle count, and report gas alongside it for 0.3.

Specify the update-submitting component as a deliverable, with lazy
push so the fastest party does not pay for every update.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Master added a Submission Deadline column to the RFP table and closed
RFP-012 and RFP-014. Carry the RFP-021 and RFP-022 rows into the new
seven-column shape with no deadline set, and correct both titles to
match the RFP frontmatter.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fryorcraken
fryorcraken force-pushed the rfp-021-wrapped-erc20 branch from 348c9b0 to 86c1d1d Compare August 27, 2026 03:56
…raft

Drop the paragraph and clauses whose only job was to reject the previous
off-chain proving framing. A first-time reader never saw it. Fold the one
new fact, where the submitter fetches update material, into the design
paragraph and state the rest positively.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fryorcraken added a commit that referenced this pull request Sep 8, 2026
RFP-021 is claimed by three older open pull requests, #158 and #169 for
Ethereum state attestation and #57 for a cross-chain privacy DEX, so this
one moves to the first free number past every current allocation.

The table also gains placeholder rows for the five remaining deliverables
in the suite, so a reader sees the shape of the whole set rather than one
RFP that refers to five documents that do not appear anywhere. The two FFI
layers are developer tooling; the JSON-RPC proxy, the two SDKs and the
further transport modules are applications and integrations.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

2 participants