import * as anchor from "@project-serum/anchor"; import { Program, BN } from "@project-serum/anchor"; import { PsyStake } from "../target/types/psy_stake"; import { deriveStakePool, deriveStakingTokenAccount } from "./pdas"; import { assert } from "chai"; import { Keypair, PublicKey } from "@solana/web3.js"; const { setupTestAccounts, MIN_EPOCH_DURATION } = require("./setup"); const { defaultVec, assertParsedError } = require("./utils"); describe("Test create StakePool instruction.", () => { const program = anchor.workspace.PsyStake as Program; const provider = anchor.Provider.env(); anchor.setProvider(provider); let network, stakePoolAuthority: Keypair; const uniqueSeed = 1; let stakePool: PublicKey, stakePoolBump: number, stakingTokenAccount: PublicKey, stakingTokenAccountBump: number, stakingTokenMint: PublicKey; before(async () => { ({ network, stakePoolAuthority } = await setupTestAccounts( program, provider )); stakingTokenMint = network.usdcToken.publicKey; [stakePool, stakePoolBump] = await deriveStakePool( program, network.usdcToken.publicKey, new BN(uniqueSeed) ); [stakingTokenAccount, stakingTokenAccountBump] = await deriveStakingTokenAccount(program, stakePool); }); it("Initialization of StakePool fails when epoch duration is too short.", async () => { const epochDuration = new BN(MIN_EPOCH_DURATION - 1); const nextEpochStartTime = new BN(new Date().getTime() / 1000 + 60); try { await program.methods .createStakePool(uniqueSeed, nextEpochStartTime, epochDuration) .accounts({ stakePoolAuthority: stakePoolAuthority.publicKey, stakePool, stakingTokenMint, stakingTokenAccount, }) .signers([stakePoolAuthority]) .rpc(); assert(false); } catch (err) { assertParsedError(err, "Epoch duration must be at least 4 hours."); } }); it("Initialization of StakePool fails when start time is in the past.", async () => { const epochDuration = new BN(MIN_EPOCH_DURATION); const nextEpochStartTime = new BN(new Date().getTime() / 1000 - 2); try { await program.methods .createStakePool(uniqueSeed, nextEpochStartTime, epochDuration) .accounts({ stakePoolAuthority: stakePoolAuthority.publicKey, stakePool, stakingTokenMint, stakingTokenAccount, }) .signers([stakePoolAuthority]) .rpc(); assert(false); } catch (err) { assertParsedError(err, "Start time of next epoch must be in the future."); } }); it("Initializes a StakePool successfully.", async () => { const epochDuration = new BN(MIN_EPOCH_DURATION); const nextEpochStartTime = new BN(new Date().getTime() / 1000 + 20); await program.methods .createStakePool(uniqueSeed, nextEpochStartTime, epochDuration) .accounts({ stakePoolAuthority: stakePoolAuthority.publicKey, stakePool, stakingTokenMint, stakingTokenAccount, }) .signers([stakePoolAuthority]) .rpc(); const stakePoolData = await program.account.stakePool.fetch(stakePool); assert.ok( stakePoolData.stakePoolAuthority.equals(stakePoolAuthority.publicKey) ); assert(stakePoolData.stakingTokenMint.equals(stakingTokenMint)); assert(stakePoolData.stakingTokenAccount.equals(stakingTokenAccount)); assert.equal(stakePoolData.rewardPoolCount, 0); assert.equal(stakePoolData.currentEpoch, 0); assert(stakePoolData.epochDuration.eq(epochDuration)); assert(stakePoolData.nextEpochStartTime.eq(nextEpochStartTime)); assert.deepEqual(stakePoolData.inactiveEpochVec, defaultVec()); assert.deepEqual(stakePoolData.startingEpochVec, defaultVec()); assert.equal(stakePoolData.totalRewardUnits.toNumber(), 0); assert.equal(stakePoolData.stakePoolBump, stakePoolBump); assert.equal( stakePoolData.stakingTokenAccountBump, stakingTokenAccountBump ); assert.equal(stakePoolData.uniqueSeed, uniqueSeed); }); it("Initializing a StakePool should fail when unique seed already exists.", async () => { const epochDuration = new BN(MIN_EPOCH_DURATION); const nextEpochStartTime = new BN(new Date().getTime() / 1000 + 1); try { await program.methods .createStakePool(uniqueSeed, nextEpochStartTime, epochDuration) .accounts({ stakePoolAuthority: stakePoolAuthority.publicKey, stakePool, stakingTokenMint, stakingTokenAccount, }) .signers([stakePoolAuthority]) .rpc(); // assert(false); } catch (err) { assert.match( err.message, /Error processing Instruction 0: custom program error: 0x0/ ); } }); });