Skip to content

zeta-chain/protocol-contracts-ton

Repository files navigation

ZetaChain TON Protocol Contracts

Contracts of official protocol contracts deployed by the core ZetaChain team.

⚠️ Important Notice

This repository is under active development and is not yet ready for production use.

Learn more about ZetaChain

Project structure

The project is built using Blueprint.

  • contracts - source code of all the smart contracts of the project and their dependencies.
  • wrappers - wrapper classes (implementing Contract from ton-core) for the contracts, including any [de] serialization primitives and compilation functions.
  • tests - tests for the contracts.
  • scripts - scripts used by the project, mainly the deployment scripts.

How to use

  • Compile FunC: make compile
  • Run tests: make test
  • Run Blueprint scripts: make run

How it works

Deposits

All deposits are represented as internal messages that have the following structure:

  • uint32 op_code - operation code. Standard for TON
  • uint64 query_id - not used right now. Standard for TON
  • ... the rest of the message is the operation-specific data

deposit (op 101)

op_code:uint32 query_id:uint64 evm_recipient:slice (160 bits)

Deposits funds to the contract (subtracting a small deposit fee to cover the gas costs). ZetaChain will observe this tx and execute cross-chain deposit to evm_recipient on Zeta.

deposit_and_call (op 102)

op_code:uint32 query_id:uint64 evm_recipient:slice (160 bits) call_data:cell

Deposits funds to the contract (subtracting a small deposit fee to cover the gas costs). ZetaChain will observe this tx and execute cross-chain deposit to evm_recipient on Zeta AND call the contract with call_data.

Note that call_data should be encoded as snakeCell

Authority operations

These "admin" operations are used to manage the contract. In the future, they will be fully managed by TSS. Currently, a dedicated authority address is used state::authority_address

  • set_deposits_enabled - toggle deposits
  • update_tss - update TSS public key
  • update_code - upgrade the contract code
  • update_authority - update authority TON address

Withdrawals

ZetaChain uses MPC (Multi Party Computation) to sign all outbound transactions using TSS (Threshold Signature Scheme). Due to the technical implementation TSS uses ECDSA cryptography in opposite to EdDSA in TON. Thus, we need to check ECDSA signatures in the contract on-chain.

All TSS commands are represented as external messages that have the following structure:

  • uint32 op_code - operation code. Standard for TON
  • [65]byte signature - ECDSA signature of the message hash (v, r, s)
  • [32]byte hash - hash of the payload
  • ref cell payload - the actual payload

By having this structure we can sign arbitrary messages using ECDSA, recover signature, then ensure sender and proceed with the operation.

The payload for op withdrawal (200) is the following:

recipient:MsgAddr amount:Coins seqno:uint32

External message signature flow:

Let’s simplify the input as ["signature", "payload_hash", "payload_data"]:

  • With signature + payload_hash, we can derive the signer's public key -> check that the message comes from TSS.
  • By having payload_hash + payload_data, we can check that the payload is exactly the same as the one that was signed.
  • Otherwise, the sender could take any valid signature + payload_hash, append an arbitrary payload, and execute the contract on behalf of TSS (e.g. "withdraw 1000 TON to address X").