Skip to content

Commit

Permalink
fix: passing all tests
Browse files Browse the repository at this point in the history
  • Loading branch information
0xksure committed Apr 19, 2024
1 parent 12a1e49 commit 61f8166
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 97 deletions.
11 changes: 4 additions & 7 deletions programs/bounty/src/instructions/claim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,15 @@ pub struct ClaimReward<'info> {
/// token pda
#[account(
mut,
token::mint = mint,
token::authority = solver,
constraint = solver_token_account.owner.eq(&signer.key()) @ BlizzardError::WrongSolverTokenAccountOwner,
)]
pub solver_token_account: Account<'info, TokenAccount>,

//
#[account(
mut,
constraint = mint.mint_authority.unwrap().eq(&protocol.key())
constraint = mint.mint_authority.unwrap().eq(&protocol.key()) @ BlizzardError::WrongProtocolMintAuthority,
)]
pub mint: Account<'info, Mint>,

pub system_program: Program<'info, System>,
pub token_program: Program<'info, Token>,
}
Expand All @@ -61,11 +58,11 @@ pub fn handler(ctx: Context<ClaimReward>) -> Result<()> {
MintTo {
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.solver_token_account.to_account_info(),
authority: ctx.accounts.signer.to_account_info(),
authority: ctx.accounts.protocol.to_account_info(),
},
&[&protocol.seeds()],
),
1,
claimable_rewards,
)?;

solver.claim_rewards()?;
Expand Down
113 changes: 39 additions & 74 deletions programs/bounty/src/instructions/complete_bounty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use anchor_spl::token::{accessor::mint, mint_to, Mint, MintTo, Token, TokenAccou
use solana_program::native_token::Sol;

use crate::{
bounty_state::calculate_bounty_payout,
complete_bounty, protocol_collector,
state::{bounty_state::BountyState, Bounty, Denomination, Protocol},
utils::{BlizzardError, BOUNTY_SEED},
Expand Down Expand Up @@ -132,31 +133,6 @@ pub struct CompleteBounty<'info> {
pub token_program: Program<'info, Token>,
}

pub fn get_solvers<'info>(
solver1: &Account<'info, Solver>,
solver2: Option<&Account<'info, Solver>>,
) -> Vec<Box<dyn TSolver>> {
let mut solvers: Vec<Box<dyn TSolver>> = Vec::new();
solvers.push(Box::new(solver1.clone().into_inner()));
if solver2.is_some() {
solvers.push(Box::new(solver2.unwrap().clone().into_inner()))
}
solvers
}

pub fn get_solver_token_accounts(
solver_token_account_1: &TokenAccount,
solver_token_account_2: &Option<TokenAccount>,
) -> Vec<TokenAccount> {
let mut solvers = Vec::new();

solvers.push(solver_token_account_1.clone());
// if solver_token_account_2.is_some() {
// solvers.push(solver_token_account_2.unwrap().clone())
// }
solvers
}

pub fn get_solver_account_info<'a>(
solver1: &Account<'a, TokenAccount>,
solver2: &Option<Account<'a, TokenAccount>>,
Expand Down Expand Up @@ -192,67 +168,56 @@ impl<'info> CompleteBounty<'info> {

pub fn handler(ctx: Context<CompleteBountyAsCreator>) -> Result<()> {
msg!("Complete bounty");
let bounty = &mut ctx.accounts.bounty;
let payer = &ctx.accounts.payer;
let protocol = &ctx.accounts.protocol;
let sand_mint = &ctx.accounts.sand_mint;
let fee_collector = &ctx.accounts.fee_collector;
let escrow = &ctx.accounts.escrow;
let token_program = &ctx.accounts.token_program;

let bounty = &mut ctx.accounts.bounty;
if !(bounty.is_owner(&payer.key())) {
return Err(BlizzardError::NotAuthToCompleteBounty.into());
} else {
// create receivers vec
msg!("Derref solvers");

// let solver_token_account2 = match ctx.accounts.solver_token_account_2 {
// Some(solver) => Some(solver.to_account_info()),
// None => None,
// };
// let mut solvers = get_solvers(&ctx.accounts.solver1, ctx.accounts.solver2.as_ref());
// let solver_token_accounts = get_solver_account_info(
// &ctx.accounts.solver_token_account_1.to_account_info(),
// solver_token_account2.as_ref(),
// );
// msg!("Complete bounty");
// let bounty_payout = ctx.accounts.bounty.calculate_bounty_payout(
// &solver_token_accounts,
// &fee_collector,
// &payer.key,
// )?;
// let escrow = &escrow;

// msg!(
// "Transfer bounty: {:?}, escrow: {:?}, total amount {}, payouts {:?}",
// ctx.accounts.bounty.escrow.to_string(),
// escrow.key().to_string(),
// ctx.accounts.bounty.bounty_amount,
// bounty_payout.iter().map(|pay| pay.1).collect::<Vec<u64>>()
// );
let solver_token_accounts = get_solver_account_info(
&ctx.accounts.solver_token_account_1,
&ctx.accounts.solver_token_account_2,
);
let boutny_payout_proto = calculate_bounty_payout(
&bounty.bounty_amount.clone(),
&solver_token_accounts,
&fee_collector.to_account_info(),
)?;

boutny_payout_proto.iter().for_each(|(solver, amount)| {
anchor_spl::token::transfer(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
anchor_spl::token::Transfer {
from: ctx.accounts.escrow.to_account_info(),
to: solver.clone(),
authority: bounty.as_mut().clone().to_account_info(),
},
&[&bounty.as_mut().clone().signing_seeds()],
),
*amount,
)
.unwrap()
});

// // update claimable mining reward
// let mining_reward = protocol.calculate_mining_reward(solvers.len(), sand_mint.decimals);
// solvers
// .iter_mut()
// .for_each(|(solver)| solver.update_rewards(mining_reward).unwrap());

// // update claimable bounty reward in a given mint
let mining_reward =
protocol.calculate_mining_reward(solver_token_accounts.len(), sand_mint.decimals);
ctx.accounts.solver1.update_rewards(mining_reward)?;
if ctx.accounts.solver2.is_some() {
ctx.accounts
.solver2
.as_mut()
.unwrap()
.update_rewards(mining_reward)?;
}

// bounty_payout.iter().for_each(|(solver, amount)| {
// anchor_spl::token::transfer(
// CpiContext::new_with_signer(
// token_program.to_account_info(),
// anchor_spl::token::Transfer {
// from: escrow.to_account_info(),
// to: solver.clone(),
// authority: bounty.to_account_info(),
// },
// &[&bounty.signing_seeds()],
// ),
// *amount,
// )
// .unwrap()
// });
bounty.complete_bounty(ctx.accounts.payer.key())?;
}
Ok(())
}
15 changes: 8 additions & 7 deletions programs/bounty/src/instructions/complete_bounty_as_relayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::{
rc::Rc,
};

use crate::{state::protocol_collector::TSolver};

use anchor_lang::prelude::*;
use anchor_spl::{
token::{mint_to, Mint, MintTo, Token, TokenAccount},
Expand All @@ -15,7 +17,7 @@ use winnow::combinator::fail;

use crate::{
bounty_state::calculate_bounty_payout,
get_solver_account_info, get_solver_token_accounts, get_solvers,
get_solver_account_info,
state::{bounty_state::BountyState, Bounty, Denomination, Protocol, Relayer},
utils::{BlizzardError, BOUNTY_SEED, DENOMINATION_SEED, FEE_REC}, Solver,
};
Expand Down Expand Up @@ -111,10 +113,8 @@ pub fn handler(ctx: Context<CompleteBountyAsRelayer>) -> Result<()> {
return Err(BlizzardError::NotAuthToCompleteBounty.into());
}

;
msg!("Derref solvers");

let mut solvers = get_solvers(&ctx.accounts.solver1, ctx.accounts.solver2.as_ref());

let solver_token_accounts = get_solver_account_info(&ctx.accounts.solver_token_account_1, &ctx.accounts.solver_token_account_2);
let boutny_payout_proto = calculate_bounty_payout(&bounty.bounty_amount.clone(), &solver_token_accounts, &fee_collector.to_account_info())?;

Expand All @@ -137,9 +137,10 @@ pub fn handler(ctx: Context<CompleteBountyAsRelayer>) -> Result<()> {

// // update claimable mining reward
let mining_reward = protocol.calculate_mining_reward(solver_token_accounts.len(), sand_mint.decimals);
solvers
.iter_mut()
.for_each(|(solver)| solver.update_rewards(mining_reward).unwrap());
ctx.accounts.solver1.update_rewards(mining_reward)?;
if ctx.accounts.solver2.is_some() {
ctx.accounts.solver2.as_mut().unwrap().update_rewards(mining_reward)?;
}

bounty.complete_bounty(ctx.accounts.payer.key())?;

Expand Down
6 changes: 6 additions & 0 deletions programs/bounty/src/utils/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,10 @@ pub enum BlizzardError {

#[msg("No claimable reward")]
NoClaimableReward,

#[msg("Wrong protocol mint authority")]
WrongProtocolMintAuthority,

#[msg("Wrong solver token account owner")]
WrongSolverTokenAccountOwner,
}
20 changes: 20 additions & 0 deletions sdk-ts/src/idl/bounty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,16 @@ export type Bounty = {
"code": 6011,
"name": "NoClaimableReward",
"msg": "No claimable reward"
},
{
"code": 6012,
"name": "WrongProtocolMintAuthority",
"msg": "Wrong protocol mint authority"
},
{
"code": 6013,
"name": "WrongSolverTokenAccountOwner",
"msg": "Wrong solver token account owner"
}
]
};
Expand Down Expand Up @@ -2194,6 +2204,16 @@ export const IDL: Bounty = {
"code": 6011,
"name": "NoClaimableReward",
"msg": "No claimable reward"
},
{
"code": 6012,
"name": "WrongProtocolMintAuthority",
"msg": "Wrong protocol mint authority"
},
{
"code": 6013,
"name": "WrongSolverTokenAccountOwner",
"msg": "Wrong solver token account owner"
}
]
};
5 changes: 2 additions & 3 deletions sdk-ts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,15 @@ export class BountySdk {
const sandMint = getSandMint();
const solverPda = getSolverPDA(solver);
const claimRewardsIx = await this.program.methods.claimRewards().accounts({
signer: solver,
protocol: protocolPda[0],
solver: solverPda[0],
solverTokenAccount: await getSolverTokenAccount(solver, sandMint[0]),
mint: sandMint[0],
}).instruction();

return {
vtx: this.createVersionedTransaction([claimRewardsIx], this.signer),
vtx: this.createVersionedTransaction([claimRewardsIx], solver),
ix: claimRewardsIx,
protocolAccountPda: protocolPda[0],
solverPda: solverPda[0],
Expand Down Expand Up @@ -375,7 +376,6 @@ export class BountySdk {
[`solver${i}`]: curr
}
}, {})
console.log("Number of solvers", solvers)

const sandTokenPDAIxs = (await this.getOrCreateAssociatedTokenAccountsIxs({
mint: sandMint[0],
Expand All @@ -384,7 +384,6 @@ export class BountySdk {
})).map((solver) => {
return solver.instruction as web3.TransactionInstruction
})
console.log("Number of sand token accounts", sandTokenPDAIxs.length)

const protocolPda = getProtocolPDA();
const feeCollector = getFeeCollectorPDA(mint);
Expand Down
30 changes: 24 additions & 6 deletions tests/rewards-v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import * as web3 from '@solana/web3.js';
import { assert, config, expect, use } from 'chai';
import * as chaiAsPromised from "chai-as-promised"
import { sendAndConfirmTransaction } from "../sdk-ts/src/utils";
import { getSandMint, getSolverPDA } from "../sdk-ts/src";
import { getProtocolPDA, getSandMint, getSolverPDA } from "../sdk-ts/src";
use(chaiAsPromised.default)

/**
Expand Down Expand Up @@ -185,8 +185,6 @@ describe('bounty', () => {

});



it('Add and remove Relayer -> Should Succees', async () => {
// add relayer - relayer should be pk + BOUNTY_SANDBLIZZARD
const relayerKeys = web3.Keypair.generate();
Expand All @@ -212,7 +210,7 @@ describe('bounty', () => {
expect(deactivatedRelayer.active, `relayer is not deactivated`).eq(false);
});

it.only('Create bounty and try to complete it as a relayer -> Should Succeed', async () => {
it('Create bounty and try to complete it as a relayer -> Should Succeed', async () => {
const bountyId = Math.floor(Math.random() * 1000000).toString();
// add relayer - relayer should be pk + BOUNTY_SANDBLIZZARD
const relayerKeys = web3.Keypair.generate();
Expand Down Expand Up @@ -262,8 +260,11 @@ describe('bounty', () => {
expect(bountyAccount.state.completed).to.exist

// get sand token balance of user
const sandMintPda = await getSandMint();
const sandMint = await spl.getMint(provider.connection, sandMintPda[0]);

const sandTokenAccount = await getAssociatedTokenAddress(
getSandMint()[0],
sandMintPda[0],
userWallet.publicKey,
);
const sandTokenBalance = await provider.connection.getTokenAccountBalance(sandTokenAccount);
Expand All @@ -272,7 +273,24 @@ describe('bounty', () => {
// check the claimable amount of the user
const claimableAmount = await getSolverPDA(userWallet.publicKey);
const claimableAmountInfo = await program.account.solver.fetch(claimableAmount[0]);
console.log("Claimable amount", claimableAmountInfo)
const claimableAmountValue = claimableAmountInfo.claimableRewards.toString();
const protocolPda = await getProtocolPDA();
const protocolAccount = await program.account.protocol.fetch(protocolPda[0]);


// test the claimable amount being equal to the 10.pow(sandMint.decimals) * protocolAccount.emission
const tokenDecimals = new anchor.BN(10).pow(new anchor.BN(sandMint.decimals));
const expectedAmount = protocolAccount.emission.mul(tokenDecimals);
expect(claimableAmountValue).to.equal(expectedAmount.toString());

// try to claim the amount
const claimAmount = await bountySdk.claimReward(
userWallet.publicKey
);
await sendAndConfirmTransaction(provider.connection, await claimAmount.vtx, [userWallet.payer])
// refetch the sand token balance
const sandTokenBalanceAfter = await provider.connection.getTokenAccountBalance(sandTokenAccount);
expect(sandTokenBalanceAfter.value.amount).to.equal(expectedAmount.toString());


});
Expand Down

0 comments on commit 61f8166

Please sign in to comment.