Associated Token Account check not enforced on withdrawal account
Description
It was found that in Withdraw
, the to_account
is not enforced to be an Associated Token Account (ATA).
#[derive(Accounts)]
#[instruction(claim: WithdrawalClaim)]
pub struct Withdraw<'info> {
[...]
#[account(mut, constraint = to_account.owner == claim.user)]
pub to_account: InterfaceAccount<'info, TokenAccount>,
The Solana Token Program allows users to arbitrarily create many token accounts belonging to the same mint. Note that anyone can create these accounts for a specified owner.
It is therefore possible for a caller to create a separate account (still controlled by the owner) to withdraw the funds.
Impact
The caller can withdraw funds to a non-ATA token account. This is not a security issue as the token account would still be controlled and managed by the owner.
Recommendations
Enforce to_account
in Withdraw
to be an ATA.
Remediation
Layer N acknowledged the issue, and decided not to apply a remediation with the following explanation:
This is intended behaviour as a flexibility of the api that we get “for free” by not enforcing ATA. The signer of the withdraw transaction is responsible for the destination account and this should be harmless as the owner is validated.