TEP-74: TON Jetton Standard Deep Dive
Technical deep dive into TEP-74: jetton master + wallet pattern, transfer messages, forward fees, mint/burn, get-methods, and how jetton differs from ERC-20.
- Author
- TON Adoption Team · research desk
- Published
Contents11sections
- What a TEP is and where it comes from
- Master + wallet: the core architectural decision
- Why all this complexity
- Transfer message structure
- Get-methods: reading state without gas
- Mint and burn
- What TEP-74 deliberately does NOT standardize
- Jetton vs ERC-20: side-by-side
- Should you write a TEP-74 contract from scratch?
- Pre-launch checklist for your own jetton
- Where to go next
TEP-74 is the technical document that defines the jetton token interface on TON. Whenever you see USDT, NOT, STON, hTON, or any other non-native token in your wallet, TEP-74 is almost certainly running under the hood. This article walks through how the standard works, why jetton differs fundamentally from ERC-20, what TEP-74 standardizes (and what it deliberately does not), and whether you should write your own contract from scratch or use a reference implementation.
The piece is aimed at developers preparing to launch a jetton and curious users who want to understand what really happens when they press “Send USDT”.
What a TEP is and where it comes from
TEP stands for TON Enhancement Proposal, by analogy with EIP (Ethereum) and BIP (Bitcoin). TEPs formalize interfaces, data formats, and contract behavior. They live in the ton-blockchain/TEPs repository on GitHub. Acceptance is an open-source process: someone drafts a proposal, the community discusses it, and at some point it becomes Final once it is de-facto standard.
The token/NFT TEP family looks like this:
| TEP | What it covers | Status |
|---|---|---|
| TEP-62 | NFT standard (item + collection) | Final |
| TEP-64 | Token metadata (on-chain / off-chain) | Final |
| TEP-66 | NFT royalty standard | Final |
| TEP-74 | Jetton standard (master + wallet) | Final |
| TEP-85 | SBT — Soul-Bound Token | Final |
| TEP-89 | Discoverable jettons | Final |
TEP-74 was finalized in 2022 and has been the baseline interface for fungible tokens on TON ever since. TEP-89 extends TEP-74 with a get_wallet_address get-method on the master, so wallets and explorers can deterministically compute jetton-wallet addresses without scanning the network.
Master + wallet: the core architectural decision
In Ethereum an ERC-20 token is a single contract. Inside that contract there is a mapping(address => uint256) balances. When Alice sends 100 USDT to Bob, she calls transfer() on that one contract and it updates two slots in the table.
TON takes a different path. Every jetton has a master contract (sometimes called the minter) and a separate jetton-wallet contract for every holder. For USDT-jetton on TON that means one master plus tens of millions of jetton-wallets — one per address that has ever held USDT.
When Alice sends 100 USDT to Bob, the flow is:
- Alice sends a
transfermessage to her USDT jetton-wallet. - Her jetton-wallet decreases the local balance by 100 and sends an
internal_transferto Bob’s jetton-wallet. - Bob’s jetton-wallet, upon receipt, increases its local balance by 100 and emits a
transfer_notificationto Bob’s regular TON wallet address. - Excess gas is returned to Alice through an
excessmessage.
The master contract is not involved in the transfer chain itself. It only handles minting, burning, and metadata. That is critical: jetton transfers are parallelizable, because they do not hit a single bottleneck contract.
Why all this complexity
The per-holder wallet idea looks excessive until you remember that TON shards. When load grows, shards split. If all USDT balances lived in a single contract, that contract would sit in one shard and USDT throughput would be capped by that single shard’s capacity. With per-holder wallet contracts, Alice’s and Bob’s balances may live in different shards and their transactions process in parallel.
The cost: the sender pays gas for two contracts (their own wallet + the recipient’s wallet) plus a forward fee on the internal message. In practice a transfer costs 0.03-0.05 TON, versus $0.5-3 on Ethereum depending on gas price. In dollar terms TON wins almost every time.
Transfer message structure
TEP-74 fixes op-codes and TL-B schemas. The key operations are:
0x0f8a7ea5— transfer (external, from user)0x178d4519— internal_transfer (between two jetton-wallets)0x7362d09c— transfer_notification (from recipient wallet to owner)0xd53276db— excesses (return of leftover gas)0x595f07bc— burn0x178d4519— internal mint (master to wallet during issuance)
An external transfer from the user carries: query_id, amount (tokens to send), destination (the recipient’s regular TON address, not their jetton-wallet), response_destination (where to send excess gas), custom_payload, forward_ton_amount (how much TON to attach to the recipient notification), forward_payload (arbitrary data the recipient’s dApp can read).
The forward_payload field is critical for DEXes and DeFi: that is exactly how STON.fi or DeDust receives a “swap these 100 USDT for TON” command when the user sends a jetton directly to the router.
Get-methods: reading state without gas
TEP-74 mandates two get-methods:
get_jetton_data() on the master returns: total_supply, mintable flag, admin_address, jetton_content (cell with TEP-64 metadata), jetton_wallet_code (code from which all wallet addresses are deterministically derived).
get_wallet_data() on a jetton-wallet returns: balance, owner_address, jetton (master address), jetton_wallet_code.
From this pair a useful property follows: given the owner address and the master address, any client can locally (without hitting the network) derive the corresponding jetton-wallet address. That is how Tonkeeper, MyTonWallet, and explorers display balances across jettons — they do not scan the entire chain, they take a known list of master addresses and compute the wallet address for the current user.
TEP-89 adds get_wallet_address(owner) on the master for clients that do not want to redo the derivation themselves.
Mint and burn
Minting a jetton is a message from master to the future holder’s address. The master creates the jetton-wallet (if it does not exist yet) and sends it an internal_transfer increasing the balance. TEP-74 does not fix an op-code for mint — that is intentional, because each issuer can implement any access policy: single admin, multisig, governance vote, vesting.
Burn (op 0x595f07bc) is a message from the user to their own jetton-wallet. The wallet decreases the balance and sends burn_notification back to the master, which lowers total_supply. Burn is mainly used in bridge flows: to move USDT from TON to Ethereum, USDT-jetton is burned on TON and the bridge releases an equivalent on the destination network.
What TEP-74 deliberately does NOT standardize
This is arguably the most important section. TEP-74 only defines the base interface. Everything beyond it is issuer-defined:
- Pause / freeze. The standard has neither pause nor freeze. But Tether’s USDT-jetton can do both — because the issuer added admin-only freeze logic on top. The community debates this, but it is fully compliant with TEP-74.
- Blacklist. Similar — bolted on top of the standard.
- Upgrade. A contract may be upgradeable (
set_code) or immutable — TEP-74 does not pick. Tether’s contract is upgradeable; most community tokens are not. - Royalty / transfer fee. A fee on transfer can be implemented, but it is non-standard and most ecosystem tooling will not account for it.
- Metadata stability. TEP-64 allows off-chain metadata (IPFS, HTTPS) — but the standard gives no guarantee that the hosting outlives the issuer.
Jetton vs ERC-20: side-by-side
| Property | ERC-20 | Jetton (TEP-74) |
|---|---|---|
| Contracts per token | 1 | 1 master + N wallets |
| Transfer cost | one storage write of gas | gas of two contracts + forward |
| Parallelism | none, single contract | yes, balances across shards |
| Balance lookup | balanceOf(addr) view call | get-method on derived address |
| Approve / allowance | yes | none (replaced by forward_payload) |
| Freeze standard | none (impl-defined) | none (impl-defined) |
| Finality | ~12-15 PoS blocks | ~5s masterchain |
The absence of approve deserves its own note. In Ethereum a DEX requires the user to first approve, then swap — two transactions. On TON it is a single transaction: the user sends the jetton directly to the DEX router and puts the swap command in forward_payload. Simpler and safer — no perpetual allowances for drainer sites to exploit.
Should you write a TEP-74 contract from scratch?
For the overwhelming majority of cases, no. There are three practical paths:
- TON Foundation reference implementation in FunC — the most conservative option. The code has been audited many times and powers the vast majority of jettons.
- Tact — a modern language; the jetton template ships in
@ton-community/jetton. Good if the team does not want to dive into FunC. - Tolk — the newest TON language, also has a ready jetton template. Faster than FunC, easier to read.
Writing from scratch only makes sense for non-standard logic: vesting, rebasing, on-chain governance with dynamic supply. In that case budget for 2-3 independent audits — bugs in jetton contracts are usually irreversible.
Pre-launch checklist for your own jetton
- TEP-64 metadata: name, symbol, decimals (typically 9 for TON-native jettons), description, image. Host on IPFS or at least your own CDN.
- Mint policy is defined: one-shot, vesting, governance-driven.
- Whether admin powers (freeze, upgrade) exist is decided and publicly documented.
- TEP-89 is implemented so wallets and explorers can resolve wallet addresses quickly.
- Contract is verified on Tonviewer / tonscan — otherwise users will not see the source.
- Indexers (DTON, TON API) are notified so DEX aggregators pick the jetton up.
Where to go next
The standard is best studied alongside the network architecture. If you have not yet wrapped your head around how TON parallelizes transactions across shards, move on to the sharding deep dive. If the contract languages themselves are what you need — there are dedicated guides on FunC vs Tact and on Tolk. And the user-facing side of jetton (how to add a custom token to a wallet, why different wallet addresses look so similar) is covered in the beginner-friendly jetton overview.
Frequently asked
How does a jetton fundamentally differ from ERC-20?
What does TEP-74 not standardize?
Do I need to write a jetton contract from scratch?
How much gas does a jetton transfer cost?
Related
- BasicsMay 16, 2026
What is a jetton and how it works: 2026 guide
Jetton is the TON token standard. How it differs from ERC-20, what jetton-master and jetton-wallet do, how to verify authenticity, and why DEXes use pTON.
- BasicsMay 16, 2026
USDT on TON: complete guide 2026
How the USDT jetton on TON works, how it differs from ERC-20 and Tron USDT, where to use it, how gas is paid, and which risks to keep in mind.
- BasicsDec 23, 2025
TON for developers: FunC, Tact and Tolk in 2026
The smart contract languages used on TON in 2026 — FunC, Tact, Tolk. Which to pick as a beginner, how they differ, what tooling you need and where to learn.
- BasicsMay 14, 2026
Tolk: TON smart contract language — intro for FunC/Tact devs
Tolk is the next-gen TON smart contract language and Acton's default. TypeScript-style syntax, strong typing, pattern matching.
- BasicsFeb 19, 2026
TON fees: how they're calculated and why so low (2026)
What makes up a TON fee — gas, storage, forward, action. Real 2026 numbers, comparison with Ethereum and Solana, how to save and why TON is cheap.