🚧 This documentation is currently under development. Content may be incomplete or subject to change. 🚧
Skip to content

Token Operations ​

High-level operations for confidential token contracts. They never revert and follow all-or-nothing semantics: if the operation cannot complete (insufficient balance, overflow), nothing changes and success is set to false. The previous ciphertexts are reassigned to the new output handles. This prevents leaking balance information through transaction success/failure (which would create a binary oracle).

These operations are composed from core primitives and executed atomically inside the TEE.

Usage ​

solidity
// Confidential ERC-20 transfer
(ebool ok, euint256 newFrom, euint256 newTo) = Nox.transfer(
    _balances[from],
    _balances[to],
    amount
);
Nox.allowThis(ok);
Nox.allowThis(newFrom);
Nox.allowThis(newTo);
Nox.allow(newFrom, from);
Nox.allow(newTo, to);
_balances[from] = newFrom;
_balances[to] = newTo;

transfer ​

solidity
function transfer(
    euint256 balanceFrom,
    euint256 balanceTo,
    euint256 amount
) internal returns (ebool success, euint256 newBalanceFrom, euint256 newBalanceTo)

Moves tokens between two balances. If amount > balanceFrom, nothing is transferred and all output handles retain the original values.

Overflow of balanceTo is impossible because the total supply is bounded by MAX_U, so balanceTo + amount <= totalSupply <= MAX_U is guaranteed.

Behavior:

if amount > balanceFrom:
    success        = false
    newBalanceFrom = balanceFrom    // ciphertext reassigned to new handle
    newBalanceTo   = balanceTo      // ciphertext reassigned to new handle
else:
    success        = true
    newBalanceFrom = balanceFrom - amount
    newBalanceTo   = balanceTo + amount
balanceFrombalanceToamountsuccessnewBalanceFromnewBalanceToReason
1000500300true700800Normal transfer
10005001000true01500Full balance transferred
10005002000false1000500Amount > balance, nothing transferred
0500100false0500Insufficient balance
1005000true100500Zero amount, no-op

mint ​

solidity
function mint(
    euint256 balanceTo,
    euint256 amount,
    euint256 totalSupply
) internal returns (ebool success, euint256 newBalanceTo, euint256 newTotalSupply)

Creates new tokens. If either balanceTo + amount or totalSupply + amount overflows, nothing is minted and success is false.

Behavior:

if overflow(balanceTo + amount) or overflow(totalSupply + amount):
    success        = false
    newBalanceTo   = balanceTo      // unchanged
    newTotalSupply = totalSupply    // unchanged
else:
    success        = true
    newBalanceTo   = balanceTo + amount
    newTotalSupply = totalSupply + amount
balanceToamounttotalSupplysuccessnewBalanceTonewTotalSupplyReason
50030010000true80010300Normal mint
010000true10001000Mint on empty
500010000true50010000Zero amount no-op

burn ​

solidity
function burn(
    euint256 balanceFrom,
    euint256 amount,
    euint256 totalSupply
) internal returns (ebool success, euint256 newBalanceFrom, euint256 newTotalSupply)

Destroys tokens. If amount > balanceFrom or totalSupply - amount underflows, nothing is burned and success is false.

Behavior:

if amount > balanceFrom or underflow(totalSupply - amount):
    success        = false
    newBalanceFrom = balanceFrom    // ciphertext reassigned to new handle
    newTotalSupply = totalSupply    // ciphertext reassigned to new handle
else:
    success        = true
    newBalanceFrom = balanceFrom - amount
    newTotalSupply = totalSupply - amount
balanceFromamounttotalSupplysuccessnewBalanceFromnewTotalSupplyReason
100501000true50950Normal burn
1000100010000true09000Full balance burned
601001000false601000Amount > balance, nothing burned
01001000false01000Insufficient balance
10001000true1001000Zero amount, no-op