Python 3 and a terminal. No Toncoin is staked and no wallet is opened.
macOS and Linux have Python; on Windows install it from python.org with
“Add python.exe to PATH” ticked. Check with
python3 --version.
The rates in these scripts are placeholders, and that is deliberate. Network reward rates, pool fees and validator minimums change; the point is not to memorise today’s numbers but to own the arithmetic, so you can drop in whatever a pool is advertising this week and see what it means for you. Where a figure is illustrative, the script says so.
⚠️ Nothing here is investment advice. Staking is modelled as a mechanism with costs and risks, which is what a security course can honestly teach about it.
How Staking Works on TON
TON uses Proof-of-Stake (PoS) consensus, meaning the network is secured by validators who lock up ("stake") Toncoin as collateral. In return, they earn rewards for honestly validating transactions and producing blocks. If they cheat or go offline, their stake is slashed (partially confiscated).
You do not need to run a validator node to earn staking rewards. TON offers several ways for regular users to participate.
Validators
Validators are the backbone of the TON network. They:
- Validate transactions: Verify that transactions are legitimate and follow network rules
- Produce blocks: Create new blocks on the masterchain and shardchains
- Participate in consensus: Vote on block proposals using the Catchain BFT protocol
- Pay for infrastructure: Run high-performance servers (16+ cores, 128GB+ RAM, fast SSD)
The minimum stake to become a validator is approximately 300,000 TON (this changes based on network conditions and elections). Validator elections happen every ~18 hours.
Nominator Pools
Most people cannot afford the minimum validator stake. Nominator pools solve this by letting many users combine their stakes and delegate to a validator:
- How it works: You deposit Toncoin into a nominator pool smart contract. The pool operator runs the validator node. Rewards are distributed proportionally minus a commission
- Minimum deposit: Typically 10-50 TON depending on the pool
- Lock period: Your stake is locked for each validation round (~18-36 hours)
- Typical APY: 3-6% annually, varying with network conditions
Only use nominator pools from verified, reputable operators. The pool operator can technically mismanage the validator, resulting in slashing that affects your stake. Check the operator's track record and whether the pool contract is audited.
Liquid Staking
Liquid staking is a newer approach that solves the lock-up problem. When you stake through a liquid staking protocol, you receive a token representing your staked position:
The advantage of liquid staking: your capital is not locked. You can trade, sell, or use your staking tokens in DeFi protocols while still earning validator rewards.
How to Stake TON (via Tonkeeper)
Tap the "Staking" or "Earn" tab in your wallet. You will see available staking options.
Select either a nominator pool (fixed lock period, direct staking) or a liquid staking protocol (flexible, tradeable tokens).
Enter how much TON to stake. Keep at least 1 TON unstaked for transaction fees. Review the details and confirm.
Your staking position will appear in the wallet. Rewards accrue automatically. For liquid staking, your received tokens will appear in your balance.
Staking Risks
- Validator slashing: If the validator you delegated to misbehaves, a portion of the pooled stake (including yours) may be slashed
- Smart contract risk: Nominator pool and liquid staking contracts could have bugs. Use only audited protocols
- Liquid staking depeg: In a market panic, liquid staking tokens (tsTON, stTON) can trade below their true value temporarily
- Opportunity cost: Staked TON (in nominator pools) is locked and cannot be sold immediately during price drops
- Impersonation scams: Fake staking pools that steal your deposit. Only use pools listed in official sources (Tonkeeper's built-in list, ton.org)
Now Work Out What Staking Actually Pays, in Five Steps
Staking is advertised with one number and delivered with several. In the next twenty minutes you will subtract the operator’s cut from an advertised rate, test whether compounding matters at these rates, work out how far your holding is from validating alone, and then price the two risks that are rarely on the marketing page: a liquid-staking token that stops being worth one coin, and a lock-up that arrives at the wrong moment. Every figure below came from running these files.
Go: open a terminal in a folder you can write to, e.g.
cd ~/Desktop (Windows: cd %USERPROFILE%\Desktop).
Do: save this as netrate.py and run
python3 netrate.py. The gross figure is what the validator earns; the pool fee
is what it keeps.
STAKE = 10_000 # your Toncoin
GROSS = 0.055 # what the validator earns, before anyone's cut
for pool_fee in (0.00, 0.10, 0.25, 0.40):
net = GROSS * (1 - pool_fee)
print(f"pool takes {pool_fee:>4.0%}: you earn {net:.3%} a year = {STAKE * net:>7,.0f} TON")
You should see: the advertised rate shrinking as the fee grows:
pool takes 0%: you earn 5.500% a year = 550 TON
pool takes 10%: you earn 4.950% a year = 495 TON
pool takes 25%: you earn 4.125% a year = 412 TON
pool takes 40%: you earn 3.300% a year = 330 TON
Put the pool’s own advertised numbers into this before committing anything: some pools quote the net rate and some quote the network’s gross rate with the fee in the small print. The difference between a 10% and a 40% operator is nearly half your return, and it is not visible in a headline percentage.
If not: if the percentages print as long decimals, the format specifier
lost its % — it is :.3%, and :>4.0% for the
fee column.
Go: same folder. Pools advertise frequent payouts as though frequency itself were profit. Measure it.
Do: save this as compound.py and run it. TON’s
validation rounds are roughly eighteen hours, so a year holds a few hundred of them.
STAKE, NET = 10_000, 0.0495 # 5.5% gross, 10% pool fee
for name, rounds in (("paid out, never restaked", 0),
("restaked once a year", 1),
("restaked every 18 hours", 487)):
if rounds == 0:
value = STAKE + STAKE * NET
else:
value = STAKE * (1 + NET / rounds) ** rounds
print(f"{name:26s} after 1 year: {value:,.2f} TON")
You should see: a difference measured in single coins:
paid out, never restaked after 1 year: 10,495.00 TON
restaked once a year after 1 year: 10,495.00 TON
restaked every 18 hours after 1 year: 10,507.43 TON
Twelve coins on ten thousand. Compounding matters enormously at 40% and hardly at all at 5%, which is worth knowing when a pool charging a higher fee advertises “auto-compounding” as the reason. Compare the fee difference from step 1 — tens or hundreds of coins — against this.
If not: if the last line is wildly larger, NET / rounds was
written as NET * rounds, which compounds the whole annual rate 487 times.
Go: same folder. Pools exist because validating alone has a floor.
Do: save this as solo.py and run it. The minimum is set
by the network and moves; the figure below is an order-of-magnitude placeholder. Replace it
with today’s number before drawing any conclusion about your own situation.
VALIDATOR_MINIMUM = 300_000 # illustrative -- look up the current figure
MY_STAKE = 10_000
print(f"to validate alone you would need about {VALIDATOR_MINIMUM:,} TON")
print(f"you have {MY_STAKE:,} TON -- that is {MY_STAKE / VALIDATOR_MINIMUM:.1%} of the way")
print(f"people like you needed to fill one pool: {VALIDATOR_MINIMUM // MY_STAKE}")
print()
print("what you give up by pooling:")
print(f" the operator's cut, every year : {10_000 * 0.055 * 0.10:>7,.0f} TON")
print(f" and you rely on them staying online and honest")
You should see: the reason pools exist, in one ratio:
to validate alone you would need about 300,000 TON
you have 10,000 TON -- that is 3.3% of the way
people like you needed to fill one pool: 30
what you give up by pooling:
the operator's cut, every year : 55 TON
and you rely on them staying online and honest
That second cost is the one to weigh. A pool operator who goes offline earns you nothing for that round, and one who is dishonest or careless can be penalised with your stake alongside theirs. Choosing a pool is choosing a counterparty, which is a security decision rather than a yield decision — look at how long they have operated, whether the contract is published, and whether the fee can be changed without warning.
If not: ZeroDivisionError means MY_STAKE was
set to 0. The // in the third line is integer division on purpose — you
cannot have a fraction of a participant.
Go: same folder. Liquid staking hands you a token representing your stake, tradeable immediately. Its value is a market price, not a promise.
Do: save this as depeg.py and run it. The token trades in a
pool where the coin balance times the token balance stays constant.
# A liquid-staking token should be worth 1 TON, but it trades on a market.
pool_ton, pool_lst = 500_000.0, 500_000.0 # a balanced trading pool
k = pool_ton * pool_lst
print(f"quoted price of 1 stTON: {pool_ton / pool_lst:.4f} TON")
for sell in (10_000, 100_000, 300_000):
ton_out = pool_ton - k / (pool_lst + sell)
print(f"someone dumps {sell:>7,} stTON -> they get {ton_out:>9,.0f} TON "
f"({ton_out / sell:.3f} per token)")
You should see: a token worth exactly one coin, until somebody needs to sell:
quoted price of 1 stTON: 1.0000 TON
someone dumps 10,000 stTON -> they get 9,804 TON (0.980 per token)
someone dumps 100,000 stTON -> they get 83,333 TON (0.833 per token)
someone dumps 300,000 stTON -> they get 187,500 TON (0.625 per token)
The token is still redeemable for one coin each — eventually, by unstaking and waiting. What the market pays for immediacy is another matter, and it collapses precisely when everybody wants out at once, which is the moment you are most likely to want out too. “Liquid” describes the good weather, not the storm.
If not: if the price per token stays at 1.000, the constant
k is being recalculated inside the loop — it must be computed once, before
the sales.
Go: same folder. Ordinary staking has no depeg risk, and a different one instead: you cannot leave immediately.
Do: save this as lockup.py and run it.
STAKE = 10_000
price_now, price_after = 5.20, 3.90 # TON in dollars, before and after a 25% fall
print(f"you decide to sell. Value today at {price_now:.2f}: {STAKE * price_now:>10,.0f} dollars")
print("your stake is locked until the validation round ends.")
print(f"by the time it unlocks the price is {price_after:.2f}: {STAKE * price_after:>10,.0f} dollars")
print(f"the lock-up cost you {STAKE * (price_now - price_after):,.0f} dollars, "
f"more than {STAKE * (price_now - price_after) / (STAKE * 0.0495 * price_now):.1f} years of staking rewards")
You should see: one delayed exit outweighing years of yield:
you decide to sell. Value today at 5.20: 52,000 dollars
your stake is locked until the validation round ends.
by the time it unlocks the price is 3.90: 39,000 dollars
the lock-up cost you 13,000 dollars, more than 5.1 years of staking rewards
This is why the reward rate is the least interesting number in the decision. A single adverse move during a lock-up erases years of it, so the honest question is not “what does it pay?” but “am I content to hold this amount, unable to sell, for the length of the unstaking period?” If the answer is no, a higher rate does not change it.
If not: if the last line reports a negative number of years, the two
prices were swapped — price_after is the lower one in this scenario.
Without scrolling up: pool A advertises 5.5% with a 40% fee and instant liquid withdrawal; pool B advertises 4.9% with a 10% fee and an eighteen-hour unstaking period. Which is the better deal, and what would change your answer? Answer: pool B pays more — step 1 shows a 40% fee on 5.5% gross nets 3.3%, well under B’s 4.9% — so A is charging you roughly a third of your return for the convenience of leaving early. What would change the answer is needing that liquidity: if you genuinely might have to exit inside a day, step 5 shows the lock-up can cost far more than the fee difference. But step 4 shows A’s instant exit is itself only as good as its trading pool, and that pool empties exactly when everyone wants out.
Now do it without the page: combine netrate.py and
lockup.py into one script that answers a single question: how large a price fall
during the lock-up would wipe out a full year of rewards at your chosen pool’s net
rate? Run it with the real numbers of a pool you are considering. That percentage —
usually a small one — is the honest summary of the trade you are making.
Summary
- TON uses Proof-of-Stake with validator elections every ~18 hours
- Running a validator requires ~300,000 TON and significant infrastructure
- Nominator pools let you delegate stake with as little as 10-50 TON
- Liquid staking (tsTON, stTON, hTON) gives flexibility — no lock-up period
- Always verify pool operators and prefer audited contracts
- Typical staking APY is 3-6% annually
You can now make informed decisions about earning yield on your Toncoin while understanding the risks involved.