Overview
PolymerProver processes proof messages from Polymer’s CrossL2ProverV2 and records proven intents. Unlike other provers, it uses log event proofs rather than direct cross-chain messaging.
Contract: contracts/prover/PolymerProver.sol
Inheritance: BaseProver, Whitelist, Semver
Proof Type: "Polymer"
Polymer uses chain IDs (not custom domain IDs) and validates cross-chain events through cryptographic proofs of event logs.
Constructor
Address of the Portal contract
Address of Polymer’s CrossL2ProverV2 contract
Maximum allowed size for encodedProofs in IntentFulfilledFromSource event data. Must be between 1 and 32,768 bytes (32 KB).
Array of whitelisted prover addresses (as bytes32)
ZeroAddress(): CrossL2ProverV2 address is zeroInvalidMaxLogDataSize(): maxLogDataSize is zero or exceeds MAX_LOG_DATA_SIZE_GUARD (32 KB)ZeroPortal(): Portal address is zero
contracts/prover/PolymerProver.sol:53
State Variables
CROSS_L2_PROVER_V2
MAX_LOG_DATA_SIZE
PROOF_TYPE
PROOF_SELECTOR
Constants
Core Functions
prove
Chain ID of the source chain (Polymer uses actual chain IDs, not domain IDs)
Encoded (intentHash, claimant) pairs. Must not exceed MAX_LOG_DATA_SIZE.
- Validates caller is PORTAL
- Validates encodedProofs size doesn’t exceed MAX_LOG_DATA_SIZE
- Emits
IntentFulfilledFromSource(sourceChainDomainID, encodedProofs)
OnlyPortal(): Caller is not the Portal contractMaxDataSizeExceeded(): encodedProofs exceeds MAX_LOG_DATA_SIZE
contracts/prover/PolymerProver.sol:194
validate
Proof of an IntentFulfilledFromSource event from Polymer’s CrossL2ProverV2
- Calls
CROSS_L2_PROVER_V2.validateEvent(proof)to verify the event - Validates emitting contract is whitelisted
- Validates topics length is 64 bytes (2 topics)
- Validates event signature matches PROOF_SELECTOR
- Validates source chain ID matches current chain
- Validates destination chain ID from proof data
- Processes each (intentHash, claimant) pair
InvalidEmittingContract(address): Emitting contract not whitelistedInvalidTopicsLength(): Topics length is not 64 bytesEmptyProofData(): Data is emptyArrayLengthMismatch(): Proof data length is invalidInvalidEventSignature(): Event signature doesn’t matchInvalidSourceChain(): Source chain ID doesn’t match current chainInvalidDestinationChain(): Destination chain from proof data doesn’t match validateEvent result
contracts/prover/PolymerProver.sol:83
validateBatch
Array of proof data to validate
validate(proof).
Location: contracts/prover/PolymerProver.sol:73
getProofType
"Polymer"
Internal Functions
processIntent
Hash of the intent being proven
Address that fulfilled the intent and should receive rewards
Destination chain ID for the intent
- If intent already proven, emits
IntentAlreadyProvenand returns - Otherwise, stores proof data and emits
IntentProven
contracts/prover/PolymerProver.sol:158
Events
IntentFulfilledFromSource
prove() is called. This event is later proven on the source chain using Polymer’s proof system.
Chain ID of the source chain (where intent was created)
Encoded (intentHash, claimant) pairs
Proof Validation Flow
Polymer uses a unique two-step flow:
- Destination Chain: Call
prove()on PolymerProver to emit IntentFulfilledFromSource event - Source Chain: Generate event proof using Polymer’s infrastructure
- Source Chain: Call
validate()orvalidateBatch()with the proof to process intents
Event Data Format
TheIntentFulfilledFromSource event data is ABI-encoded bytes containing:
Validation Steps
-
CrossL2ProverV2 Validation:
- Polymer’s CrossL2ProverV2 cryptographically verifies the event occurred on destination chain
- Returns: destinationChainId, emittingContract, topics, data
-
Authorization Check:
- Validates emittingContract is whitelisted (must be trusted PolymerProver instance)
-
Event Signature Validation:
- Verifies topics[0] matches PROOF_SELECTOR
- Verifies topics[1] (source chain ID) matches current chain
-
Data Validation:
- Decodes ABI-encoded bytes from event data
- Extracts chain ID from first 8 bytes
- Verifies chain ID matches destinationChainId from CrossL2ProverV2
-
Intent Processing:
- Iterates through (intentHash, claimant) pairs
- Skips invalid EVM addresses
- Stores proof data or emits IntentAlreadyProven
Usage Example
On Destination Chain (Intent Fulfillment)
On Source Chain (Proof Validation)
Domain ID vs Chain ID
Polymer uses actual chain IDs, not custom domain IDs. The
sourceChainDomainID parameter in prove() should be the actual chain ID of the source chain.Examples:- Ethereum Mainnet: 1
- Optimism: 10
- Arbitrum: 42161
- Base: 8453
Security Considerations
Whitelist Management
Only whitelisted prover addresses can emit valid IntentFulfilledFromSource events. This prevents unauthorized proof submissions.Max Log Data Size
The MAX_LOG_DATA_SIZE limit prevents:- Excessive gas costs during event emission
- Potential DoS attacks via large event logs
- Storage bloat from oversized proofs
Address Validation
Thevalidate() function skips non-EVM addresses (where upper 96 bits are non-zero), ensuring compatibility with EVM-based reward claims.