Skip to content

Reject foreign-owned token definitions in InitializeAccount #80

@3esmit

Description

@3esmit

Summary

token::initialize_account should reject token definition accounts that are not owned by the executing token program.

The current implementation only checks that the destination holding account is uninitialized and authorized, then deserializes the supplied definition account as TokenDefinition. It does not check definition_account.account.program_owner, so a Borsh-valid definition owned by a foreign token-like program can be used to create a holding that is claimed by the canonical token program but points at a non-canonical definition.

This is the token-program subissue for the trust-boundary hardening tracked in #70. It complements the AMM deposit-account case in #69, where the broader question is whether token accounts should be tied to a specific token program ID.

Affected Area

  • token/src/initialize.rs has a TODO for checking definition ownership, but currently accepts any account whose data decodes as TokenDefinition.
  • token/methods/guest/src/bin/token.rs exposes InitializeAccount without passing the executing token program ID into the token implementation.
  • token/src/tests.rs covers successful initialization and missing authorization, but does not cover a foreign-owner definition account.

Why This Matters

Token holdings should not be initialized against definitions from another program namespace. Otherwise downstream code can see a token-owned holding whose definition_id refers to a definition account that the token program does not own.

That weakens the ownership model that AMM and ATA need to rely on when deciding whether an account is a canonical token account. The token program should enforce the invariant at the point where it creates the holding.

Proposed Scope

  • Make InitializeAccount compare the definition account owner with the executing token program ID.
  • Reject a foreign-owner definition before deriving the zeroized holding.
  • Thread the executing program ID into the token initialize path if the current guest wrapper does not expose it to the handler.
  • Keep the check local to token ownership; AMM and ATA dispatch hardening should remain separate subissues under #70.

Acceptance Criteria

  • token::initialize_account rejects a definition account whose program_owner is not the executing token program ID.
  • The rejection happens before writing a token holding for the destination account.
  • Unit tests cover a Borsh-valid TokenDefinition with a foreign program_owner.
  • Integration coverage exercises InitializeAccount through the token guest path with a foreign-owner definition account.
  • Existing valid InitializeAccount behavior continues to work for canonical token-owned definitions.

Notes

  • The current LEZ/SPEL input model includes self_program_id; the implementation should use that value rather than adding a user-supplied token program argument.
  • The failure should be explicit and deterministic, matching the repository's existing token-program assertion style unless the error surface is refactored separately.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions