From f2d3f99366b7bf804759e39f4bdf45b87e5a2801 Mon Sep 17 00:00:00 2001 From: Coalus Date: Fri, 13 Mar 2026 20:05:25 +0300 Subject: [PATCH 1/6] docs(staking): add stake calculation explanation page --- docs.json | 1 + ecosystem/staking/stake-calculation.mdx | 194 ++++++++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 ecosystem/staking/stake-calculation.mdx diff --git a/docs.json b/docs.json index f067a5821..61dfa3f31 100644 --- a/docs.json +++ b/docs.json @@ -316,6 +316,7 @@ "group": "Staking", "pages": [ "ecosystem/staking/overview", + "ecosystem/staking/stake-calculation", "ecosystem/staking/liquid-staking", "ecosystem/staking/single-nominator", "ecosystem/staking/nominator-pools" diff --git a/ecosystem/staking/stake-calculation.mdx b/ecosystem/staking/stake-calculation.mdx new file mode 100644 index 000000000..da085c3d1 --- /dev/null +++ b/ecosystem/staking/stake-calculation.mdx @@ -0,0 +1,194 @@ +--- +title: "Stake calculation" +sidebarTitle: "Stake calculation" +description: "How MyTonCtrl computes the stake amount for each election round, including inputs, priority rules, safety reserves, and network limit guards." +--- + +import { Aside } from '/snippets/aside.jsx'; + + + +MyTonCtrl automatically calculates the stake amount before submitting an election entry. The calculation balances operator preferences, staking mode, network-imposed limits, and fee reserves to produce a single integer value (in TON) sent to the elector contract. + +Understanding this logic helps operators predict MyTonCtrl behavior, troubleshoot unexpected stake amounts, and choose the right configuration. + +## Inputs + +The calculation draws on several sources: + +| Source | Parameter | Role | +| --- | --- | --- | +| Operator setting | `stake` | Fixed stake amount (TON). When set, overrides percentage-based calculation. | +| Operator setting | `stakePercent` | Percentage of balance to stake. Defaults to `99` when unset. | +| Wallet state | `balance` | Current TON balance of the staking account (validator wallet, pool, or controller). | +| Validator console | Active validator count | Number of validators currently running on this node. Determines whether the node is new or already participating. | +| On-chain config #17 | `minStake` | Network minimum stake. Submissions below this value are rejected by the elector. | +| On-chain config #17 | `maxStake` | Network maximum stake. Submissions above this value are clamped. | +| Node configuration | Staking mode | Whether the node uses a nominator pool, single nominator pool, liquid staking controller, or direct staking. | + +Configure `stake` and `stakePercent` with the [`set`](/ecosystem/nodes/cpp/mytonctrl/core#set) command: + +```mytonctrl +set stake 500000 +``` + +```mytonctrl +set stakePercent 99 +``` + +Retrieve current values with `get stake` or `get stakePercent`. + +## Priority cascade + +MyTonCtrl evaluates stake sources in a fixed priority order. The first rule that produces a value wins; later rules are skipped. + +### Priority 1: Explicit argument + +When the operator passes a stake value directly (for example, through an election entry command), MyTonCtrl uses it as-is. + +- **Percentage form** (e.g., `75%`): computes `stake = balance * 75 / 100`. +- **Absolute form** (e.g., `500000`): uses the number directly. +- **Invalid input**: logs an error and aborts the election entry. + +After parsing, a safety clamp applies: if the computed stake exceeds `balance - 10`, MyTonCtrl reduces it to `balance - 10` to reserve 10 TON for transaction fees. + +### Priority 2: Saved fixed stake + +If the operator previously ran `set stake `, MyTonCtrl uses that stored amount. The same `balance - 10` fee reserve applies. + +### Priority 3: Nominator pool mode + +When the node operates through a standard nominator pool (not a single nominator pool), MyTonCtrl sets: + +```text +stake = balance - 20 +``` + +The 20 TON reserve covers the higher fee overhead of pool operations (deploy, process, distribute messages). + + + +### Priority 4: Liquid staking controller mode + +When the node uses a liquid staking controller, MyTonCtrl sets: + +```text +stake = balance - 50 +``` + +The 50 TON reserve is the largest of all modes. Liquid staking controllers perform complex multi-step transactions (minting, burning, balance adjustments), requiring a bigger fee cushion. + +### Priority 5: Percentage-based calculation (default) + +If none of the above rules produce a value, MyTonCtrl falls back to percentage-based calculation using `stakePercent`. This is the most common path for single nominator pools and direct staking. + +The logic depends on whether the node already has active validators: + +**New validator (no active validators):** + +```text +stake = balance * stakePercent / 100 / 2 +``` + +The balance is halved. This solves a cold-start problem: on the first election, the elector locks the entire stake for a full validation round. By staking only half, the node keeps the other half available for the next election, which opens before the current round ends. Without halving, a new validator would be locked out of alternating rounds. + +**Exception:** if halving produces a value below `minStake`, MyTonCtrl abandons the halving and stakes the full percentage instead. Participating in one round is better than being rejected by the elector for staking too little. + +**Existing validator (active validators present):** + +```text +stake = balance * stakePercent / 100 +``` + +No halving is needed. The returning stake from the previous round replenishes the balance in time for the next election. + +**Fee deduction at 100%:** when `stakePercent` is exactly `100`, MyTonCtrl subtracts 20 TON from the result to prevent draining the wallet completely. At lower percentages, the non-staked remainder covers fees implicitly. + +## Validation guards + +After the stake amount is determined, three sequential checks run regardless of which priority rule produced the value: + +| Check | Condition | Action | +| --- | --- | --- | +| Maximum stake | `stake > maxStake` | Clamps stake down to `maxStake`. Logs a warning. Election entry continues. | +| Minimum stake | `stake < minStake` | Raises an error. Election entry is aborted. | +| Insufficient balance | `stake > balance` | Raises an error. Election entry is aborted. | + +The asymmetry is intentional: exceeding the maximum is recoverable (clamp and continue), but falling below the minimum or exceeding the available balance would waste transaction fees on a doomed submission. + +## Safety reserves by mode + +Each staking mode reserves a different amount for transaction fees: + +| Mode | Reserve (TON) | Reason | +| --- | --- | --- | +| Direct staking (explicit arg or fixed stake) | 10 | Minimal fees for a single stake transaction. | +| Nominator pool | 20 | Multiple messages for pool lifecycle operations. | +| Liquid staking controller | 50 | Complex multi-step DeFi transactions. | +| Percentage at 100% (default mode) | 20 | General safety margin when no non-staked remainder exists. | + +## Examples + +### New validator with 800,000 TON balance + +Settings: `stakePercent = 99`, no fixed `stake`, single nominator pool mode. + +1. No explicit argument, no saved fixed stake, not a standard nominator pool, not a controller. +2. Falls through to percentage-based calculation (Priority 5). +3. No active validators detected (new node): halving applies. +4. `stake = 800,000 * 99 / 100 / 2 = 396,000`. +5. `396,000 > minStake` (300,000): halving is kept. +6. Result: **396,000 TON** is submitted. The remaining balance covers the next election. + +### Returning validator with 1,600,000 TON balance + +Settings: `stakePercent = 99`, single nominator pool mode, already validating. + +1. Falls through to percentage-based calculation. +2. Active validators present: no halving. +3. `stake = 1,600,000 * 99 / 100 = 1,584,000`. +4. Result: **1,584,000 TON** is submitted. + +### New validator with exactly 600,100 TON (near minimum) + +Settings: `stakePercent = 100`, single nominator pool mode. + +1. Falls through to percentage-based calculation. +2. No active validators: halving would give `600,100 / 2 = 300,050`. +3. `300,050 > minStake` (300,000): halving is kept. +4. `stakePercent == 100`: 20 TON fee deduction applies: `300,050 - 20 = 300,030`. +5. Result: **300,030 TON** is submitted. + +### New validator with exactly 500,000 TON (halving would go below minimum) + +Settings: `stakePercent = 100`, single nominator pool mode. + +1. Falls through to percentage-based calculation. +2. No active validators: halving would give `500,000 / 2 = 250,000`. +3. `250,000 < minStake` (300,000): halving is abandoned. +4. Full percentage is used: `500,000`. +5. `stakePercent == 100`: 20 TON fee deduction: `500,000 - 20 = 499,980`. +6. Result: **499,980 TON** is submitted. The node participates in this round but may miss the next one because all funds are locked. + + + +### Nominator pool with 2,000,000 TON balance + +Settings: standard nominator pool mode (not single nominator). + +1. Pool mode detected (Priority 3). +2. `stake = 2,000,000 - 20 = 1,999,980`. +3. Result: **1,999,980 TON** is submitted. + +## See also + +- [Staking overview](/ecosystem/staking/overview) — comparison of staking solutions and minimum requirements. +- [Run a validator](/ecosystem/nodes/cpp/run-validator#step-4-set-optimal-stake-for-validator) — step-by-step guide for setting optimal stake. +- [MyTonCtrl settings](/ecosystem/nodes/cpp/mytonctrl/core#supported-settings) — full list of configurable parameters including `stake` and `stakePercent`. +- [Single nominator pools](/ecosystem/staking/single-nominator) — recommended staking contract for large holders. From 6a91fdf22f78d970c254834e204faed2bdabd999 Mon Sep 17 00:00:00 2001 From: Coalus Date: Fri, 13 Mar 2026 21:58:41 +0300 Subject: [PATCH 2/6] chore: fix styling --- ecosystem/staking/stake-calculation.mdx | 104 ++++++++++++------------ 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/ecosystem/staking/stake-calculation.mdx b/ecosystem/staking/stake-calculation.mdx index da085c3d1..880f983fa 100644 --- a/ecosystem/staking/stake-calculation.mdx +++ b/ecosystem/staking/stake-calculation.mdx @@ -6,27 +6,28 @@ description: "How MyTonCtrl computes the stake amount for each election round, i import { Aside } from '/snippets/aside.jsx'; -