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

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions