From 3a0d137f6d5b24ddbba2fd41ca97aff6df0fb006 Mon Sep 17 00:00:00 2001 From: keyvan Date: Fri, 22 Mar 2024 15:33:29 -0700 Subject: [PATCH] feat: add failed account recovery test This commit refactors the staking tests and adds a new test case for unsuccessful stake account recovery attempts. It also enhances imports with new functions from the utility modules and changes the name of the type for stake account owner updates. This change will provide more robust testing scenarios for our staking mechanism. --- staking/tests/recouver_account.ts | 85 +++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/staking/tests/recouver_account.ts b/staking/tests/recouver_account.ts index 199982b6..5128adf1 100644 --- a/staking/tests/recouver_account.ts +++ b/staking/tests/recouver_account.ts @@ -1,4 +1,9 @@ -import { AnchorProvider, Program } from "@coral-xyz/anchor"; +import { + AnchorProvider, + parseIdlErrors, + Program, + Wallet, +} from "@coral-xyz/anchor"; import { Keypair, PublicKey, @@ -19,7 +24,12 @@ import { requestPythAirdrop, startValidator, } from "./utils/before"; -import { createMint, getTargetAccount, StakeTarget } from "./utils/utils"; +import { + createMint, + expectFailApi, + getTargetAccount, + StakeTarget, +} from "./utils/utils"; import BN from "bn.js"; import assert from "assert"; import path from "path"; @@ -113,7 +123,7 @@ describe("config", async () => { await program.methods.advanceClock(new BN(5)).rpc({ skipPreflight: DEBUG }); }); - it("creates recover account instruction", async () => { + it("updates stake account owner with governance authority", async () => { const governanceConnection = await StakeConnection.createStakeConnection( program.provider.connection, provider.wallet as NodeWallet, @@ -179,4 +189,73 @@ describe("config", async () => { newOwner.publicKey.toString() ); }); + + it("does not update stake account owner without governance authority", async () => { + const governanceConnection = await StakeConnection.createStakeConnection( + program.provider.connection, + provider.wallet as NodeWallet, + program.programId + ); + + const alice = new Keypair(); + const aliceConnection = await StakeConnection.createStakeConnection( + program.provider.connection, + new Wallet(alice), + program.programId + ); + + const aliceAssociatedTokenAddress = await Token.getAssociatedTokenAddress( + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + pythMintAccount.publicKey, + alice.publicKey, + true + ); + + const createAssociatedTokenAccountInstruction = + Token.createAssociatedTokenAccountInstruction( + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + pythMintAccount.publicKey, + aliceAssociatedTokenAddress, + alice.publicKey, + pythMintAuthority.publicKey + ); + + const instructions: TransactionInstruction[] = [ + createAssociatedTokenAccountInstruction, + ]; + + const badStakeAccountAddress = await governanceConnection.withCreateAccount( + instructions, + aliceAssociatedTokenAddress, + { + fullyVested: {}, + } + ); + + const transaction: Transaction = new Transaction(); + transaction.instructions.push(...instructions); + + await governanceConnection.program.provider.sendAndConfirm(transaction, [ + pythMintAuthority, + ]); + + // The fix + + const recoverAccountInstruction = + await aliceConnection.buildRecoverAccountInstruction( + badStakeAccountAddress, + provider.wallet.publicKey + ); + const recoverAccountTransaction = new Transaction(); + recoverAccountTransaction.instructions.push(recoverAccountInstruction); + + await expectFailApi( + aliceConnection.program.provider.sendAndConfirm( + recoverAccountTransaction + ), + "Signature verification failed" + ); + }); });