Skip to content

Latest commit

 

History

History
425 lines (346 loc) · 12.6 KB

ARCHITECTURE.md

File metadata and controls

425 lines (346 loc) · 12.6 KB

Taskmaster Bridge - Architecture Documentation

Overview

Taskmaster Bridge is a multi-chain bridge smart contract built on Solana that enables secure asset transfers between Solana and EVM-compatible chains (Ethereum, Arbitrum, and BSC). The architecture emphasizes security, modularity, and scalability.

Core Design Principles

1. Security First

  • Multi-signature Validation: All inbound transactions require threshold signatures from validators
  • Multi-signature Governance: Admin operations require multiple approvals
  • Replay Protection: Unique nonce system prevents transaction replay attacks
  • Emergency Controls: Circuit breaker mechanism for pause/unpause operations
  • Access Control: Role-based permissions using PDA-based account ownership

2. Modularity

  • Separation of Concerns: Clear separation between state, instructions, and business logic
  • Independent Modules: Each instruction type has its own dedicated module
  • Reusable Components: Shared utilities in constants and error modules

3. Scalability

  • Configurable Parameters: Validator and admin thresholds can be adjusted
  • Dynamic Management: Validators and admins can be added/removed without redeployment
  • Multiple Chains: Architecture supports adding new chains without major changes
  • Token Flexibility: Supports both native and wrapped tokens

System Components

1. State Management

Bridge State (state/bridge.rs)

Central configuration account that stores:

  • Authority and references to admin/validator sets
  • Fee configuration (basis points and minimum fee)
  • Operational status (paused/active)
  • Global nonce for transaction ordering
  • Statistics (total transactions, total value locked)

Key Methods:

  • get_next_nonce(): Atomically increments and returns transaction nonce
  • is_operational(): Checks if bridge is active

Validator Set (state/validator.rs)

Manages the validator set for cross-chain verification:

  • List of authorized validator public keys
  • Threshold for required signatures
  • Methods for adding/removing validators

Key Methods:

  • is_validator(): Check if address is authorized
  • add_validator(): Add new validator with duplicate prevention
  • remove_validator(): Remove validator with threshold adjustment
  • verify_threshold(): Verify signature count meets threshold

Admin Set (state/admin.rs)

Multi-signature governance structure:

  • List of admin public keys
  • Threshold for admin operations
  • Similar structure to ValidatorSet for consistency

Key Methods:

  • is_admin(): Check admin authorization
  • add_admin() / remove_admin(): Manage admin set
  • verify_admin_action(): Verify admin signature threshold

Token Pair (state/token_pair.rs)

Maps tokens between Solana and external chains:

  • Solana token mint address
  • External chain ID and token address
  • Token type (native vs wrapped)
  • Active status flag
  • Statistics (total locked, total wrapped)

Key Methods:

  • is_operational(): Check if pair is active
  • increase_locked() / decrease_locked(): Track locked tokens
  • increase_wrapped() / decrease_wrapped(): Track wrapped tokens

Bridge Transaction (state/bridge_transaction.rs)

Records all bridge transactions:

  • Transaction metadata (nonce, direction, status)
  • Chain IDs (source and destination)
  • Token and amount information
  • External transaction hash for verification
  • Validator signatures
  • Timestamp

Transaction States:

  • Pending: Awaiting validator signatures
  • Verified: Threshold met, ready for execution
  • Executed: Successfully completed
  • Failed: Transaction failed

Transaction Directions:

  • Lock: Locking native tokens (Solana → External)
  • Unlock: Unlocking native tokens (External → Solana)
  • MintWrapped: Minting wrapped tokens (External → Solana)
  • BurnWrapped: Burning wrapped tokens (Solana → External)

2. Instruction Handlers

Initialization (instructions/initialize.rs)

Sets up the bridge with initial configuration:

  • Creates bridge, validator set, and admin set accounts
  • Validates initial parameters
  • Establishes fee structure

Accounts Created:

  • Bridge (PDA)
  • ValidatorSet (PDA)
  • AdminSet (PDA)

Token Operations

Lock Tokens (instructions/lock_tokens.rs)

Locks native SPL tokens to bridge to external chain:

  1. Validates inputs and bridge state
  2. Calculates and collects fee
  3. Transfers tokens from user to vault
  4. Creates executed transaction record
  5. Updates bridge statistics

Account Flow:

User Token Account → Bridge Vault (amount - fee)
User Token Account → Fee Collector (fee)
Unlock Tokens (instructions/unlock_tokens.rs)

Releases locked tokens from external chain:

  1. Validator initiates with external transaction proof
  2. Creates pending transaction record
  3. Other validators call verify_transaction to add signatures
  4. Once verified, execute_unlock transfers tokens to recipient

Multi-phase Process:

Phase 1: Initiate (validator) → Status: Pending
Phase 2: Verify (other validators) → Status: Verified (when threshold met)
Phase 3: Execute (anyone) → Status: Executed
Mint Wrapped (instructions/mint_wrapped.rs)

Mints wrapped tokens representing external assets:

  1. Validator initiates with external transaction proof
  2. Similar multi-phase verification as unlock
  3. Mints new wrapped tokens to recipient

Key Feature:

  • Bridge has mint authority over wrapped token
  • PDA-based minting for security
Burn Wrapped (instructions/burn_wrapped.rs)

Burns wrapped tokens to release on external chain:

  1. Validates and burns wrapped tokens
  2. Collects fee (in wrapped tokens)
  3. Creates executed transaction record

Verification System (instructions/verify_transaction.rs)

Verify Transaction

Validators sign pending transactions:

  • Adds validator signature
  • Checks for duplicates
  • Updates status to Verified when threshold met
Execute Unlock

Executes verified unlock transactions:

  • Validates transaction is verified
  • Transfers tokens from vault using PDA signer
  • Updates statistics
  • Changes status to Executed
Execute Mint Wrapped

Executes verified mint transactions:

  • Validates transaction is verified
  • Mints tokens using PDA signer
  • Updates statistics
  • Changes status to Executed

Administrative Operations

Pause/Unpause (instructions/pause.rs)

Emergency circuit breaker:

  • Any admin can pause the bridge
  • Prevents all bridging operations
  • Can be unpaused by admin
Validator Management (instructions/update_validators.rs)

Dynamic validator set management:

  • add_validator: Add new validator
  • remove_validator: Remove validator (prevents removing last one)
  • update_validator_threshold: Adjust signature requirement
  • Similar functions for admin management
Token Pair Management (instructions/register_token_pair.rs)

Register Native Token Pair:

  • Creates token pair for existing SPL token
  • Creates vault to hold locked tokens
  • Vault authority is bridge PDA

Register Wrapped Token Pair:

  • Creates new wrapped token mint
  • Mint authority is bridge PDA
  • Creates token pair mapping

Toggle Token Pair:

  • Enable/disable specific token pairs
  • Allows granular control without deletion
Fee Management (instructions/update_fee.rs)

Configurable fee structure:

  • Update percentage fee (basis points)
  • Update minimum fee (lamports)
  • Update fee collector address

Security Mechanisms

1. Program Derived Addresses (PDAs)

All critical accounts use PDAs with deterministic seeds:

Bridge:           ["bridge"]
ValidatorSet:     ["validator_set", bridge_pubkey]
AdminSet:         ["admin_set", bridge_pubkey]
TokenPair:        ["token_pair", bridge_pubkey, mint, chain_id]
BridgeTransaction:["bridge_tx", bridge_pubkey, nonce]
Vault:            ["vault", bridge_pubkey, mint]
WrappedMint:      ["wrapped_mint", bridge_pubkey, external_addr, chain_id]

2. Multi-signature Verification

// Validator signature verification
pub fn verify_threshold(&self, signers: &[Pubkey]) -> Result<()> {
    // Check for duplicates
    // Count valid signatures
    // Ensure threshold is met
}

3. Replay Protection

  • Each transaction has unique nonce
  • Nonce must match current bridge nonce
  • Nonce increments atomically
  • Transaction records are permanent

4. Access Control Patterns

// Admin-only operations
#[account(
    constraint = admin_set.is_admin(&admin.key()) @ BridgeError::Unauthorized
)]
pub admin: Signer<'info>,

// Validator-only operations
#[account(
    constraint = validator_set.is_validator(&validator.key()) @ BridgeError::Unauthorized
)]
pub validator: Signer<'info>,

// Bridge operational check
#[account(
    constraint = bridge.is_operational() @ BridgeError::BridgePaused
)]
pub bridge: Account<'info, Bridge>,

5. State Transition Validation

// Only allow valid state transitions
match (self.status, new_status) {
    (Pending, Verified) => {},
    (Verified, Executed) => {},
    (Pending | Verified, Failed) => {},
    _ => return Err(InvalidTransactionStatus),
}

Transaction Flows

Outbound Flow (Solana → External Chain)

User Action
    ↓
Lock/Burn on Solana (instant execution)
    ↓
Transaction Record Created (status: Executed)
    ↓
Relayer Monitors Solana
    ↓
Relayer Submits to External Chain
    ↓
Validators Sign External Transaction
    ↓
Asset Released on External Chain

Inbound Flow (External Chain → Solana)

External Chain Transaction
    ↓
Validator Detects
    ↓
Validator Initiates Unlock/Mint (status: Pending)
    ↓
Other Validators Monitor
    ↓
Validators Call verify_transaction (add signatures)
    ↓
Threshold Met (status: Verified)
    ↓
Anyone Calls Execute
    ↓
Tokens Released/Minted (status: Executed)

Fee Structure

Calculation

fn calculate_fee(amount: u64, fee_basis_points: u16, min_fee: u64) -> Result<u64> {
    let percentage_fee = (amount * fee_basis_points) / 10000;
    Ok(max(percentage_fee, min_fee))
}

Fee Collection

  • Fees collected in the same token being bridged
  • Sent to designated fee collector account
  • Fee collector can be updated by admins

Error Handling

Custom error codes for all failure scenarios:

  • BridgePaused: Operations blocked during pause
  • Unauthorized: Permission denied
  • InsufficientSignatures: Threshold not met
  • InvalidChainId: Unsupported chain
  • TransactionAlreadyProcessed: Replay attempt
  • And 20+ more specific errors

Scalability Considerations

Adding New Chains

  1. Add chain ID constant to constants.rs
  2. Update chain ID validation in instructions
  3. No other code changes required

Adding New Validators

  • Dynamic: Use add_validator instruction
  • No redeployment needed
  • Automatic threshold adjustment on removal

Token Support

  • Unlimited token pairs
  • Each pair is independent PDA
  • Can be enabled/disabled individually

Testing Strategy

Unit Tests

  • Test each instruction handler independently
  • Test state transitions
  • Test access control
  • Test error conditions

Integration Tests

  • Test complete transaction flows
  • Test multi-signature verification
  • Test admin operations
  • Test edge cases and attack vectors

Security Audits

Before mainnet deployment:

  1. Internal code review
  2. External security audit
  3. Testnet deployment and testing
  4. Bug bounty program

Deployment Checklist

  1. Pre-deployment

    • Security audit completed
    • All tests passing
    • Program ID updated in lib.rs and Anchor.toml
    • Initial validators identified
    • Initial admins identified
    • Fee structure decided
  2. Deployment

    • Deploy to devnet
    • Test all operations on devnet
    • Deploy to mainnet-beta
    • Initialize bridge with production parameters
  3. Post-deployment

    • Register initial token pairs
    • Set up relayer infrastructure
    • Monitor transactions
    • Maintain validator set

Future Enhancements

Potential Improvements

  1. Governance Token: Decentralized governance
  2. Dynamic Fees: Market-based fee adjustment
  3. Slashing: Penalize malicious validators
  4. Batching: Batch multiple transactions for efficiency
  5. Cross-chain Messaging: Support arbitrary data transfer
  6. Additional Chains: Support more blockchains (Polygon, Avalanche, etc.)

Upgrade Path

  • Use program upgradability carefully
  • Consider using proxy pattern for major changes
  • Maintain backwards compatibility where possible
  • Plan migration strategy for state changes

Conclusion

This architecture provides a secure, scalable, and flexible foundation for cross-chain asset bridging. The modular design allows for easy maintenance and feature additions, while multiple layers of security protect user assets.