Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support token_2022 program #5

Merged
merged 14 commits into from
Sep 6, 2024
2 changes: 1 addition & 1 deletion Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

[[test.genesis]]
andrewsource147 marked this conversation as resolved.
Show resolved Hide resolved
address = "EBZDYx7599krFc4m2govwBdZcicr4GgepqC78m71nsHS"
program = "tests/external_program/transfer_hook_counter.so"
program = "artifacts/transfer_hook_counter.so"
4 changes: 4 additions & 0 deletions programs/locker/src/instructions/claim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,27 @@ use crate::*;
#[event_cpi]
#[derive(Accounts)]
pub struct ClaimCtx<'info> {
/// Escrow.
#[account(
mut,
has_one = recipient,
constraint = escrow.load()?.cancelled_at == 0 @ LockerError::AlreadyCancelled
)]
pub escrow: AccountLoader<'info, VestingEscrow>,

/// Escrow Token Account.
#[account(
mut,
associated_token::mint = escrow.load()?.token_mint,
associated_token::authority = escrow
)]
pub escrow_token: Box<Account<'info, TokenAccount>>,

/// Recipient.
#[account(mut)]
pub recipient: Signer<'info>,

/// Recipient Token Account.
#[account(
mut,
constraint = recipient_token.key() != escrow_token.key() @ LockerError::InvalidRecipientTokenAccount
Expand Down
13 changes: 9 additions & 4 deletions programs/locker/src/instructions/create_vesting_escrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,41 +85,46 @@ impl CreateVestingEscrowParameters {
#[event_cpi]
#[derive(Accounts)]
pub struct CreateVestingEscrowCtx<'info> {
// Base.
codewithgun marked this conversation as resolved.
Show resolved Hide resolved
#[account(mut)]
pub base: Signer<'info>,

// Escrow.
codewithgun marked this conversation as resolved.
Show resolved Hide resolved
#[account(
init,
seeds = [
b"escrow".as_ref(),
base.key().as_ref(),
b"escrow".as_ref(),
base.key().as_ref(),
],
bump,
payer = sender,
space = 8 + VestingEscrow::INIT_SPACE
)]
pub escrow: AccountLoader<'info, VestingEscrow>,

// Escrow Token Account.
#[account(
mut,
associated_token::mint = sender_token.mint,
associated_token::authority = escrow
)]
pub escrow_token: Box<Account<'info, TokenAccount>>,

// Sender.
#[account(mut)]
pub sender: Signer<'info>,

// Sender Token Account.
#[account(mut)]
pub sender_token: Box<Account<'info, TokenAccount>>,

/// CHECK: recipient account
/// CHECK: recipient account.
pub recipient: UncheckedAccount<'info>,

/// Token program.
pub token_program: Program<'info, Token>,

// system program
// system program.
pub system_program: Program<'info, System>,
}

Expand Down
28 changes: 16 additions & 12 deletions programs/locker/src/instructions/v2/cancel_vesting_escrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ pub struct CancelVestingEscrow<'info> {
)]
pub escrow: AccountLoader<'info, VestingEscrow>,

/// Mint.
pub token_mint: Box<InterfaceAccount<'info, Mint>>,
andrewsource147 marked this conversation as resolved.
Show resolved Hide resolved

/// Escrow Token Account.
#[account(
mut,
associated_token::mint = token_mint,
Expand All @@ -32,6 +34,7 @@ pub struct CancelVestingEscrow<'info> {
)]
pub escrow_token: Box<InterfaceAccount<'info, TokenAccount>>,

/// Creator Token Account.
#[account(
mut,
associated_token::mint = token_mint,
Expand All @@ -40,6 +43,7 @@ pub struct CancelVestingEscrow<'info> {
)]
pub creator_token: Box<InterfaceAccount<'info, TokenAccount>>,
andrewsource147 marked this conversation as resolved.
Show resolved Hide resolved

/// Receipient Token Account.
#[account(
mut,
associated_token::mint = token_mint,
Expand All @@ -48,7 +52,7 @@ pub struct CancelVestingEscrow<'info> {
)]
pub recipient_token: Box<InterfaceAccount<'info, TokenAccount>>,

/// CHECKED: the creator will receive the rent back
/// CHECKED: The Token Account will receive the rent
#[account(mut)]
pub rent_receiver: UncheckedAccount<'info>,

Expand Down Expand Up @@ -83,7 +87,7 @@ impl<'info> CancelVestingEscrow<'info> {
}

pub fn handle_cancel_vesting_escrow<'c: 'info, 'info>(
mut ctx: Context<'_, '_, 'c, 'info, CancelVestingEscrow<'info>>,
ctx: Context<'_, '_, 'c, 'info, CancelVestingEscrow<'info>>,
remaining_accounts_info: Option<RemainingAccountsInfo>,
) -> Result<()> {
let mut escrow = ctx.accounts.escrow.load_mut()?;
Expand All @@ -102,14 +106,14 @@ pub fn handle_cancel_vesting_escrow<'c: 'info, 'info>(
drop(escrow);

// Process remaining accounts
let remaining_accounts = if remaining_accounts_info.is_none() {
ParsedRemainingAccounts::default()
} else {
parse_remaining_accounts(
&mut ctx.remaining_accounts,
&remaining_accounts_info.unwrap().slices,
&[AccountsType::TransferHookCancel],
)?
let mut remaining_accounts = &ctx.remaining_accounts[..];
let parsed_transfer_hook_accounts = match remaining_accounts_info {
Some(info) => parse_remaining_accounts(
&mut remaining_accounts,
&info.slices,
&[AccountsType::TransferHookEscrow],
)?,
None => ParsedRemainingAccounts::default(),
};

// Transfer the claimable amount to the recipient
Expand All @@ -124,7 +128,7 @@ pub fn handle_cancel_vesting_escrow<'c: 'info, 'info>(
memo: TRANSFER_MEMO_CANCEL_VESTING.as_bytes(),
}),
claimable_amount,
remaining_accounts.transfer_hook_cancel,
parsed_transfer_hook_accounts.transfer_hook_escrow,
)?;

// Transfer the remaining amount to the creator
Expand All @@ -139,7 +143,7 @@ pub fn handle_cancel_vesting_escrow<'c: 'info, 'info>(
memo: TRANSFER_MEMO_CANCEL_VESTING.as_bytes(),
}),
remaining_amount,
remaining_accounts.transfer_hook_cancel,
parsed_transfer_hook_accounts.transfer_hook_escrow,
)?;

ctx.accounts.close_escrow_token()?;
Expand Down
25 changes: 15 additions & 10 deletions programs/locker/src/instructions/v2/claim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::util::{MemoTransferContext, transfer_to_user_v2};
#[event_cpi]
andrewsource147 marked this conversation as resolved.
Show resolved Hide resolved
#[derive(Accounts)]
pub struct ClaimV2<'info> {
/// Escrow.
#[account(
mut,
has_one = token_mint,
Expand All @@ -18,8 +19,10 @@ pub struct ClaimV2<'info> {
)]
pub escrow: AccountLoader<'info, VestingEscrow>,

/// Mint.
pub token_mint: Box<InterfaceAccount<'info, Mint>>,

/// Escrow Token Account.
#[account(
mut,
associated_token::mint = token_mint,
Expand All @@ -28,9 +31,11 @@ pub struct ClaimV2<'info> {
)]
pub escrow_token: Box<InterfaceAccount<'info, TokenAccount>>,

/// Recipient.
#[account(mut)]
pub recipient: Signer<'info>,

/// Recipient Token Account.
#[account(
mut,
constraint = recipient_token.key() != escrow_token.key() @ LockerError::InvalidRecipientTokenAccount
Expand All @@ -45,7 +50,7 @@ pub struct ClaimV2<'info> {
}

pub fn handle_claim_v2<'c: 'info, 'info>(
mut ctx: Context<'_, '_, 'c, 'info, ClaimV2<'info>>,
ctx: Context<'_, '_, 'c, 'info, ClaimV2<'info>>,
max_amount: u64,
remaining_accounts_info: Option<RemainingAccountsInfo>,
) -> Result<()> {
Expand All @@ -55,16 +60,16 @@ pub fn handle_claim_v2<'c: 'info, 'info>(
drop(escrow);

// Process remaining accounts
let remaining_accounts = if remaining_accounts_info.is_none() {
ParsedRemainingAccounts::default()
} else {
parse_remaining_accounts(
&mut ctx.remaining_accounts,
&remaining_accounts_info.unwrap().slices,
let mut remaining_accounts = &ctx.remaining_accounts[..];
let parsed_transfer_hook_accounts = match remaining_accounts_info {
Some(info) => parse_remaining_accounts(
&mut remaining_accounts,
&info.slices,
&[
AccountsType::TransferHookClaim,
AccountsType::TransferHookEscrow,
],
)?
)?,
None => ParsedRemainingAccounts::default(),
};
andrewsource147 marked this conversation as resolved.
Show resolved Hide resolved

transfer_to_user_v2(
Expand All @@ -78,7 +83,7 @@ pub fn handle_claim_v2<'c: 'info, 'info>(
memo: TRANSFER_MEMO_CLAIM_VESTING.as_bytes(),
}),
amount,
remaining_accounts.transfer_hook_claim,
parsed_transfer_hook_accounts.transfer_hook_escrow,
)?;

let current_ts = Clock::get()?.unix_timestamp as u64;
Expand Down
28 changes: 17 additions & 11 deletions programs/locker/src/instructions/v2/create_vesting_escrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ use crate::*;
#[event_cpi]
#[derive(Accounts)]
pub struct CreateVestingEscrowV2<'info> {
// Base.
#[account(mut)]
pub base: Signer<'info>,

// Escrow.
#[account(
init,
seeds = [
Expand All @@ -27,8 +29,10 @@ pub struct CreateVestingEscrowV2<'info> {
)]
pub escrow: AccountLoader<'info, VestingEscrow>,

// Mint.
pub token_mint: Box<InterfaceAccount<'info, Mint>>,

// Escrow Token Account.
#[account(
mut,
associated_token::mint = token_mint,
Expand All @@ -37,9 +41,11 @@ pub struct CreateVestingEscrowV2<'info> {
)]
pub escrow_token: Box<InterfaceAccount<'info, TokenAccount>>,

// Sender.
#[account(mut)]
pub sender: Signer<'info>,

// Sender Token Account.
#[account(mut)]
pub sender_token: Box<InterfaceAccount<'info, TokenAccount>>,

Expand All @@ -49,12 +55,12 @@ pub struct CreateVestingEscrowV2<'info> {
/// Token program.
pub token_program: Interface<'info, TokenInterface>,

// system program
// system program.
pub system_program: Program<'info, System>,
}

pub fn handle_create_vesting_escrow_v2<'c: 'info, 'info>(
mut ctx: Context<'_, '_, 'c, 'info, CreateVestingEscrowV2<'info>>,
ctx: Context<'_, '_, 'c, 'info, CreateVestingEscrowV2<'info>>,
params: &CreateVestingEscrowParameters,
remaining_accounts_info: Option<RemainingAccountsInfo>,
) -> Result<()> {
Expand All @@ -79,14 +85,14 @@ pub fn handle_create_vesting_escrow_v2<'c: 'info, 'info>(
)?;

// Process remaining accounts
let remaining_accounts = if remaining_accounts_info.is_none() {
ParsedRemainingAccounts::default()
} else {
parse_remaining_accounts(
&mut ctx.remaining_accounts,
&remaining_accounts_info.unwrap().slices,
&[AccountsType::TransferHookInput],
)?
let mut remaining_accounts = &ctx.remaining_accounts[..];
let parsed_transfer_hook_accounts = match remaining_accounts_info {
Some(info) => parse_remaining_accounts(
&mut remaining_accounts,
&info.slices,
&[AccountsType::TransferHookEscrow],
)?,
None => ParsedRemainingAccounts::default(),
};

transfer_to_escrow_v2(
Expand All @@ -99,7 +105,7 @@ pub fn handle_create_vesting_escrow_v2<'c: 'info, 'info>(
params.get_total_deposit_amount()?,
&ctx.accounts.token_mint,
)?,
remaining_accounts.transfer_hook_input,
parsed_transfer_hook_accounts.transfer_hook_escrow,
)?;

let &CreateVestingEscrowParameters {
Expand Down
2 changes: 2 additions & 0 deletions programs/locker/src/util/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub const TRANSFER_MEMO_CLAIM_VESTING: &str = "Jup-Lock ClaimVesting";
pub const TRANSFER_MEMO_CANCEL_VESTING: &str = "Jup-Lock CancelVesting";
4 changes: 3 additions & 1 deletion programs/locker/src/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pub use constants::*;
pub use remaining_accounts::*;
pub use token2022::*;

pub mod constants;
pub mod remaining_accounts;
pub mod token;
pub mod token2022;
pub mod remaining_accounts;
26 changes: 5 additions & 21 deletions programs/locker/src/util/remaining_accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use crate::LockerError;

#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)]
pub enum AccountsType {
TransferHookInput,
TransferHookClaim,
TransferHookCancel,
TransferHookEscrow,
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
Expand All @@ -22,9 +20,7 @@ pub struct RemainingAccountsInfo {

#[derive(Default)]
pub struct ParsedRemainingAccounts<'a, 'info> {
pub transfer_hook_input: Option<&'a [AccountInfo<'info>]>,
pub transfer_hook_claim: Option<&'a [AccountInfo<'info>]>,
pub transfer_hook_cancel: Option<&'a [AccountInfo<'info>]>,
pub transfer_hook_escrow: Option<&'a [AccountInfo<'info>]>,
}

pub fn parse_remaining_accounts<'a, 'info>(
Expand Down Expand Up @@ -56,23 +52,11 @@ pub fn parse_remaining_accounts<'a, 'info>(
*remaining_accounts = &remaining_accounts[end_idx..];

match slice.accounts_type {
AccountsType::TransferHookInput => {
if parsed_remaining_accounts.transfer_hook_input.is_some() {
AccountsType::TransferHookEscrow => {
codewithgun marked this conversation as resolved.
Show resolved Hide resolved
if parsed_remaining_accounts.transfer_hook_escrow.is_some() {
return Err(LockerError::DuplicatedRemainingAccountTypes.into());
}
parsed_remaining_accounts.transfer_hook_input = Some(accounts);
}
AccountsType::TransferHookClaim => {
if parsed_remaining_accounts.transfer_hook_claim.is_some() {
return Err(LockerError::DuplicatedRemainingAccountTypes.into());
}
parsed_remaining_accounts.transfer_hook_claim = Some(accounts);
}
AccountsType::TransferHookCancel => {
if parsed_remaining_accounts.transfer_hook_cancel.is_some() {
return Err(LockerError::DuplicatedRemainingAccountTypes.into());
}
parsed_remaining_accounts.transfer_hook_cancel = Some(accounts);
parsed_remaining_accounts.transfer_hook_escrow = Some(accounts);
}
}
}
Expand Down
Loading
Loading