◂ labs
TIER 2 · CPI & PDAs · 6-duplicate-mutable-accounts
DUPLICATE MUTABLE ACCOUNTS
Pass the same account twice in the accounts array and the runtime hands your handler two mutable references to one account. Debit it as "A" and "B" — you just debited twice the same balance.
seen in the wild
Classic double-spend primitive; the fix is a one-line key equality check Anchor does via constraints.
rust · anchor
use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod duplicate_mutable_accounts_insecure {
use super::*;
pub fn update(ctx: Context<Update>, a: u64, b: u64) -> ProgramResult {
let user_a = &mut ctx.accounts.user_a;
let user_b = &mut ctx.accounts.user_b;
user_a.data = a;
user_b.data = b;
Ok(())
}
}
#[derive(Accounts)]
pub struct Update<'info> {
user_a: Account<'info, User>,
user_b: Account<'info, User>,
}
#[account]
pub struct User {
data: u64,
}
next labBUMP SEED CANONICALIZATION ▸