The Token contract implements an ERC-20-like token with Aztec-specific privacy extensions. It supports transfers and interactions through both private and public balances, offering full coverage of Aztec's confidentiality features.
This implementation provides a robust foundation for fungible tokens on Aztec, enabling developers to build applications with flexible privacy controls and seamless interoperability between private and public states.
This contract follows the AIP-20 Aztec Token Standard. Feel free to review and discuss the specification on the Aztec forum.
The contract emits a public Transfer { from, to, amount } event on every balance-changing operation (mints, burns, public transfers, and cross-domain private ↔ public moves), enabling indexers to track token movements.
| Operation | Event Pattern |
|---|---|
| Mint to public | Transfer(0x0, recipient, amount) |
| Mint to private | Transfer(0x0, PRIVATE_ADDRESS, amount) |
| Burn from public | Transfer(from, 0x0, amount) |
| Burn from private | Transfer(PRIVATE_ADDRESS, 0x0, amount) |
| Public-to-public | Transfer(from, to, amount) |
| Public-to-private | Transfer(from, PRIVATE_ADDRESS, amount) |
| Private-to-public | Transfer(PRIVATE_ADDRESS, to, amount) |
| Private-to-private | (no public events) |
Sentinel values: 0x0 denotes mint origin (from) or burn destination (to), following ERC-20. PRIVATE_ADDRESS (sha224 of "PRIVATE_ADDRESS") denotes the private side of a balance change when the counterpart cannot be revealed.
name: str<31>: Token name (compressed).symbol: str<31>: Token symbol (compressed).decimals: u8: Decimal precision.private_balances: Map<AztecAddress, BalanceSet>: Private balances per account.public_balances: Map<AztecAddress, u128>: Public balances per account.total_supply: u128: Total token supply.minter: AztecAddress: Authorized minter address (if set).
/// @notice Initializes the token with an initial supply
/// @dev Since this constructor doesn't set a minter address the mint functions will be disabled
/// @param name The name of the token
/// @param symbol The symbol of the token
/// @param decimals The number of decimals of the token
/// @param initial_supply The initial supply of the token
/// @param to The address to mint the initial supply to
#[public]
#[initializer]
fn constructor_with_initial_supply(
name: str<31>,
symbol: str<31>,
decimals: u8,
initial_supply: u128,
to: AztecAddress,
) { /* ... */ }/// @notice Initializes the token with a minter
/// @param name The name of the token
/// @param symbol The symbol of the token
/// @param decimals The number of decimals of the token
/// @param minter The address of the minter
#[public]
#[initializer]
fn constructor_with_minter(
name: str<31>,
symbol: str<31>,
decimals: u8,
minter: AztecAddress,
) { /* ... */ }/// @notice Returns the public balance of `owner`
/// @param owner The address of the owner
/// @return The public balance of `owner`
#[public]
#[view]
fn balance_of_public(owner: AztecAddress) -> u128 { /* ... */ }/// @notice Returns the total supply of the token
/// @return The total supply of the token
#[public]
#[view]
fn total_supply() -> u128 { /* ... */ }/// @notice Returns the name of the token
/// @return The name of the token
#[public]
#[view]
fn name() -> FieldCompressedString { /* ... */ }/// @notice Returns the symbol of the token
/// @return The symbol of the token
#[public]
#[view]
fn symbol() -> FieldCompressedString { /* ... */ }/// @notice Returns the decimals of the token
/// @return The decimals of the token
#[public]
#[view]
fn decimals() -> u8 { /* ... */ }/// @notice Returns the private balance of `owner`
/// @param owner The address of the owner
/// @return The private balance of `owner`
#[utility]
unconstrained fn balance_of_private(owner: AztecAddress) -> u128 { /* ... */ }/// @notice Transfers tokens from public balance to public balance
/// @dev Public call to decrease account balance and a public call to increase recipient balance
/// @param from The address of the sender
/// @param to The address of the recipient
/// @param amount The amount of tokens to transfer
/// @param nonce The nonce used for authwit
#[public]
fn transfer_public_to_public(
from: AztecAddress,
to: AztecAddress,
amount: u128,
nonce: Field,
) { /* ... */ }/// @notice Finalizes a transfer of token `amount` from public balance of `from` to a commitment of `to`
/// @dev The transfer must be prepared by calling `initialize_transfer_commitment` first and the resulting
/// `commitment` must be passed as an argument to this function
/// @param from The address of the sender
/// @param commitment The Field representing the commitment (privacy entrance)
/// @param amount The amount of tokens to transfer
/// @param nonce The nonce used for authwit
#[public]
fn transfer_public_to_commitment(
from: AztecAddress,
commitment: Field,
amount: u128,
nonce: Field,
) { /* ... */ }/// @notice Mints tokens to a public balance
/// @dev Increases the public balance of `to` by `amount` and the total supply
/// @param to The address of the recipient
/// @param amount The amount of tokens to mint
#[public]
fn mint_to_public(
to: AztecAddress,
amount: u128,
) { /* ... */ }/// @notice Finalizes a mint to a commitment
/// @dev Finalizes a mint to a commitment and updates the total supply
/// @param commitment The Field representing the mint commitment (privacy entrance)
/// @param amount The amount of tokens to mint
#[public]
fn mint_to_commitment(
commitment: Field,
amount: u128,
) { /* ... */ }/// @notice Burns tokens from a public balance
/// @dev Burns tokens from a public balance and updates the total supply
/// @param from The address of the sender
/// @param amount The amount of tokens to burn
/// @param nonce The nonce used for authwit
#[public]
fn burn_public(
from: AztecAddress,
amount: u128,
nonce: Field,
) { /* ... */ }/// @notice Transfer tokens from private balance to public balance
/// @dev Spends notes, emits a new note (UintNote) with any remaining change, and enqueues a public call
/// @param from The address of the sender
/// @param to The address of the recipient
/// @param amount The amount of tokens to transfer
/// @param nonce The nonce used for authwit
#[private]
fn transfer_private_to_public(
from: AztecAddress,
to: AztecAddress,
amount: u128,
nonce: Field,
) { /* ... */ }/// @notice Transfer tokens from private balance to public balance with a commitment
/// @dev Spends notes, emits a new note (UintNote) with any remaining change, enqueues a public call, and returns a partial note
/// @param from The address of the sender
/// @param to The address of the recipient
/// @param amount The amount of tokens to transfer
/// @param nonce The nonce used for authwit
/// @return commitment The partial note utilized for the transfer commitment (privacy entrance)
#[private]
fn transfer_private_to_public_with_commitment(
from: AztecAddress,
to: AztecAddress,
amount: u128,
nonce: Field,
) -> Field { /* ... */ }/// @notice Transfer tokens from private balance to private balance
/// @dev Spends notes, emits a new note (UintNote) with any remaining change, and sends a note to the recipient
/// @param from The address of the sender
/// @param to The address of the recipient
/// @param amount The amount of tokens to transfer
/// @param nonce The nonce used for authwit
#[private]
fn transfer_private_to_private(
from: AztecAddress,
to: AztecAddress,
amount: u128,
nonce: Field,
) { /* ... */ }/// @notice Transfer tokens from private balance to the recipient commitment (recipient must create a commitment first)
/// @dev Spends notes, emits a new note (UintNote) with any remaining change, and enqueues a public call
/// @param from The address of the sender
/// @param commitment The Field representing the commitment (privacy entrance that the recipient shares with the sender)
/// @param amount The amount of tokens to transfer
/// @param nonce The nonce used for authwit
#[private]
fn transfer_private_to_commitment(
from: AztecAddress,
commitment: Field,
amount: u128,
nonce: Field,
) { /* ... */ }/// @notice Transfer tokens from public balance to private balance
/// @dev Enqueues a public call to decrease account balance and emits a new note with balance difference
/// @param from The address of the sender
/// @param to The address of the recipient
/// @param amount The amount of tokens to transfer
/// @param nonce The nonce used for authwit
#[private]
fn transfer_public_to_private(
from: AztecAddress,
to: AztecAddress,
amount: u128,
nonce: Field,
) { /* ... */ }/// @notice Initializes a transfer commitment to be used for transfers/mints
/// @dev Returns a partial note that can be used to execute transfers/mints
/// @param to The address of the recipient
/// @param completer The address used to compute the validity commitment
/// @return commitment The partial note initialized for the transfer/mint commitment
#[private]
fn initialize_transfer_commitment(to: AztecAddress, completer: AztecAddress) -> Field { /* ... */ }/// @notice Mints tokens into a private balance
/// @dev Requires minter, enqueues supply update
/// @param to The address of the recipient
/// @param amount The amount of tokens to mint
#[private]
fn mint_to_private(to: AztecAddress, amount: u128) { /* ... */ }/// @notice Burns tokens from a private balance
/// @dev Requires authwit, enqueues supply update
/// @param from The address of the sender
/// @param amount The amount of tokens to burn
/// @param nonce The nonce used for authwit
#[private]
fn burn_private(from: AztecAddress, amount: u128, nonce: Field) { /* ... */ }