Contract ABI

The main Tongo contract implements the ITongo interface and manages all confidential payment operations:

#![allow(unused)]
fn main() {
#[starknet::interface]
pub trait ITongo<TContractState> {
    // Tongo general setup:
    /// Returns the contract address that Tongo is wraping.
    fn ERC20(self: @TContractState) -> ContractAddress;

    /// Returns the rate of conversion between the wrapped ERC20 a tongo:
    ///
    /// ERC20_amount = Tongo_amount*rate
    ///
    /// The amount variable in all operation refers to the amount of Tongos.
    fn get_rate(self: @TContractState) -> u256;

    /// Returns the bit_size set for this Tongo contract.
    fn get_bit_size(self: @TContractState) -> u32;

    /// Returns the contract address of the owner of the Tongo account.
    fn get_owner(self: @TContractState) -> ContractAddress;

    // User operations:
    /// Funds a tongo account. Callable only by the account owner
    ///
    /// Emits FundEvent
    fn fund(ref self: TContractState, fund: Fund);

    /// Withdraw Tongos and send the ERC20 to a starknet address.
    ///
    /// Emits WithdrawEvent
    fn withdraw(ref self: TContractState, withdraw: Withdraw);

    /// Withdraw all the balance of an account and send the ERC20 to a starknet address. This proof
    /// avoids the limitations of the range prove that are present in the regular withdraw.
    ///
    /// Emits RagequitEvent
    fn ragequit(ref self: TContractState, ragequit: Ragequit);

    /// Transfer Tongos from the balanca of te sender to the pending of the receiver
    ///
    /// Emits TransferEvent
    fn transfer(ref self: TContractState, transfer: Transfer);

    /// Moves to the balance the amount stored in the pending. Callable only by the account owner.
    ///
    /// Emits RolloverEvent
    fn rollover(ref self: TContractState, rollover: Rollover);

    // State reading functions
    /// Returns the curretn stored balance of a Tongo account
    fn get_balance(self: @TContractState, y: PubKey) -> CipherBalance;

    /// Returns the current pending balance of a Tongo account
    fn get_pending(self: @TContractState, y: PubKey) -> CipherBalance;

    /// Return, if the Tongo instance allows, the current declared balance of a Tongo account for
    /// the auditor
    fn get_audit(self: @TContractState, y: PubKey) -> Option<CipherBalance>;

    /// Returns the current nonce of a Tongo account
    fn get_nonce(self: @TContractState, y: PubKey) -> u64;

    /// Returns the current state of a Tongo account.
    fn get_state(self: @TContractState, y: PubKey) -> State;

    // Auditor handling
    /// Returns the current auditor public key.
    fn auditor_key(self: @TContractState) -> Option<PubKey>;

    /// Rotates the current auditor public key.
    fn change_auditor_key(ref self: TContractState, new_auditor_key: PubKey);
}
}

Storage Structure

#![allow(unused)]
fn main() {
#[storage]
struct Storage {
    /// The contract address that is owner of the Tongo instance.
    owner: ContractAddress,
    /// The contract address of the ERC20 that Tongo is wrapping.
    ERC20: ContractAddress,
    /// The conversion  rage between the wrapped ERC20 a tongo:
    ///
    /// ERC20_amount = Tongo_amount*rate
    rate: u256,
    /// The bit size this contract will work with. This limites the values that cant be proven
    /// by a range proof. If is set to 32 that means that range proof will only work for values
    /// between 0 and 2**32-1.
    /// Note: The computational cost of verifying a tranfers operation (the most expensive one)
    /// is about (30 + 10*n) ec_muls and (20 + 8n) ec_adds, where n is the bit_size
    bit_size: u32,
    /// The encrypted balance for the given pubkey.
    balance: Map<PubKey, CipherBalance>,
    /// The encrypted pending balance for the given pubkey. The pending balance is the sum of
    /// incoming transfer. User has to execute a rollover operation to convert this to usable
    /// balance.
    pending: Map<PubKey, CipherBalance>,
    /// The nonce of the given pubkey. Nonce is increased in every user operation.
    nonce: Map<PubKey, u64>,
    /// Hint to fast decrypt the balance of the given pubkey. This encrypts the same amount that
    /// is stored in `balance`. It is neither check nor enforced by the protocol, only the the
    /// user can decrypt it with knowledge of the private key and it is only usefull for
    /// attempting a fast decryption of `balance.
    ae_balance: Map<PubKey, AEBalance>,
    /// The balance of the given pubkey enrypted for the auditor key.
    ///
    /// If the contract was deployed witouth an auditor, the map is empty and all keys return
    /// the Default CipherBalance {L: {x:0, y:0}, R:{x:0,y:0}};
    audit_balance: Map<PubKey, CipherBalance>,
    /// Hint to fast decrypt the audited balance of the given pubkey. This encrypts the same
    /// amount that is stored in `audit_balance`. It is neither check nor enforced by the
    /// protocol, only the auditor can decrypt it with knowledge of the auditor private key and
    /// it is only usefull for attempting a fast decryption of `audit_balance`.
    ae_audit_balance: Map<PubKey, AEBalance>,
    /// The auditor pubkey. If the contract was deployed without auditor this will be an
    /// Option::None without a way to change it.
    auditor_key: Option<PubKey>,
    /// The increasing number that identifies the public key
    key_number: u128,
}
}

Events

The contract emits events for all operations to enable off-chain monitoring:

#![allow(unused)]
fn main() {
/// Event emited in a Fund operation.
///
/// - to: The Tongo account to fund.
/// - nonce: The nonce of the Tongo account.
/// - amount: The ammount of tongo to fund.
#[derive(Drop, starknet::Event)]
pub struct FundEvent {
    #[key]
    pub to: PubKey,
    #[key]
    pub nonce: u64,
    pub amount: u128,
}

/// Event emited in a Rollover operation.
///
/// - to: The Tongo account to rollover.
/// - nonce: The nonce of the Tongo account.
/// - rolloverred: The cipherbalance of the rolloverred amount.
#[derive(Drop, starknet::Event)]
pub struct RolloverEvent {
    #[key]
    pub to: PubKey,
    #[key]
    pub nonce: u64,
    pub rollovered: CipherBalance,
}


/// Event emited in a Withdraw operation.
///
/// - from: The Tongo account to withdraw from.
/// - nonce: The nonce of the Tongo account.
/// - amount: The ammount of tongo to withdraw.
/// - to: The starknet contract address to send the funds to.
#[derive(Drop, starknet::Event)]
pub struct WithdrawEvent {
    #[key]
    pub from: PubKey,
    #[key]
    pub nonce: u64,
    pub amount: u128,
    pub to: ContractAddress,
}


/// Event emited in a Transfer operation.
///
/// - to: The Tongo account to send tongos to.
/// - from: The Tongo account to take tongos from.
/// - nonce: The nonce of the Tongo account (from).
/// - transferBalance: The amount to transfer encrypted for the pubkey of `to`.
/// - transferBalanceSelf: The amount to transfer encrypted for the pubkey of `from`.
/// - hintTransfer: AE encryption of the amount to transfer to `to`.
/// - hintLeftover: AE encryption of the leftover balance of `from`.
#[derive(Drop, starknet::Event)]
pub struct TransferEvent {
    #[key]
    pub to: PubKey,
    #[key]
    pub from: PubKey,
    #[key]
    pub nonce: u64,
    pub transferBalance: CipherBalance,
    pub transferBalanceSelf: CipherBalance,
    pub hintTransfer: AEBalance,
    pub hintLeftover: AEBalance,
}


/// Event emited in a Ragequit operation.
///
/// - from: The Tongo account to withdraw from.
/// - nonce: The nonce of the Tongo account.
/// - amount: The ammount of tongo to ragequit (the total amount of tongos in the account).
/// - to: The starknet contract address to send the funds to.
#[derive(Drop, starknet::Event)]
pub struct RagequitEvent {
    #[key]
    pub from: PubKey,
    #[key]
    pub nonce: u64,
    pub amount: u128,
    pub to: ContractAddress,
}

/// Event emited when users declare their balances to the auditor.
///
/// - from: The Tongo account that is declaring its balance.
/// - nonce: The nonce of the Tongo accout.
/// - auditorPubKey: The current public key of the auditor.
/// - declaredCipherBalance: The balance of the user encrypted for the auditor pubkey.
/// - hint: AE encryption of the balance for the auditor fast decryption.
#[derive(Drop, starknet::Event)]
pub struct BalanceDeclared {
    #[key]
    pub from: PubKey,
    #[key]
    pub nonce: u64,
    pub auditorPubKey: PubKey,
    pub declaredCipherBalance: CipherBalance,
    pub hint: AEBalance,
}


/// Event emited when users declare a transfer to the auditor.
///
/// - from: The Tongo account that is executing the transfer.
/// - to: The Tongo account that is receiving the transfer.
/// - nonce: The nonce of the Tongo accout (from).
/// - auditorPubKey: The current public key of the auditor.
/// - declaredCipherBalance: The transfer amount encrypted for the auditor pubkey.
/// - hint: AE encryption of the balance for the auditor fast decryption.
#[derive(Drop, starknet::Event)]
pub struct TransferDeclared {
    #[key]
    pub from: PubKey,
    #[key]
    pub to: PubKey,
    #[key]
    pub nonce: u64,
    pub auditorPubKey: PubKey,
    pub declaredCipherBalance: CipherBalance,
    pub hint: AEBalance,
}

/// Event emited when the owner sets a public key for the auditor.
///
/// - keyNumber: An increasing number that identifies the public key
/// - AuditorPubKey: The newly set auditor public key.
#[derive(Drop, starknet::Event)]
pub struct AuditorPubKeySet {
    #[key]
    pub keyNumber: u128,
    pub AuditorPubKey: PubKey,
}
}

Operations

1. Fund Operation

Converts ERC20 tokens to encrypted balances:

#![allow(unused)]
fn main() {
This code is a simplification of the actual code

/// Funds a tongo account. Callable only by the account owner
///
/// Emits FundEvent
fn fund(ref self: ContractState, fund: Fund) {
    verify_fund(/* public inputs */, proof);

    self._transfer_from_caller(amount);

    let cipher = CipherBalanceTrait::new(to, amount, 'fund');
    self._add_balance(to, cipher);
    self.emit(FundEvent);

    if self.auditor.is_some() {
        self._handle_audit(auditPart);
    }
}
}

2. Transfer Operation

Performs confidential transfers between accounts:

#![allow(unused)]
fn main() {
This code is a simplification of the actual code

/// Transfer Tongos from the balance of the sender to the pending of the receiver
///
/// Emits TransferEvent
fn transfer(ref self: ContractState, transfer: Transfer) {
    verify_transfer(/* public inputs */, proof);

    self._subtract_balance(from, transferBalanceSelf);
    self._add_pending(to, transferBalance);
    self.emit( TransferEvent );

    if self.auditor.is_some() {
        self._handle_audit(auditPart);
    }
}
}

3. Rollover Operation

Merges pending transfers into main balance:

#![allow(unused)]
fn main() {
This code is a simplification of the actual code

/// Moves to the balance the amount stored in the pending. Callable only by the account
/// owner.
///
/// Emits RolloverEvent
fn rollover(ref self: TContractState, rollover: Rollover) {
    verify_rollover(/* public inputs */, proof);

    self._pending_to_balance(to);

    self.emit( RolloverEvent );
}
}

4. Withdraw Operation

Convert back to standard ERC20 tokens:

#![allow(unused)]
fn main() {
This code is a simplification of the actual code

/// Withdraw Tongos and send the ERC20 to a starknet address.
///
/// Emits WithdrawEvent
fn withdraw(ref self: ContractState, withdraw: Withdraw) {
    verify_withdraw(/* public inputs */, proof);

    let cipher = CipherBalanceTrait::new(from, amount, 'withdraw');
    self._subtract_balance(from, cipher);
    self._transfer_to(to, amount);

    self.emit( WithdrawEvent );

    if self.auditor.is_some() {
        self._handle_audit(auditPart);
    }
}

}