Skip to content

[API-699] feat(polymer): Solana -> EVM proof path - #127

Open
reednaa wants to merge 3 commits into
feature/api-699-provable-non-fill-refundsfrom
feature/api-699-polymer-solana
Open

[API-699] feat(polymer): Solana -> EVM proof path#127
reednaa wants to merge 3 commits into
feature/api-699-provable-non-fill-refundsfrom
feature/api-699-polymer-solana

Conversation

@reednaa

@reednaa reednaa commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

Adds a Solana → EVM proof path to PolymerOracle — Linear API-699: Provable Non-Fill Refunds.

New receiveSolanaMessage, backed by ICrossL2ProverV2.validateSolLogs, lets fills and non-fills executed on Solana be attested on EVM via Polymer, so the non-fill refund flow (and regular fill finalisation) works for Solana output chains.

Trust model

  • The remote-oracle identity is taken from Polymer's authenticated returnedProgramId, never from log content. Attestations self-namespace under the emitting program id; honest orders set output.oracle to the trusted Solana program id.
  • Each log must begin with exactly "program: " + base58(returnedProgramId) + ", ", enforced via a new on-chain Base58 encoder; any mismatch reverts SolanaProgramIdMismatch. The prefix is computed once per proof (invariant across logs), so multi-log proofs stay within gas limits.
  • Only the trailing base64 field of the "program: <id>, <blob>" log is decoded; blob layout is application(32) || payload. Empty payloads (blob ≤ 32 bytes) are rejected rather than attesting over keccak256("").

Deployment coupling

Requires the paired catalyst-intent-svm change (submit emits source || payload, oracle identified by program id) to be deployed together.

Testing

Golden-fixture cases for receiveSolanaMessage on both the base and mapped oracles, program-id-mismatch reverts in both directions, empty-payload revert, Base58 encoder unit tests (golden vectors + leading-zero rule), and an extended MockCrossL2ProverV2 that renders the log prefix in base58 to match the enforced check. A captured real Polymer proof fixture remains a follow-up.

Stacked PRs

This is PR 2 of 2, stacked on #126 (feature/api-699-provable-non-fill-refunds). It will retarget to main automatically when #126 merges.

🤖 Generated with Claude Code

reednaa and others added 3 commits July 16, 2026 11:20
Adds receiveSolanaMessage backed by ICrossL2ProverV2.validateSolLogs so
fills and non-fills executed on Solana can be attested on EVM via Polymer.

Trust model: the remote-oracle identity is taken from Polymer's authenticated
returnedProgramId, never from log content, so attestations self-namespace under
the emitting program id (honest orders set output.oracle to the trusted Solana
program id). Only the trailing base64 field of the "program: <id>, <blob>" log
is decoded; blob layout is application(32) || payload.

Requires the paired catalyst-intent-svm change (submit emits source||payload,
oracle identified by program id) to be deployed together.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- PolymerOracle: correct stale SVM-envelope comment to base64(source||payload);
  make Solana constants `internal constant`, prover `internal immutable`;
  use revert-style errors and ++i in the log loop
- MockCrossL2ProverV2: centralize proof offsets into named constants and
  replace require-strings with custom errors
- tests: golden-fixture cases for receiveSolanaMessage (base + mapped)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…gramId

Addresses review findings on the Solana proof path:

- Finding 1 (critical): the oracle discarded each log's `program: <id>` prefix and
  keyed attestations solely on `returnedProgramId`, never binding the two. Per
  Polymer's Solana proof-validation guidance the returned program id MUST equal the
  id embedded in every log. Add an on-chain Base58 encoder and require each log to
  begin with exactly `"program: " + base58(returnedProgramId) + ", "`, reverting
  SolanaProgramIdMismatch otherwise. Prefix is computed once per proof (invariant),
  not per log, so multi-log proofs stay within gas limits.
- Finding 3 (low): reject empty payloads (blob length <= 32) instead of attesting
  over keccak256("").
- Finding 2 (tests): mock renders the log prefix in base58 (matching the enforced
  check); add negative tests asserting a program-id mismatch reverts in both
  directions, an empty-payload revert, and Base58 encoder unit tests (golden vector
  + leading-zero rule). A captured real Polymer proof fixture remains a follow-up.

Co-Authored-By: Claude Opus 4.8 <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.

1 participant