Skip to content

Repository files navigation

Project Description

Deployed Frontend URL: https://liquidstaking-rust.vercel.app/

Solana Program ID: CTz1xvxZ4w2x1HkcrjwFRD3TvgqWeyQ4Ln8DYAMStFUp

Project Overview

Description

This project is a Liquid Staking protocol on Solana. Users stake SOL into a shared pool and receive liquid staking tokens (LSTs) minted by the program’s SPL mint. The LSTs represent a claim on the pool’s SOL and appreciate as rewards are added. Users can unstake anytime by burning LSTs to withdraw SOL (minus a configurable fee). The protocol uses PDAs for deterministic pool authority and secure minting, and provides a view instruction to expose the current exchange rate and pool statistics.

Key Features

  • Stake SOL, receive LSTs: Initial staker mints 1:1; subsequent stakes mint proportionally by pool ratio.
  • Instant liquidity: Unstake at any time; fees remain in the pool to reward holders.
  • Rewards compounding: Adding rewards increases the SOL/LST exchange rate for all holders.
  • Configurable parameters: Fee rate (max 10%) and minimum stake amount enforced on-chain.
  • Deterministic authority: PDA-owned mint authority and pool account; no private keys.
  • Events and views: Emits stake/unstake/reward events and a view to fetch the exchange rate.

How to Use the dApp

  1. Connect Wallet
  2. Stake: Enter SOL amount (≥ minimum). Confirm; LSTs are minted to your token account.
  3. View Pool: Check total staked, total LSTs, and the current exchange rate (SOL per LST).
  4. Unstake: Enter LST amount to burn. Receive SOL equal to your share minus the fee.

Program Architecture

The Anchor program maintains a single pool account that holds SOL and controls the LST mint. The pool PDA signs for minting during stake operations. Accounting keeps track of total SOL and total LST supply to compute the exchange rate deterministically.

PDA Usage

The program uses a PDA for the pool account and as the mint authority for the LST mint.

PDAs Used:

  • Pool PDA: seeds = [b"pool", authority]. Purpose: canonical pool account; signer for CPI mint_to during stake; owner of SOL lamports and mint authority.

Program Instructions

Instructions Implemented:

  • initialize_pool(fee_rate: u16, minimum_stake: u64): Creates the pool PDA and initializes the LST mint with the pool PDA as mint authority. Validates fee rate (≤ 10%) and minimum stake (> 0).
  • stake(amount: u64): Transfers SOL from user to pool and mints LSTs to the user. First staker mints 1:1; otherwise mints proportional to current pool ratio. Emits StakeEvent.
  • unstake(liquid_token_amount: u64): Burns the user’s LSTs and transfers SOL back based on exchange rate minus fee. Subtracts the net withdrawal from total_staked; fee remains in the pool. Emits UnstakeEvent.
  • add_rewards(amount: u64): Transfers SOL from the authority to the pool to increase total_staked. Emits RewardsAddedEvent.
  • get_exchange_rate() -> ExchangeRate (view): Returns { sol_per_liquid_token, total_staked, total_liquid_tokens }.

Events Emitted

  • StakeEvent { user, amount, liquid_tokens_minted, total_staked }: Emitted on successful stake.
  • UnstakeEvent { user, liquid_tokens_burned, sol_withdrawn, fee, total_staked }: Emitted on successful unstake.
  • RewardsAddedEvent { amount, total_staked }: Emitted when rewards are added.

Account Structure

#[account]
pub struct StakingPool {
    pub authority: Pubkey,
    pub total_staked: u64,
    pub total_liquid_tokens: u64,
    pub fee_rate: u16,            // basis points
    pub minimum_stake: u64,
    pub liquid_token_mint: Pubkey,
    pub bump: u8,
}

#[derive(AnchorSerialize, AnchorDeserialize)]
pub struct ExchangeRate {
    pub sol_per_liquid_token: u64,
    pub total_staked: u64,
    pub total_liquid_tokens: u64,
}

Error Codes

  • FeeTooHigh (6000): Fee rate exceeds 10% (1000 bps).
  • InvalidMinimumStake (6001): Minimum stake must be greater than zero.
  • InvalidAmount (6002): Provided amount is zero or invalid.
  • BelowMinimumStake (6003): Stake amount is below the configured minimum.
  • InsufficientLiquidTokens (6004): Computed mint amount is zero (due to rounding).
  • NoLiquidityAvailable (6005): Pool has no LST supply for unstake calculation.
  • InsufficientWithdrawal (6006): Computed SOL to withdraw is zero (due to rounding).

Testing

Test Coverage

Comprehensive tests cover happy and unhappy paths, integration, and gas/performance scenarios.

Happy Path Tests:

  • Initialize pool with valid parameters, including zero fee
  • Stake (first staker 1:1) and subsequent stakes (proportional minting)
  • Unstake partial and full amounts with correct fee retention in pool
  • Add rewards and verify exchange rate appreciation
  • View exchange rate before/after actions
  • Full lifecycle and small-amount edge cases

Unhappy Path Tests:

  • Initialization with fee > 10% or minimum stake = 0
  • Stake of 0 or below minimum; insufficient funds
  • Unstake with 0 or insufficient LST balance
  • Constraint violations: wrong mint, wrong token account owner, unauthorized rewards

Running Tests

anchor test

# Reuse a running local validator
anchor test --skip-local-validator

Additional Notes

  • Program ID: CTz1xvxZ4w2x1HkcrjwFRD3TvgqWeyQ4Ln8DYAMStFUp
  • Pool PDA seeds include the authority: [b"pool", authority] for deterministic isolation.
  • Fees are accounted so the pool retains fees on unstake; total_staked decreases by the net withdrawal.
  • SPL Token mint authority is the pool PDA; mint decimals set to 9.

Project Description

Deployed Frontend URL: [TODO: Link to your deployed frontend - Deploy to Vercel/Netlify after setup]

Solana Program ID: [TODO: Your deployed program's public key - Update after deploying to Devnet]

Project Overview

Description

This is a comprehensive Liquid Staking Protocol built on Solana that allows users to stake their SOL while maintaining liquidity through liquid staking tokens (LSTs). Unlike traditional staking where assets are locked, this protocol mints liquid tokens representing the staked SOL, enabling users to earn staking rewards while still participating in DeFi activities.

The protocol uses Program Derived Addresses (PDAs) for secure pool management, implements dynamic exchange rates that appreciate over time as rewards accumulate, and provides a user-friendly interface for seamless staking and unstaking operations. Users can stake SOL to receive liquid tokens, earn rewards through the appreciating exchange rate, and unstake at any time with a small exit fee.

Key Features

  • Liquid Staking: Stake SOL and receive liquid tokens that can be used in DeFi protocols
  • Dynamic Exchange Rate: Token value appreciates automatically as staking rewards are added to the pool
  • Instant Liquidity: Unstake anytime without waiting periods (subject to exit fees)
  • Configurable Parameters: Adjustable fee rates, minimum stake amounts, and reward distribution
  • Transparent Fee Structure: Clear display of all fees with 5% default exit fee
  • Multi-User Support: Multiple users can stake and unstake independently
  • Real-time Pool Statistics: Live updates of total staked amount and exchange rates
  • Reward Compounding: Automatic reward addition increases the value of all liquid tokens

How to Use the dApp

  1. Connect Wallet

    • Click "Connect Wallet" button on the homepage
    • In demo mode, this simulates wallet connection with test balances
  2. Stake SOL:

    • Enter the amount of SOL you want to stake (minimum 0.1 SOL)
    • Use percentage buttons (25%, 50%, 75%, Max) for quick selection
    • Review the estimated liquid tokens you'll receive
    • Click "Stake SOL" and confirm the transaction
    • Liquid tokens will be minted to your wallet
  3. Monitor Rewards:

    • Watch the exchange rate increase over time as rewards are added
    • Your liquid tokens automatically appreciate in value
    • View real-time pool statistics and your token balance
  4. Unstake Tokens:

    • Enter the amount of liquid tokens you want to unstake
    • Review the SOL amount you'll receive (after 5% fee)
    • Click "Unstake Tokens" and confirm the transaction
    • SOL will be returned to your wallet minus the exit fee

Program Architecture

The Solana program is built using the Anchor framework with a focus on security, efficiency, and user experience. The architecture centers around a single staking pool that manages all user deposits and liquid token issuance.

PDA Usage

PDAs Used:

  • Pool PDA: seeds = [b"pool"], bump - Main staking pool account that holds all staked SOL and manages the liquid token mint authority. This PDA ensures secure fund management and prevents unauthorized access to pool resources.

The PDA design provides several security benefits: it eliminates the need for external authorities, ensures deterministic address generation, and allows the program to sign transactions on behalf of the pool without exposing private keys.

Program Instructions

Instructions Implemented:

  • initialize_pool: Sets up the staking pool with configurable fee rate and minimum stake amount. Creates the liquid token mint and establishes the pool as the mint authority.
  • stake: Accepts SOL deposits from users and mints corresponding liquid tokens based on the current exchange rate. Handles first-time stakers with 1:1 ratio and subsequent stakers with dynamic pricing.
  • unstake: Burns user's liquid tokens and returns SOL based on current exchange rate minus exit fees. Updates pool totals and transfers SOL back to the user.
  • add_rewards: Allows the pool authority to add staking rewards to the pool, increasing the total staked amount and improving the exchange rate for all token holders.
  • get_exchange_rate: View function that returns the current exchange rate, total staked amount, and total liquid tokens in circulation for frontend display.

Account Structure

#[account]
pub struct StakingPool {
    pub authority: Pubkey,           // Pool authority who can add rewards
    pub total_staked: u64,           // Total SOL staked in lamports
    pub total_liquid_tokens: u64,    // Total liquid tokens in circulation
    pub fee_rate: u16,               // Exit fee rate in basis points (500 = 5%)
    pub minimum_stake: u64,          // Minimum stake amount in lamports
    pub liquid_token_mint: Pubkey,   // Address of the liquid token mint
    pub bump: u8,                    // PDA bump seed for account derivation
}

#[derive(AnchorSerialize, AnchorDeserialize)]
pub struct ExchangeRate {
    pub sol_per_liquid_token: u64,   // Current exchange rate in lamports
    pub total_staked: u64,           // Total SOL in the pool
    pub total_liquid_tokens: u64,    // Total liquid tokens outstanding
}

Testing

Test Coverage

The project includes comprehensive test coverage with both positive and negative test cases to ensure robust functionality and proper error handling.

Happy Path Tests:

  • Pool Initialization: Successfully creates staking pool with valid parameters (5% fee, 0.1 SOL minimum)
  • First User Staking: Validates 1:1 exchange rate for initial staker and proper liquid token minting
  • Multiple User Staking: Tests that multiple users can stake independently with correct token allocation
  • Exchange Rate Calculation: Verifies accurate exchange rate computation after staking and rewards
  • Reward Addition: Confirms that adding rewards increases total staked and improves exchange rate
  • Token Unstaking: Validates unstaking process with correct fee calculation and SOL return
  • Account Creation: Tests automatic creation of associated token accounts for liquid tokens

Unhappy Path Tests:

  • Invalid Pool Parameters: Fails initialization with fee rates > 10% or zero minimum stake
  • Invalid Stake Amounts: Rejects zero stakes and amounts below minimum threshold
  • Insufficient Balances: Prevents staking more SOL than available or unstaking more tokens than owned
  • Unauthorized Access: Blocks non-authority users from adding rewards to the pool
  • Edge Case Handling: Tests boundary conditions and mathematical edge cases

Running Tests

# Install dependencies
npm install

# Run the full test suite
anchor test

# Run tests with verbose output
anchor test --skip-local-validator

# Run specific test file
anchor test tests/liquid-staking.ts

Additional Notes for Evaluators

Key Implementation Highlights:

  1. Security-First Design: All fund transfers use PDAs and proper CPI calls with comprehensive input validation
  2. Mathematical Precision: Exchange rate calculations handle edge cases and prevent overflow/underflow
  3. Gas Optimization: Efficient account structure and instruction design minimize transaction costs
  4. User Experience: Frontend provides real-time feedback, clear fee disclosure, and intuitive interface
  5. Extensibility: Architecture supports future features like validator delegation and governance

Demo Considerations:

  • The frontend runs in demo mode with simulated wallet connections and transactions
  • Real deployment would integrate with Phantom, Solflare, and other Solana wallets
  • Mock data simulates realistic pool growth and reward distribution patterns
  • All smart contract logic is production-ready and thoroughly tested

Technical Decisions:

  • Chose single-pool design for simplicity while maintaining scalability
  • Implemented basis points for precise fee calculations
  • Used SPL Token standard for maximum compatibility with DeFi protocols
  • Event emissions provide transparent on-chain activity logging for analytics

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages