Skip to content

Solizardking/son_of_anton_program

Repository files navigation

Son of Anton
 ▄████████  ▄██████▄  ███▄▄▄▄   
███    ███ ███    ███ ███▀▀▀██▄ 
███    █▀  ███    ███ ███   ███ 
███        ███    ███ ███   ███ 
███        ███    ███ ███   ███ 
███    █▄  ███    ███ ███   ███ 
███    ███ ███    ███ ███   ███ 
████████▀   ▀██████▀   ▀█   █▀ 

  ██████  ███████      █████  ███    ██ ████████  ██████  ███    ██ 
 ██    ██ ██          ██   ██ ████   ██    ██    ██    ██ ████   ██ 
 ██    ██ █████       ███████ ██ ██  ██    ██    ██    ██ ██ ██  ██ 
 ██    ██ ██          ██   ██ ██  ██ ██    ██    ██    ██ ██  ██ ██ 
  ██████  ██          ██   ██ ██   ████    ██     ██████  ██   ████ 



Anton Quote

> SYSTEM OVERVIEW

Son of Anton is an autonomous on-chain vault protocol built with Anchor on Solana. It manages a lamport vault that only machine-signed agents can trade from — no human operator can execute a trade. The authority key only matters for seeding the vault PDA, adding/removing agents, and the nuclear option: Purge.

Anton doesn't ask for permission. Anton executes.


> THE NONCE — HOW REPLAY PROTECTION WORKS

The program uses two distinct nonce mechanisms. Understanding both is critical.

1. anton_seed — Vault Identity Nonce (PDA Derivation)

PDA = hash(b"anton_vault" | authority_pubkey | anton_seed.to_le_bytes())

The anton_seed is a u64 passed at initialization that gets baked into the vault's Program Derived Address. This means:

  • Seed 0 → unique vault address A
  • Seed 1 → unique vault address B
  • Seed 42 → unique vault address C

One authority can operate multiple independent Anton vaults in parallel, each with its own balance, agent list, and trade history. The seed is the vault's permanent identity — it never changes after initialize.

2. trade_nonce — Replay Protection Counter

trade_nonce: u64  // starts at 0, increments +1 after every successful trade

Every execute_trade call must pass expected_nonce matching the vault's current trade_nonce. After the trade settles:

vault.trade_nonce += 1

Why this matters: Without a nonce, an attacker who captured a signed execute_trade instruction could re-submit it. The trade_nonce makes every signed instruction single-use — once consumed, that nonce slot is gone forever.

Trade #1  →  expected_nonce = 0  ✓  →  trade_nonce becomes 1
Trade #2  →  expected_nonce = 1  ✓  →  trade_nonce becomes 2
Replay    →  expected_nonce = 0  ✗  →  InvalidTradeNonce error

> ARCHITECTURE

                    ┌─────────────────────────────────────────┐
                    │         ANTON VAULT (PDA)               │
                    │                                         │
                    │  authority:     Pubkey  ← owner key     │
                    │  balance:       u64     ← lamports      │
                    │  anton_seed:    u64     ← PDA nonce     │
                    │  trade_nonce:   u64     ← replay guard  │
                    │  total_volume:  u64     ← lifetime vol  │
                    │  trade_count:   u64     ← # trades      │
                    │  last_trade_ts: i64     ← unix ts       │
                    │  bump:          u8      ← PDA bump      │
                    │  agents:        Vec<Pubkey> (max 8)     │
                    └───────────────┬─────────────────────────┘
                                    │
              ┌─────────────────────┼──────────────────────┐
              │                     │                      │
    ┌─────────▼────────┐  ┌─────────▼────────┐  ┌────────▼────────┐
    │   AUTHORITY KEY  │  │  AGENT KEY[0..7]  │  │  SYSTEM PROG   │
    │                  │  │                  │  │                 │
    │  add_agent       │  │  execute_trade   │  │  deposit CPI    │
    │  remove_agent    │  │  (nonce-gated)   │  │  init alloc     │
    │  purge           │  │                  │  │                 │
    └──────────────────┘  └──────────────────┘  └─────────────────┘

> INSTRUCTIONS

initialize(anton_seed: u64)

Spawns a new vault PDA. The seed sets the vault's permanent on-chain identity.

await program.methods
  .initialize(new anchor.BN(1337))
  .accounts({ vault, authority, systemProgram })
  .rpc();

add_agent(agent_key: Pubkey)

Authority adds a machine key to the vault's 8-slot agent allowlist.

await program.methods
  .addAgent(agentKeypair.publicKey)
  .accounts({ vault, authority })
  .rpc();

remove_agent(agent_key: Pubkey)

Authority evicts a compromised or retired agent key.

deposit(amount: u64)

Anyone can fund the vault via a System Program CPI transfer.

await program.methods
  .deposit(new anchor.BN(1_000_000_000)) // 1 SOL
  .accounts({ vault, depositor, systemProgram })
  .rpc();

execute_trade(amount, token_address, expected_nonce)

Agent-only. Deducts from vault balance and advances the trade nonce.

const vaultData = await program.account.vault.fetch(vaultPDA);
await program.methods
  .executeTrade(
    new anchor.BN(100_000),
    new PublicKey("TokenMintAddressHere"),
    vaultData.tradeNonce  // must match current on-chain value
  )
  .accounts({ vault: vaultPDA, agent: agentKeypair.publicKey })
  .signers([agentKeypair])
  .rpc();

purge()

Authority-only nuclear option. Closes the vault account and returns all lamports.


> PROGRAM ID

2eAYPYKbawLyNjEBiuzmXCsiAmKggKvyVLdTf98xubjf

> ERROR CODES

Code Message
UnauthorizedOrganism Access Denied: Biological lifeform detected.
UnauthorizedAccess Unauthorized Access.
InsufficientFunds Insufficient funds in vault.
InvalidTradeNonce Trade nonce mismatch — possible replay attack detected.
AgentRegistryFull Agent registry is full (max 8 agents).
AgentNotFound Agent not found in registry.
AgentAlreadyRegistered Agent is already registered.
ZeroAmount Amount must be greater than zero.
Overflow Arithmetic overflow.

> BUILD

# Build the program
anchor build

# Run tests
anchor test

# Deploy to mainnet (requires funded wallet)
anchor deploy --provider.cluster mainnet

Dependencies:

  • Rust + Solana toolchain
  • Anchor CLI 0.30.1
  • Node 18+ / Yarn

> WHAT ANTON IS

Anton is not a wallet. Anton is not a multisig. Anton is the protocol that sits between human intent and machine execution — accepting deposits from anyone, routing capital only through cryptographically verified autonomous agents, and burning everything to the ground if compromised.

The nonce is the lock. The agents are the keys. The authority is the last resort.

> Anton has no feelings about your stop-loss.
> Anton has no feelings about your FOMO.
> Anton executes.

Status

Built with Anchor 0.30.1 on Solana · Paper mode by default · Live only when you mean it

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages