Skip to main content

MEV Resistance

RP1 implements multiple layers of MEV (Maximal Extractable Value) protection to ensure fair transaction ordering.

The MEV Problem

On most blockchains, validators/miners can:

  • Front-run: See your trade, execute theirs first
  • Sandwich: Buy before your trade, sell after
  • Back-run: Execute profitable transactions after yours
Without Protection:
User submits: Buy 1000 TOKEN at market price

Attacker sees mempool:
1. Attacker buys TOKEN (price goes up)
2. User's buy executes (at higher price)
3. Attacker sells TOKEN (profit!)

User loses ~2-5% to MEV extraction

RP1's Solution

1. Encrypted Mempool

Transactions are encrypted until block proposal:

┌─────────────────────────────────────────────────────────────┐
│ User Transaction │
│ │ │
│ ┌─────▼─────┐ │
│ │ Encrypt │ (Threshold public key) │
│ └─────┬─────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Mempool │ (Encrypted, opaque) │
│ └─────┬─────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Block │ (Proposer decrypts) │
│ │ Proposal │ │
│ └─────┬─────┘ │
│ │ │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ ▼ │
│ Decrypt Decrypt Decrypt │
│ │
│ Fair ordering (no front-running possible) │
└─────────────────────────────────────────────────────────────┘

2. Threshold Encryption

Uses Shamir's Secret Sharing for decryption:

// Configuration
type ThresholdConfig struct {
Threshold int // Minimum shares needed (e.g., 7)
TotalParts int // Total key holders (e.g., 10)
Committee []string // Validator addresses holding shares
}

// Encryption
encrypted := ThresholdEncrypt(tx, publicKey) // Anyone can encrypt

// Decryption requires threshold cooperation
shares := CollectShares(validators, encrypted) // 7 of 10 needed
decrypted := ThresholdDecrypt(shares, encrypted)
  • 7-of-10 threshold by default
  • No single party can decrypt alone
  • Decryption only at block proposal time

3. Commit-Reveal Scheme

Alternative for sensitive transactions:

Phase 1 (Commit):
User submits: Hash(tx_data + secret)

Phase 2 (Reveal):
User submits: tx_data + secret
Validators verify: Hash(tx_data + secret) == commitment

Timeline:

Block N:   Submit commitment
Block N+1: Submit reveal
Block N+2: Transaction executes

4. Fair Ordering

Transactions ordered by commit timestamp, not gas price:

Traditional: Higher gas = earlier execution (auction for position)

RP1: First-committed = first-executed (fair FIFO)

┌──────────────────────────────────────────┐
│ Mempool Ordering │
│ │
│ T=0: Tx-A committed │
│ T=1: Tx-B committed (higher gas) │
│ T=2: Tx-C committed │
│ │
│ Execution order: A → B → C │
│ (Not B → A → C based on gas) │
└──────────────────────────────────────────┘

Protection Levels

MethodProtectionLatencyUse Case
Encrypted MempoolFull+0msDefault for all
Commit-RevealFull+2 blocksHigh-value trades
StandardNone+0msNon-sensitive

Using MEV Protection

TypeScript SDK

import { RP1Client, MEVProtection } from '@rp1/sdk';

const client = new RP1Client('https://rpc.rp.one');

// Encrypted transaction (default)
const tx = await client.swap({
tokenIn: 'urp1',
tokenOut: 'uusdc',
amountIn: '1000000',
protection: MEVProtection.ENCRYPTED, // default
});

// Commit-reveal for large trades
const largeTx = await client.swap({
tokenIn: 'urp1',
tokenOut: 'uusdc',
amountIn: '100000000000', // Large amount
protection: MEVProtection.COMMIT_REVEAL,
});

CLI

# Standard encrypted (automatic)
rp1d tx dex swap urp1 uusdc 1000000 --from wallet

# Explicit commit-reveal
rp1d tx dex swap urp1 uusdc 1000000 \
--from wallet \
--mev-protection commit-reveal

Validator Responsibilities

Validators in the threshold committee must:

  1. Hold key share securely (HSM recommended)
  2. Participate in decryption at block proposal
  3. Never collude to decrypt early

Slashing conditions:

  • Early decryption attempt: 100% stake slash
  • Non-participation in decryption: Jail + 1% slash

Security Analysis

AttackProtectedMechanism
Front-runningEncryption hides tx content
SandwichCan't see victim's trade
Back-running⚠️Post-execution visible
Time-banditInstant finality
Censorship⚠️Requires committee collusion

Performance Impact

MetricWithout MEV ProtectionWith MEV Protection
Latency~200ms~200ms
Throughput100K TPS95K TPS
Proof sizeN/A+64 bytes/tx

Configuration

app.toml

[mev-protection]
enabled = true
default_method = "encrypted" # or "commit-reveal"
threshold = 7
total_parts = 10
committee_rotation = "100 blocks"

[commit-reveal]
reveal_window = 2 # blocks
max_pending = 10000

Next Steps