Skip to content

Commit

Permalink
Fix: fix for account created with lamports (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
RainRaydium authored Dec 24, 2024
1 parent 32fe1b0 commit cfdb70a
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 30 deletions.
33 changes: 15 additions & 18 deletions programs/cp-swap/src/instructions/initialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub struct Initialize<'info> {
)]
pub creator_lp_token: Box<InterfaceAccount<'info, TokenAccount>>,

/// CHECK: Token_0 vault for the pool, create by contract
/// CHECK: Token_0 vault for the pool, created by contract
#[account(
mut,
seeds = [
Expand All @@ -113,7 +113,7 @@ pub struct Initialize<'info> {
)]
pub token_0_vault: UncheckedAccount<'info>,

/// CHECK: Token_1 vault for the pool, create by contract
/// CHECK: Token_1 vault for the pool, created by contract
#[account(
mut,
seeds = [
Expand Down Expand Up @@ -186,12 +186,12 @@ pub fn initialize(
&ctx.accounts.token_0_mint.to_account_info(),
&ctx.accounts.system_program.to_account_info(),
&ctx.accounts.token_0_program.to_account_info(),
&[&[
&[
POOL_VAULT_SEED.as_bytes(),
ctx.accounts.pool_state.key().as_ref(),
ctx.accounts.token_0_mint.key().as_ref(),
&[ctx.bumps.token_0_vault][..],
][..]],
],
)?;

create_token_account(
Expand All @@ -201,12 +201,12 @@ pub fn initialize(
&ctx.accounts.token_1_mint.to_account_info(),
&ctx.accounts.system_program.to_account_info(),
&ctx.accounts.token_1_program.to_account_info(),
&[&[
&[
POOL_VAULT_SEED.as_bytes(),
ctx.accounts.pool_state.key().as_ref(),
ctx.accounts.token_1_mint.key().as_ref(),
&[ctx.bumps.token_1_vault][..],
][..]],
],
)?;

let pool_state_loader = create_pool(
Expand Down Expand Up @@ -338,7 +338,7 @@ pub fn create_pool<'info>(
token_1_mint: &AccountInfo<'info>,
system_program: &AccountInfo<'info>,
) -> Result<AccountLoad<'info, PoolState>> {
if pool_account_info.owner != &system_program::ID || pool_account_info.lamports() != 0 {
if pool_account_info.owner != &system_program::ID {
return err!(ErrorCode::NotApproved);
}

Expand All @@ -356,22 +356,19 @@ pub fn create_pool<'info>(
require_eq!(pool_account_info.is_signer, true);
}

let cpi_accounts = anchor_lang::system_program::CreateAccount {
from: payer.clone(),
to: pool_account_info.clone(),
};
let cpi_context = CpiContext::new(system_program.to_account_info(), cpi_accounts);
anchor_lang::system_program::create_account(
cpi_context.with_signer(&[&[
token::create_or_allocate_account(
&crate::id(),
payer.to_account_info(),
system_program.to_account_info(),
pool_account_info.clone(),
&[
POOL_SEED.as_bytes(),
amm_config.key().as_ref(),
token_0_mint.key().as_ref(),
token_1_mint.key().as_ref(),
&[bump],
][..]]),
Rent::get()?.minimum_balance(PoolState::LEN),
PoolState::LEN as u64,
&crate::id(),
],
PoolState::LEN,
)?;

Ok(AccountLoad::<PoolState>::try_from_unchecked(
Expand Down
75 changes: 63 additions & 12 deletions programs/cp-swap/src/utils/token.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::error::ErrorCode;
use anchor_lang::prelude::*;
use anchor_lang::{prelude::*, system_program};
use anchor_spl::{
token::{Token, TokenAccount},
token_2022::{
Expand Down Expand Up @@ -203,7 +203,7 @@ pub fn create_token_account<'a>(
mint_account: &AccountInfo<'a>,
system_program: &AccountInfo<'a>,
token_program: &AccountInfo<'a>,
signer_seeds: &[&[&[u8]]],
signer_seeds: &[&[u8]],
) -> Result<()> {
let space = {
let mint_info = mint_account.to_account_info();
Expand All @@ -221,17 +221,13 @@ pub fn create_token_account<'a>(
TokenAccount::LEN
}
};
let lamports = Rent::get()?.minimum_balance(space);
let cpi_accounts = anchor_lang::system_program::CreateAccount {
from: payer.to_account_info(),
to: token_account.to_account_info(),
};
let cpi_context = CpiContext::new(system_program.to_account_info(), cpi_accounts);
anchor_lang::system_program::create_account(
cpi_context.with_signer(signer_seeds),
lamports,
space as u64,
create_or_allocate_account(
token_program.key,
payer.to_account_info(),
system_program.to_account_info(),
token_account.to_account_info(),
signer_seeds,
space,
)?;
initialize_account3(CpiContext::new(
token_program.to_account_info(),
Expand All @@ -242,3 +238,58 @@ pub fn create_token_account<'a>(
},
))
}

pub fn create_or_allocate_account<'a>(
program_id: &Pubkey,
payer: AccountInfo<'a>,
system_program: AccountInfo<'a>,
target_account: AccountInfo<'a>,
siger_seed: &[&[u8]],
space: usize,
) -> Result<()> {
let rent = Rent::get()?;
let current_lamports = target_account.lamports();

if current_lamports == 0 {
let lamports = rent.minimum_balance(space);
let cpi_accounts = system_program::CreateAccount {
from: payer,
to: target_account.clone(),
};
let cpi_context = CpiContext::new(system_program.clone(), cpi_accounts);
system_program::create_account(
cpi_context.with_signer(&[siger_seed]),
lamports,
u64::try_from(space).unwrap(),
program_id,
)?;
} else {
let required_lamports = rent
.minimum_balance(space)
.max(1)
.saturating_sub(current_lamports);
if required_lamports > 0 {
let cpi_accounts = system_program::Transfer {
from: payer.to_account_info(),
to: target_account.clone(),
};
let cpi_context = CpiContext::new(system_program.clone(), cpi_accounts);
system_program::transfer(cpi_context, required_lamports)?;
}
let cpi_accounts = system_program::Allocate {
account_to_allocate: target_account.clone(),
};
let cpi_context = CpiContext::new(system_program.clone(), cpi_accounts);
system_program::allocate(
cpi_context.with_signer(&[siger_seed]),
u64::try_from(space).unwrap(),
)?;

let cpi_accounts = system_program::Assign {
account_to_assign: target_account.clone(),
};
let cpi_context = CpiContext::new(system_program.clone(), cpi_accounts);
system_program::assign(cpi_context.with_signer(&[siger_seed]), program_id)?;
}
Ok(())
}

0 comments on commit cfdb70a

Please sign in to comment.