molpha/evm-verifier · Solidity 0.8.31 · Cancun · Apache-2.0
The EVM Verifier is a stateless on-chain check: given a DataUpdate and an aggregate Schnorr signature, it answers one question — did enough selected Molpha nodes sign this exact payload under the stated registry version? It does not store feeds, rounds, or consumed updates. Your contract owns freshness, replay, feed authorization, and value decoding.
Solana is the canonical chain. Feeds, staking, and the authoritative node registry live on Solana. Each EVM deployment mirrors the node public-key set as versioned SSTORE2 snapshots and exposes
verify as a view function. The signed message intentionally omits chainId, so one gateway payload verifies on every supported EVM chain.Quick start
- Pin a deployed verifier address from Deployments.
- Map a gateway
DataUpdateResultwithbuildEvmVerifierArgs(or build the structs yourself). - Call
verifyand require the boolean — a bad signature returnsfalse, it does not revert. - Enforce your own freshness / replay /
feedIdchecks before usingvalue.
What the contract does (and does not)
Shared crypto (selection, message hash, Schnorr identity): Cryptography.
Install / depend on the contracts
Calldata: structs
Defined inIVerifier.
DataUpdate
SchnorrSignature
Gateway → on-chain mapping
verify
Pipeline (in order)
registryVersion < registryPointers.length(elseInvalidRegistryVersion).- Snapshot has at least one node (else
NoNodes). - Structural guards: non-zero
signaturesRequired,signersBitmap,signature,commitment;signature < Q(else custom errors). popcount(signersBitmap) >= signaturesRequired(elseNotEnoughSignatures).- Derive selection set; require
signersBitmap ⊆ selectionBitmap(elseSignerNotSelected). - Sum signers’ public keys in ascending index order; verify Schnorr over the canonical message.
- Return
true/falsefor crypto validity — do not treatfalseas a revert.
Signed message
chainId. Same digest verifies on every EVM deployment.
Selection seed and group size
NodeGroupBitmapLib expands the seed with keccak256(seed ‖ keccak256("MOLPHA_SELECTION_DERIVE") ‖ counter), samples without replacement (bias-rejecting uint32 limbs), and uses the complement path when groupSize > nodeCount / 2.
Bitmap convention
Biti - 1 ↔ 1-based registry index i. Index 0 in each snapshot is the running aggregate key, not a signer. Node indices can change after removeNode (swap-and-pop); resolve live indices with getNodeIndex(address).
Consumer checklist
Do these in your contract (or off-chain client) around everyverify call:
- Require the boolean return value.
- Authorize
feedId(and optionallysignaturesRequired) for your product. - Freshness — compare
canonicalTimestamptoblock.timestamp(or your clock). - Replay — track last timestamp / digest if the same valid payload must not settle twice.
- Decode
valuewith your feed’s encoding; treat it as opaquebytes32until then. - Pass the exact
registryVersionused when the nodes signed (historical versions stay valid).
Registry & admin API
OnlyprotocolAdmin can mutate the registry or redundancy buffer.
Proof-of-possession (registration only)
addNode and is not part of verify. Nodes register per deployment (address is in the digest).
Reads
Registry version
0 is the empty constructor snapshot. See Registry Versions.
Errors
verify / admin paths revert with these IVerifier errors when inputs are malformed or policy fails. Invalid crypto after passing guards returns false instead.
Gas (reference)
Measured withFOUNDRY_PROFILE=gas forge test -vv --match-contract VerifierGasTest (Solidity 0.8.31, Cancun, IR, 1M optimizer runs). Fixed 128-node registry, redundancy buffer 2. Total = execution + calldata + 21 000 base.
Cost scales mainly with the number of keys summed for the coalition, not total registry size (selection + key reads dominate).
Security surface
- Treat every deployment as a verification component, not a full oracle product. Review registry ops, consumer freshness/replay, and feed authorization before production use.
- Report vulnerabilities per
SECURITY.md— not public GitHub issues. - Protocol trust assumptions: Security Model.