Skip to content

feat: world id state bridge#382

Open
0xOsiris wants to merge 49 commits intomainfrom
feat/state-bridge
Open

feat: world id state bridge#382
0xOsiris wants to merge 49 commits intomainfrom
feat/state-bridge

Conversation

@0xOsiris
Copy link
Contributor

@0xOsiris 0xOsiris commented Feb 10, 2026

State Bridge (ERC-7786) — PR Overview

Addresses: #191
Spec: RFC — World ID 4.0 State Bridge
Standard: ERC-7786 (Interop Messaging)


Overview

This PR introduces the first implementation of the World ID 4.0 State Bridge, designed to align with ERC-7786.

The system follows a hub-and-spoke architecture:

  • Source — deployed on World Chain, originates state commitments
  • Satellites — deployed on external chains, consume verified state
  • Gateways — pluggable authentication adapters that define how messages are verified

A Satellite’s security model is determined entirely by its configured Gateway.


ERC-7786 Message Flow

Gateway Entrypoint:

function sendMessage(
    bytes calldata recipient,
    bytes calldata payload,
    bytes[] calldata attributes
) external payable returns (bytes32 sendId)
{
    // Verify gateway-specific proof and extract authenticated chain head
    bytes32 chainHead = _verifyAndExtract(payload, attributes);

    bytes memory sender =
        InteroperableAddress.formatEvmV1(ANCHOR_CHAIN_ID, ANCHOR_BRIDGE);

    bytes memory encoded = abi.encode(chainHead, payload);

    require(
        IERC7786Recipient(STATE_BRIDGE).receiveMessage(receiveId, sender, encoded)
            == IERC7786Recipient.receiveMessage.selector,
        InvalidRecipientResponse()
    );
}

Gateway Adapters

Three authentication strategies for gateway chain head verification, each targeting a different trust/availability tradeoff.

Adapter Security Model Status Target Chains
PermissionedGatewayAdapter Trusted relayer Ready Any chain
EthereumMPTGatewayAdapter Fully permissionless Ready OP Stack L2s
LightClientGatewayAdapter Fully permissionless WIP (~1-3 weeks) Any chain with BN254 precompiles

PermissionedGatewayAdapter

Multisig-validated relayer that forwards chain heads directly. Enables day-one interoperability on arbitrary destination chains with no protocol-level dependencies.


EthereumMPTGatewayAdapter

Authenticates chain heads via Ethereum L1 storage proofs. Verifies the OP DisputeGame output root, then proves the WorldChainSource.keccakChain slot against the claimed World Chain state root using an MPT account proof + storage proof.

chainHead = Lib.proveStorageSlot(
    ANCHOR_BRIDGE,
    STATE_BRIDGE_STORAGE_SLOT,
    wcAccountProof,
    wcStorageProof,
    wcStateRoot
);
Property Detail
Trust assumption Ethereum L1 finality + DisputeGame resolution
Verification MPT account proof + storage proof against L1 state root
Scope Native interop across all OP Stack L2s
External dependencies None — no validators, oracles, or committees

LightClientGatewayAdapter

Verifies a ZK proof of Ethereum consensus (Helios light client) — specifically, the sync committee's aggregated BLS signature over an L1 state root. The proven state root is then used to verify an MPT storage proof of the StateBridge.keccakChain slot on L1.

verifier.verifyProof(programVKey, abi.encode(po), proof);

chainHead = Lib.proveStorageSlot(
    ANCHOR_BRIDGE,
    STATE_BRIDGE_STORAGE_SLOT,
    accountProof,
    storageProof,
    executionStateRoot
);
Property Detail
Trust assumption Ethereum PoS consensus (sync committee supermajority)
Verification ZK consensus proof + MPT account proof + storage proof
Scope Any chain with BN254 curve precompiles
Target chains Solana, Tempo, Arc, and any chain capable of verifying World ID proofs

Review Scope:
crosschain/adapters, crosschain/lib/, crosschain/Source.sol, crosschain/Satellite.sol

@0xOsiris 0xOsiris changed the title Feat/state bridge wip: world id state bridge sdk Feb 10, 2026
Copy link
Contributor

@alessandromazza98 alessandromazza98 left a comment

Choose a reason for hiding this comment

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

great work. As I wrote in the RFC, I still think it would be a good idea to initially start by only using something like wormhole (I mean a third party bridge) for all destination chains (Ethereum included) so that you only need one type of adapter and it's easier to handle at the start. It's also cheaper from a gas perspective.

With only one concrete solution you can bridge to all chains you need because they all support wormhole.

What do you think about it?

@0xOsiris
Copy link
Contributor Author

0xOsiris commented Feb 10, 2026

great work. As I wrote in the RFC, I still think it would be a good idea to initially start by only using something like wormhole (I mean a third party bridge) for all destination chains (Ethereum included) so that you only need one type of adapter and it's easier to handle at the start. It's also cheaper from a gas perspective.

With only one concrete solution you can bridge to all chains you need because they all support wormhole.

What do you think about it?

I agree it'd be easier, but I disagree that this is the correct approach. The way I have built this now is as a verifiable rolling hash chain of the sequence of updates that occur on any of the 3 contracts - Verifiable against only an L1 block hash. Without a verifiable link from World Chain State -> Destination Chain state then we have a very brittle, and high trust bridge.

In the current implementation any chain with access to an Ethereum block hash via Oracle, or Native rollup can verify both the correctness of order, and timing on any inbound state changes without having to trust the relayer at all. Less importantly we now "finalize" state, and have a way to provably invalidate previous state at dispute game resolution (even though this should never happen)

Wormhole, Hyperlane, etc. are just transports by which we provide these proofs to the destination Verifier contracts - Integrating transports is the easy part

@0xOsiris 0xOsiris marked this pull request as ready for review February 11, 2026 19:18
@0xOsiris 0xOsiris requested a review from a team as a code owner February 11, 2026 19:18
@0xOsiris 0xOsiris changed the title wip: world id state bridge sdk feat: world id state bridge sdk Feb 11, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 40 out of 43 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (2)

bridge/contracts/src/types/IStateBridge.sol:1

  • Correct spelling: 'commiting' → 'committing'.
    justfiles/forge.just:1
  • --via--ir looks like a typo and will likely be rejected by solc/forge. If the intent is IR compilation, use the correct flag (--via-ir), and consider whether it should be a forge flag (pre---) vs a solc passthrough (post---).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@0xOsiris
Copy link
Contributor Author

0xOsiris commented Feb 17, 2026

@cursoragent review @codex review

@cursor
Copy link

cursor bot commented Feb 17, 2026

Unable to authenticate your request. Please make sure to connect your GitHub account to Cursor. Go to Cursor


### Environment Variables

Only three env vars exist. Everything else lives in the config JSON.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: there are 4 env vars in the table below

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is necessary to inherit the ERC-7786 interfaces

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Necessary for ERC-7786

@@ -107,7 +107,6 @@ abstract contract WorldIDBase is Initializable, Ownable2StepUpgradeable, UUPSUpg
__Ownable_init(msg.sender);
__Ownable2Step_init();
__EIP712_init(name, version);
__UUPSUpgradeable_init();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not on UUPSUpgradeable api anymore. This was a no-op previously

@0xOsiris 0xOsiris changed the title feat: world id state bridge sdk feat: world id state bridge Feb 18, 2026
ProvenPubKeyInfo memory issuerPubKeyInfo = issuerSchemaIdToPubkeyAndProofId(issuerSchemaId);
if (issuerPubKeyInfo.pubKey.x == 0 && issuerPubKeyInfo.pubKey.y == 0) revert UnregisteredIssuerSchemaId();

ProvenPubKeyInfo memory oprfPubKeyInfo = oprfKeyIdToPubkeyAndProofId(uint160(issuerSchemaId));
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be using rpId here not issuerSchemaId

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.

State bridges & verifier on other chains (ETH mainnet, Optimism, Base, ...)

3 participants