anchor/tests/cfo/tests/utils/stake.js

188 lines
5.3 KiB
JavaScript

const anchor = require("@coral-xyz/anchor");
const serumCmn = require("@project-serum/common");
const TokenInstructions = require("@project-serum/serum").TokenInstructions;
const utils = require("../../deps/stake/tests/utils");
const lockup = anchor.workspace.Lockup;
const registry = anchor.workspace.Registry;
const provider = anchor.AnchorProvider.env();
// hack so we don't have to update serum-common library
// to the new AnchorProvider class and Provider interface
provider.send = provider.sendAndConfirm;
let lockupAddress = null;
let mint = null;
let god = null;
let registrarAccount = null;
let registrarSigner = null;
let nonce = null;
let poolMint = null;
const registrar = new anchor.web3.Account();
const rewardQ = new anchor.web3.Account();
const withdrawalTimelock = new anchor.BN(4);
const stakeRate = new anchor.BN(2);
const rewardQLen = 170;
let member = null;
let memberAccount = null;
let memberSigner = null;
let balances = null;
let balancesLocked = null;
const WHITELIST_SIZE = 10;
async function setupStakePool(mint, god) {
// Registry genesis.
const [_registrarSigner, _nonce] =
await anchor.web3.PublicKey.findProgramAddress(
[registrar.publicKey.toBuffer()],
registry.programId
);
registrarSigner = _registrarSigner;
nonce = _nonce;
poolMint = await serumCmn.createMint(provider, registrarSigner);
try {
// Init registry.
await registry.state.rpc.new({
accounts: { lockupProgram: lockup.programId },
});
// Init lockup.
await lockup.state.rpc.new({
accounts: {
authority: provider.wallet.publicKey,
},
});
} catch (err) {
// Skip errors for convenience when developing locally,
// since the state constructors can only be called once.
}
// Initialize stake pool.
await registry.rpc.initialize(
mint,
provider.wallet.publicKey,
nonce,
withdrawalTimelock,
stakeRate,
rewardQLen,
{
accounts: {
registrar: registrar.publicKey,
poolMint,
rewardEventQ: rewardQ.publicKey,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
},
signers: [registrar, rewardQ],
instructions: [
await registry.account.registrar.createInstruction(registrar),
await registry.account.rewardQueue.createInstruction(rewardQ, 8250),
],
}
);
registrarAccount = await registry.account.registrar.fetch(
registrar.publicKey
);
console.log("Registrar", registrar.publicKey.toString());
console.log("Wallet", registry.provider.wallet.publicKey.toString());
// Create account for staker.
const seed = anchor.utils.sha256
.hash(`${registrar.publicKey.toString()}:Member`)
.slice(0, 32);
member = await anchor.web3.PublicKey.createWithSeed(
registry.provider.wallet.publicKey,
seed,
registry.programId
);
const [_memberSigner, nonce2] =
await anchor.web3.PublicKey.findProgramAddress(
[registrar.publicKey.toBuffer(), member.toBuffer()],
registry.programId
);
memberSigner = _memberSigner;
const [mainTx, _balances] = await utils.createBalanceSandbox(
provider,
registrarAccount,
memberSigner
);
const [lockedTx, _balancesLocked] = await utils.createBalanceSandbox(
provider,
registrarAccount,
memberSigner
);
balances = _balances;
balancesLocked = _balancesLocked;
const tx = registry.transaction.createMember(nonce2, {
accounts: {
registrar: registrar.publicKey,
member: member,
beneficiary: provider.wallet.publicKey,
memberSigner,
balances,
balancesLocked,
tokenProgram: TokenInstructions.TOKEN_PROGRAM_ID,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
},
instructions: [
anchor.web3.SystemProgram.createAccountWithSeed({
fromPubkey: registry.provider.wallet.publicKey,
newAccountPubkey: member,
basePubkey: registry.provider.wallet.publicKey,
seed,
lamports:
await registry.provider.connection.getMinimumBalanceForRentExemption(
registry.account.member.size
),
space: registry.account.member.size,
programId: registry.programId,
}),
],
});
const signers = [provider.wallet.payer];
const allTxs = [mainTx, lockedTx, { tx, signers }];
await provider.sendAll(allTxs);
memberAccount = await registry.account.member.fetch(member);
// Deposit into stake program.
const depositAmount = new anchor.BN(120);
await registry.rpc.deposit(depositAmount, {
accounts: {
depositor: god,
depositorAuthority: provider.wallet.publicKey,
tokenProgram: TokenInstructions.TOKEN_PROGRAM_ID,
vault: memberAccount.balances.vault,
beneficiary: provider.wallet.publicKey,
member: member,
},
});
// Stake.
const stakeAmount = new anchor.BN(10);
await registry.rpc.stake(stakeAmount, false, {
accounts: {
// Stake instance.
registrar: registrar.publicKey,
rewardEventQ: rewardQ.publicKey,
poolMint,
// Member.
member: member,
beneficiary: provider.wallet.publicKey,
balances,
balancesLocked,
// Program signers.
memberSigner,
registrarSigner,
// Misc.
clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
tokenProgram: TokenInstructions.TOKEN_PROGRAM_ID,
},
});
}
module.exports = {
setupStakePool,
};