I've noticed many programs on Solana written with Anchor asks for the bump in the instruction data, then checks it inside the #account macro with bump = bump.

I've tried omitting the caller-supplied bump parameter, using just #[account(seeds = [...], bump)] and passing a non-canonical PDA address, and Anchor correctly throws an error Cross-program invocation with unauthorized signer or writable account.

So it seems like having the caller-supplied bump makes no difference to checking if the PDA is canonical. Furthermore you can always retrieve the canonical bump via ctx.bumps.get("<account>").

Am I missing something here?

1 Answer 1


Okay so got an answer from the man/myth/legend Armani:

  1. Never pass bump via instruction data
  2. init should not specify a bump explicitly
  3. Recommended: store bump in PDA
  4. Recommended: subsequent use of seeds should always specify a bump from the account data, ie bump = account.bump constraint

(3)/(4) are recommended but not necessary since you can still use a naked bump constraint, but less efficient since find_program_address needs to be invoked + validated.

  • Richard, 1. Why should we store bump in PDA ? 2. Number (4) is unclear to me Aug 29, 2022 at 8:04
  • because it is faster and deterministic to derive the PDA when you provide the bump. If you don't provide the bump, the lib will loop trying to "find" the PDA with different bumps (255->0), so the computation units can vary depending on the seeds you use. E.g. you're using user account as seed and not storing bump: consequence: the instruction has different cost depending on the user account (more or less tries to find the first PDA), so the instruction can fail for some (all CPU budget consumed) and work for others May 10, 2023 at 9:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.