Skip to content

Commit

Permalink
lang: add rent exempt check for init_if_needed when init is not needed (
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-schaaf committed Jan 6, 2022
1 parent a830644 commit 4d4cba5
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -13,6 +13,7 @@ incremented for features.

### Fixes

* lang: `init_if_needed` now checks rent exemption when init is not needed ([#1250](https://github.com/project-serum/anchor/pull/1250)).
* lang: Add missing owner check when `associated_token::authority` is used ([#1240](https://github.com/project-serum/anchor/pull/1240)).
* ts: Add type declarations for conditional `workspace` and `Wallet` exports ([#1137](https://github.com/project-serum/anchor/pull/1137)).
* ts: Change commitment message `recent` to `processed` and `max` to `finalized` ([#1128](https://github.com/project-serum/anchor/pull/1128))
Expand Down
7 changes: 7 additions & 0 deletions lang/syn/src/codegen/accounts/constraints.rs
Expand Up @@ -621,6 +621,13 @@ pub fn generate_init(
return Err(anchor_lang::__private::ErrorCode::ConstraintOwner.into());
}

{
let required_lamports = __anchor_rent.minimum_balance(space);
if pa.to_account_info().lamports() < required_lamports {
return Err(anchor_lang::__private::ErrorCode::ConstraintRentExempt.into());
}
}

#pda_check
}
pa
Expand Down
19 changes: 19 additions & 0 deletions tests/misc/programs/misc/src/context.rs
Expand Up @@ -360,3 +360,22 @@ pub struct EnforceRentExempt<'info> {
#[account(rent_exempt = enforce)]
pub data: AccountInfo<'info>,
}

#[derive(Accounts)]
pub struct InitDecreaseLamports<'info> {
#[account(init, payer = user, space = 1000)]
pub data: AccountInfo<'info>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>
}

#[derive(Accounts)]
pub struct InitIfNeededChecksRentExemption<'info> {
#[account(init_if_needed, payer = user, space = 1000)]
pub data: AccountInfo<'info>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>
}

10 changes: 10 additions & 0 deletions tests/misc/programs/misc/src/lib.rs
Expand Up @@ -258,4 +258,14 @@ pub mod misc {
pub fn test_enforce_rent_exempt(ctx: Context<EnforceRentExempt>) -> ProgramResult {
Ok(())
}

pub fn init_decrease_lamports(ctx: Context<InitDecreaseLamports>) -> ProgramResult {
**ctx.accounts.data.try_borrow_mut_lamports()? -= 1;
**ctx.accounts.user.try_borrow_mut_lamports()? += 1;
Ok(())
}

pub fn init_if_needed_checks_rent_exemption(_ctx: Context<InitIfNeededChecksRentExemption>) -> ProgramResult {
Ok(())
}
}
26 changes: 26 additions & 0 deletions tests/misc/tests/misc.js
Expand Up @@ -1398,6 +1398,32 @@ describe("misc", () => {
}
});

it("init_if_needed checks rent_exemption if init is not needed", async () => {
const data = anchor.web3.Keypair.generate();
await program.rpc.initDecreaseLamports({
accounts: {
data: data.publicKey,
user: anchor.getProvider().wallet.publicKey,
systemProgram: SystemProgram.programId,
},
signers: [data],
});

try {
await program.rpc.initIfNeededChecksRentExemption({
accounts: {
data: data.publicKey,
user: anchor.getProvider().wallet.publicKey,
systemProgram: SystemProgram.programId,
},
signers: [data],
});
assert.ok(false);
} catch (err) {
assert.equal(err.code, 2005);
}
});

it("Can use multidimensional array", async () => {
const array2d = new Array(10).fill(new Array(10).fill(99));
const data = anchor.web3.Keypair.generate();
Expand Down

0 comments on commit 4d4cba5

Please sign in to comment.