Skip to content

How to verify a Nimiq validator's restake yourself

Last updated Written by the ImpactZero validator team

In short

A validator's restake claim can be checked because every distribution is an on-chain add-stake transaction. Two checks cover it: each staker gets floor(staker balance x paid / sum of staker balances) of what a cycle paid out, and the undistributed balance (rewards in, payouts out, carried from cycle to cycle) never goes negative or grows past one batch of rewards.

The claim behind "this validator restakes"

Nimiq has no protocol-level restaking switch. When a validator declares a restake payout it is describing its own policy: when rewards arrive, it sends them back into staker records as add-stake transactions rather than paying them out as plain transfers. That policy is code, and code you can read. But its output is the stronger proof, because every distribution is an ordinary transaction on the chain everyone reads.

This article is a recipe. It gives you the two checks, shows what numbers feed them, and points at the two pages on this site that run them continuously: /staking for your own record and /verify for the ledger of every cycle.

Two checks, every cycle

The whole of the verification is this:

expected = floor( stakerBalance x paid / sumOfStakerBalances )
carried  = carriedBefore + rewards - paid

stakerBalance is the balance on one staker record when the cycle opened, and sumOfStakerBalances is the same for every staker of the validator (the validator's own deposit is not a staker). paid is the sum of the cycle's add-stake transactions and rewards the coinbase it earned. The first line says each staker got their stake share of what was paid. The second says the right amount was paid: the carried balance must never go negative (more paid than earned) and never grow past one batch of rewards (rewards withheld).

Why carry at all? The bot pays about a minute after a reward lands, so a cycle can end between a reward and the payout that distributes it: one cycle holds two rewards and one payout, the next one reward and two payouts. Judged alone, both would look wrong; carried, both add up. A skim that stays proportional cannot hide either: the carried balance keeps growing until it trips the limit. Because every term is a public chain value, you can reproduce any recorded credit by hand.

The receipt is on chain

A credit that matched the formula still has to be real, which is where the transaction comes in. Each share leaves the validator wallet as an add-stake transaction with a hash. Paste that hash into the explorer (or any Nimiq block explorer) and you see the amount, the sender and the staker record it landed on. So a verified cycle is two checks: the arithmetic matches, and the transaction on chain moves the right amount to the right record.

What this site automates

/staking is your own ledger. Sign in with your Nimiq wallet and it looks you up in the tracker's staker list: your current stake, your pool share, your last few credits with their blocks and transaction links, and a projected annual note. It tells you plainly if you are not staked with ImpactZero and shows the public pool table either way.

/verify is the integrity ledger. For each cycle, latest first, it shows the cycle id, a status and the block range it opened and closed. Expand a cycle to see every staker expected versus actual credit with an ok indicator, and the cycle's rewards, what it paid and the balance carried after it. The page records whether everything matched, and it does not ask you to take its word for it: the arithmetic uses chain numbers you can read yourself.

Read the source as a cross-check

The bot's constants live in the open: the minute-by-minute trigger, the integer split that pays every staker's share down to the last luna, the fail-closed sentinel. The exact code is published on GitHub, and the ledger receipts stay on the chain. Reading the source tells you how a restake is intended to run; reading the ledger tells you whether it actually did. Both are public, and the two together are the whole check.

Questions people ask

Why is an add-stake transaction proof of a restake?
A restake is the validator sending NIM back into staker records instead of out to stakers as a plain transfer. The chain exposes every such send as a stake transaction signed by the validator, moving from its wallet to a specific staker record. So the receipt is public, reproducible and impossible to fake after the fact: it is on the chain everyone reads.
What numbers do I need for the formula?
Each staker's balance at the start of the cycle (the validator's own deposit is not a staker; the ImpactZero bot pays the deposit's slice to stakers too), and what the cycle paid, the sum of its add-stake transactions. Expected = floor(staker balance x paid / sum of staker balances). For the carried balance you also need the cycle's coinbase rewards. The tracker reads these from the same chain data the bot reads.
What does /verify actually show?
It records the ledger for each restake cycle: cycle id, status and the block range it opened and closed. Expand a cycle and you see every staker expected versus actual credit with a check when they match, plus the cycle's rewards, what it paid and the balance carried after it. Everything is recomputed from chain numbers, so nothing is asserted that you cannot reproduce.
What does a MISMATCH status mean?
Either a staker's credit missed their stake share of what the cycle paid (the reason names them), or the carried balance broke its bounds: negative means more was paid than earned, above one batch means rewards are being withheld. The bot paying about a minute after a reward lands is not a mismatch any more: that timing is exactly what the carried balance absorbs, and a cycle only closes once its payout batch is complete, so a batch spread over two blocks is judged as one. The usual recent reason is a staker joining, leaving or adding stake while a cycle is open: the bot pays from its live staker list, the tracker from the balances at the start, and it flags the difference rather than guess, while the cycle's totals still add up. Open the cycle and read the reason, then compare to the on-chain transaction.
Do I have to trust this dashboard?
No, and that is the point. The page only automates arithmetic on public numbers. You can run the same formula with the staker records and a cycle's add-stake transactions from the chain, add up rewards and payouts yourself, and compare to the transaction hashes in any explorer. The dashboard is a convenience, not an authority.

Sources