For the complete documentation index, see llms.txt. This page is also available as Markdown.

Fees

KTON charges one performance fee on the yield it produces, plus a handful of small flat fees that cover round accounting and message gas. There is no separate, per-user "protocol fee" beyond these and ordinary TON network gas. Crucially, the headline fee is a commission on rewards, not on your principal: it is taken from each round's profit, and the APY shown in the app is already net of it.

This chapter explains each fee, where it is charged in the contract, and how to confirm the live values yourself on-chain.

The short version

Fee
Amount
What it applies to
When it hits you

Governance fee

16% (public pool, live)

Staking rewards (yield) only, never principal

Taken from each round's profit before it compounds; APY shown is already net

Deposit processing budget

~1 Gram, mostly refunded

Each deposit

Not a fee KTON keeps. The transaction carries ~1 Gram to fund minting KTON to your wallet; the unused part is returned to you, so you really only pay the small network gas consumed

Withdrawal minimum

0.5 Gram

Each unstake request

A minimum value the burn message must carry, not a deduction

Round-finalize fee

1 Gram

The round, once

Subtracted from round profit before the rate updates (socialized across all holders)

Instant-withdrawal fee

Variable, effectively ~100% on the live pool

The optional instant-exit path only

Only if you opt into instant withdrawal, which on the live pool is disabled by setting this near 100%

Network gas

Small, variable

Every TON transaction

Paid to the network, not to KTON

Governance fee: a commission on yield, not principal

The only fee that scales with your earnings is the governance fee. It is a commission on the staking rewards the pool realizes each settlement cycle, and it is taken before the profit is folded into the pool. Your staked principal is never touched by it.

On the public KTON pool the live governance fee is 16%. That number is variable and tunable by governance (it is not hardcoded into the token), so treat 16% as the current on-chain value rather than a permanent constant. See "Verify the live values" below.

How it works in the contract

At the end of each settlement cycle the pool finalizes the round. In contracts/pool.func, finalize_lending_round computes the fee from the round's realized profit:

profit -= FINALIZE_ROUND_FEE;
int fee = max(muldiv(governance_fee_share, profit, SHARE_BASIS), 0);
profit -= fee;
total_balance += profit;

Reading that in order:

  1. The 1 Gram round-finalize fee comes off the round's profit first.

  2. The governance fee is governance_fee_share / SHARE_BASIS of what remains. SHARE_BASIS is 16,777,216 (2^24), the fixed-point divisor the contract uses for all share-style parameters. A live raw governance_fee_share of 2,684,355 works out to 16.00%.

  3. Only the leftover profit is added to total_balance.

Because KTON is a rate-appreciating token, "added to total_balance" is exactly what makes each KTON redeem for more Gram over time. The fee is subtracted before that step, so the exchange rate (and therefore the displayed APY) already reflects the net-of-fee yield. You do not pay it again on withdrawal.

The collected fee is routed to the protocol treasury role. After computing fee, the contract folds in any previously deferred fee (fee += accrued_governance_fee) and, if the total is worth sending, dispatches it to the treasury with the treasury::operation_fee message:

One subtlety worth knowing: if the computed fee is below the network's SERVICE_NOTIFICATION_AMOUNT (0.02 Gram), it is too small to be worth a message, so the contract carries it forward in accrued_governance_fee and sends it together with a later round's fee. Either way it is deducted from profit; it is never silently waived to you, and it is never double-charged.

There is no fee on principal. Staking and unstaking do not skim a percentage of the Gram you put in or take out. The only percentage fee in the system is this commission on yield.

Flat fees

These are small fixed amounts defined in contracts/pool.func. They exist to cover the gas and message costs of round accounting and payout distribution, not to extract value from users.

Deposit processing budget: ~1 Gram (mostly refunded)

This is the part most often misdescribed as a "1 Gram deposit fee." It is not a fee the protocol keeps. When you stake, the pool sets aside DEPOSIT_FEE (1 Gram) of your message to fund the work of the deposit: minting KTON to your wallet, the transfer notifications, and (on your first deposit) deploying your KTON jetton wallet. The amount that gets staked is the rest:

That 1 Gram is forwarded through the mint, not retained by KTON. The mint chain carries your address as the response destination, so the unused portion comes back to your wallet. The contract comment says it plainly next to PAYOUT_DISTRIBUTION_AMOUNT: "we will get excesses back." In practice the only cost you actually bear is the small network gas consumed (a fraction of a Gram); the rest of the 1 Gram is refunded.

The only size requirement is that something is left to stake: deposit_amount > 0. If nothing remains, the transaction reverts with deposit_amount_too_low (error 0xf200). There is no 1-Gram-stake protocol minimum and no 50,000-Gram minimum for users. (The 50,000-Gram figure that appears elsewhere is a validator stake floor in the controller logic, not a user deposit minimum.) In practice you want about 1 Gram in your wallet beyond the amount you intend to stake so the transaction can carry this processing budget; most of it is returned to you.

Withdrawal minimum: 0.5 Gram

The 0.5 Gram withdrawal fee is a minimum message value, not a flat deduction from your payout. When you unstake by burning KTON, the resulting message must carry more than 0.5 Gram of gas budget:

This guarantees the request can pay for the work of queuing your withdrawal and minting your receipt NFT. It is not a 0.5 Gram charge against the Gram you are redeeming. Wallets attach this gas budget for you.

Round-finalize fee: 1 Gram

The 1 Gram finalize fee is charged once per settlement cycle against that cycle's profit (see the finalize_lending_round snippet above). It is socialized across all holders: it lowers that round's net profit slightly before the rate updates, so everyone in the pool shares it proportionally rather than any single user paying it. It covers the messages the pool sends at round-end to start payout distribution and notify the interest manager. If a round's profit happens to be smaller than 1 Gram, the shortfall is simply reflected in a marginally lower rate that cycle.

Instant-withdrawal fee (and why instant withdrawal is disabled live)

KTON's contract supports an optional fast-exit path that, when liquidity allows, pays your Gram in the same transaction instead of after the ~36-hour queued cycle. That path carries its own fee, instant_withdrawal_fee, also a share out of SHARE_BASIS. If you take the instant path, the fee is computed on your payout and added to the accrued governance fee:

On the live public pool this fee is set to effectively ~100% (raw 0xffffff, the maximum). That is a deliberate choice: it disables the instant path economically. If you tried to use it you would forfeit nearly your entire withdrawal to the fee. So in practice nobody should ever take the instant route on the live pool. The real, intended exit is the normal queued withdrawal that settles at the end of the current cycle (about 36 hours). You pay no instant-withdrawal fee on that normal path.

For the full picture of why the instant path is a trap and how the queued exit works, see the Unstaking chapter.

Network gas

Every action on KTON is a TON transaction, so you pay ordinary TON network gas, just as with any TON contract interaction. This goes to the network, not to KTON, and is small and variable. The flat fees above are sized to fund the on-chain messages your action triggers; modern TON wallets estimate and attach the right gas automatically.

No hidden per-user fee

To be explicit, because some liquid-staking docs claim "no protocol fee" (which would be misleading here): KTON does take a fee. The real protocol fee is the 16% governance commission on yield (never on principal; the displayed APY is already net of it). The deposit and withdrawal amounts in the table are gas and processing budgets, not money KTON keeps: the ~1 Gram deposit budget is mostly refunded, and the 0.5 Gram withdrawal figure is only a minimum message value. The round-finalize fee comes out of round profit and is socialized across all holders. Beyond those and ordinary network gas, there is no additional per-user fee skimmed on top, and none of the percentage fees touch your principal.

Verify the live values

The fee numbers that matter (especially the governance fee and the instant-withdrawal fee) are governance-tunable parameters stored in the pool contract's state, not fixed constants baked into the token. Always confirm the current value on-chain rather than trusting any single document.

  • Public KTON pool: EQA9HwEZD_tONfVz6lJS0PVKR5viEiEGyj9AuQewGQVnXPg0

  • KTON jetton master: EQBuIhXNNkWf9AW9miNGNTSO_uFZ23ejfIWrieXge5f733mw (9 decimals)

You can read the live governance_fee_share and instant_withdrawal_fee from the pool's get-methods (for example via a TON explorer or get_pool_full_data_raw) and divide the raw value by SHARE_BASIS (16,777,216) to get the percentage. As of this writing the public pool's governance_fee_share raw is 2,684,355, which is exactly 16.00%.

A warning for developers reading the repository: the TypeScript constants in PoolConstants.ts are stale upstream/test defaults and do not reflect the live deployment. For example, Conf.governanceFee = 155n * BigInt(2 ** 8) resolves to about 0.236%, which is not the live fee, and Conf.depositFee/Conf.withdrawlFee = 0.25 are controller-level values, not the pool's 1 Gram / 0.5 Gram. Treat the FunC source (contracts/pool.func) as authoritative for fee mechanics, and on-chain state as authoritative for the current tunable values. Never quote Conf.* as live numbers.

Next: Security and Audits

Last updated