Technical Specification: Kings Card NFT Rewards Smart Contract

1. Contract Overview

1.1 Purpose

The Kings Card NFT Rewards Smart Contract monitors $PEASANT token purchases and distributes gamified NFT rewards to incentivize community participation and token holding. The contract implements a sophisticated lottery system with three distinct card types, each offering different redemption mechanisms and reward structures.

1.2 Contract Architecture

The system consists of two interconnected smart contracts:

  • Roundtable DAO Contract: Manages governance, treasury, and escrow functions
  • Kings Card NFT Contract: Handles purchase monitoring, NFT distribution, and reward mechanics

2. Core Data Structures

2.1 Purchase Tracking

#[account]
pub struct Purchase {
    pub buyer: Pubkey,                    // Wallet address of buyer
    pub amount_usd: u64,                  // Purchase amount in USDT cents
    pub token_amount: u64,                // Amount of $PEASANT tokens purchased  
    pub timestamp: i64,                   // Unix timestamp of purchase
    pub block_number: u64,                // Block number for ordering
    pub processed: bool,                  // Whether purchase was processed for rewards
}

#[account]
pub struct PurchaseBlock {
    pub block_id: u64,                    // Sequential block identifier (1, 2, 3...)
    pub start_purchase: u64,              // First purchase number in block
    pub end_purchase: u64,                // Last purchase number in block  
    pub entries: Vec<BlockEntry>,         // All entries in this block
    pub processed_auto: bool,             // Auto-redeem cards distributed
    pub processed_flexible: bool,         // Flexible cards distributed
    pub total_entries: u32,               // Total lottery entries in block
}

#[account]
pub struct BlockEntry {
    pub wallet: Pubkey,                   // Wallet address
    pub entry_count: u8,                  // Number of entries (1-12 max per day)
    pub purchase_amounts: Vec<u64>,       // Amounts for each entry
    pub token_amounts: Vec<u64>,          // Token amounts for each entry
}

2.2 NFT Card Structures

#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)]
pub enum CardType {
    AutoRedeem {
        auto_redeem_time: i64,            // Unix timestamp for automatic redemption
    },
    Flexible {
        min_hold_period: i64,             // Minimum hold time in seconds
        full_value_period: i64,           // Full value window in seconds
        max_hold_deadline: i64,           // Deadline before forced redemption
    },
    Legendary {
        expiry_date: i64,                 // Expiry timestamp
        decay_start: i64,                 // When daily decay begins
    },
}

#[account]
pub struct KingsCard {
    pub card_id: u64,                     // Unique card identifier
    pub card_type: CardType,              // Card type with specific parameters
    pub reward_token_amount: u64,         // Amount of $PEASANT tokens as reward
    pub reward_usd_cap: u64,             // USD value cap at time of issuance
    pub mint_time: i64,                   // When card was minted
    pub owner: Pubkey,                    // Current owner wallet
    pub original_purchase_amount: u64,    // Original purchase that won this card
    pub is_redeemed: bool,               // Redemption status
    pub redemption_time: Option<i64>,     // When card was redeemed (if applicable)
}

2.3 System State Management

#[account]
pub struct ContractState {
    pub total_purchases: u64,             // Total purchases processed
    pub current_block: u64,               // Current purchase block number
    pub legendary_milestone: u64,         // Next legendary card milestone
    
    // Card circulation tracking
    pub auto_cards_in_circulation: u16,   // Current auto-redeem cards (max 400)
    pub flexible_cards_in_circulation: u16, // Current flexible cards (max 200)
    pub legendary_cards_in_circulation: u8, // Current legendary cards (max 5)
    
    // Recycling queues
    pub auto_card_recycle_queue: Vec<RecycleEntry>,
    pub flexible_card_recycle_queue: Vec<RecycleEntry>,
    pub legendary_card_recycle_queue: Vec<RecycleEntry>,
    
    pub authority: Pubkey,                // Contract authority
    pub escrow_account: Pubkey,           // Token escrow account
    pub treasury_account: Pubkey,         // Tax collection account
}

#[account]
pub struct RecycleEntry {
    pub card_id: u64,                     // Card that was redeemed
    pub recycle_time: i64,                // When card becomes available (24h delay)
}

#[account] 
pub struct WalletLimits {
    pub wallet: Pubkey,                   // Wallet address
    pub daily_entries: u8,                // Entries used today (max 12)
    pub last_reset: i64,                  // Last daily reset timestamp
    pub hourly_purchases: Vec<HourlyPurchase>, // Purchases in current hour
}

#[account]
pub struct HourlyPurchase {
    pub timestamp: i64,                   // Purchase timestamp
    pub usd_amount: u64,                  // Purchase amount in USDT cents
    pub counted: bool,                    // Whether this purchase counted toward limits
}

3. Core Algorithm Specifications

3.1 Purchase Processing Algorithm

pub fn process_purchase(
    ctx: Context<ProcessPurchase>, 
    usd_amount: u64,               // Purchase amount in USDT cents
    token_amount: u64,             // Actual $PEASANT tokens purchased
    price_feed_data: PriceFeedData // Oracle price data for verification
) -> Result<()> {
    
    // Step 1: Validate purchase meets minimum threshold ($10 USD)
    require!(usd_amount >= 1000, ErrorCode::PurchaseTooSmall); // $10.00 in cents
    
    // Step 2: Apply anti-gaming limits
    let wallet_limits = &mut ctx.accounts.wallet_limits;
    let current_time = Clock::get()?.unix_timestamp;
    
    // Reset daily counter if 24h passed
    if current_time >= wallet_limits.last_reset + 86400 {
        wallet_limits.daily_entries = 0;
        wallet_limits.hourly_purchases.clear();
        wallet_limits.last_reset = current_time;
    }
    
    // Remove purchases older than 1 hour
    wallet_limits.hourly_purchases.retain(|p| current_time - p.timestamp < 3600);
    
    // Add current purchase
    wallet_limits.hourly_purchases.push(HourlyPurchase {
        timestamp: current_time,
        usd_amount,
        counted: false,
    });
    
    // Apply hourly limit (max 2 purchases per hour)
    let mut counted_this_hour = 0;
    let mut eligible_purchases = Vec::new();
    
    // Sort by amount (ascending) to count smallest first
    wallet_limits.hourly_purchases.sort_by_key(|p| p.usd_amount);
    
    for purchase in &mut wallet_limits.hourly_purchases {
        if counted_this_hour < 2 && !purchase.counted {
            purchase.counted = true;
            eligible_purchases.push(purchase.usd_amount);
            counted_this_hour += 1;
        }
    }
    
    // Calculate total eligible amount and entries
    let total_eligible_amount: u64 = eligible_purchases.iter().sum();
    let entries = std::cmp::min(
        total_eligible_amount / 100000, // Each $1000 = 1 entry (100000 cents)
        12 - wallet_limits.daily_entries as u64 // Respect daily limit
    ) as u8;
    
    require!(entries > 0, ErrorCode::NoEligibleEntries);
    
    // Update daily entry count
    wallet_limits.daily_entries += entries;
    
    // Step 3: Record purchase and add to current block
    let state = &mut ctx.accounts.contract_state;
    state.total_purchases += 1;
    
    let current_block_num = ((state.total_purchases - 1) / 100) + 1;
    if current_block_num > state.current_block {
        state.current_block = current_block_num;
        // Initialize new block if needed
    }
    
    // Step 4: Add entries to current block
    add_entries_to_block(ctx, entries, usd_amount, token_amount)?;
    
    // Step 5: Check if block is complete (100 purchases)
    if state.total_purchases % 100 == 0 {
        process_block_lottery(ctx, current_block_num)?;
    }
    
    // Step 6: Check legendary milestone (every 1000 purchases)
    if state.total_purchases % 1000 == 0 {
        process_legendary_milestone(ctx)?;
    }
    
    Ok(())
}

3.2 Block Lottery Processing

pub fn process_block_lottery(
    ctx: Context<ProcessBlockLottery>,
    block_number: u64,
) -> Result<()> {
    let state = &mut ctx.accounts.contract_state;
    let block = &mut ctx.accounts.purchase_block;
    
    // Step 1: Check available card slots
    let auto_slots_available = 400 - state.auto_cards_in_circulation;
    let flexible_slots_available = 200 - state.flexible_cards_in_circulation;
    
    let auto_cards_to_award = std::cmp::min(4, auto_slots_available);
    let flexible_cards_to_award = std::cmp::min(2, flexible_slots_available);
    
    // Step 2: Process recycled cards (24h delay)
    process_card_recycling(ctx)?;
    
    // Step 3: Generate random selections
    let vrf_data = &ctx.accounts.vrf_account.load()?;
    let random_seed = vrf_data.get_result()?;
    
    // Step 4: Award Auto-Redeem cards
    if auto_cards_to_award > 0 {
        let winners = select_random_entries(
            &block.entries, 
            auto_cards_to_award as usize,
            random_seed,
            0  // Salt for auto cards
        );
        
        for (winner_idx, entry_idx) in winners {
            mint_auto_redeem_card(
                ctx,
                &block.entries[winner_idx],
                entry_idx,
                generate_auto_redeem_params(random_seed, winner_idx)?,
            )?;
        }
        
        state.auto_cards_in_circulation += auto_cards_to_award;
        block.processed_auto = true;
    }
    
    // Step 5: Award Flexible cards
    if flexible_cards_to_award > 0 {
        let winners = select_random_entries(
            &block.entries,
            flexible_cards_to_award as usize, 
            random_seed,
            1  // Salt for flexible cards
        );
        
        for (winner_idx, entry_idx) in winners {
            mint_flexible_card(
                ctx,
                &block.entries[winner_idx],
                entry_idx,
                generate_flexible_params(random_seed, winner_idx)?,
            )?;
        }
        
        state.flexible_cards_in_circulation += flexible_cards_to_award;
        block.processed_flexible = true;
    }
    
    Ok(())
}

3.3 Random Selection Algorithm

fn select_random_entries(
    entries: &[BlockEntry],
    count: usize,
    random_seed: [u8; 32],
    salt: u8,
) -> Result<Vec<(usize, usize)>> {
    // Create weighted entry pool
    let mut entry_pool = Vec::new();
    
    for (entry_idx, entry) in entries.iter().enumerate() {
        for sub_entry_idx in 0..entry.entry_count {
            entry_pool.push((entry_idx, sub_entry_idx as usize));
        }
    }
    
    require!(entry_pool.len() > 0, ErrorCode::NoEntriesAvailable);
    
    // Fisher-Yates shuffle with seeded random
    let mut rng = create_seeded_rng(random_seed, salt);
    let mut winners = Vec::new();
    
    for _ in 0..std::cmp::min(count, entry_pool.len()) {
        let idx = rng.next_u32() as usize % entry_pool.len();
        winners.push(entry_pool.swap_remove(idx));
    }
    
    Ok(winners)
}

fn create_seeded_rng(seed: [u8; 32], salt: u8) -> ChaCha20Rng {
    let mut final_seed = seed;
    final_seed[0] ^= salt;  // XOR salt into seed
    ChaCha20Rng::from_seed(final_seed)
}

3.4 Card Generation Parameters

fn generate_auto_redeem_params(
    random_seed: [u8; 32],
    winner_idx: usize,
) -> Result<(i64, u8)> {
    let mut rng = create_seeded_rng(random_seed, (winner_idx as u8) ^ 0xAA);
    
    // Random auto-redeem time: 4-10 days
    let days = 4 + (rng.next_u32() % 7); // 4-10 days
    let auto_redeem_time = Clock::get()?.unix_timestamp + (days as i64 * 86400);
    
    // Random reward percentage: 1-5%
    let reward_percent = 1 + (rng.next_u32() % 5) as u8; // 1-5%
    
    Ok((auto_redeem_time, reward_percent))
}

fn generate_flexible_params(
    random_seed: [u8; 32],
    winner_idx: usize,
) -> Result<(i64, i64, i64, u8)> {
    let mut rng = create_seeded_rng(random_seed, (winner_idx as u8) ^ 0xBB);
    let current_time = Clock::get()?.unix_timestamp;
    
    // Random hold period: 4 days to 3 weeks
    let min_days = 4;
    let max_days = 21;
    let hold_days = min_days + (rng.next_u32() % (max_days - min_days + 1));
    let full_value_period = hold_days as i64 * 86400;
    
    // Forced redemption deadline: 1 week after full value period
    let max_hold_deadline = current_time + full_value_period + (7 * 86400);
    
    // Random reward percentage: 1-5%
    let reward_percent = 1 + (rng.next_u32() % 5) as u8;
    
    Ok((
        4 * 86400,              // min_hold_period (4 days)
        full_value_period,      // full_value_period  
        max_hold_deadline,      // max_hold_deadline
        reward_percent,         // reward_percent
    ))
}

fn generate_legendary_params(
    random_seed: [u8; 32],
    winner_idx: usize,
) -> Result<(i64, u8)> {
    let mut rng = create_seeded_rng(random_seed, (winner_idx as u8) ^ 0xCC);
    let current_time = Clock::get()?.unix_timestamp;
    
    // Random expiry: 4 weeks to 6 months
    let min_weeks = 4;
    let max_weeks = 26; // ~6 months
    let expiry_weeks = min_weeks + (rng.next_u32() % (max_weeks - min_weeks + 1));
    let expiry_date = current_time + (expiry_weeks as i64 * 7 * 86400);
    
    // Random reward percentage: 1-5%
    let reward_percent = 1 + (rng.next_u32() % 5) as u8;
    
    Ok((expiry_date, reward_percent))
}

4. NFT Minting and Management

4.1 NFT Minting Functions

The contract includes specialized minting functions for each card type, calculating rewards based on purchase amounts and applying the $1000 USD cap:

pub fn mint_auto_redeem_card(
    ctx: Context<MintCard>,
    winning_entry: &BlockEntry,
    entry_idx: usize,
    params: (i64, u8), // (auto_redeem_time, reward_percent)
) -> Result<()> {
    let (auto_redeem_time, reward_percent) = params;
    
    // Calculate reward amount
    let purchase_amount = winning_entry.purchase_amounts[entry_idx];
    let token_amount = winning_entry.token_amounts[entry_idx];
    let base_reward = (token_amount as u128 * reward_percent as u128) / 100;
    
    // Apply $1000 USD cap
    let usd_cap = 100000; // $1000.00 in cents
    let reward_token_amount = if purchase_amount > usd_cap {
        // Cap reward at $1000 worth of tokens
        calculate_tokens_for_usd(usd_cap, ctx.accounts.price_feed)?
    } else {
        base_reward as u64
    };
    
    // Create card
    let card = &mut ctx.accounts.kings_card;
    card.card_id = generate_card_id()?;
    card.card_type = CardType::AutoRedeem { auto_redeem_time };
    card.reward_token_amount = reward_token_amount;
    card.reward_usd_cap = usd_cap;
    card.mint_time = Clock::get()?.unix_timestamp;
    card.owner = winning_entry.wallet;
    card.original_purchase_amount = purchase_amount;
    card.is_redeemed = false;
    
    // Mint NFT using Metaplex
    mint_nft_metadata(ctx, &format!("Auto-Redeem Kings Card #{}", card.card_id))?;
    
    emit!(CardMinted {
        card_id: card.card_id,
        card_type: "AutoRedeem".to_string(),
        owner: card.owner,
        reward_amount: reward_token_amount,
    });
    
    Ok(())
}

4.2 Redemption Logic

Each card type has specific redemption rules with timing constraints, pro-rating mechanisms, and automatic tax collection:

pub fn redeem_auto_card(ctx: Context<RedeemCard>) -> Result<()> {
    let card = &mut ctx.accounts.kings_card;
    let current_time = Clock::get()?.unix_timestamp;
    
    match &card.card_type {
        CardType::AutoRedeem { auto_redeem_time } => {
            require!(
                current_time >= *auto_redeem_time,
                ErrorCode::AutoRedeemNotReady
            );
        },
        _ => return Err(ErrorCode::WrongCardType.into()),
    }
    
    // Calculate current token value and tax
    let current_token_price = get_current_token_price(ctx.accounts.price_feed)?;
    let reward_value_usd = (card.reward_token_amount as u128 * current_token_price as u128) / 1e9 as u128;
    
    // Apply 5% tax
    let tax_amount = (card.reward_token_amount as u128 * 5) / 100;
    let user_reward = card.reward_token_amount - tax_amount as u64;
    
    // Transfer tokens to user
    transfer_tokens(
        ctx.accounts.escrow_account.to_account_info(),
        ctx.accounts.user_token_account.to_account_info(),
        user_reward,
    )?;
    
    // Transfer tax to treasury
    transfer_tokens(
        ctx.accounts.escrow_account.to_account_info(), 
        ctx.accounts.treasury_account.to_account_info(),
        tax_amount as u64,
    )?;
    
    // Mark as redeemed and schedule for recycling
    card.is_redeemed = true;
    card.redemption_time = Some(current_time);
    
    schedule_card_recycling(ctx, card.card_id, current_time + 86400)?; // 24h delay
    
    // Update circulation count
    let state = &mut ctx.accounts.contract_state;
    state.auto_cards_in_circulation -= 1;
    
    emit!(CardRedeemed {
        card_id: card.card_id,
        owner: card.owner,
        token_amount: user_reward,
        tax_amount: tax_amount as u64,
    });
    
    Ok(())
}

5. Legendary Card System

5.1 Legendary Milestone Processing

Every 1000 purchases triggers a legendary card lottery, selecting a winner from all entries in the previous 1000 purchases:

pub fn process_legendary_milestone(ctx: Context<ProcessLegendary>) -> Result<()> {
    let state = &mut ctx.accounts.contract_state;
    
    // Check if legendary slot available
    if state.legendary_cards_in_circulation >= 5 {
        // No slots available, skip this milestone
        return Ok(());
    }
    
    // Select winner from last 1000 purchases
    let end_purchase = state.total_purchases;
    let start_purchase = if end_purchase >= 1000 {
        end_purchase - 999 // Last 1000 purchases
    } else {
        1 // From beginning if less than 1000 total
    };
    
    // Collect all entries from the range
    let mut candidate_entries = Vec::new();
    for purchase_num in start_purchase..=end_purchase {
        let block_num = ((purchase_num - 1) / 100) + 1;
        let entry_in_block = ((purchase_num - 1) % 100) as usize;
        
        // Load block and get entry
        let block = load_purchase_block(ctx, block_num)?;
        if let Some(entry) = get_entry_for_purchase(block, entry_in_block) {
            candidate_entries.push((block_num, entry_in_block, entry));
        }
    }
    
    require!(!candidate_entries.is_empty(), ErrorCode::NoLegendaryCanditates);
    
    // Random selection
    let vrf_data = &ctx.accounts.vrf_account.load()?;
    let random_seed = vrf_data.get_result()?;
    let mut rng = create_seeded_rng(random_seed, 0xCC);
    
    // Flatten to individual entries
    let mut all_entries = Vec::new();
    for (block_num, entry_idx, entry) in candidate_entries {
        for sub_entry_idx in 0..entry.entry_count {
            all_entries.push((block_num, entry_idx, sub_entry_idx, &entry));
        }
    }
    
    let winner_idx = rng.next_u32() as usize % all_entries.len();
    let (_, _, sub_entry_idx, winning_entry) = &all_entries[winner_idx];
    
    // Generate legendary card parameters
    let (expiry_date, reward_percent) = generate_legendary_params(random_seed, winner_idx)?;
    
    // Mint legendary card
    mint_legendary_card(
        ctx,
        winning_entry,
        *sub_entry_idx,
        (expiry_date, reward_percent),
    )?;
    
    state.legendary_cards_in_circulation += 1;
    
    Ok(())
}

6. Error Handling and Security

6.1 Error Codes

#[error_code]
pub enum ErrorCode {
    #[msg("Purchase amount too small (minimum $10 USD)")]
    PurchaseTooSmall,
    
    #[msg("No eligible entries after applying limits")]
    NoEligibleEntries,
    
    #[msg("Auto-redeem time not reached yet")]
    AutoRedeemNotReady,
    
    #[msg("Minimum hold period not met")]
    MinHoldNotMet,
    
    #[msg("Wrong card type for this operation")]
    WrongCardType,
    
    #[msg("Card has expired and has no value")]
    CardExpired,
    
    #[msg("No entries available for lottery")]
    NoEntriesAvailable,
    
    #[msg("No candidates available for legendary card")]
    NoLegendaryCanditates,
    
    #[msg("Insufficient escrow balance")]
    InsufficientEscrow,
    
    #[msg("Invalid price feed data")]
    InvalidPriceFeed,
    
    #[msg("Daily entry limit exceeded")]
    DailyLimitExceeded,
    
    #[msg("Hourly purchase limit exceeded")]
    HourlyLimitExceeded,
}

6.2 Security Measures

The contract implements multiple security layers including price feed validation, ownership verification, and anti-reentrancy protection:

  • Price Feed Validation: Ensures oracle data is recent (within 5 minutes) and purchase amounts match expected token quantities
  • Ownership Verification: Validates card ownership and redemption status before processing
  • Safe Token Transfers: Implements balance verification before and after transfers to prevent reentrancy attacks
  • Anti-Gaming Limits: Enforces hourly and daily purchase limits to prevent system manipulation

7. Integration Requirements

7.1 Oracle Integration

  • Price Feeds: Integration with Pyth, Switchboard, or Chainlink for real-time $PEASANT/USDT pricing
  • Randomness: Switchboard VRF or Chainlink VRF for verifiable random number generation
  • Update Frequency: Price feeds updated every 30 seconds, randomness requested per lottery event

7.2 External Dependencies

  • SPL Token Program: For $PEASANT token transfers and account management
  • Metaplex Token Metadata: For NFT creation and metadata management
  • Associated Token Account Program: For token account creation and management
  • System Program: For account creation and rent payments

7.3 Event Logging

The contract emits comprehensive events for all major operations, enabling off-chain monitoring and analytics:

#[event]
pub struct PurchaseProcessed {
    pub buyer: Pubkey,
    pub usd_amount: u64,
    pub token_amount: u64,
    pub entries_awarded: u8,
    pub block_number: u64,
}

#[event]
pub struct CardMinted {
    pub card_id: u64,
    pub card_type: String,
    pub owner: Pubkey,
    pub reward_amount: u64,
}

#[event]
pub struct CardRedeemed {
    pub card_id: u64,
    pub owner: Pubkey,
    pub token_amount: u64,
    pub tax_amount: u64,
}

#[event]
pub struct LegendaryMilestone {
    pub milestone_number: u64,
    pub total_candidates: u32,
    pub winner: Option<Pubkey>,
}

8. Testing and Deployment Specifications

8.1 Unit Test Requirements

  • Purchase processing with various amounts and limits
  • Random selection algorithms with deterministic seeds
  • Card minting for all three types with parameter validation
  • Redemption logic with timing and pro-rating calculations
  • Anti-gaming limit enforcement
  • Error condition handling

8.2 Integration Test Requirements

  • End-to-end purchase-to-redemption flows
  • Multi-block lottery processing
  • Legendary milestone triggering and processing
  • Card recycling and circulation management
  • Oracle integration and price feed validation

8.3 Security Audit Focus Areas

  • Random number generation and seed management
  • Access control and authorization
  • Integer overflow/underflow protection
  • Reentrancy attack prevention
  • Front-running resistance
  • Economic incentive alignment

8.4 Performance Requirements

  • Process up to 1000 purchases per block efficiently
  • Maintain sub-second response times for redemption
  • Support concurrent users without race conditions
  • Optimize storage costs through efficient data structures

9. Deployment Configuration

9.1 Network Configuration

// Devnet deployment
pub const DEVNET_CONFIG: ContractConfig = ContractConfig {
    min_purchase_usd: 1000,        // $10.00 in cents
    max_daily_entries: 12,
    hourly_purchase_limit: 2,
    auto_card_limit: 400,
    flexible_card_limit: 200,
    legendary_card_limit: 5,
    recycle_delay: 86400,          // 24 hours
    tax_rate: 500,                 // 5.00% in basis points
};

// Mainnet deployment
pub const MAINNET_CONFIG: ContractConfig = ContractConfig {
    min_purchase_usd: 1000,        // $10.00 in cents
    max_daily_entries: 12,
    hourly_purchase_limit: 2,
    auto_card_limit: 400,
    flexible_card_limit: 200, 
    legendary_card_limit: 5,
    recycle_delay: 86400,          // 24 hours
    tax_rate: 500,                 // 5.00% in basis points
};

9.2 Initial State Setup

pub fn initialize_contract(
    ctx: Context<Initialize>,
    config: ContractConfig,
    authority: Pubkey,
    escrow_account: Pubkey,
    treasury_account: Pubkey,
) -> Result<()> {
    let state = &mut ctx.accounts.contract_state;
    
    state.total_purchases = 0;
    state.current_block = 0;
    state.legendary_milestone = 1000;
    state.auto_cards_in_circulation = 0;
    state.flexible_cards_in_circulation = 0;
    state.legendary_cards_in_circulation = 0;
    state.authority = authority;
    state.escrow_account = escrow_account;
    state.treasury_account = treasury_account;
    
    // Initialize recycling queues
    state.auto_card_recycle_queue = Vec::new();
    state.flexible_card_recycle_queue = Vec::new();
    state.legendary_card_recycle_queue = Vec::new();
    
    Ok(())
}

This technical specification provides comprehensive implementation details for the Kings Card NFT Rewards Smart Contract system. It covers all core mechanics, data structures, algorithms, and security measures required to build a robust, fair, and transparent reward distribution system for the $PEASANT token revival project.