Skip to content

feat: ARC-20/ARC-22 token interface detection on Program#61

Merged
iamalwaysuncomfortable merged 2 commits into
masterfrom
feat/arc20-arc22-detection
Jul 23, 2026
Merged

feat: ARC-20/ARC-22 token interface detection on Program#61
iamalwaysuncomfortable merged 2 commits into
masterfrom
feat/arc20-arc22-detection

Conversation

@iamalwaysuncomfortable

Copy link
Copy Markdown
Member

Summary

Adds Program.is_arc20() and Program.is_arc22(), classifying a parsed .aleo program against the ARC-20 (IARC20) and ARC-22 (IARC22) token interfaces. Ported from the wasm SDK's implementation so both SDKs classify programs identically.

Detection is exact signature matching, not name presence — the two standards share every function name and differ only in signatures:

  • Required records with open entries (the spec's ..): Token (owner private + amount: u128), plus ComplianceRecord for ARC-22.
  • Required functions with exact input/output types; Final outputs must be the program's own future.
  • ARC-22 [MerkleProof; 2u32] inputs matched structurally — the struct may be local (shape checked) or imported from a freeze-list program (name-only).
  • The seven shared view functions (balance_of, allowance, supply, max_supply, decimals, name, symbol) via snarkVM's first-class view declarations.
  • is_arc22 covers the token interface only, not IARC22Freezelist (separate registry program).

Bug fix

While porting, found that get_function_inputs reported the program name instead of the struct name as struct_id for imported (external) structs — snarkVM's Locator::name() returns the program name; resource() is the struct name. Fixed with a regression test.

Test vectors

fixture is_arc20 is_arc22
test_arc20_eth.aleo (deployed testnet)
compliant_token_template.aleo (Leo-compiled, imports MerkleProof from freezelist.aleo)
test_usdcx_stablecoin.aleo (deployed testnet near-miss: IARC22 signatures, no views)
arc20_token.aleo / arc22_token.aleo (synthetic, for mutation tests) ✅/✗ ✗/✅

Plus mutation tests: wrong amount type, missing function/view, wrong view signature, foreign futures, public record owner, wrong record name, wrong MerkleProof shape, missing ComplianceRecord.

Testing

  • cargo check + cargo fmt --check clean
  • Full pytest suite: 874 passed (22 in test_programs.py, 21 new)

Program.is_arc20() / Program.is_arc22() classify a parsed .aleo program
against the IARC20 / IARC22 token interfaces by exact signature matching:
required records (Token, ComplianceRecord) with open entries, required
functions (own-program future outputs, structural MerkleProof matching for
local or imported structs), and the seven shared view functions via
snarkVM's first-class view declarations. Ported from the wasm SDK to keep
semantics identical across SDKs.

Also fixes get_function_inputs reporting the program name instead of the
struct name as struct_id for imported (external) structs — Locator::name()
returns the program name; resource() is the struct name.

Test vectors: the deployed testnet test_arc20_eth.aleo (ARC-20 pass), the
Leo-compiled compliant_token_template.aleo (ARC-22 pass, external
MerkleProof), the deployed test_usdcx_stablecoin.aleo (near-miss: IARC22
signatures but no views), plus synthetic minimal programs for mutation
tests.
pip install --find-links dist aleo-sdk also consults PyPI. While the
branch version outversioned PyPI this always resolved locally, but now
that 0.2.2 is published the same version exists in both sources and
pip breaks the tie by wheel-tag preference: on linux the local
manylinux_2_38 tag outranks PyPI's manylinux_2_28, but on macOS and
Windows the tags are identical and pip picks the PyPI wheel — so the
test jobs silently exercised the released binary instead of the one
just built from the branch (the ARC-20/22 failures on this PR).

Install every locally built wheel by explicit path so the artifact
under test is always the one that was just built.
@Roee-87
Roee-87 self-requested a review July 23, 2026 21:44
@iamalwaysuncomfortable
iamalwaysuncomfortable merged commit 256c7a3 into master Jul 23, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants