fix(transfer-sol): require payer signature + checked lamport math#532
fix(transfer-sol): require payer signature + checked lamport math#532yukikm wants to merge 1 commit intosolana-developers:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR hardens the Anchor transfer_sol_with_program example to prevent unauthorized lamport drains by requiring the source (payer) to sign and by using checked lamport arithmetic with explicit error reporting.
Changes:
- Require
payerto be aSigner<'info>(while still enforcingowner = id()). - Add explicit insufficient-funds check plus checked
sub/addfor lamport math, returning custom errors. - Update the Anchor TS test to include
payerAccountas an explicit signer.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| basics/transfer-sol/anchor/programs/transfer-sol/src/lib.rs | Enforces payer signature + checked lamport mutation with custom error codes. |
| basics/transfer-sol/anchor/tests/test.ts | Updates the “Transfer SOL with Program” test to sign with the program-owned payer keypair. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let payer_lamports = ctx.accounts.payer.to_account_info().lamports(); | ||
| require!(payer_lamports >= amount, TransferSolError::InsufficientFunds); | ||
|
|
||
| **ctx.accounts.payer.try_borrow_mut_lamports()? = payer_lamports | ||
| .checked_sub(amount) | ||
| .ok_or(TransferSolError::LamportArithmeticOverflow)?; |
There was a problem hiding this comment.
New failure modes are introduced here (missing payer signature, insufficient funds, arithmetic error), but the test suite only covers the success path. Add negative tests that (1) omit .signers([payerAccount]) and assert the instruction fails due to missing signature, and (2) attempt to transfer more than the payer balance and assert InsufficientFunds is returned (and balances remain unchanged).
This fixes a dangerous footgun in the Anchor transfer-sol example.
Problem:
transfer_sol_with_programmutates lamports of a program-ownedpayeraccount but previously did not require the payer to sign.payer.Fix:
payer: Signer<'info>while keepingowner = id()constraint..signers([payerAccount]).