Token System Design
Три стандарта токенов на TON
Проектирование Custom Jetton
Когда использовать стандартный Jetton vs custom
| Сценарий | Стандартный Jetton | Custom Jetton |
|---|---|---|
| Простой transfer token | Да | Overkill |
| Token с fees on transfer | Нет | Да Custom transfer logic |
| Rebase token (elastic supply) | Нет | Да Custom balance logic |
| Token с vesting | Нет | Да Lock/unlock in wallet |
| Governance token + voting | Нет | Да Snapshot + delegation |
Custom Jetton Architecture: Governance Token
Governance Jetton:
├── Master Contract
│ ├── total_supply, admin, metadata
│ ├── proposal_count, voting_config
│ └── create_proposal(), finalize_proposal()
├── Wallet Contract (per holder)
│ ├── balance, owner
│ ├── delegated_to: Address (vote delegation)
│ ├── locked_until: uint32 (voting lock)
│ └── transfer() — blocked if locked_until > now()
└── Proposal Contract (per proposal)
├── votes_for, votes_against, deadline
├── status: active/passed/rejected
└── vote() — checks balance via wallet verification
Mintless Jettons (TEP-177): airdrop без mint per recipient
Проблема: airdrop на миллионы адресов
Классический Jetton airdrop требует отдельной транзакции mint для каждого получателя:
Классический airdrop на 10M адресов:
10M mint transactions
~0.05 TON gas per mint = 500,000 TON суммарно
Месяцы исполнения
Огромная нагрузка на индексаторы и шарды
NotPixel, DOGS, HMSTR (Hamster Kombat) — все запускались с миллионами потенциальных получателей. Решение классическим mint было бы экономически невозможным.
Решение TEP-177: Merkle proof claim
TEP-177 Mintless Jettons (расширение к TEP-74) — стандарт, позволяющий:
- Off-chain compressed state: всю таблицу
address → amountдля airdrop’а упаковать в Merkle tree. - On-chain хранится только Merkle root (256 bit) в master контракте.
- Lazy claim: получатель сам предъявляет Merkle proof в момент первого использования jetton’а.
- Без preliminary mint: jetton wallet “появляется” на адресе пользователя только при первом claim/transfer.
Mintless airdrop architecture:
Off-chain (provider):
Merkle Tree:
Leaf: keccak(address || amount) - per recipient
Node: keccak(left || right)
Root: 256-bit hash
airdrop.json (in TON Storage / IPFS):
[
{ "address": "EQ...alice", "amount": "1000", "proof": [...] },
{ "address": "EQ...bob", "amount": "500", "proof": [...] },
...
]
On-chain:
Jetton Master:
merkle_root: 256 bits
total_supply: N tokens
claimed_bitmap: optional (предотвращение double-claim)
Claim flow
User claim flow (Mintless Jetton):
1. User открывает Mini App / wallet
2. Wallet проверяет airdrop.json: address есть → amount = X
3. User инициирует первый transfer/claim
4. Wallet формирует proof_path для своего адреса
5. Send: transfer(amount=X, to=recipient, proof=proof_path)
6. Jetton Wallet (deployed on-the-fly):
- verify Merkle proof → match against master.merkle_root
- mark claimed (bitmap or sub-contract)
- process transfer как обычный Jetton
7. Master никогда не видит явного mint
Production examples
| Проект | Получателей | Tooling |
|---|---|---|
| NotCoin (мультивариант) | 35M+ | Запустили волну mass minting на TON |
| DOGS | 17M+ адресов | Reference mintless setup |
| HMSTR (Hamster Kombat) | 131M+ users in funnel | Distribution через мультихоп |
| NotPixel | миллионы | Mintless distribution |
Design implications
| Аспект | Преимущество Mintless |
|---|---|
| Cost | Storage cost — константа O(1), не O(N) |
| Time-to-launch | Airdrop запускается мгновенно (нет очереди mint-ов) |
| Indexer load | Нет миллионов mint-транзакций для парсинга |
| User UX | Claim происходит “в момент использования”, не отдельным шагом |
| Sybil resistance | Snapshot off-chain → можно применить любые фильтры до публикации root |
Trade-offs
- Доступность airdrop.json: если файл с proof’ами потерян (TON Storage/IPFS pin исчез) — пользователи не могут построить proof. Решение: dual storage (TON Storage + IPFS + project CDN).
- Computational cost верификации: Merkle proof verification on-chain — O(log N) hashes. Для 10M получателей это ~24 hash операции — приемлемо по gas.
- Replay protection: master должен tracking-овать claimed status (через bitmap или sub-contracts), иначе double-claim.
TEP-177 совместим с TEP-74 и TEP-89
Mintless Jetton — не заменяет стандартный Jetton, а расширяет его. После claim wallet работает идентично TEP-74 — те же transfer, burn, balance. Кошельки и DEX, не знающие про TEP-177, продолжают работать как раньше.
NFT Collection Design
Metadata Standards
On-chain NFT Item state:
index: uint64 // 0, 1, 2, ...
collection: MsgAddress // parent collection
owner: MsgAddress // current owner
content: ^Cell // metadata reference
Off-chain metadata (JSON):
{
"name": "Cool Cat #42",
"description": "A very cool cat",
"image": "ipfs://QmX.../42.png",
"attributes": [
{"trait_type": "Background", "value": "Blue"},
{"trait_type": "Fur", "value": "Golden"}
]
}
Royalty Design
TON NFT стандарт включает royalty:
Royalty Flow:
1. NFT sold on marketplace (price: 100 TON)
2. Marketplace checks: royalty_params from Collection
3. Royalty: 5% = 5 TON → creator_address
4. Marketplace fee: 2% = 2 TON → marketplace
5. Seller receives: 93 TON
Design decision:
Royalty on-chain (enforced) vs off-chain (optional)
TON: royalty params stored in Collection contract
Marketplace SHOULD enforce, but technically can ignore
→ Similar to Ethereum debate (enforced royalty is hard)
SBT Design Patterns
Use Case 1: KYC Token
KYC SBT:
Issuer: KYC provider (verified entity)
Holder: verified user
Data:
verified_level: uint8 (1=basic, 2=enhanced, 3=institutional)
country_code: uint16
expiry: uint32
Transfer: BLOCKED (soulbound)
Revoke: issuer can revoke (set status=revoked)
Verify: any contract can check KYC status via get-method
Use Case 2: Achievement Badges
Achievement SBT:
Collection: "TON Developer Achievements"
Items:
- "First Contract Deployed" (auto-mint on first deploy)
- "1000 Transactions" (auto-mint at milestone)
- "Hackathon Winner" (manually issued)
Design: items are auto-minted by trigger contracts
No transfer: badges are earned, not bought
Token Economics Design
Supply Models
| Model | Description | Use Case |
|---|---|---|
| Fixed supply | Total supply set at creation | Bitcoin, governance tokens |
| Inflationary | New tokens minted over time | Staking rewards, validator incentives |
| Deflationary | Tokens burned on usage | Fee-burn mechanics |
| Elastic | Supply adjusts to target price | Algorithmic stablecoins |
Fee Distribution
Protocol Fee Distribution Design:
Swap fee: 0.3% per trade
├── 0.25% → LP providers (proportional to LP tokens)
├── 0.04% → Protocol treasury
└── 0.01% → Referral program
Implementation:
Pool contract accumulates fees in reserves
LP providers claim proportional share at withdrawal
Protocol fee → separate treasury contract (periodic withdrawal)
Referral → tracked per-user, claimable via referral contract
Системный дизайн токена опирается на конкретные стандарты: Jetton (TEP-74) для FT, NFT/SBT для non-fungible. Подробный разбор архитектуры стандартов и message flow между Master/Wallet — в курсе по TON.
Jetton: архитектура стандарта