testsvm_quarry/
test_merge_pool.rs

1//! # Merge Pool Testing Utilities
2//!
3//! Test helpers for Quarry merge pool management.
4//!
5//! This module provides the `TestMergePool` struct for creating and managing
6//! merge pools in the Quarry protocol. Merge pools enable multiple quarries
7//! to share rewards through a unified staking mechanism, where miners can
8//! earn from both primary and replica token pools.
9//!
10//! ## Features
11//!
12//! - **Pool Creation**: Initialize new merge pools with primary and replica mints
13//! - **Miner Management**: Create and manage merge miners within pools
14//! - **Token Operations**: Handle wrapped token minting and distribution
15//! - **Type Safety**: Strongly typed account references for all pool components
16
17use anchor_lang::prelude::*;
18use anyhow::Result;
19use solana_sdk::instruction::Instruction;
20use testsvm::prelude::*;
21
22use crate::{TestMergeMiner, quarry_merge_mine, quarry_mine};
23
24/// Helper for managing a merge pool with type-safe account references
25pub struct TestMergePool {
26    pub label: String,
27    pub pool: AccountRef<quarry_merge_mine::accounts::MergePool>,
28    pub primary_mint: AccountRef<anchor_spl::token::Mint>,
29    pub replica_mint: AccountRef<anchor_spl::token::Mint>,
30}
31
32impl TestMergePool {
33    /// Create and set up a new merge pool
34    pub fn new(
35        env: &mut TestSVM,
36        label: &str,
37        primary_mint: AccountRef<anchor_spl::token::Mint>,
38    ) -> Result<Self> {
39        // Calculate merge pool PDA
40        let pool = env.get_pda::<quarry_merge_mine::accounts::MergePool>(
41            &format!("merge_pool[{label}].pool"),
42            &[b"MergePool", primary_mint.key.as_ref()],
43            quarry_merge_mine::ID,
44        )?;
45
46        // Calculate replica mint PDA
47        let replica_mint = env.get_pda::<anchor_spl::token::Mint>(
48            &format!("merge_pool[{label}].replica_mint"),
49            &[b"ReplicaMint", pool.key.as_ref()],
50            quarry_merge_mine::ID,
51        )?;
52
53        // Create new_pool_v2 instruction
54        let instruction = Instruction {
55            program_id: quarry_merge_mine::ID,
56            accounts: quarry_merge_mine::client::accounts::NewPoolV2 {
57                pool: pool.key,
58                primary_mint: primary_mint.key,
59                replica_mint: replica_mint.key,
60                payer: env.default_fee_payer(),
61                token_program: anchor_spl::token::ID,
62                system_program: solana_sdk::system_program::ID,
63                rent: solana_sdk::sysvar::rent::ID,
64            }
65            .to_account_metas(None),
66            data: quarry_merge_mine::client::args::NewPoolV2 {}.data(),
67        };
68
69        env.execute_ixs(&[instruction])?;
70
71        Ok(Self {
72            label: label.to_string(),
73            pool,
74            primary_mint,
75            replica_mint,
76        })
77    }
78
79    /// Create a merge miner for this merge pool with the specified owner
80    pub fn create_merge_miner(
81        &self,
82        env: &mut TestSVM,
83        label: &str,
84        owner: Pubkey,
85    ) -> Result<TestMergeMiner> {
86        // Calculate merge miner PDA
87        let merge_miner = env.get_pda(
88            &format!("merge_miner[{label}]"),
89            &[b"MergeMiner", self.pool.key.as_ref(), owner.as_ref()],
90            quarry_merge_mine::ID,
91        )?;
92
93        // Create merge miner primary token account ATA
94        let (create_mm_primary_ata_ix, primary_tokens) = env.create_ata_ix(
95            &format!("merge_miner[{label}].primary_tokens"),
96            &merge_miner.into(),
97            &self.primary_mint.into(),
98        )?;
99
100        // Create merge miner primary token account ATA
101        let (create_mm_replica_ata_ix, replica_tokens) = env.create_ata_ix(
102            &format!("merge_miner[{label}].replica_tokens"),
103            &merge_miner.into(),
104            &self.replica_mint.into(),
105        )?;
106
107        // Create init_merge_miner_v2 instruction
108        let init_merge_miner_ix = anchor_instruction(
109            quarry_merge_mine::ID,
110            quarry_merge_mine::client::accounts::InitMergeMinerV2 {
111                pool: self.pool.key,
112                owner,
113                mm: merge_miner.key,
114                payer: env.default_fee_payer(),
115                system_program: solana_sdk::system_program::ID,
116            },
117            quarry_merge_mine::client::args::InitMergeMinerV2 {},
118        );
119
120        env.execute_ixs(&[
121            create_mm_primary_ata_ix,
122            create_mm_replica_ata_ix,
123            init_merge_miner_ix,
124        ])?;
125
126        Ok(TestMergeMiner {
127            merge_miner,
128            primary_tokens,
129            replica_tokens,
130        })
131    }
132
133    /// Create necessary token accounts for staking operations
134    pub fn setup_staking_accounts(
135        &self,
136        env: &mut TestSVM,
137        merge_miner: &AccountRef<quarry_merge_mine::accounts::MergeMiner>,
138        primary_quarry: &Pubkey,
139    ) -> Result<()> {
140        // Create merge miner primary token account ATA
141        let (create_mm_primary_ata_ix, _mm_primary_token_account) = env.create_ata_ix(
142            "mm_primary_token_account",
143            &merge_miner.into(),
144            &self.primary_mint.into(),
145        )?;
146
147        // Get primary miner PDA
148        let primary_miner = env.get_pda::<quarry_mine::accounts::Miner>(
149            "primary_miner",
150            &[b"Miner", primary_quarry.as_ref(), merge_miner.as_ref()],
151            crate::quarry_mine::ID,
152        )?;
153
154        // Create primary miner vault ATA
155        let (create_miner_vault_ix, _primary_miner_vault) = env.create_ata_ix(
156            "primary_miner_vault",
157            &primary_miner.into(),
158            &self.primary_mint.into(),
159        )?;
160
161        // Execute the account creation instructions
162        env.execute_ixs(&[create_mm_primary_ata_ix, create_miner_vault_ix])?;
163
164        Ok(())
165    }
166}