Skip to content

cybertronprime/collateral-vault

Repository files navigation

Collateral Vault Management System - Technical Documentation

Version: 1.0.0
Network: Solana Devnet
Program ID: 4EFWHK5D9m5UL1KjW9xbb5ZHupGbM3AZDvQgYiJYt2c9


Table of Contents

  1. System Architecture
  2. Smart Contract Documentation
  3. SPL Token Integration
  4. Backend Service Documentation
  5. Security Analysis

1. System Architecture

1.1 Overview

Non-custodial collateral management system for a decentralized perpetual futures exchange on Solana. Users deposit USDT into program-controlled vaults (PDAs) that can be locked for margin requirements during trading.

Component Technology
Smart Contract Rust + Anchor 0.30.1
Backend Rust + Axum 0.7 + Tokio
Database PostgreSQL + sqlx
Blockchain Solana Devnet

1.2 Vault Structure Diagram

┌─────────────────────────────────────────────────────────────────────────┐
│                         COLLATERAL VAULT SYSTEM                         │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                    VaultAuthority (Singleton PDA)                │   │
│  │  Seeds: ["authority"]                                            │   │
│  │  ┌─────────────────────────────────────────────────────────────┐│   │
│  │  │ admin: Pubkey              (32 bytes)                       ││   │
│  │  │ authorized_programs: Vec   (4 + 32*n bytes)                 ││   │
│  │  │ bump: u8                   (1 byte)                         ││   │
│  │  └─────────────────────────────────────────────────────────────┘│   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                    │                                    │
│                    Controls Lock/Unlock/Transfer                        │
│                                    ▼                                    │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                    CollateralVault (Per-User PDA)                │   │
│  │  Seeds: ["vault", user_pubkey]                                   │   │
│  │  ┌─────────────────────────────────────────────────────────────┐│   │
│  │  │ owner: Pubkey              (32 bytes)                       ││   │
│  │  │ token_account: Pubkey      (32 bytes)                       ││   │
│  │  │ total_balance: u64         (8 bytes)                        ││   │
│  │  │ locked_balance: u64        (8 bytes)                        ││   │
│  │  │ available_balance: u64     (8 bytes)                        ││   │
│  │  │ total_deposited: u64       (8 bytes)                        ││   │
│  │  │ total_withdrawn: u64       (8 bytes)                        ││   │
│  │  │ created_at: i64            (8 bytes)                        ││   │
│  │  │ bump: u8                   (1 byte)                         ││   │
│  │  └─────────────────────────────────────────────────────────────┘│   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                    │                                    │
│                                    ▼                                    │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                    Vault Token Account (ATA)                     │   │
│  │  ┌─────────────────────────────────────────────────────────────┐│   │
│  │  │ mint: USDT_MINT                                             ││   │
│  │  │ owner: vault_pda (PDA authority)                            ││   │
│  │  │ amount: actual token balance                                ││   │
│  │  └─────────────────────────────────────────────────────────────┘│   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
│  INVARIANT: available_balance = total_balance - locked_balance          │
└─────────────────────────────────────────────────────────────────────────┘

1.3 PDA Derivation Scheme

Account Seeds Derivation Code
Vault PDA ["vault", user_pubkey] Pubkey::find_program_address(&[b"vault", user.as_ref()], &program_id)
Authority PDA ["authority"] Pubkey::find_program_address(&[b"authority"], &program_id)
Vault ATA Standard ATA get_associated_token_address(&vault_pda, &usdt_mint)

1.4 CPI Flow Diagrams

Deposit Flow

┌──────────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│    User      │     │   Backend    │     │   Solana     │     │  SPL Token   │
│   Wallet     │     │   Service    │     │   Program    │     │   Program    │
└──────┬───────┘     └──────┬───────┘     └──────┬───────┘     └──────┬───────┘
       │                    │                    │                    │
       │ 1. POST /deposit   │                    │                    │
       │ ─────────────────► │                    │                    │
       │                    │                    │                    │
       │ 2. Unsigned Tx     │                    │                    │
       │ ◄───────────────── │                    │                    │
       │                    │                    │                    │
       │ 3. Sign with Wallet                     │                    │
       │ ─────────────────────────────────────► │                    │
       │                    │                    │                    │
       │                    │                    │ 4. CPI: Transfer   │
       │                    │                    │ ─────────────────► │
       │                    │                    │                    │
       │                    │                    │ 5. Tokens Moved    │
       │                    │                    │ ◄───────────────── │
       │                    │                    │                    │
       │                    │                    │ 6. Update Vault    │
       │                    │                    │    State           │
       │                    │                    │                    │
       │ 7. Tx Confirmed    │                    │                    │
       │ ◄─────────────────────────────────────  │                    │
       │                    │                    │                    │
       │ 8. POST /confirm   │                    │                    │
       │ ─────────────────► │                    │                    │
       │                    │                    │                    │
       │                    │ 9. Update DB       │                    │
       │                    │                    │                    │
       │ 10. Success        │                    │                    │
       │ ◄───────────────── │                    │                    │

Withdrawal Flow

┌──────────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│    User      │     │   Backend    │     │   Solana     │     │  SPL Token   │
│   Wallet     │     │   Service    │     │   Program    │     │   Program    │
└──────┬───────┘     └──────┬───────┘     └──────┬───────┘     └──────┬───────┘
       │                    │                    │                    │
       │ 1. POST /withdraw  │                    │                    │
       │ ─────────────────► │                    │                    │
       │                    │                    │                    │
       │                    │ 2. Check balance   │                    │
       │                    │                    │                    │
       │ 3. Unsigned Tx     │                    │                    │
       │ ◄───────────────── │                    │                    │
       │                    │                    │                    │
       │ 4. Sign with Wallet                     │                    │
       │ ─────────────────────────────────────► │                    │
       │                    │                    │                    │
       │                    │                    │ 5. Verify Owner    │
       │                    │                    │ 6. Check Balance   │
       │                    │                    │                    │
       │                    │                    │ 7. CPI: Transfer   │
       │                    │                    │    (PDA Signs)     │
       │                    │                    │ ─────────────────► │
       │                    │                    │                    │
       │                    │                    │ 8. Tokens Moved    │
       │                    │                    │ ◄───────────────── │
       │                    │                    │                    │
       │ 9. Tx Confirmed    │                    │                    │
       │ ◄─────────────────────────────────────  │                    │
       │                    │                    │                    │
       │ 10. POST /confirm  │                    │                    │
       │ ─────────────────► │                    │                    │

Lock/Unlock Collateral Flow

┌──────────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   Position   │     │   Vault      │     │   Vault      │     │   Backend    │
│   Manager    │     │   Authority  │     │   Program    │     │   Service    │
└──────┬───────┘     └──────┬───────┘     └──────┬───────┘     └──────┬───────┘
       │                    │                    │                    │
       │ 1. User Opens Position                  │                    │
       │                    │                    │                    │
       │ 2. CPI: lock_collateral                 │                    │
       │ ─────────────────────────────────────► │                    │
       │                    │                    │                    │
       │                    │ 3. Verify caller   │                    │
       │                    │    in whitelist    │                    │
       │                    │ ◄───────────────── │                    │
       │                    │                    │                    │
       │                    │ 4. Authorized ✓    │                    │
       │                    │ ─────────────────► │                    │
       │                    │                    │                    │
       │                    │                    │ 5. Update Vault:   │
       │                    │                    │    locked += amt   │
       │                    │                    │    available -= amt│
       │                    │                    │                    │
       │ 6. Lock Success    │                    │                    │
       │ ◄─────────────────────────────────────  │                    │
       │                    │                    │                    │
       │                    │                    │                    │ 7. Update DB

Transfer Collateral Flow (Liquidation)

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│ Liquidation  │     │   Vault      │     │   Vault      │
│   Engine     │     │   Program    │     │   Accounts   │
└──────┬───────┘     └──────┬───────┘     └──────┬───────┘
       │                    │                    │
       │ 1. Detect Under-   │                    │
       │    collateralized  │                    │
       │                    │                    │
       │ 2. CPI: transfer_collateral             │
       │ ─────────────────► │                    │
       │                    │                    │
       │                    │ 3. Verify Auth     │
       │                    │                    │
       │                    │ 4. From Vault:     │
       │                    │    total -= amt    │
       │                    │    available -= amt│
       │                    │ ─────────────────► │
       │                    │                    │
       │                    │ 5. To Vault:       │
       │                    │    total += amt    │
       │                    │    available += amt│
       │                    │ ─────────────────► │
       │                    │                    │
       │ 6. Transfer Done   │                    │
       │ ◄───────────────── │                    │

1.5 Security Model

┌─────────────────────────────────────────────────────────────────────────────┐
│                              UNTRUSTED ZONE                                  │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  External Users          Network Traffic          Malicious Actors   │    │
│  │  • Wallet connections    • HTTP requests          • Replay attacks   │    │
│  │  • User inputs           • WebSocket msgs         • Overflow attacks │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                           VALIDATION LAYER                                   │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  Input Validation        Signature Verification    Rate Limiting     │    │
│  │  • Pubkey format         • Ed25519 signatures      • Request limits  │    │
│  │  • Amount > 0            • Transaction signing     • Connection caps │    │
│  │  • Balance checks        • Owner verification                        │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                              TRUSTED ZONE                                    │
│  ┌───────────────────┐  ┌───────────────────┐  ┌───────────────────────┐    │
│  │   Backend Service │  │   Smart Contract  │  │   Solana Runtime      │    │
│  │   • Tx building   │  │   • PDA custody   │  │   • BPF execution     │    │
│  │   • State sync    │  │   • Access control│  │   • Signature verify  │    │
│  │   • No key access │  │   • Atomic updates│  │   • Account ownership │    │
│  └───────────────────┘  └───────────────────┘  └───────────────────────┘    │
└─────────────────────────────────────────────────────────────────────────────┘

2. Smart Contract Documentation

2.1 Account Structures

CollateralVault

#[account]
pub struct CollateralVault {
    pub owner: Pubkey,           // 32 bytes - Wallet owner
    pub token_account: Pubkey,   // 32 bytes - Associated token account
    pub total_balance: u64,      // 8 bytes  - Total USDT in vault
    pub locked_balance: u64,     // 8 bytes  - Locked for positions
    pub available_balance: u64,  // 8 bytes  - Available for withdrawal
    pub total_deposited: u64,    // 8 bytes  - Lifetime deposits
    pub total_withdrawn: u64,    // 8 bytes  - Lifetime withdrawals
    pub created_at: i64,         // 8 bytes  - Creation timestamp
    pub bump: u8,                // 1 byte   - PDA bump seed
}
// Total: 8 (discriminator) + 113 = 121 bytes

VaultAuthority

#[account]
pub struct VaultAuthority {
    pub admin: Pubkey,                    // 32 bytes - Admin who can add programs
    pub authorized_programs: Vec<Pubkey>, // 4 + 32*n bytes - Whitelisted programs
    pub bump: u8,                         // 1 byte - PDA bump seed
}
// Max 10 authorized programs

2.2 Instruction Specifications

Instruction Signer Description
initialize_vault User Create PDA vault + token account
deposit User Transfer USDT from user to vault
withdraw User Transfer USDT from vault to user
lock_collateral Authorized Program Lock funds for margin
unlock_collateral Authorized Program Release locked funds
transfer_collateral Authorized Program Transfer between vaults
initialize_authority Admin Create authority singleton
add_authorized_program Admin Whitelist a program

initialize_vault Accounts

Account Type Description
user Signer, Mut Wallet owner, pays rent
vault PDA, Init New vault account
usdt_mint Account USDT token mint
vault_token_account ATA, Init Vault's token account
system_program Program System program
token_program Program SPL Token program
associated_token_program Program ATA program

deposit Accounts

Account Type Description
user Signer, Mut Depositor
vault PDA, Mut User's vault
user_token_account TokenAccount, Mut User's USDT account
vault_token_account TokenAccount, Mut Vault's USDT account
usdt_mint Account USDT mint
token_program Program SPL Token program

withdraw Accounts

Account Type Description
user Signer, Mut Withdrawer (must be owner)
vault PDA, Mut User's vault (signs via seeds)
user_token_account TokenAccount, Mut User's USDT account
vault_token_account TokenAccount, Mut Vault's USDT account
usdt_mint Account USDT mint
token_program Program SPL Token program

lock_collateral / unlock_collateral Accounts

Account Type Description
authority Signer Must be in authorized_programs list
vault_authority PDA Authority singleton
vault Account, Mut Target vault

transfer_collateral Accounts

Account Type Description
authority Signer Must be authorized
vault_authority PDA Authority singleton
from_vault Account, Mut Source vault
to_vault Account, Mut Destination vault

2.3 PDA Seeds and Bumps

// Vault PDA derivation
impl CollateralVault {
    pub const SEED_PREFIX: &'static [u8] = b"vault";
}
// Seeds: ["vault", user_pubkey]

// Authority PDA derivation  
impl VaultAuthority {
    pub const SEED_PREFIX: &'static [u8] = b"authority";
}
// Seeds: ["authority"]

2.4 Authority Validation

// Constraint validation for vault ownership
#[account(
    mut,
    seeds = [b"vault", user.key().as_ref()],
    bump = vault.bump,
    constraint = vault.owner == user.key() @ VaultError::UnauthorizedCaller,
)]
pub vault: Account<'info, CollateralVault>,

// Authority whitelist check in instruction logic
let caller = ctx.accounts.authority.key();
require!(
    ctx.accounts.vault_authority.authorized_programs.contains(&caller),
    VaultError::UnauthorizedCaller
);

2.5 Error Codes

Code Name Description
6000 InvalidAmount Amount must be > 0
6001 InsufficientAvailableBalance Not enough unlocked funds
6002 InsufficientLockedBalance Not enough locked funds
6003 UnauthorizedCaller Caller not authorized
6004 Overflow Arithmetic overflow
6005 InvalidTokenAccount Token account mismatch
6006 MaxAuthorizedProgramsReached Max 10 programs
6007 ProgramAlreadyAuthorized Duplicate program

3. SPL Token Integration

3.1 Token Transfer Flows

Deposit: User → Vault (User Signs)

token::transfer(
    CpiContext::new(
        ctx.accounts.token_program.to_account_info(),
        Transfer {
            from: ctx.accounts.user_token_account.to_account_info(),
            to: ctx.accounts.vault_token_account.to_account_info(),
            authority: ctx.accounts.user.to_account_info(),
        },
    ),
    amount,
)?;

Withdraw: Vault → User (PDA Signs)

let user_key = ctx.accounts.user.key();
let seeds = &[b"vault", user_key.as_ref(), &[vault.bump]];

token::transfer(
    CpiContext::new_with_signer(
        ctx.accounts.token_program.to_account_info(),
        Transfer {
            from: ctx.accounts.vault_token_account.to_account_info(),
            to: ctx.accounts.user_token_account.to_account_info(),
            authority: vault.to_account_info(),
        },
        &[seeds],
    ),
    amount,
)?;

3.2 Associated Token Accounts

// Vault token account initialization (ATA)
#[account(
    init,
    payer = user,
    associated_token::mint = usdt_mint,
    associated_token::authority = vault,
)]
pub vault_token_account: Account<'info, TokenAccount>,

// User token account validation
#[account(
    mut,
    constraint = user_token_account.mint == usdt_mint.key() @ VaultError::InvalidTokenAccount,
    constraint = user_token_account.owner == user.key() @ VaultError::UnauthorizedCaller,
)]
pub user_token_account: Account<'info, TokenAccount>,

3.3 CPI to Token Program

The program uses anchor_spl::token for all token operations:

use anchor_spl::token::{self, Token, TokenAccount, Transfer};

// Standard CPI (user authority)
token::transfer(CpiContext::new(token_program, transfer_accounts), amount)?;

// PDA-signed CPI (vault authority)
token::transfer(CpiContext::new_with_signer(token_program, transfer_accounts, signer_seeds), amount)?;

3.4 Error Handling

// Balance validation before transfer
require!(amount > 0, VaultError::InvalidAmount);
require!(amount <= vault.available_balance, VaultError::InsufficientAvailableBalance);

// Checked arithmetic to prevent overflow
vault.total_balance = vault.total_balance.checked_add(amount).ok_or(VaultError::Overflow)?;
vault.available_balance = vault.available_balance.checked_sub(amount).ok_or(VaultError::Overflow)?;

4. Backend Service Documentation

4.1 Module Architecture

backend/src/
├── main.rs              # Entry point, server setup
├── config.rs            # Environment configuration
├── api/
│   ├── mod.rs           # API module exports
│   ├── routes.rs        # REST endpoint handlers
│   └── websocket.rs     # WebSocket event handlers
├── vault_manager.rs     # Core vault business logic
├── vault_monitor.rs     # TVL monitoring and analytics
├── balance_tracker.rs   # Real-time balance tracking
├── tx_builder.rs        # Transaction construction
├── cpi_manager.rs       # CPI helper utilities
├── solana_types.rs      # Solana type definitions
└── db/
    ├── mod.rs           # Database module exports
    ├── models.rs        # Data structures
    └── queries.rs       # SQL operations

4.2 API Specifications

REST Endpoints

Method Endpoint Description
POST /vault/initialize Build unsigned vault init tx
POST /vault/deposit Build unsigned deposit tx
POST /vault/withdraw Build unsigned withdraw tx
POST /vault/confirm Confirm on-chain transaction
POST /vault/lock Lock collateral (internal)
POST /vault/unlock Unlock collateral (internal)
GET /vault/balance/:user Get vault balance
GET /vault/transactions/:user Get transaction history
GET /vault/tvl Get total value locked

Request/Response Examples

POST /vault/initialize

// Request
{ "user_pubkey": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU" }

// Response
{
  "success": true,
  "data": {
    "vault_pubkey": "9xYLm3DN87e98UYKTEqcF6kCkieTrB94UStRvKthBtV",
    "vault_token_account": "...",
    "unsigned_tx": {
      "instructions": [...],
      "required_signers": ["7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU"],
      "message": "Sign this transaction to initialize your vault"
    }
  }
}

POST /vault/deposit

// Request
{ "user_pubkey": "7xKXtg2...", "amount": 1000000 }

// Response
{
  "success": true,
  "data": {
    "unsigned_tx": {...},
    "vault_pubkey": "...",
    "current_balance": { "total": 0, "locked": 0, "available": 0 }
  }
}

POST /vault/confirm

// Request
{
  "user_pubkey": "7xKXtg2...",
  "tx_signature": "5KtVZ...",
  "tx_type": "deposit",
  "amount": 1000000
}

// Response
{
  "success": true,
  "data": {
    "confirmed": true,
    "new_balance": { "total": 1000000, "locked": 0, "available": 1000000 }
  }
}

GET /vault/balance/:user

{
  "success": true,
  "data": { "total": 1000000, "locked": 250000, "available": 750000 }
}

WebSocket Events

Endpoint: ws://localhost:3000/ws/events

// Subscribe to vault updates
{ "action": "subscribe_vault", "user": "7xKXtg2..." }

// Subscribe to TVL updates
{ "action": "subscribe_tvl" }

// Event types: balance_update, deposit, withdrawal, lock, unlock, tvl_update

4.3 Transaction Building

The backend builds unsigned transactions for client-side signing:

pub struct TransactionBuilder {
    program_id: Pubkey,
    usdt_mint: Pubkey,
}

impl TransactionBuilder {
    // Derive vault PDA for user
    pub fn derive_vault_pda(&self, user: &Pubkey) -> (Pubkey, u8) {
        Pubkey::find_program_address(&[b"vault", user.as_ref()], &self.program_id)
    }

    // Derive associated token account
    pub fn derive_ata(&self, owner: &Pubkey, mint: &Pubkey) -> Pubkey {
        get_associated_token_address(owner, mint)
    }

    // Build deposit instruction
    pub fn build_deposit(&self, user: &Pubkey, amount: u64) -> Result<BuiltTransaction> {
        let (vault_pda, _) = self.derive_vault_pda(user);
        let user_ata = self.derive_ata(user, &self.usdt_mint);
        let vault_ata = self.derive_ata(&vault_pda, &self.usdt_mint);
        // ... build instruction with accounts
    }
}

4.4 Database Schema

vaults Table

CREATE TABLE vaults (
    id SERIAL PRIMARY KEY,
    owner_pubkey VARCHAR(44) UNIQUE NOT NULL,
    vault_pubkey VARCHAR(44) UNIQUE NOT NULL,
    token_account_pubkey VARCHAR(44) NOT NULL,
    total_balance BIGINT NOT NULL DEFAULT 0,
    locked_balance BIGINT NOT NULL DEFAULT 0,
    available_balance BIGINT NOT NULL DEFAULT 0,
    status VARCHAR(20) NOT NULL DEFAULT 'active',
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

transactions Table

CREATE TABLE transactions (
    id SERIAL PRIMARY KEY,
    vault_id INTEGER REFERENCES vaults(id),
    tx_signature VARCHAR(88) UNIQUE,
    tx_type VARCHAR(20) NOT NULL,
    amount BIGINT NOT NULL,
    from_vault_pubkey VARCHAR(44),
    to_vault_pubkey VARCHAR(44),
    status VARCHAR(20) NOT NULL DEFAULT 'pending',
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    confirmed_at TIMESTAMP
);

balance_snapshots Table

CREATE TABLE balance_snapshots (
    id SERIAL PRIMARY KEY,
    vault_id INTEGER REFERENCES vaults(id),
    total_balance BIGINT NOT NULL,
    locked_balance BIGINT NOT NULL,
    available_balance BIGINT NOT NULL,
    snapshot_at TIMESTAMP NOT NULL DEFAULT NOW()
);

reconciliation_logs Table

CREATE TABLE reconciliation_logs (
    id SERIAL PRIMARY KEY,
    vault_id INTEGER REFERENCES vaults(id),
    on_chain_balance BIGINT NOT NULL,
    off_chain_balance BIGINT NOT NULL,
    discrepancy BIGINT NOT NULL,
    resolved BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

5. Security Analysis

5.1 Threat Model

Threat Risk Level Mitigation
Unauthorized fund access Critical PDA custody + owner signature required
Integer overflow High Checked arithmetic on all operations
Replay attacks Medium Solana's built-in tx deduplication
Unauthorized lock/unlock High Authority whitelist validation
Token account spoofing High Constraint validation on accounts
Front-running Low Atomic transactions

5.2 Access Control Mechanisms

Operation Owner Authorized Program Admin Backend
Initialize Vault ✅ Signs Builds Tx
Deposit ✅ Signs Builds Tx
Withdraw ✅ Signs Builds Tx
Lock Collateral ✅ Signs Tracks State
Unlock Collateral ✅ Signs Tracks State
Transfer Collateral ✅ Signs Tracks State
Add Authorized Program ✅ Signs
Query Balance Read Only Read Only Read Only

5.3 Attack Surface Analysis

Attack Vector Mitigation
Unauthorized Withdrawal Owner signature required + PDA ownership check
Unauthorized Lock/Unlock Caller must be in authorized_programs whitelist
Integer Overflow All arithmetic uses checked_* operations
Replay Attack Solana's built-in transaction deduplication
Front-Running Transactions are atomic; state changes are immediate
Token Account Mismatch Constraints verify token account matches vault
Fake Authority Authority PDA derived deterministically from seeds
Balance Manipulation Invariant: available = total - locked enforced
Private Key Theft Non-custodial design - backend never holds keys

5.4 Best Practices Implemented

Smart Contract Security

  • PDA Custody: Funds held in program-controlled PDAs with no private key
  • Owner Validation: Only vault owner can deposit/withdraw their funds
  • Authority Whitelist: Only pre-authorized programs can lock/unlock/transfer
  • Checked Arithmetic: All math uses checked_add/checked_sub to prevent overflow
  • Constraint Validation: Anchor constraints verify all account relationships

Backend Security

  • Non-Custodial Design: Backend never holds private keys
  • Input Validation: All pubkeys and amounts validated before processing
  • Transaction Verification: Users sign and submit transactions themselves
  • State Synchronization: Database mirrors on-chain state for fast queries

Constraint Validation Examples

// Vault ownership check
#[account(
    mut,
    seeds = [b"vault", user.key().as_ref()],
    bump = vault.bump,
    constraint = vault.owner == user.key() @ VaultError::UnauthorizedCaller,
)]
pub vault: Account<'info, CollateralVault>,

// Token account validation
#[account(
    mut,
    constraint = user_token_account.mint == usdt_mint.key() @ VaultError::InvalidTokenAccount,
    constraint = user_token_account.owner == user.key() @ VaultError::UnauthorizedCaller,
)]
pub user_token_account: Account<'info, TokenAccount>,

// Vault token account validation
#[account(
    mut,
    constraint = vault_token_account.key() == vault.token_account @ VaultError::InvalidTokenAccount,
)]
pub vault_token_account: Account<'info, TokenAccount>,

Appendix

Program Addresses

Name Address
Collateral Vault Program 4EFWHK5D9m5UL1KjW9xbb5ZHupGbM3AZDvQgYiJYt2c9
USDT Mint (Mainnet) Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB
SPL Token Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Associated Token Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL

Configuration

DATABASE_URL=postgres://localhost/collateral_vault
SOLANA_RPC_URL=https://api.devnet.solana.com
PROGRAM_ID=4EFWHK5D9m5UL1KjW9xbb5ZHupGbM3AZDvQgYiJYt2c9
USDT_MINT=Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB
SERVER_HOST=127.0.0.1
SERVER_PORT=3000

Glossary

Term Definition
PDA Program Derived Address - deterministic address with no private key
CPI Cross-Program Invocation - calling one program from another
ATA Associated Token Account - deterministic token account for a wallet/mint pair
TVL Total Value Locked - sum of all deposited funds across all vaults

Testing

Smart Contract Tests (19 passing)

anchor test --provider.cluster devnet

Backend API Tests

./backend/tests/api_tests.sh

About

Collateral Vault Management System

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published