Skip to content

Lock token-program ownership and chained-call dispatch across AMM, ATA, and token #70

@3esmit

Description

@3esmit

Summary

The same trust-boundary bug class appears across amm, ata, and token: downstream token-program identity and account validity are derived from attacker-controlled account metadata or PDA occupancy instead of a canonical token-program identity plus validated account shape.

That currently leaves room for:

  • AMM pool, vault, and LP namespace squatting through attacker-controlled token-like programs
  • ATA PDA poisoning through non-canonical child-program dispatch
  • Token-owned zombie holdings initialized against foreign definitions
  • Invalid ATA-PDA occupants being treated as idempotent success

This should be treated as a single security hardening issue because the fixes all live in the same ownership and dispatch decisions.

Affected Areas

  • amm::new_definition can forward AMM PDA authority into an attacker-controlled token-like program.
  • ata has the same confused-deputy pattern and can poison ATA PDAs.
  • token::initialize_account accepts foreign definitions and can create zombie holdings.
  • ata::create treats any preexisting ATA-PDA occupant as valid idempotent success.

Related GitHub Issues

  • #43 and #48 cover LEZ and SPEL dependency alignment. The LEZ change includes self_program_id and caller_program_id, which can make ownership and call-origin checks easier to express.
  • #69 tracks the AMM subset raised from status-im/audit-reports#81: user deposit accounts are not checked against the vault token-program owner, so malicious token-program-owned deposits can advance AMM accounting without moving real vault tokens. It also asks whether all token accounts should be required to use a specific token program ID.

Proposed Scope

  • Bind AMM child dispatch to a canonical token program instead of trusting user-supplied holding ownership.
  • Require validated token definition accounts as the authority source for AMM pool creation.
  • Make ATA create, transfer, and burn reject downstream dispatch unless the token definition and ATA contents match token-program invariants.
  • Require token::initialize_account to reject definitions whose program_owner is not the executing token program.
  • Make ATA idempotent create validate the existing PDA occupant before returning success.
  • Tighten any user-facing comments or docs that currently imply looser trust assumptions.

Acceptance Criteria

  • amm::new_definition rejects holdings unless they resolve to a trusted token program and validated token definitions.
  • ata::create, ata::transfer, and ata::burn reject non-canonical token-program dispatch.
  • token::initialize_account rejects foreign-owner definitions.
  • ata::create returns an explicit failure when the ATA PDA is occupied by an incompatible account.
  • Unit and integration tests cover malicious token-like child programs, ATA poisoning attempts, foreign-owner definitions, and malformed ATA occupants.

Notes

  • This issue intentionally groups the ownership and dispatch validation failures because they share the same trust boundary.
  • If the LEZ dependency alignment lands first, this issue should re-evaluate whether self_program_id and caller_program_id can reduce validation complexity.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions