TON-EVM token bridge - FunC smart contracts.
Developed by RSquad by order of TON Foundation.
Bridge supports all ERC-20-compatible tokens with:
-
0 <= Total supply <= (2^120 - 1)
uint256
is used for amounts in Ethereum, TON jettons usesVarUInteger 16 = Coins
for amounts, maximum is2^120 - 1
(124 bit in serialized form).Since in practice all useful tokens fit into this limit, we decided not to change the jettons.
-
0 <= Decimals <= 255
ERC-20 has
uint8
decimals so all valid ERC-20 tokens are supported.
-
User calls
lock
method on the EVM smart contract, indicating the address of the ERC-20 token, the token amount and destination TON address to receive jettons. -
EVM smart contract emits
Lock
event. -
export const MULTISIG_QUERY_TIMEOUT = 30 * 24 * 60 * 60; // 30 days const VERSION = 2; const timeout = evmTransaction.blockTime + MULTISIG_QUERY_TIMEOUT + VERSION; const queryId = timeout << 32 + first 32 bits of sha256(evmTransaction.blockHash + '_' + evmTransaction.transactionHash + '_' + evmTransaction.logIndex)
-
User pays
bridgeMintFee
in Toncoins by sendingop::pay_swap
tojetton-bridge
TON smart contract with correspondingqueryId
. -
Oracles detects new
Lock
event andswap_paid
log, check its validity and submits votes tomultisig
TON smart contract with correspondingqueryId
. -
When enough oracles votes are collected in the multisig, the multisig sends
op::execute_voting::swap
message to thejetton-bridge
. -
jetton-bridge
creates (if it doesn't already exist)jetton-minter
smart contract corresponding this ERC-20 token and fill-up user'sjetton-wallet
.
-
User send
burn
message to hisjetton-wallet
, indicating the destination EVM address to receive ERC-20 tokens. -
jetton-wallet
sendsburn-notification
tojetton-minter
andjetton-minter
forward it tojetton-bridge
. -
jetton-bridge
produceburn
log on validburn-notification
. -
Oracles detects new
burn
log, check its validity and submits EVM-signatures tovotes-collector
TON Smart Contract. -
When enough oracles signature are collected, user call
unlock
method of the EVM smart contract, indicating these signatures, and get ERC-20 tokens.
Token bridge based on code of Toncoin Bridge and Standard Jetton.
Jettons:
-
dicovery-params.fc
,op-codes.fc
,params.fc
,stdlib.fc
,utils.fc
- changes do not affect functionality. -
jetton-wallet.fc
- same, butuint160 destination_address
(destination address in EVM network) added incustom_payload
ofburn
message and toburn_notification
message.min_tons_for_storage
andgas_consumption
constants moved to config.3 additional
burn
checks:throw_if( error::operation_suspended, state_flags & 1);
throw_unless(error::burn_fee_not_matched, msg_value == bridge_burn_fee);
-bridge_burn_fee
must include network fees ;throw_unless(error::not_enough_funds, jetton_amount > 0);
- forbid zero burns; -
jetton-minter.fc
- same withjetton-minter-discoverable.fc
but:-
no
admin_address
in data - admin isbridge_address
from network config -
mint - different mint message structure, sending fees deducted from message
-
burn_notification
withcontent
is forwarded to the jetton-bridge, no burn response message is sent -
no
change_admin
,change_content
-
get_jetton_data
constructs semi-chain data in runtime -
provide_address_gas_consumption
andmin_tons_for_storage
constants moved to config
-
Bridge:
-
config.fc
- similar, but additional fields added. -
multisig.fc
- same, just another config, fixedget_messages_unsigned_by_id
get-method, prevent send non-bounceable messages to bridge. -
votes-collector.fc
- same, just another config and inability to remove old votes if config.state & 8