A fully on-chain perpetual futures decentralized exchange built on Solana. Trade perpetuals on crypto, equities, commodities, and more with up to 20x leverage, powered by a virtual AMM (vAMM) and Pyth Network oracles.
Frontend: https://volt-perp.vercel.app
Program (Devnet): 13AnH1QtGRHjWXbBowRWKASJQ77iSdD1tADSGvKV9TfK
- Perpetual Futures: Trade synthetic perpetual contracts without expiry
- Up to 20x Leverage: Configurable per-market maximum leverage
- Long & Short Positions: Profit from both rising and falling markets
- Position Size Precision: Specify position sizes up to 4 decimal places (e.g., 0.0001)
- Multiple Simultaneous Positions: Open up to 16 positions per market simultaneously
- Cross-Market Trading: Hold positions across different markets at the same time
- Isolated Margin: Each position has its own isolated margin, limiting loss to deposited margin
- Partial Close: Close a portion of your position to take partial profits
- Virtual AMM (vAMM): Constant product automated market maker (x * y = k) for price discovery
- Pyth Oracle Integration: Real-time oracle prices for funding rate calculations
- Slippage Protection: User-defined maximum slippage tolerance on trades
- Accrued Funding Payments: Funding accrues continuously and is settled when position is closed or partially closed
- Oracle-Based Funding: Funding rate calculated from vAMM vs oracle price deviation
- Capped Funding Rate: Maximum ±1% per funding period to prevent extreme rates
- Entry Funding Tracking: Each position tracks its funding entry point for accurate PnL
- Maintenance Margin: Positions liquidated when effective margin falls below maintenance threshold (2-3%)
- Liquidation Rewards: Liquidators earn 5% of position's margin
- Protocol Penalty: 10% protocol penalty on liquidations for ecosystem sustainability
- Bad Debt Absorption: Protocol vault absorbs losses when margin is insufficient
- Market Pause/Resume: Admin can pause markets during extreme volatility
- Liquidate & Earn: Dedicated interface to find and liquidate underwater positions
- Confidence Score: Visual indicator showing likelihood of successful liquidation
- Reward Breakdown: See liquidation reward + account rent before executing
- One-Click Liquidation: Simple UX for executing liquidations
┌─────────────────────────────────────────────────────────────────────────────┐
│ VoltPERP Architecture │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────────────────┐ │
│ │ Frontend │────▶│ Solana RPC │────▶│ VoltPERP Program │ │
│ │ (React) │ │ (Devnet) │ │ (Anchor/Rust) │ │
│ └───────────────┘ └───────────────┘ └───────────────────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌─────────────────┐ │
│ │ │ Pyth Oracle │ │
│ │ │ (Price Feeds) │ │
│ │ └─────────────────┘ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Wallet Adapter│ │
│ │ (Phantom etc) │ │
│ └───────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Account Structure │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ VAULT (PDA: ["vault"]) │
│ ├── admin: Pubkey │
│ ├── pool_balance: u64 # Total SOL in protocol vault │
│ ├── total_markets: u16 # Number of markets created │
│ ├── protocol_fees: u64 # Accumulated trading fees │
│ ├── total_bad_debt: u64 # Cumulative absorbed losses │
│ └── bump: u8 │
│ │
│ MARKET (PDA: ["market", market_index]) │
│ ├── market_index: u16 │
│ ├── name: String # e.g., "ETH-SOL" │
│ ├── feed_id: [u8; 32] # Pyth oracle feed ID │
│ ├── max_leverage: u64 # Maximum allowed leverage │
│ ├── maintenance_margin: u64 # Liquidation threshold (bps) │
│ ├── base_reserve: u128 # vAMM base asset reserve │
│ ├── quote_reserve: u128 # vAMM quote asset reserve │
│ ├── cum_funding: i128 # Cumulative funding rate (bps) │
│ ├── last_funding_ts: i64 # Last funding update timestamp │
│ ├── long_oi: u64 # Total long open interest │
│ ├── short_oi: u64 # Total short open interest │
│ ├── is_active: bool # Market trading status │
│ └── bump: u8 │
│ │
│ USER (PDA: ["user", user_pubkey]) │
│ ├── authority: Pubkey │
│ ├── deposit: u64 # User's deposited SOL balance │
│ └── bump: u8 │
│ │
│ USER_MARKET_INFO (PDA: ["user_market", user_pubkey, market_index]) │
│ ├── authority: Pubkey │
│ ├── market_index: u16 │
│ ├── position_bitmap: u16 # Bitmask of occupied position slots │
│ └── bump: u8 │
│ │
│ POSITION (PDA: ["position", user_pubkey, market_index, slot]) │
│ ├── authority: Pubkey │
│ ├── market_index: u16 │
│ ├── position_slot: u8 # Slot index (0-15) │
│ ├── is_long: bool # Long or short position │
│ ├── size: u64 # Position size × SIZE_PRECISION │
│ ├── entry_price: u64 # Entry price in lamports │
│ ├── margin: u64 # Isolated margin in lamports │
│ ├── leverage: u64 # Position leverage │
│ ├── entry_funding: i128 # Funding rate at entry (bps) │
│ ├── opened_at: i64 # Position open timestamp │
│ └── bump: u8 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
VoltPERP uses a constant product AMM formula for price discovery:
base_reserve × quote_reserve = k (constant)
Price Calculation:
mark_price = quote_reserve / base_reserve
Trade Execution:
- Long: Decreases
base_reserve, increasesquote_reserve(buying base asset) - Short: Increases
base_reserve, decreasesquote_reserve(selling base asset) - Price impact depends on trade size relative to reserves
| Constant | Value | Description |
|---|---|---|
PRICE_PRECISION |
10^9 | Matches lamport precision (9 decimals) |
SIZE_PRECISION |
10^4 | Position size precision (4 decimals) |
| Fee Type | Rate | Description |
|---|---|---|
| Trading Fee | 0.05% (5 bps) | Charged on position open/close |
| Liquidation Fee | 5% (500 bps) | Paid to liquidator from margin |
| Protocol Penalty | 10% (1000 bps) | Protocol fee on liquidations |
| Parameter | Value | Description |
|---|---|---|
| Minimum Margin | 0.0001 SOL | Minimum margin per position |
| Maintenance Margin | 2-3% | Liquidation threshold (configurable per market) |
| Maximum Leverage | 20x | Maximum allowed leverage |
| Limit | Value | Description |
|---|---|---|
| Max Positions per Market | 16 | Each user can have up to 16 simultaneous positions in a single market |
| Max Leverage | 20x | Configurable per market, up to 20x |
| Position Size Precision | 4 decimals | e.g., 1.2345 units |
Funding accrues continuously based on the deviation between vAMM price and oracle price. Payments are settled when a position is closed, partially closed, or liquidated:
funding_rate = (vAMM_price - oracle_price) / oracle_price × time_elapsed / 3600
Capped at: ±1% per funding period
- When vAMM > Oracle (Premium): Longs pay shorts
- When vAMM < Oracle (Discount): Shorts pay longs
funding_payment = position_value × (current_cum_funding - entry_funding)
A position becomes liquidatable when:
effective_margin_ratio < maintenance_margin_ratio
Where:
effective_margin_ratio = (margin + unrealized_pnl) / position_notional_value × 100
| Recipient | Amount |
|---|---|
| Liquidator | 5% of position margin + account rent |
| Protocol | 10% of position margin |
| User | Remaining margin after fees (if any) |
When a position's margin is insufficient to cover losses:
- User loses entire margin
- Protocol vault absorbs the remaining loss (bad debt)
- Bad debt is tracked in
vault.total_bad_debt
- Real-time vAMM price and oracle price display
- Interactive leverage slider (1x to market's max leverage)
- Position size input with 4 decimal precision
- Slippage tolerance configuration
- Live cost breakdown (margin + fees)
- One-click long/short position opening
- All open positions displayed in table format
- Real-time PnL updates (Price PnL, Funding PnL, Net PnL)
- Effective margin ratio monitoring
- Add margin to existing positions
- Partial close functionality
- Detailed position modal with full breakdown
- Mark price (vAMM)
- Oracle price (Pyth)
- Cumulative funding rate
- Long/Short open interest
- Maximum leverage
- Maintenance margin %
- Last funding update timestamp
- Market status (Active/Paused)
- Scan all markets for liquidatable positions
- Confidence score based on EM% vs MM% gap
- Reward breakdown (Liq. Reward + Account Rent)
- Sort by confidence or total reward
- One-click liquidation execution
- Initialize protocol vault
- Create new markets with custom parameters
- Pause/Resume markets
- Inject funds into vault
- Claim protocol fees
- Price chart with candlestick visualization
- Funding rate chart displaying historical rates
- Time interval selection (1m, 5m, 15m, 1h, 4h, 1D)
- PDA-based account derivation (no arbitrary account access)
- Strict authority checks on all instructions
- Oracle staleness validation
- Slippage protection on all trades
- Circuit breaker: Admin can pause markets if price deviation exceeds 20%
- Each position has independent margin
- Maximum loss limited to position's margin
- No cross-margin liquidation cascade
- Pyth Network price feeds for reliable pricing
- SOL/USD feed for cross-currency conversions
- Configurable staleness threshold (currently 48h for devnet)
| Instruction | Description |
|---|---|
init_vault |
Initialize protocol vault (one-time setup) |
create_market |
Create new trading market with custom parameters |
pause_market |
Pause trading on a market |
resume_market |
Resume trading on a paused market |
inject_funds |
Add SOL to protocol vault |
claim_fees |
Withdraw accumulated protocol fees |
| Instruction | Description |
|---|---|
deposit |
Deposit SOL into user account |
withdraw |
Withdraw SOL from user account |
open_position |
Open new long/short position |
close_position |
Close entire position |
partial_close |
Close portion of position |
add_margin |
Add margin to existing position |
liquidate |
Liquidate underwater position |
The program emits events for all major actions:
| Event | Triggered When |
|---|---|
Deposited |
User deposits SOL |
Withdrawn |
User withdraws SOL |
PositionOpened |
New position opened |
PositionClosed |
Position fully closed |
PartialClosed |
Position partially closed |
MarginAdded |
Margin added to position |
Liquidated |
Position liquidated |
FundingUpdated |
Funding rate updated |
PriceUpdated |
vAMM price changed |
Built with ⚡ on Solana