Vyral
Whitepaper

Smart Contract Architecture

Technical implementation of VCoin token and platform contracts

Smart Contract Architecture

Technical implementation of VCoin token and platform contracts

Contract Addresses

💰
Reward Distribution
EqjS5FgEfoGe9wnrRkvWyKendb3fb3Aza6WuxCbmaxPz

View on Explorer →

🔥
Burn Tracker

HMf4URTq1NJCk7K9KNmPWnwxReFj6HX4wy2RdyXqXJoq

View on Explorer →

Vesting

GAEVrgug7i7zUAZss1s7od2bhFiAhv2e91zT2svX7nb3

View on Explorer →

💳
Fee Collection
EU361fP6SN2zhXzHHwUhZ9b6ozWa7V9aV2CguuP9WKoB

View on Explorer →

All smart contract addresses are deployed on Solana devnet and can be verified on Solana Explorer.

Source Code Verification

All smart contracts are open-source and can be independently verified. Below is the complete source code for each deployed program:

burn.rs
use anchor_lang::prelude::*;

declare_id!("HMf4URTq1NJCk7K9KNmPWnwxReFj6HX4wy2RdyXqXJoq");

#[program]
pub mod burn_tracker {
use super::\*;

    // Initialize burn tracker
    pub fn initialize(
        ctx: Context<Initialize>,
    ) -> Result<()> {
        let burn_stats = &mut ctx.accounts.burn_stats;
        burn_stats.authority = ctx.accounts.authority.key();
        burn_stats.total_burned = 0;
        burn_stats.tip_burns = 0;
        burn_stats.marketplace_burns = 0;
        burn_stats.premium_burns = 0;
        burn_stats.withdrawal_burns = 0;
        burn_stats.other_burns = 0;
        burn_stats.burn_count = 0;
        burn_stats.last_burn_timestamp = 0;
        burn_stats.largest_single_burn = 0;

        msg!("Burn Tracker initialized");
        msg!("Authority: {}", ctx.accounts.authority.key());

        Ok(())
    }

    // Record a burn event
    pub fn record_burn(
        ctx: Context<RecordBurn>,
        amount: u64,
        source: BurnSource,
    ) -> Result<()> {
        require!(amount > 0, ErrorCode::InvalidAmount);

        let burn_stats = &mut ctx.accounts.burn_stats;
        let current_time = Clock::get()?.unix_timestamp;

        // Update total burned
        burn_stats.total_burned = burn_stats
            .total_burned
            .checked_add(amount)
            .unwrap();

        // Update source-specific counter
        match source {
            BurnSource::Tip => {
                burn_stats.tip_burns = burn_stats
                    .tip_burns
                    .checked_add(amount)
                    .unwrap();
            }
            BurnSource::Marketplace => {
                burn_stats.marketplace_burns = burn_stats
                    .marketplace_burns
                    .checked_add(amount)
                    .unwrap();
            }
            BurnSource::Premium => {
                burn_stats.premium_burns = burn_stats
                    .premium_burns
                    .checked_add(amount)
                    .unwrap();
            }
            BurnSource::Withdrawal => {
                burn_stats.withdrawal_burns = burn_stats
                    .withdrawal_burns
                    .checked_add(amount)
                    .unwrap();
            }
            BurnSource::Other => {
                burn_stats.other_burns = burn_stats
                    .other_burns
                    .checked_add(amount)
                    .unwrap();
            }
        }

        // Update burn count
        burn_stats.burn_count = burn_stats
            .burn_count
            .checked_add(1)
            .unwrap();

        // Update largest single burn
        if amount > burn_stats.largest_single_burn {
            burn_stats.largest_single_burn = amount;
        }

        // Update last burn timestamp
        burn_stats.last_burn_timestamp = current_time;

        emit!(BurnRecorded {
            amount,
            source: source.clone(),
            total_burned: burn_stats.total_burned,
            burn_count: burn_stats.burn_count,
            timestamp: current_time,
        });

        msg!("Burn recorded: {} lamports from {:?}", amount, source);
        msg!("Total burned: {} lamports", burn_stats.total_burned);

        Ok(())
    }

    // Record daily burn aggregate (for efficiency)
    pub fn record_daily_aggregate(
        ctx: Context<RecordDailyAggregate>,
        date: i64,
        tip_burns: u64,
        marketplace_burns: u64,
        premium_burns: u64,
        withdrawal_burns: u64,
        other_burns: u64,
    ) -> Result<()> {
        let daily_stats = &mut ctx.accounts.daily_stats;

        daily_stats.date = date;
        daily_stats.tip_burns = tip_burns;
        daily_stats.marketplace_burns = marketplace_burns;
        daily_stats.premium_burns = premium_burns;
        daily_stats.withdrawal_burns = withdrawal_burns;
        daily_stats.other_burns = other_burns;
        daily_stats.total_burned = tip_burns
            .checked_add(marketplace_burns)
            .unwrap()
            .checked_add(premium_burns)
            .unwrap()
            .checked_add(withdrawal_burns)
            .unwrap()
            .checked_add(other_burns)
            .unwrap();

        emit!(DailyBurnAggregated {
            date,
            total_burned: daily_stats.total_burned,
        });

        msg!("Daily burn aggregate recorded for date: {}", date);
        msg!("Total burned: {} lamports", daily_stats.total_burned);

        Ok(())
    }

    // Get burn statistics (view function)
    pub fn get_burn_stats(
        ctx: Context<GetBurnStats>,
    ) -> Result<BurnStatistics> {
        let burn_stats = &ctx.accounts.burn_stats;

        Ok(BurnStatistics {
            total_burned: burn_stats.total_burned,
            tip_burns: burn_stats.tip_burns,
            marketplace_burns: burn_stats.marketplace_burns,
            premium_burns: burn_stats.premium_burns,
            withdrawal_burns: burn_stats.withdrawal_burns,
            other_burns: burn_stats.other_burns,
            burn_count: burn_stats.burn_count,
            largest_single_burn: burn_stats.largest_single_burn,
            last_burn_timestamp: burn_stats.last_burn_timestamp,
        })
    }

    // Get circulating supply (total supply - burned)
    pub fn get_circulating_supply(
        ctx: Context<GetCirculatingSupply>,
        total_supply: u64,
    ) -> Result<u64> {
        let burn_stats = &ctx.accounts.burn_stats;

        let circulating = total_supply
            .checked_sub(burn_stats.total_burned)
            .unwrap();

        Ok(circulating)
    }

    // Get daily burn stats
    pub fn get_daily_stats(
        ctx: Context<GetDailyStats>,
    ) -> Result<DailyBurnStats> {
        let daily_stats = &ctx.accounts.daily_stats;

        Ok(DailyBurnStats {
            date: daily_stats.date,
            total_burned: daily_stats.total_burned,
            tip_burns: daily_stats.tip_burns,
            marketplace_burns: daily_stats.marketplace_burns,
            premium_burns: daily_stats.premium_burns,
            withdrawal_burns: daily_stats.withdrawal_burns,
            other_burns: daily_stats.other_burns,
        })
    }

    // Update authority
    pub fn update_authority(
        ctx: Context<UpdateAuthority>,
        new_authority: Pubkey,
    ) -> Result<()> {
        let burn_stats = &mut ctx.accounts.burn_stats;

        require!(
            ctx.accounts.authority.key() == burn_stats.authority,
            ErrorCode::Unauthorized
        );

        let old_authority = burn_stats.authority;
        burn_stats.authority = new_authority;

        msg!("Authority updated from {} to {}", old_authority, new_authority);

        Ok(())
    }

}

// ===== ACCOUNTS STRUCTS =====

#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(
init,
payer = authority,
space = 8 + BurnStats::INIT_SPACE,
seeds = [b"burn_stats"],
bump
)]
pub burn_stats: Account<'info, BurnStats>,

    #[account(mut)]
    pub authority: Signer<'info>,

    pub system_program: Program<'info, System>,

}

#[derive(Accounts)]
pub struct RecordBurn<'info> {
#[account(
mut,
seeds = [b"burn_stats"],
bump
)]
pub burn_stats: Account<'info, BurnStats>,

    #[account(
        constraint = authority.key() == burn_stats.authority @ ErrorCode::Unauthorized
    )]
    pub authority: Signer<'info>,

}

#[derive(Accounts)] #[instruction(date: i64)]
pub struct RecordDailyAggregate<'info> {
#[account(
seeds = [b"burn_stats"],
bump
)]
pub burn_stats: Account<'info, BurnStats>,

    #[account(
        init,
        payer = authority,
        space = 8 + DailyBurnStats::INIT_SPACE,
        seeds = [b"daily_stats", date.to_le_bytes().as_ref()],
        bump
    )]
    pub daily_stats: Account<'info, DailyBurnStats>,

    #[account(
        mut,
        constraint = authority.key() == burn_stats.authority @ ErrorCode::Unauthorized
    )]
    pub authority: Signer<'info>,

    pub system_program: Program<'info, System>,

}

#[derive(Accounts)]
pub struct GetBurnStats<'info> {
#[account(
seeds = [b"burn_stats"],
bump
)]
pub burn_stats: Account<'info, BurnStats>,
}

#[derive(Accounts)]
pub struct GetCirculatingSupply<'info> {
#[account(
seeds = [b"burn_stats"],
bump
)]
pub burn_stats: Account<'info, BurnStats>,
}

#[derive(Accounts)] #[instruction(date: i64)]
pub struct GetDailyStats<'info> {
#[account(
seeds = [b"daily_stats", date.to_le_bytes().as_ref()],
bump
)]
pub daily_stats: Account<'info, DailyBurnStats>,
}

#[derive(Accounts)]
pub struct UpdateAuthority<'info> {
#[account(
mut,
seeds = [b"burn_stats"],
bump
)]
pub burn_stats: Account<'info, BurnStats>,

    pub authority: Signer<'info>,

}

// ===== STATE =====

#[account] #[derive(InitSpace)]
pub struct BurnStats {
pub authority: Pubkey,
pub total_burned: u64,
pub tip_burns: u64,
pub marketplace_burns: u64,
pub premium_burns: u64,
pub withdrawal_burns: u64,
pub other_burns: u64,
pub burn_count: u64,
pub last_burn_timestamp: i64,
pub largest_single_burn: u64,
}

#[account] #[derive(InitSpace)]
pub struct DailyBurnStats {
pub date: i64,
pub total_burned: u64,
pub tip_burns: u64,
pub marketplace_burns: u64,
pub premium_burns: u64,
pub withdrawal_burns: u64,
pub other_burns: u64,
}

// ===== ENUMS =====

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq)]
pub enum BurnSource {
Tip,
Marketplace,
Premium,
Withdrawal,
Other,
}

// ===== RETURN TYPES =====

#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct BurnStatistics {
pub total_burned: u64,
pub tip_burns: u64,
pub marketplace_burns: u64,
pub premium_burns: u64,
pub withdrawal_burns: u64,
pub other_burns: u64,
pub burn_count: u64,
pub largest_single_burn: u64,
pub last_burn_timestamp: i64,
}

// ===== EVENTS =====

#[event]
pub struct BurnRecorded {
pub amount: u64,
pub source: BurnSource,
pub total_burned: u64,
pub burn_count: u64,
pub timestamp: i64,
}

#[event]
pub struct DailyBurnAggregated {
pub date: i64,
pub total_burned: u64,
}

// ===== ERRORS =====

#[error_code]
pub enum ErrorCode { #[msg("Invalid burn amount")]
InvalidAmount,

    #[msg("Unauthorized access")]
    Unauthorized,

}
fee.rs
use anchor_lang::prelude::*;
use anchor_spl::token::{self, Token, TokenAccount, Transfer, Burn, Mint};

declare_id!("EU361fP6SN2zhXzHHwUhZ9b6ozWa7V9aV2CguuP9WKoB");

#[program]
pub mod fee_collection {
    use super::*;

    // Initialize the fee collection program
    pub fn initialize(
        ctx: Context<Initialize>,
        platform_wallet: Pubkey,
    ) -> Result<()> {
        let fee_config = &mut ctx.accounts.fee_config;
        fee_config.authority = ctx.accounts.authority.key();
        fee_config.platform_wallet = platform_wallet;
        fee_config.vcoin_mint = ctx.accounts.vcoin_mint.key();
        fee_config.total_tips_processed = 0;
        fee_config.total_marketplace_sales = 0;
        fee_config.total_subscriptions = 0;
        fee_config.total_burned = 0;

        msg!("Fee Collection initialized");
        msg!("Platform wallet: {}", platform_wallet);
        msg!("VCoin mint: {}", ctx.accounts.vcoin_mint.key());

        Ok(())
    }

    // Process tip: 80% creator, 19% platform, 1% burn
    pub fn process_tip(
        ctx: Context<ProcessTip>,
        amount: u64,
    ) -> Result<()> {
        require!(amount > 0, ErrorCode::InvalidAmount);

        // Calculate splits
        let creator_amount = amount
            .checked_mul(80)
            .unwrap()
            .checked_div(100)
            .unwrap();

        let platform_amount = amount
            .checked_mul(19)
            .unwrap()
            .checked_div(100)
            .unwrap();

        let burn_amount = amount
            .checked_sub(creator_amount)
            .unwrap()
            .checked_sub(platform_amount)
            .unwrap();

        // Validate it adds up
        require!(
            creator_amount + platform_amount + burn_amount == amount,
            ErrorCode::InvalidSplit
        );

        // Transfer to creator (80%)
        token::transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.sender_token_account.to_account_info(),
                    to: ctx.accounts.creator_token_account.to_account_info(),
                    authority: ctx.accounts.sender.to_account_info(),
                },
            ),
            creator_amount,
        )?;

        // Transfer to platform (19%)
        token::transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.sender_token_account.to_account_info(),
                    to: ctx.accounts.platform_token_account.to_account_info(),
                    authority: ctx.accounts.sender.to_account_info(),
                },
            ),
            platform_amount,
        )?;

        // Burn (1%)
        token::burn(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Burn {
                    mint: ctx.accounts.vcoin_mint.to_account_info(),
                    from: ctx.accounts.sender_token_account.to_account_info(),
                    authority: ctx.accounts.sender.to_account_info(),
                },
            ),
            burn_amount,
        )?;

        // Update stats
        let fee_config = &mut ctx.accounts.fee_config;
        fee_config.total_tips_processed = fee_config
            .total_tips_processed
            .checked_add(1)
            .unwrap();
        fee_config.total_burned = fee_config
            .total_burned
            .checked_add(burn_amount)
            .unwrap();

        // Emit event
        emit!(TipProcessed {
            sender: ctx.accounts.sender.key(),
            creator: ctx.accounts.creator.key(),
            amount,
            creator_amount,
            platform_amount,
            burn_amount,
            timestamp: Clock::get()?.unix_timestamp,
        });

        msg!("Tip processed: {} VCoin", amount);
        msg!("Creator received: {} VCoin", creator_amount);
        msg!("Platform fee: {} VCoin", platform_amount);
        msg!("Burned: {} VCoin", burn_amount);

        Ok(())
    }

    // Process marketplace sale: 95% seller, 4% platform, 1% burn
    pub fn process_marketplace_sale(
        ctx: Context<ProcessMarketplaceSale>,
        amount: u64,
    ) -> Result<()> {
        require!(amount > 0, ErrorCode::InvalidAmount);

        // Calculate splits
        let seller_amount = amount
            .checked_mul(95)
            .unwrap()
            .checked_div(100)
            .unwrap();

        let platform_amount = amount
            .checked_mul(4)
            .unwrap()
            .checked_div(100)
            .unwrap();

        let burn_amount = amount
            .checked_sub(seller_amount)
            .unwrap()
            .checked_sub(platform_amount)
            .unwrap();

        require!(
            seller_amount + platform_amount + burn_amount == amount,
            ErrorCode::InvalidSplit
        );

        // Transfer to seller (95%)
        token::transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.buyer_token_account.to_account_info(),
                    to: ctx.accounts.seller_token_account.to_account_info(),
                    authority: ctx.accounts.buyer.to_account_info(),
                },
            ),
            seller_amount,
        )?;

        // Transfer to platform (4%)
        token::transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.buyer_token_account.to_account_info(),
                    to: ctx.accounts.platform_token_account.to_account_info(),
                    authority: ctx.accounts.buyer.to_account_info(),
                },
            ),
            platform_amount,
        )?;

        // Burn (1%)
        token::burn(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Burn {
                    mint: ctx.accounts.vcoin_mint.to_account_info(),
                    from: ctx.accounts.buyer_token_account.to_account_info(),
                    authority: ctx.accounts.buyer.to_account_info(),
                },
            ),
            burn_amount,
        )?;

        // Update stats
        let fee_config = &mut ctx.accounts.fee_config;
        fee_config.total_marketplace_sales = fee_config
            .total_marketplace_sales
            .checked_add(1)
            .unwrap();
        fee_config.total_burned = fee_config
            .total_burned
            .checked_add(burn_amount)
            .unwrap();

        emit!(MarketplaceSaleProcessed {
            buyer: ctx.accounts.buyer.key(),
            seller: ctx.accounts.seller.key(),
            amount,
            seller_amount,
            platform_amount,
            burn_amount,
            timestamp: Clock::get()?.unix_timestamp,
        });

        msg!("Marketplace sale processed: {} VCoin", amount);

        Ok(())
    }

    // Process subscription: 95% creator, 5% platform, no burn
    pub fn process_subscription(
        ctx: Context<ProcessSubscription>,
        amount: u64,
    ) -> Result<()> {
        require!(amount > 0, ErrorCode::InvalidAmount);

        // Calculate splits (no burn on subscriptions)
        let creator_amount = amount
            .checked_mul(95)
            .unwrap()
            .checked_div(100)
            .unwrap();

        let platform_amount = amount
            .checked_sub(creator_amount)
            .unwrap();

        require!(
            creator_amount + platform_amount == amount,
            ErrorCode::InvalidSplit
        );

        // Transfer to creator (95%)
        token::transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.subscriber_token_account.to_account_info(),
                    to: ctx.accounts.creator_token_account.to_account_info(),
                    authority: ctx.accounts.subscriber.to_account_info(),
                },
            ),
            creator_amount,
        )?;

        // Transfer to platform (5%)
        token::transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.subscriber_token_account.to_account_info(),
                    to: ctx.accounts.platform_token_account.to_account_info(),
                    authority: ctx.accounts.subscriber.to_account_info(),
                },
            ),
            platform_amount,
        )?;

        // Update stats
        let fee_config = &mut ctx.accounts.fee_config;
        fee_config.total_subscriptions = fee_config
            .total_subscriptions
            .checked_add(1)
            .unwrap();

        emit!(SubscriptionProcessed {
            subscriber: ctx.accounts.subscriber.key(),
            creator: ctx.accounts.creator.key(),
            amount,
            creator_amount,
            platform_amount,
            timestamp: Clock::get()?.unix_timestamp,
        });

        msg!("Subscription processed: {} VCoin", amount);

        Ok(())
    }

    // Process withdrawal: 98% user, 2% platform, no burn
    pub fn process_withdrawal(
        ctx: Context<ProcessWithdrawal>,
        amount: u64,
    ) -> Result<()> {
        require!(amount > 0, ErrorCode::InvalidAmount);

        // Calculate splits
        let user_amount = amount
            .checked_mul(98)
            .unwrap()
            .checked_div(100)
            .unwrap();

        let fee_amount = amount
            .checked_sub(user_amount)
            .unwrap();

        require!(
            user_amount + fee_amount == amount,
            ErrorCode::InvalidSplit
        );

        // Transfer to user external wallet (98%)
        token::transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.platform_token_account.to_account_info(),
                    to: ctx.accounts.user_external_account.to_account_info(),
                    authority: ctx.accounts.platform_authority.to_account_info(),
                },
            ),
            user_amount,
        )?;

        // Fee (2%) stays in platform wallet automatically

        emit!(WithdrawalProcessed {
            user: ctx.accounts.user.key(),
            amount,
            user_amount,
            fee_amount,
            timestamp: Clock::get()?.unix_timestamp,
        });

        msg!("Withdrawal processed: {} VCoin", amount);

        Ok(())
    }

    // Process premium feature payment: 70% platform, 30% burn
    pub fn process_premium_payment(
        ctx: Context<ProcessPremiumPayment>,
        amount: u64,
    ) -> Result<()> {
        require!(amount > 0, ErrorCode::InvalidAmount);

        // Calculate splits
        let platform_amount = amount
            .checked_mul(70)
            .unwrap()
            .checked_div(100)
            .unwrap();

        let burn_amount = amount
            .checked_sub(platform_amount)
            .unwrap();

        require!(
            platform_amount + burn_amount == amount,
            ErrorCode::InvalidSplit
        );

        // Transfer to platform (70%)
        token::transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.user_token_account.to_account_info(),
                    to: ctx.accounts.platform_token_account.to_account_info(),
                    authority: ctx.accounts.user.to_account_info(),
                },
            ),
            platform_amount,
        )?;

        // Burn (30%)
        token::burn(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Burn {
                    mint: ctx.accounts.vcoin_mint.to_account_info(),
                    from: ctx.accounts.user_token_account.to_account_info(),
                    authority: ctx.accounts.user.to_account_info(),
                },
            ),
            burn_amount,
        )?;

        // Update stats
        let fee_config = &mut ctx.accounts.fee_config;
        fee_config.total_burned = fee_config
            .total_burned
            .checked_add(burn_amount)
            .unwrap();

        emit!(PremiumPaymentProcessed {
            user: ctx.accounts.user.key(),
            amount,
            platform_amount,
            burn_amount,
            timestamp: Clock::get()?.unix_timestamp,
        });

        msg!("Premium payment processed: {} VCoin", amount);

        Ok(())
    }
}

// ===== ACCOUNTS STRUCTS =====

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = authority,
        space = 8 + FeeConfig::INIT_SPACE,
        seeds = [b"fee_config"],
        bump
    )]
    pub fee_config: Account<'info, FeeConfig>,

    pub vcoin_mint: Account<'info, Mint>,

    #[account(mut)]
    pub authority: Signer<'info>,

    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct ProcessTip<'info> {
    #[account(
        mut,
        seeds = [b"fee_config"],
        bump
    )]
    pub fee_config: Account<'info, FeeConfig>,

    #[account(mut)]
    pub sender: Signer<'info>,

    /// CHECK: Creator wallet
    pub creator: AccountInfo<'info>,

    #[account(
        mut,
        constraint = sender_token_account.mint == fee_config.vcoin_mint
    )]
    pub sender_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = creator_token_account.mint == fee_config.vcoin_mint
    )]
    pub creator_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = platform_token_account.mint == fee_config.vcoin_mint
    )]
    pub platform_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        address = fee_config.vcoin_mint
    )]
    pub vcoin_mint: Account<'info, Mint>,

    pub token_program: Program<'info, Token>,
}

#[derive(Accounts)]
pub struct ProcessMarketplaceSale<'info> {
    #[account(
        mut,
        seeds = [b"fee_config"],
        bump
    )]
    pub fee_config: Account<'info, FeeConfig>,

    #[account(mut)]
    pub buyer: Signer<'info>,

    /// CHECK: Seller wallet
    pub seller: AccountInfo<'info>,

    #[account(
        mut,
        constraint = buyer_token_account.mint == fee_config.vcoin_mint
    )]
    pub buyer_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = seller_token_account.mint == fee_config.vcoin_mint
    )]
    pub seller_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = platform_token_account.mint == fee_config.vcoin_mint
    )]
    pub platform_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        address = fee_config.vcoin_mint
    )]
    pub vcoin_mint: Account<'info, Mint>,

    pub token_program: Program<'info, Token>,
}

#[derive(Accounts)]
pub struct ProcessSubscription<'info> {
    #[account(
        mut,
        seeds = [b"fee_config"],
        bump
    )]
    pub fee_config: Account<'info, FeeConfig>,

    #[account(mut)]
    pub subscriber: Signer<'info>,

    /// CHECK: Creator wallet
    pub creator: AccountInfo<'info>,

    #[account(
        mut,
        constraint = subscriber_token_account.mint == fee_config.vcoin_mint
    )]
    pub subscriber_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = creator_token_account.mint == fee_config.vcoin_mint
    )]
    pub creator_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = platform_token_account.mint == fee_config.vcoin_mint
    )]
    pub platform_token_account: Account<'info, TokenAccount>,

    pub token_program: Program<'info, Token>,
}

#[derive(Accounts)]
pub struct ProcessWithdrawal<'info> {
    #[account(
        seeds = [b"fee_config"],
        bump
    )]
    pub fee_config: Account<'info, FeeConfig>,

    /// CHECK: User requesting withdrawal
    pub user: AccountInfo<'info>,

    #[account(
        mut,
        constraint = platform_authority.key() == fee_config.authority
    )]
    pub platform_authority: Signer<'info>,

    #[account(
        mut,
        constraint = platform_token_account.mint == fee_config.vcoin_mint
    )]
    pub platform_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = user_external_account.mint == fee_config.vcoin_mint
    )]
    pub user_external_account: Account<'info, TokenAccount>,

    pub token_program: Program<'info, Token>,
}

#[derive(Accounts)]
pub struct ProcessPremiumPayment<'info> {
    #[account(
        mut,
        seeds = [b"fee_config"],
        bump
    )]
    pub fee_config: Account<'info, FeeConfig>,

    #[account(mut)]
    pub user: Signer<'info>,

    #[account(
        mut,
        constraint = user_token_account.mint == fee_config.vcoin_mint
    )]
    pub user_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = platform_token_account.mint == fee_config.vcoin_mint
    )]
    pub platform_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        address = fee_config.vcoin_mint
    )]
    pub vcoin_mint: Account<'info, Mint>,

    pub token_program: Program<'info, Token>,
}

// ===== STATE =====

#[account]
#[derive(InitSpace)]
pub struct FeeConfig {
    pub authority: Pubkey,
    pub platform_wallet: Pubkey,
    pub vcoin_mint: Pubkey,
    pub total_tips_processed: u64,
    pub total_marketplace_sales: u64,
    pub total_subscriptions: u64,
    pub total_burned: u64,
}

// ===== EVENTS =====

#[event]
pub struct TipProcessed {
    pub sender: Pubkey,
    pub creator: Pubkey,
    pub amount: u64,
    pub creator_amount: u64,
    pub platform_amount: u64,
    pub burn_amount: u64,
    pub timestamp: i64,
}

#[event]
pub struct MarketplaceSaleProcessed {
    pub buyer: Pubkey,
    pub seller: Pubkey,
    pub amount: u64,
    pub seller_amount: u64,
    pub platform_amount: u64,
    pub burn_amount: u64,
    pub timestamp: i64,
}

#[event]
pub struct SubscriptionProcessed {
    pub subscriber: Pubkey,
    pub creator: Pubkey,
    pub amount: u64,
    pub creator_amount: u64,
    pub platform_amount: u64,
    pub timestamp: i64,
}

#[event]
pub struct WithdrawalProcessed {
    pub user: Pubkey,
    pub amount: u64,
    pub user_amount: u64,
    pub fee_amount: u64,
    pub timestamp: i64,
}

#[event]
pub struct PremiumPaymentProcessed {
    pub user: Pubkey,
    pub amount: u64,
    pub platform_amount: u64,
    pub burn_amount: u64,
    pub timestamp: i64,
}

// ===== ERRORS =====

#[error_code]
pub enum ErrorCode {
    #[msg("Amount must be greater than 0")]
    InvalidAmount,

    #[msg("Fee split calculation error")]
    InvalidSplit,
}
reward.rs
use anchor_lang::prelude::*;
use anchor_spl::token::{self, Token, TokenAccount, Transfer, Mint};

declare_id!("EqjS5FgEfoGe9wnrRkvWyKendb3fb3Aza6WuxCbmaxPz");

// Constants
const DAILY_REWARD_POOL: u64 = 1_095_890_000_000_000; // 1,095,890 VCoin with 9 decimals
const MAX_DAILY_REWARD_PER_USER: u64 = 10_000_000_000_000; // 10,000 VCoin with 9 decimals
const REWARD_EXPIRY_SECONDS: i64 = 30 _ 24 _ 60 \* 60; // 30 days

#[program]
pub mod reward_distribution {
use super::\*;

    // Initialize the reward distribution program
    pub fn initialize(
        ctx: Context<Initialize>,
        rewards_pool_wallet: Pubkey,
    ) -> Result<()> {
        let reward_config = &mut ctx.accounts.reward_config;
        reward_config.authority = ctx.accounts.authority.key();
        reward_config.rewards_pool_wallet = rewards_pool_wallet;
        reward_config.vcoin_mint = ctx.accounts.vcoin_mint.key();
        reward_config.total_rewards_distributed = 0;
        reward_config.total_users_rewarded = 0;
        reward_config.distribution_start_date = Clock::get()?.unix_timestamp;
        reward_config.daily_pool_remaining = DAILY_REWARD_POOL;
        reward_config.last_distribution_date = 0;

        msg!("Reward Distribution initialized");
        msg!("Rewards pool wallet: {}", rewards_pool_wallet);
        msg!("VCoin mint: {}", ctx.accounts.vcoin_mint.key());
        msg!("Daily reward pool: {} lamports", DAILY_REWARD_POOL);

        Ok(())
    }

    // Initialize user reward account
    pub fn initialize_user_account(
        ctx: Context<InitializeUserAccount>,
    ) -> Result<()> {
        let user_rewards = &mut ctx.accounts.user_rewards;
        user_rewards.user = ctx.accounts.user.key();
        user_rewards.pending_rewards = 0;
        user_rewards.total_claimed = 0;
        user_rewards.last_claim_date = 0;
        user_rewards.rewards_count = 0;

        msg!("User reward account initialized for: {}", ctx.accounts.user.key());

        Ok(())
    }

    // Record daily rewards for a user (called by backend)
    pub fn record_rewards(
        ctx: Context<RecordRewards>,
        engagement_score: u64,
        date: i64,
    ) -> Result<()> {
        require!(engagement_score > 0, ErrorCode::InvalidEngagementScore);

        let reward_config = &mut ctx.accounts.reward_config;
        let user_rewards = &mut ctx.accounts.user_rewards;

        // Check if we need to reset daily pool (new day)
        let current_date = date / 86400; // Convert to days
        let last_date = reward_config.last_distribution_date / 86400;

        if current_date > last_date {
            // New day - reset daily pool
            reward_config.daily_pool_remaining = DAILY_REWARD_POOL;
            reward_config.last_distribution_date = date;
            msg!("New day - daily pool reset to: {}", DAILY_REWARD_POOL);
        }

        // Calculate reward amount based on engagement score
        let reward_amount = engagement_score
            .checked_mul(1_000_000_000)
            .unwrap()
            .min(MAX_DAILY_REWARD_PER_USER);

        // Check if daily pool has enough
        require!(
            reward_amount <= reward_config.daily_pool_remaining,
            ErrorCode::DailyPoolExhausted
        );

        // Add to pending rewards
        user_rewards.pending_rewards = user_rewards
            .pending_rewards
            .checked_add(reward_amount)
            .unwrap();

        user_rewards.rewards_count = user_rewards
            .rewards_count
            .checked_add(1)
            .unwrap();

        // Update daily pool
        reward_config.daily_pool_remaining = reward_config
            .daily_pool_remaining
            .checked_sub(reward_amount)
            .unwrap();

        // Store expiry date (30 days from now)
        let expiry_date = date + REWARD_EXPIRY_SECONDS;

        emit!(RewardsRecorded {
            user: ctx.accounts.user.key(),
            amount: reward_amount,
            engagement_score,
            date,
            expiry_date,
        });

        msg!("Rewards recorded for user: {}", ctx.accounts.user.key());
        msg!("Amount: {} lamports", reward_amount);
        msg!("Expires at: {}", expiry_date);

        Ok(())
    }

    // Claim pending rewards
    pub fn claim_rewards(
        ctx: Context<ClaimRewards>,
    ) -> Result<()> {
        let user_rewards = &mut ctx.accounts.user_rewards;
        let reward_config = &mut ctx.accounts.reward_config;

        // Check user has pending rewards
        require!(
            user_rewards.pending_rewards > 0,
            ErrorCode::NoPendingRewards
        );

        let claim_amount = user_rewards.pending_rewards;

        // Transfer from rewards pool to user
        token::transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.rewards_pool_account.to_account_info(),
                    to: ctx.accounts.user_token_account.to_account_info(),
                    authority: ctx.accounts.rewards_pool_authority.to_account_info(),
                },
            ),
            claim_amount,
        )?;

        // Update user state
        user_rewards.total_claimed = user_rewards
            .total_claimed
            .checked_add(claim_amount)
            .unwrap();

        user_rewards.pending_rewards = 0;
        user_rewards.last_claim_date = Clock::get()?.unix_timestamp;

        // Update global stats
        reward_config.total_rewards_distributed = reward_config
            .total_rewards_distributed
            .checked_add(claim_amount)
            .unwrap();

        reward_config.total_users_rewarded = reward_config
            .total_users_rewarded
            .checked_add(1)
            .unwrap();

        emit!(RewardsClaimed {
            user: ctx.accounts.user.key(),
            amount: claim_amount,
            total_claimed: user_rewards.total_claimed,
            timestamp: Clock::get()?.unix_timestamp,
        });

        msg!("Rewards claimed by: {}", ctx.accounts.user.key());
        msg!("Amount: {} lamports", claim_amount);
        msg!("Total claimed: {} lamports", user_rewards.total_claimed);

        Ok(())
    }

    // Expire old unclaimed rewards (cleanup function)
    pub fn expire_rewards(
        ctx: Context<ExpireRewards>,
        expiry_date: i64,
    ) -> Result<()> {
        let current_time = Clock::get()?.unix_timestamp;

        require!(
            current_time > expiry_date,
            ErrorCode::RewardsNotExpired
        );

        let user_rewards = &mut ctx.accounts.user_rewards;
        let expired_amount = user_rewards.pending_rewards;

        // Reset pending rewards
        user_rewards.pending_rewards = 0;

        emit!(RewardsExpired {
            user: ctx.accounts.user.key(),
            amount: expired_amount,
            expiry_date,
            timestamp: current_time,
        });

        msg!("Expired rewards for user: {}", ctx.accounts.user.key());
        msg!("Amount expired: {} lamports", expired_amount);

        Ok(())
    }

    // Update authority (admin function)
    pub fn update_authority(
        ctx: Context<UpdateAuthority>,
        new_authority: Pubkey,
    ) -> Result<()> {
        let reward_config = &mut ctx.accounts.reward_config;

        require!(
            ctx.accounts.authority.key() == reward_config.authority,
            ErrorCode::Unauthorized
        );

        let old_authority = reward_config.authority;
        reward_config.authority = new_authority;

        msg!("Authority updated from {} to {}", old_authority, new_authority);

        Ok(())
    }

    // Get user pending rewards (view function)
    pub fn get_pending_rewards(
        ctx: Context<GetPendingRewards>,
    ) -> Result<u64> {
        Ok(ctx.accounts.user_rewards.pending_rewards)
    }

    // Get global stats (view function)
    pub fn get_stats(
        ctx: Context<GetStats>,
    ) -> Result<RewardStats> {
        let reward_config = &ctx.accounts.reward_config;

        Ok(RewardStats {
            total_distributed: reward_config.total_rewards_distributed,
            total_users: reward_config.total_users_rewarded,
            daily_pool_remaining: reward_config.daily_pool_remaining,
            distribution_start: reward_config.distribution_start_date,
        })
    }

}

// ===== ACCOUNTS STRUCTS =====

#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(
init,
payer = authority,
space = 8 + RewardConfig::INIT_SPACE,
seeds = [b"reward_config"],
bump
)]
pub reward_config: Account<'info, RewardConfig>,

    pub vcoin_mint: Account<'info, Mint>,

    #[account(mut)]
    pub authority: Signer<'info>,

    pub system_program: Program<'info, System>,

}

#[derive(Accounts)]
pub struct InitializeUserAccount<'info> {
#[account(
init,
payer = user,
space = 8 + UserRewards::INIT_SPACE,
seeds = [b"user_rewards", user.key().as_ref()],
bump
)]
pub user_rewards: Account<'info, UserRewards>,

    #[account(mut)]
    pub user: Signer<'info>,

    pub system_program: Program<'info, System>,

}

#[derive(Accounts)]
pub struct RecordRewards<'info> {
#[account(
mut,
seeds = [b"reward_config"],
bump
)]
pub reward_config: Account<'info, RewardConfig>,

    #[account(
        mut,
        seeds = [b"user_rewards", user.key().as_ref()],
        bump
    )]
    pub user_rewards: Account<'info, UserRewards>,

    /// CHECK: User receiving rewards
    pub user: AccountInfo<'info>,

    #[account(
        constraint = authority.key() == reward_config.authority @ ErrorCode::Unauthorized
    )]
    pub authority: Signer<'info>,

}

#[derive(Accounts)]
pub struct ClaimRewards<'info> {
#[account(
mut,
seeds = [b"reward_config"],
bump
)]
pub reward_config: Account<'info, RewardConfig>,

    #[account(
        mut,
        seeds = [b"user_rewards", user.key().as_ref()],
        bump
    )]
    pub user_rewards: Account<'info, UserRewards>,

    #[account(mut)]
    pub user: Signer<'info>,

    #[account(
        mut,
        constraint = rewards_pool_account.mint == reward_config.vcoin_mint
    )]
    pub rewards_pool_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = user_token_account.mint == reward_config.vcoin_mint,
        constraint = user_token_account.owner == user.key()
    )]
    pub user_token_account: Account<'info, TokenAccount>,

    /// CHECK: Rewards pool authority (platform wallet)
    pub rewards_pool_authority: Signer<'info>,

    pub token_program: Program<'info, Token>,

}

#[derive(Accounts)]
pub struct ExpireRewards<'info> {
#[account(
mut,
seeds = [b"user_rewards", user.key().as_ref()],
bump
)]
pub user_rewards: Account<'info, UserRewards>,

    /// CHECK: User whose rewards are expiring
    pub user: AccountInfo<'info>,

    #[account(
        seeds = [b"reward_config"],
        bump
    )]
    pub reward_config: Account<'info, RewardConfig>,

    #[account(
        constraint = authority.key() == reward_config.authority @ ErrorCode::Unauthorized
    )]
    pub authority: Signer<'info>,

}

#[derive(Accounts)]
pub struct UpdateAuthority<'info> {
#[account(
mut,
seeds = [b"reward_config"],
bump
)]
pub reward_config: Account<'info, RewardConfig>,

    pub authority: Signer<'info>,

}

#[derive(Accounts)]
pub struct GetPendingRewards<'info> {
#[account(
seeds = [b"user_rewards", user.key().as_ref()],
bump
)]
pub user_rewards: Account<'info, UserRewards>,

    /// CHECK: User querying rewards
    pub user: AccountInfo<'info>,

}

#[derive(Accounts)]
pub struct GetStats<'info> {
#[account(
seeds = [b"reward_config"],
bump
)]
pub reward_config: Account<'info, RewardConfig>,
}

// ===== STATE =====

#[account] #[derive(InitSpace)]
pub struct RewardConfig {
pub authority: Pubkey,
pub rewards_pool_wallet: Pubkey,
pub vcoin_mint: Pubkey,
pub total_rewards_distributed: u64,
pub total_users_rewarded: u64,
pub distribution_start_date: i64,
pub daily_pool_remaining: u64,
pub last_distribution_date: i64,
}

#[account] #[derive(InitSpace)]
pub struct UserRewards {
pub user: Pubkey,
pub pending_rewards: u64,
pub total_claimed: u64,
pub last_claim_date: i64,
pub rewards_count: u64,
}

// ===== RETURN TYPES =====

#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct RewardStats {
pub total_distributed: u64,
pub total_users: u64,
pub daily_pool_remaining: u64,
pub distribution_start: i64,
}

// ===== EVENTS =====

#[event]
pub struct RewardsRecorded {
pub user: Pubkey,
pub amount: u64,
pub engagement_score: u64,
pub date: i64,
pub expiry_date: i64,
}

#[event]
pub struct RewardsClaimed {
pub user: Pubkey,
pub amount: u64,
pub total_claimed: u64,
pub timestamp: i64,
}

#[event]
pub struct RewardsExpired {
pub user: Pubkey,
pub amount: u64,
pub expiry_date: i64,
pub timestamp: i64,
}

// ===== ERRORS =====

#[error_code]
pub enum ErrorCode { #[msg("Invalid engagement score")]
InvalidEngagementScore,

    #[msg("Daily reward pool exhausted")]
    DailyPoolExhausted,

    #[msg("No pending rewards to claim")]
    NoPendingRewards,

    #[msg("Rewards have not expired yet")]
    RewardsNotExpired,

    #[msg("Unauthorized access")]
    Unauthorized,

}
vesting.rs
use anchor_lang::prelude::*;
use anchor_spl::token::{self, Token, TokenAccount, Transfer, Mint};

declare_id!("GAEVrgug7i7zUAZss1s7od2bhFiAhv2e91zT2svX7nb3");

// Constants
const SECONDS_PER_DAY: i64 = 86400;
const DAYS_PER_MONTH: i64 = 30;

#[program]
pub mod vesting {
    use super::*;

    // Initialize vesting program
    pub fn initialize(
        ctx: Context<Initialize>,
    ) -> Result<()> {
        let vesting_config = &mut ctx.accounts.vesting_config;
        vesting_config.authority = ctx.accounts.authority.key();
        vesting_config.vcoin_mint = ctx.accounts.vcoin_mint.key();
        vesting_config.total_schedules_created = 0;
        vesting_config.total_vested_amount = 0;

        msg!("Vesting program initialized");
        msg!("Authority: {}", ctx.accounts.authority.key());

        Ok(())
    }

    // Create vesting schedule
    pub fn create_vesting_schedule(
        ctx: Context<CreateVestingSchedule>,
        total_amount: u64,
        cliff_months: u64,
        vesting_months: u64,
        release_frequency_days: u64,
    ) -> Result<()> {
        require!(total_amount > 0, ErrorCode::InvalidAmount);
        require!(vesting_months > 0, ErrorCode::InvalidVestingPeriod);
        require!(release_frequency_days > 0, ErrorCode::InvalidReleaseFrequency);

        let current_time = Clock::get()?.unix_timestamp;

        let vesting_schedule = &mut ctx.accounts.vesting_schedule;
        vesting_schedule.beneficiary = ctx.accounts.beneficiary.key();
        vesting_schedule.total_amount = total_amount;
        vesting_schedule.claimed_amount = 0;
        vesting_schedule.start_timestamp = current_time;

        // Calculate cliff timestamp
        vesting_schedule.cliff_timestamp = current_time +
            (cliff_months as i64 * DAYS_PER_MONTH * SECONDS_PER_DAY);

        // Calculate end timestamp
        vesting_schedule.end_timestamp = current_time +
            (vesting_months as i64 * DAYS_PER_MONTH * SECONDS_PER_DAY);

        vesting_schedule.release_frequency_seconds =
            release_frequency_days as i64 * SECONDS_PER_DAY;

        vesting_schedule.last_claim_timestamp = 0;
        vesting_schedule.is_revoked = false;

        // Transfer tokens to vesting account
        token::transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.source_token_account.to_account_info(),
                    to: ctx.accounts.vesting_token_account.to_account_info(),
                    authority: ctx.accounts.authority.to_account_info(),
                },
            ),
            total_amount,
        )?;

        // Update config
        let vesting_config = &mut ctx.accounts.vesting_config;
        vesting_config.total_schedules_created = vesting_config
            .total_schedules_created
            .checked_add(1)
            .unwrap();

        emit!(VestingScheduleCreated {
            beneficiary: ctx.accounts.beneficiary.key(),
            total_amount,
            cliff_months,
            vesting_months,
            start_timestamp: current_time,
            cliff_timestamp: vesting_schedule.cliff_timestamp,
            end_timestamp: vesting_schedule.end_timestamp,
        });

        msg!("Vesting schedule created for: {}", ctx.accounts.beneficiary.key());
        msg!("Total amount: {} lamports", total_amount);
        msg!("Cliff: {} months", cliff_months);
        msg!("Vesting period: {} months", vesting_months);

        Ok(())
    }

    // Claim vested tokens
    pub fn claim_vested_tokens(
        ctx: Context<ClaimVestedTokens>,
    ) -> Result<()> {
        let vesting_schedule = &mut ctx.accounts.vesting_schedule;
        let current_time = Clock::get()?.unix_timestamp;

        // Check schedule is not revoked
        require!(!vesting_schedule.is_revoked, ErrorCode::VestingRevoked);

        // Check cliff has passed
        require!(
            current_time >= vesting_schedule.cliff_timestamp,
            ErrorCode::CliffNotReached
        );

        // Calculate vested amount
        let vested_amount = calculate_vested_amount(
            vesting_schedule.total_amount,
            vesting_schedule.start_timestamp,
            vesting_schedule.end_timestamp,
            current_time,
        )?;

        // Calculate claimable amount (vested - already claimed)
        let claimable_amount = vested_amount
            .checked_sub(vesting_schedule.claimed_amount)
            .unwrap();

        require!(claimable_amount > 0, ErrorCode::NoTokensToCliam);

        // Transfer vested tokens to beneficiary
        let seeds = &[
            b"vesting_schedule",
            vesting_schedule.beneficiary.as_ref(),
            &[ctx.bumps.vesting_schedule],
        ];
        let signer = &[&seeds[..]];

        token::transfer(
            CpiContext::new_with_signer(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.vesting_token_account.to_account_info(),
                    to: ctx.accounts.beneficiary_token_account.to_account_info(),
                    authority: vesting_schedule.to_account_info(),
                },
                signer,
            ),
            claimable_amount,
        )?;

        // Update schedule
        vesting_schedule.claimed_amount = vesting_schedule
            .claimed_amount
            .checked_add(claimable_amount)
            .unwrap();

        vesting_schedule.last_claim_timestamp = current_time;

        // Update config
        let vesting_config = &mut ctx.accounts.vesting_config;
        vesting_config.total_vested_amount = vesting_config
            .total_vested_amount
            .checked_add(claimable_amount)
            .unwrap();

        emit!(TokensClaimed {
            beneficiary: ctx.accounts.beneficiary.key(),
            amount: claimable_amount,
            total_claimed: vesting_schedule.claimed_amount,
            timestamp: current_time,
        });

        msg!("Tokens claimed by: {}", ctx.accounts.beneficiary.key());
        msg!("Amount: {} lamports", claimable_amount);
        msg!("Total claimed: {} lamports", vesting_schedule.claimed_amount);

        Ok(())
    }

    // Get vested amount (view function)
    pub fn get_vested_amount(
        ctx: Context<GetVestedAmount>,
    ) -> Result<VestedInfo> {
        let vesting_schedule = &ctx.accounts.vesting_schedule;
        let current_time = Clock::get()?.unix_timestamp;

        // Check if cliff reached
        if current_time < vesting_schedule.cliff_timestamp {
            return Ok(VestedInfo {
                vested_amount: 0,
                claimable_amount: 0,
                claimed_amount: vesting_schedule.claimed_amount,
                total_amount: vesting_schedule.total_amount,
                cliff_reached: false,
            });
        }

        let vested_amount = calculate_vested_amount(
            vesting_schedule.total_amount,
            vesting_schedule.start_timestamp,
            vesting_schedule.end_timestamp,
            current_time,
        )?;

        let claimable_amount = vested_amount
            .checked_sub(vesting_schedule.claimed_amount)
            .unwrap();

        Ok(VestedInfo {
            vested_amount,
            claimable_amount,
            claimed_amount: vesting_schedule.claimed_amount,
            total_amount: vesting_schedule.total_amount,
            cliff_reached: true,
        })
    }

    // Revoke vesting (emergency function)
    pub fn revoke_vesting(
        ctx: Context<RevokeVesting>,
    ) -> Result<()> {
        let vesting_schedule = &mut ctx.accounts.vesting_schedule;

        require!(!vesting_schedule.is_revoked, ErrorCode::AlreadyRevoked);

        vesting_schedule.is_revoked = true;

        emit!(VestingRevoked {
            beneficiary: vesting_schedule.beneficiary,
            timestamp: Clock::get()?.unix_timestamp,
        });

        msg!("Vesting revoked for: {}", vesting_schedule.beneficiary);

        Ok(())
    }
}

// ===== HELPER FUNCTIONS =====

fn calculate_vested_amount(
    total_amount: u64,
    start_timestamp: i64,
    end_timestamp: i64,
    current_timestamp: i64,
) -> Result<u64> {
    // If vesting period ended, all tokens are vested
    if current_timestamp >= end_timestamp {
        return Ok(total_amount);
    }

    // Calculate elapsed time since start
    let elapsed = current_timestamp
        .checked_sub(start_timestamp)
        .unwrap() as u64;

    // Calculate total vesting duration
    let total_duration = end_timestamp
        .checked_sub(start_timestamp)
        .unwrap() as u64;

    // Calculate proportional vested amount
    let vested = (total_amount as u128)
        .checked_mul(elapsed as u128)
        .unwrap()
        .checked_div(total_duration as u128)
        .unwrap() as u64;

    Ok(vested)
}

// ===== ACCOUNTS STRUCTS =====

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = authority,
        space = 8 + VestingConfig::INIT_SPACE,
        seeds = [b"vesting_config"],
        bump
    )]
    pub vesting_config: Account<'info, VestingConfig>,

    pub vcoin_mint: Account<'info, Mint>,

    #[account(mut)]
    pub authority: Signer<'info>,

    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct CreateVestingSchedule<'info> {
    #[account(
        mut,
        seeds = [b"vesting_config"],
        bump
    )]
    pub vesting_config: Account<'info, VestingConfig>,

    #[account(
        init,
        payer = authority,
        space = 8 + VestingSchedule::INIT_SPACE,
        seeds = [b"vesting_schedule", beneficiary.key().as_ref()],
        bump
    )]
    pub vesting_schedule: Account<'info, VestingSchedule>,

    /// CHECK: Beneficiary of vesting
    pub beneficiary: AccountInfo<'info>,

    #[account(
        init,
        payer = authority,
        token::mint = vcoin_mint,
        token::authority = vesting_schedule,
        seeds = [b"vesting_token_account", beneficiary.key().as_ref()],
        bump
    )]
    pub vesting_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = source_token_account.mint == vesting_config.vcoin_mint
    )]
    pub source_token_account: Account<'info, TokenAccount>,

    pub vcoin_mint: Account<'info, Mint>,

    #[account(
        mut,
        constraint = authority.key() == vesting_config.authority @ ErrorCode::Unauthorized
    )]
    pub authority: Signer<'info>,

    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
    pub rent: Sysvar<'info, Rent>,
}

#[derive(Accounts)]
pub struct ClaimVestedTokens<'info> {
    #[account(
        mut,
        seeds = [b"vesting_config"],
        bump
    )]
    pub vesting_config: Account<'info, VestingConfig>,

    #[account(
        mut,
        seeds = [b"vesting_schedule", beneficiary.key().as_ref()],
        bump
    )]
    pub vesting_schedule: Account<'info, VestingSchedule>,

    #[account(
        mut,
        seeds = [b"vesting_token_account", beneficiary.key().as_ref()],
        bump
    )]
    pub vesting_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = beneficiary_token_account.owner == beneficiary.key(),
        constraint = beneficiary_token_account.mint == vesting_config.vcoin_mint
    )]
    pub beneficiary_token_account: Account<'info, TokenAccount>,

    #[account(
        mut,
        constraint = beneficiary.key() == vesting_schedule.beneficiary @ ErrorCode::Unauthorized
    )]
    pub beneficiary: Signer<'info>,

    pub token_program: Program<'info, Token>,
}

#[derive(Accounts)]
pub struct GetVestedAmount<'info> {
    #[account(
        seeds = [b"vesting_schedule", beneficiary.key().as_ref()],
        bump
    )]
    pub vesting_schedule: Account<'info, VestingSchedule>,

    /// CHECK: Beneficiary querying vested amount
    pub beneficiary: AccountInfo<'info>,
}

#[derive(Accounts)]
pub struct RevokeVesting<'info> {
    #[account(
        seeds = [b"vesting_config"],
        bump
    )]
    pub vesting_config: Account<'info, VestingConfig>,

    #[account(
        mut,
        seeds = [b"vesting_schedule", vesting_schedule.beneficiary.as_ref()],
        bump
    )]
    pub vesting_schedule: Account<'info, VestingSchedule>,

    #[account(
        constraint = authority.key() == vesting_config.authority @ ErrorCode::Unauthorized
    )]
    pub authority: Signer<'info>,
}

// ===== STATE =====

#[account]
#[derive(InitSpace)]
pub struct VestingConfig {
    pub authority: Pubkey,
    pub vcoin_mint: Pubkey,
    pub total_schedules_created: u64,
    pub total_vested_amount: u64,
}

#[account]
#[derive(InitSpace)]
pub struct VestingSchedule {
    pub beneficiary: Pubkey,
    pub total_amount: u64,
    pub claimed_amount: u64,
    pub start_timestamp: i64,
    pub cliff_timestamp: i64,
    pub end_timestamp: i64,
    pub release_frequency_seconds: i64,
    pub last_claim_timestamp: i64,
    pub is_revoked: bool,
}

// ===== RETURN TYPES =====

#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct VestedInfo {
    pub vested_amount: u64,
    pub claimable_amount: u64,
    pub claimed_amount: u64,
    pub total_amount: u64,
    pub cliff_reached: bool,
}

// ===== EVENTS =====

#[event]
pub struct VestingScheduleCreated {
    pub beneficiary: Pubkey,
    pub total_amount: u64,
    pub cliff_months: u64,
    pub vesting_months: u64,
    pub start_timestamp: i64,
    pub cliff_timestamp: i64,
    pub end_timestamp: i64,
}

#[event]
pub struct TokensClaimed {
    pub beneficiary: Pubkey,
    pub amount: u64,
    pub total_claimed: u64,
    pub timestamp: i64,
}

#[event]
pub struct VestingRevoked {
    pub beneficiary: Pubkey,
    pub timestamp: i64,
}

// ===== ERRORS =====

#[error_code]
pub enum ErrorCode {
    #[msg("Invalid amount")]
    InvalidAmount,

    #[msg("Invalid vesting period")]
    InvalidVestingPeriod,

    #[msg("Invalid release frequency")]
    InvalidReleaseFrequency,

    #[msg("Cliff period not reached")]
    CliffNotReached,

    #[msg("No tokens available to claim")]
    NoTokensToCliam,

    #[msg("Vesting has been revoked")]
    VestingRevoked,

    #[msg("Vesting already revoked")]
    AlreadyRevoked,

    #[msg("Unauthorized access")]
    Unauthorized,
}

All smart contract source code is deployed on Solana devnet and can be independently verified against the program IDs listed above. The code uses the Anchor framework and includes comprehensive error handling, access control, and event emission for transparency.

VCoin Token Contract

Token Technical Specifications

Blockchain
Solana Mainnet (TBD)
Standard
SPL Token-2022
Name
VCoin
Symbol
VYC
Decimals
9
Total Supply
10,000,000,000

Key Features

🔒
Mint Authority: DISABLED
No more minting possible
Freeze Authority: DISABLED
Tokens can't be frozen
Transfer Hooks: ENABLED
Automated fee collection
📝
Metadata: On-chain
Name, symbol, logo stored
🔥
Burn Mechanism: Built-in
Deflationary by design

Security Properties

Audited before mainnet
Open source (public verification)
Immutable supply
No admin backdoors

The core VCoin token implements the SPL Token-2022 standard with specific configurations optimized for platform use. The total supply mints exactly once during initial deployment to the platform's treasury wallet, after which the mint authority disables permanently. This makes the 10 billion token supply absolutely fixed with no possibility of inflation through additional minting.

Transfer hooks enable automated fee collection for certain transaction types. When users tip creators or make marketplace purchases, the hook automatically splits the transaction according to configured percentages—for example, routing 80% to the creator and 20% to platform fees on tips. The burn mechanism also operates through transfer hooks, automatically routing specified percentages to a dead address during qualifying transactions. These hooks eliminate the need for complex middleware or manual transaction processing, making the token "smart" in its ability to self-execute platform economic rules.

Metadata extensions store rich information about VCoin directly on-chain including the token name, symbol, logo URI pointing to decentralized storage, and links to this whitepaper and other documentation. This metadata displays automatically in wallets, exchanges, and blockchain explorers without requiring manual updates or centralized registries.

The token contract undergoes professional security audit before mainnet deployment. All critical and high severity findings must be resolved before launch, with audit reports published publicly for community review. A bug bounty program launches simultaneously with mainnet deployment, offering rewards up to $50,000 for critical vulnerabilities, incentivizing white-hat hackers to responsibly disclose issues rather than exploit them.

Custodial Wallet System

🔐 How Your VCoins Are Secured

🔥 Hot Wallets (Daily Use)

Hold10-20% of balances
SecurityHSM, multi-factor auth
Purpose
Process withdrawals quickly
Risk
Limited exposure if breached

❄️ Cold Storage (Bulk Reserves)

Hold80-90% of balances
SecurityMulti-sig (3-of-5)
Location
Air-gapped, geographically distributed
Risk
Nearly impossible to breach

Daily Sweep Process

1.Hot wallet fills up during day
2.Automated sweep to cold storage
3.Keeps hot wallet exposure minimal
Maximizes security

Your Balance

Tracked in database (instant updates)
Backed by real tokens on blockchain
Daily reconciliation verifies accuracy
Best of both worlds

For optimal user experience, the platform maintains custodial control over user VCoins by default, similar to how Coinbase or other exchanges hold crypto on behalf of users. This enables instant transactions without blockchain confirmation delays, eliminates gas fees for in-app transfers, and removes the complexity of wallet management for non-technical users.

The architecture segregates hot wallets for daily operations from cold storage for bulk reserves. Hot wallets hold approximately 10-20% of total user balances—enough to process daily withdrawal requests and transactions but not so much that a breach would be catastrophic. These hot wallets deploy on hardened servers with Hardware Security Modules (HSMs), multi-factor authentication, IP whitelisting, transaction rate limiting, and comprehensive logging of all operations.

Cold storage holds the remaining 80-90% of reserves in multi-signature wallets requiring 3-of-5 signatures from geographically distributed keyholders. Cold wallet private keys never touch internet-connected computers, residing exclusively on air-gapped hardware wallets. Scheduled sweeps transfer excess funds from hot wallets to cold storage daily, minimizing hot wallet exposure. Cold-to-hot transfers require manual approval from multiple team members with justification logged.

Individual user balances track in the platform's centralized database with redundant backups and point-in-time recovery capabilities. Daily reconciliation processes verify database balances match blockchain holdings exactly. Any discrepancies trigger immediate investigation and resolution. This hybrid approach provides the performance and user experience of centralized systems while maintaining the security and transparency of blockchain backing.

Liquidity Manager Contract

A dedicated smart contract manages the accumulation and deployment of the 20% revenue allocation for liquidity. This contract operates autonomously once deployed, executing without human intervention according to programmed rules.

The receiveSalesRevenue() function triggers automatically whenever a user purchases VCoins with fiat currency. It receives exactly 20% of the transaction amount in USDC, records the contribution on-chain with timestamp and amount, and emits an event visible to block explorers. Anyone can query the contract to verify the current accumulated balance and historical contribution timeline.

The batchAddLiquidity() function monitors the accumulated balance and automatically adds to the Raydium pool whenever the threshold ($5,000 by default) is met. It transfers the accumulated USDC, calculates the matching number of VCoins needed based on current pool ratio, withdraws those VCoins from the Liquidity Reserve treasury, and executes the Raydium pool addition transaction. The entire process completes atomically—either all steps succeed or all revert, preventing partial executions that could create inconsistencies.

The getReserveProof() function provides cryptographic proof of reserves, showing that claimed backing matches actual holdings. Users can independently verify that the liquidity pool contains the stated amounts of USDC and VCoins, building trust through transparency rather than requiring faith in platform statements.

An emergencyPause() function enables authorized administrators to temporarily halt all liquidity operations if exploitation or severe bugs are detected. This pause requires multi-signature authorization from 3-of-5 designated key holders, preventing unilateral control while enabling rapid response to crises. The pause automatically expires after 7 days unless renewed through another multi-signature transaction, ensuring temporary pauses cannot become permanent without ongoing consensus.

Parameter updates like changing the $5,000 addition threshold implement through time-locked transactions with a 48-hour delay between submission and execution. This gives the community time to review proposed changes and raise concerns before they take effect. All parameter update proposals publish publicly with rationale, allowing community oversight of contract management.

Vesting Contracts

Team and operations token allocations deploy through battle-tested vesting contracts that enforce the four-year release schedule with six-month cliff. Each beneficiary (founder, team member, advisor) receives a dedicated contract instance deployed at launch containing their allocation.

The contracts implement the standard cliff-and-linear-vesting pattern: zero tokens unlock during the first six months, then one-fourteenth of the total allocation unlocks every quarter for the subsequent 42 months. Beneficiaries can claim unlocked tokens at any time after they vest, or leave them in the contract for security. Unclaimed vested tokens remain in the contract and do not disappear or transfer elsewhere, ensuring beneficiaries never lose access to rightfully vested holdings.

Importantly, these vesting contracts cannot be modified, canceled, or overridden after deployment. The schedule is immutable code on the blockchain, giving the community certainty that the stated vesting timeline will execute exactly as described regardless of team members' wishes or changing circumstances. This immutability builds trust that founders cannot simply give themselves early access to tokens if market conditions become favorable.

Each vesting contract emits events when tokens vest and when beneficiaries claim them, creating a public audit trail. Block explorers and monitoring tools can track exactly when each vesting milestone occurs and whether beneficiaries are claiming and selling tokens. This transparency allows the community to observe founder behavior and adjust their own strategies accordingly.

Security Model and Risk Mitigation

The smart contract architecture implements defense-in-depth with multiple overlapping security controls. Access controls restrict sensitive functions to specific authorized addresses with no single address having complete control. Time locks delay high-impact actions like parameter changes or liquidity withdrawals, enabling community review before execution. Rate limiting prevents rapid-fire transactions that might indicate exploitation attempts. Circuit breakers automatically pause operations if unusual activity is detected—for example, if more than 10% of TVL attempts to withdraw in a single hour.

Formal verification proves critical contract properties mathematically, ensuring specific behaviors are impossible regardless of how functions are called or what parameters are provided. For example, formal verification can prove that the total supply can never exceed 10 billion tokens, that vesting schedules cannot release tokens early, and that fee calculations always sum correctly.

The multi-signature model applies not just to cold storage wallets but to smart contract governance, requiring consensus among multiple keyholders before executing sensitive operations. The 3-of-5 threshold balances security against operational flexibility—three signatures is harder to compromise than single-signature but doesn't require all five keyholders to be available, preventing deadlock if one or two become unavailable.

Insurance coverage for smart contract exploits and custodial breaches is explored as the platform scales. While crypto insurance remains expensive and limited, options like Nexus Mutual, Bridge Mutual, or traditional crypto custody insurance can provide some protection against catastrophic losses. Once platform reserves exceed $1 million, allocating $100,000+ annually for insurance becomes economically rational.

Regular security reviews occur quarterly even after launch, as new vulnerabilities and attack vectors continuously emerge. Keeping security practices current requires ongoing investment rather than one-time audits. The bug bounty program remains active indefinitely with rewards scaling as TVL increases, maintaining incentives for responsible disclosure.