Posted By : Siddharth
This article explores a concise yet comprehensive guide on creating a staking smart contract on Solana utilizing Anchor. Explore the vast potential of Solana blockchain development services by leveraging Anchor's capabilities to build robust staking mechanisms.
Solana is a high-performance blockchain platform that provides fast, secure, and scalable transactions for decentralized applications (dApps) and marketplaces. Solana uses a unique consensus algorithm called Proof of History (PoH), which allows the network to verify transactions and reach consensus quickly and efficiently.
Solana also provides a suite of developer tools, including a web-based wallet, smart contract language, and decentralized exchange (DEX) for developers to build on its platform. Its native cryptocurrency, SOL, is used for transaction fees, staking, and exchange within the Solana ecosystem.
Suggested Read | What Makes Solana Blockchain Development Stand Out
A smart contract is a self-executing program that automatically enforces the rules and regulations of a contract when certain pre-defined conditions are met. Smart contracts are usually written in programming languages such as Solidity for Ethereum or Rust for Solana and are stored on a blockchain, making them immutable and tamper-proof.
Smart contracts are an integral part of decentralized applications (dApps) that operate on blockchain networks. Smart contracts are transparent and secure, and provide a trustless environment for parties to interact with each other.
Also, Explore | Top 5 Smart Contract Development Companies
A staking contract is a type of smart contract that allows users to earn rewards by staking their tokens or cryptocurrencies in a particular blockchain network. By staking their tokens, users can participate in the consensus process and earn rewards in return.
Staking contracts can also include various features such as slashing mechanisms, where a portion of a staker's tokens is taken away as a penalty for malicious behavior or failure to perform network duties. Staking contracts can also implement additional features, such as delegation, slashing, and governance, to improve the staking experience and incentivize participation.
Check It Out | An Explainer to Liquidity Staking Solution
You can follow the link to install all the dependencies.
Also, Discover | Exploring the Potential of Liquid Staking Derivatives (LSD)
use anchor_lang::prelude::*;
use anchor_spl::token::{self, MintTo, Transfer};
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
declare_id!("7MHr6ZPGTWZkRk6m52GfEWoMxSV7EoDjYyoXAYf3MBwS");
#[program]
pub mod solana_staking_blog {
use super::*;
pub fn initialize(ctx: Context<Initialize>, start_slot: u64, end_slot: u64) -> Result<()> {
msg!("Instruction: Initialize");
let pool_info = &mut ctx.accounts.pool_info;
pool_info.admin = ctx.accounts.admin.key();
pool_info.start_slot = start_slot;
pool_info.end_slot = end_slot;
pool_info.token = ctx.accounts.staking_token.key();
Ok(())
}
pub fn stake(ctx: Context<Stake>, amount: u64) -> Result<()> {
msg!("Instruction: Stake");
let user_info = &mut ctx.accounts.user_info;
let clock = Clock::get()?;
if user_info.amount > 0 {
let reward = (clock.slot - user_info.deposit_slot) - user_info.reward_debt;
let cpi_accounts = MintTo {
mint: ctx.accounts.staking_token.to_account_info(),
to: ctx.accounts.user_staking_wallet.to_account_info(),
authority: ctx.accounts.admin.to_account_info(),
};
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
token::mint_to(cpi_ctx, reward)?;
}
let cpi_accounts = Transfer {
from: ctx.accounts.user_staking_wallet.to_account_info(),
to: ctx.accounts.admin_staking_wallet.to_account_info(),
authority: ctx.accounts.user.to_account_info(),
};
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
token::transfer(cpi_ctx, amount)?;
user_info.amount += amount;
user_info.deposit_slot = clock.slot;
user_info.reward_debt = 0;
Ok(())
}
pub fn unstake(ctx: Context<Unstake>) -> Result<()> {
msg!("Instruction: Unstake");
let user_info = &mut ctx.accounts.user_info;
let clock = Clock::get()?;
let reward = (clock.slot - user_info.deposit_slot) - user_info.reward_debt;
let cpi_accounts = MintTo {
mint: ctx.accounts.staking_token.to_account_info(),
to: ctx.accounts.user_staking_wallet.to_account_info(),
authority: ctx.accounts.admin.to_account_info(),
};
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
token::mint_to(cpi_ctx, reward)?;
let cpi_accounts = Transfer {
from: ctx.accounts.admin_staking_wallet.to_account_info(),
to: ctx.accounts.user_staking_wallet.to_account_info(),
authority: ctx.accounts.admin.to_account_info(),
};
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
token::transfer(cpi_ctx, user_info.amount)?;
user_info.amount = 0;
user_info.deposit_slot = 0;
user_info.reward_debt = 0;
Ok(())
}
pub fn claim_reward(ctx: Context<ClaimReward>) -> Result<()> {
msg!("Instruction: Claim Reward");
let user_info = &mut ctx.accounts.user_info;
let clock = Clock::get()?;
let reward = (clock.slot - user_info.deposit_slot) - user_info.reward_debt;
let cpi_accounts = MintTo {
mint: ctx.accounts.staking_token.to_account_info(),
to: ctx.accounts.user_staking_wallet.to_account_info(),
authority: ctx.accounts.admin.to_account_info(),
};
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
token::mint_to(cpi_ctx, reward)?;
user_info.reward_debt += reward;
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(mut)]
pub admin: Signer<'info>,
#[account(init, payer = admin, space = 8 + PoolInfo::LEN)]
pub pool_info: Account<'info, PoolInfo>,
#[account(mut)]
pub staking_token: InterfaceAccount<'info, Mint>,
#[account(mut)]
pub admin_staking_wallet: InterfaceAccount<'info, TokenAccount>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct Stake<'info> {
#[account(mut)]
pub user: Signer<'info>,
/// CHECK:
#[account(mut)]
pub admin: AccountInfo<'info>,
#[account(init, payer = user, space = 8 + UserInfo::LEN)]
pub user_info: Account<'info, UserInfo>,
#[account(mut)]
pub user_staking_wallet: InterfaceAccount<'info, TokenAccount>,
#[account(mut)]
pub admin_staking_wallet: InterfaceAccount<'info, TokenAccount>,
#[account(mut)]
pub staking_token: InterfaceAccount<'info, Mint>,
pub token_program: Interface<'info, TokenInterface>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct Unstake<'info> {
/// CHECK:
#[account(mut)]
pub user: AccountInfo<'info>,
/// CHECK:
#[account(mut)]
pub admin: AccountInfo<'info>,
#[account(mut)]
pub user_info: Account<'info, UserInfo>,
#[account(mut)]
pub user_staking_wallet: InterfaceAccount<'info, TokenAccount>,
#[account(mut)]
pub admin_staking_wallet: InterfaceAccount<'info, TokenAccount>,
#[account(mut)]
pub staking_token: InterfaceAccount<'info, Mint>,
pub token_program: Interface<'info, TokenInterface>,
}
#[derive(Accounts)]
pub struct ClaimReward<'info> {
/// CHECK:
#[account(mut)]
pub user: AccountInfo<'info>,
/// CHECK:
#[account(mut)]
pub admin: AccountInfo<'info>,
#[account(mut)]
pub user_info: Account<'info, UserInfo>,
#[account(mut)]
pub user_staking_wallet: InterfaceAccount<'info, TokenAccount>,
#[account(mut)]
pub admin_staking_wallet: InterfaceAccount<'info, TokenAccount>,
#[account(mut)]
pub staking_token: InterfaceAccount<'info, Mint>,
pub token_program: Interface<'info, TokenInterface>,
}
#[account]
pub struct PoolInfo {
pub admin: Pubkey,
pub start_slot: u64,
pub end_slot: u64,
pub token: Pubkey,
}
#[account]
pub struct UserInfo {
pub amount: u64,
pub reward_debt: u64,
pub deposit_slot: u64,
}
impl UserInfo {
pub const LEN: usize = 8 + 8 + 8;
}
impl PoolInfo {
pub const LEN: usize = 32 + 8 + 8 + 32;
}
You May Also Like | NFT Staking Platform Development Explained
solana-staking-blog
✔ Initialize
✔ Stake
✔ Claim Reward
✔ Unstake
The complete code can be found here.
If you want more information about Solana blockchain development or want to get started with a project, connect with our skilled blockchain developers.
September 8, 2024 at 02:39 am
Your comment is awaiting moderation.