Skip to content

jvr0x/solana-bond-program

Repository files navigation

Bond Program

A Solana program built with Anchor that allows users to bond tokens for a configurable period of time. After the lock period expires, users can withdraw their bonded tokens.

Overview

The Bond program implements a simple token locking mechanism with the following features:

  • Configurable parameters: Admin can set the allowed mint, bond duration, and required bond amount
  • Single mint restriction: Only one token mint can be used for bonding (set by admin)
  • Time-locked bonds: Tokens are locked for a configurable duration before withdrawal
  • 2-step ownership transfer: Secure admin transfer requiring both parties to act

Architecture

Accounts

Config (PDA)

Global configuration account that stores program parameters.

Field Type Description
authority Pubkey Admin who can update config
allowed_mint Pubkey The only mint allowed for bonding
bond_duration_seconds i64 Lock period in seconds
bond_amount u64 Required bond amount (base units)
pending_authority Option<Pubkey> For 2-step ownership transfer
bump u8 PDA bump seed

Seeds: [b"config"]

BondAccount (PDA)

Per-user bond record.

Field Type Description
signer Pubkey User who created the bond
mint Pubkey Token mint address
total_bonded u64 Amount of tokens locked
start_time i64 Unix timestamp of bond creation
bump u8 PDA bump seed
token_account_bump u8 Token account PDA bump

Seeds: [b"bond_account", signer, mint]

Bond Token Account (PDA)

Token account that holds the bonded tokens, controlled by the program.

Seeds: [b"bond_token_account", signer, mint]

Instructions

initialize

Initializes the global config. Can only be called once.

Parameters:

  • bond_duration_seconds: i64 - Lock period (must be > 30 days)
  • bond_amount: u64 - Required bond amount in base units
  • authority: Option<Pubkey> - Admin address (defaults to signer)

Accounts:

  • signer - Payer and default authority
  • allowed_mint - The mint to allow for bonding
  • config - Config PDA (created)
  • system_program

create_bond

Creates a new bond by transferring tokens to a program-controlled account.

Parameters:

  • amount: u64 - Must equal config.bond_amount * 10^decimals

Accounts:

  • signer - User creating the bond
  • mint - Must match config.allowed_mint
  • bond_account - User's bond record (created)
  • signer_token_account - User's token account (source)
  • bond_token_account - Program token account (created)
  • config - Global config
  • associated_token_program, system_program, token_program

withdraw_bond

Withdraws bonded tokens after the lock period has elapsed.

Accounts:

  • signer - Must be the original bonder
  • mint - Token mint
  • bond_account - User's bond record
  • signer_token_account - User's token account (destination)
  • bond_token_account - Program token account (source)
  • config - Global config
  • associated_token_program, system_program, token_program

update_config

Updates configuration parameters. Admin only.

Parameters:

  • bond_duration_seconds: i64 - New lock period
  • bond_amount: u64 - New bond amount

Accounts:

  • signer - Must be current authority
  • new_allowed_mint - Optional new mint to allow
  • config - Global config

transfer_ownership

Transfers admin ownership using a 2-step process.

Parameters:

  • action: AuthorityAction - SetPending or AcceptPending
  • new_authority: Pubkey - New admin address

Accounts:

  • signer - Current authority (for SetPending) or pending authority (for AcceptPending)
  • config - Global config

Flow:

  1. Current admin calls with SetPending and new admin's address
  2. New admin calls with AcceptPending to complete transfer

Constants

Constant Value Description
BOND_PERIOD_MIN 2,592,000 (30 days) Minimum bond duration
BOND_AMOUNT_MIN 100 Minimum bond amount (base units)

Error Codes

Error Description
AlreadyBonded User already has an active bond
InvalidBondAmount Amount doesn't match config or below minimum
NoBondToWithdraw No active bond or wrong signer
CannotWithdrawBondYet Lock period hasn't elapsed
MinimumBondDurationNotMet Duration below 30 days
Unauthorized Caller lacks permission
InvalidMint Mint doesn't match allowed mint

Building

# Build the program
anchor build

# Run tests
anchor test

# Deploy to devnet
anchor deploy --provider.cluster devnet

Usage Example

import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { Bond } from "../target/types/bond";

// Initialize config (admin only, once)
await program.methods
  .initialize(
    new anchor.BN(60 * 60 * 24 * 30), // 30 days
    new anchor.BN(100),                // 100 tokens (base units)
    null                               // use signer as authority
  )
  .accounts({
    signer: admin.publicKey,
    allowedMint: tokenMint,
    config: configPda,
    systemProgram: SystemProgram.programId,
  })
  .signers([admin])
  .rpc();

// Create a bond
await program.methods
  .createBond(new anchor.BN(100_000_000)) // 100 tokens with 6 decimals
  .accounts({
    signer: user.publicKey,
    mint: tokenMint,
    bondAccount: bondAccountPda,
    signerTokenAccount: userTokenAccount,
    bondTokenAccount: bondTokenAccountPda,
    config: configPda,
    // ... other accounts
  })
  .signers([user])
  .rpc();

// Withdraw after lock period
await program.methods
  .withdrawBond()
  .accounts({
    signer: user.publicKey,
    mint: tokenMint,
    bondAccount: bondAccountPda,
    signerTokenAccount: userTokenAccount,
    bondTokenAccount: bondTokenAccountPda,
    config: configPda,
    // ... other accounts
  })
  .signers([user])
  .rpc();

Security Considerations

  • Single bond per user per mint: Each user can only have one active bond for the configured mint
  • Time-based unlock: Bonds cannot be withdrawn before start_time + bond_duration_seconds
  • Admin controls: Only the authority can update config parameters
  • 2-step ownership: Prevents accidental admin lockout during transfers
  • Mint validation: Only the configured mint is accepted for bonding

License

MIT

About

A simple bond program with configurable bond amount and period, as well as transferrable authority.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published