Add Circle CCTP integration#2
Open
JuanMarchetto wants to merge 2 commits into
Open
Conversation
Extend Puente to support Circle's Cross-Chain Transfer Protocol (CCTP) alongside existing LayerZero V2 OFT support. Enables local testing of USDC bridge flows with mock attestation signing. New modules: - cctp.rs: CCTP message wire format (116-byte header + 132-byte BurnMessage), domain IDs, mock attestation signing (secp256k1), PDA helpers - cctp_watcher.rs: Solana + EVM watchers for MessageSent events - cctp_delivery.rs: Bidirectional delivery (EVM→Solana, Solana→EVM) with ABI-encoded receiveMessage(bytes,bytes) calldata Mock contract: - MessageTransmitterMock.sol: sendMessage, receiveMessage with ECDSA attestation verification and nonce replay protection Integration: - Relay routes CCTP messages by domain ID (Solana=5, Ethereum=0) - env.rs conditionally deploys CCTP mock and starts watchers - Optional [cctp] config section (no breaking changes) Tests: 14 new tests covering wire format, attestation, config, security All 114 existing tests continue to pass.
Comprehensive security tests organized by attack category:
SEC-1: Attestation Security (6 tests)
- Forged attestation produces different signer
- Empty/truncated attestation rejection
- Message modification invalidates attestation
- Attestation covers full message, not just body
- Recovery ID normalization (v ∈ {0,1})
SEC-2: Nonce Replay Protection (5 tests)
- Identical messages produce identical digests for dedup
- Nonce isolation across source domains (PDA uniqueness)
- u64::MAX nonce boundary
- Bucket boundary correctness (0-63 vs 64-127)
- Relay watermark dedup for CCTP domain IDs
SEC-3: Amount & Token Security (7 tests)
- Zero amount transfers nothing
- uint256 overflow beyond u64 detected
- u64::MAX roundtrip safety
- Amount/burn_token/recipient modification changes digest
- Dust amount boundary testing
SEC-4: Domain & Routing Security (4 tests)
- Self-transfer (same domain) is parseable but should be rejected on-chain
- Domain spoofing (swap src/dst) changes digest
- Invalid domain IDs are parseable (on-chain must validate)
- CCTP domains never collide with LayerZero EIDs
SEC-5: Message Integrity (6 tests)
- Truncated header/body rejected at every length
- Version mismatch parses (on-chain must validate)
- All 8 header fields contribute to digest independently
SEC-6: Destination Caller (2 tests)
- Zero caller = unrestricted relay
- Non-zero caller changes digest (enforced by on-chain)
SEC-7: PDA Security (5 tests)
- used_nonces PDA unique per domain+bucket
- token_pair PDA unique per domain and per token
- custody PDA unique per mint
- BE vs LE encoding mismatch detection
SEC-8: Mint/Burn Symmetry (3 tests)
- Amount preserved across serialization for all edge values
- message_sender vs sender field independence
- Body offset correctness (starts at byte 116)
SEC-9: Cross-Chain Invariants (4 tests)
- Deterministic digest across implementations
- Wire format field offset verification (CctpMessage + BurnMessage)
- All known domain IDs have names
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MessageTransmitterMock.sol) with ECDSA attestation verification and nonce replay protection[cctp]config section — no breaking changes to existing configsDetails
k256crate) — same pattern as Wormhole guardian signingreceiveMessage(bytes message, bytes attestation)ABI encoding for EVM, Anchor instruction building for Solanak256andhex(already used by Wormhole NTT branch)Test plan
puentewith[cctp]config against local validators