← Back to Wiki
Mining / Chain Data

The Mining Revenue Formula Everyone Uses Is Wrong, and It Fails Silently

Every mining calculator uses the same formula. Your hashrate over the network hashrate, times blocks per day, times the block reward. On Ergo it was overstating daily revenue by 75%. The arithmetic is correct, the inputs are real, and nothing in the code looks wrong. That is what makes it worth writing down.

Share on X

The formula everyone uses

coins_per_day = (my_hashrate / network_hashrate) * blocks_per_day * block_reward

It needs three numbers off the chain. Network hashrate, block time, block reward.

Two of those carry per-chain unit conventions that nobody agrees on.

And it invites one specific mistake, which is the subject of this article.

Three different network hashrates, same chain, same second

Ergo, measured in one sitting.

SourceValue
node difficulty divided by the 120 s target546.8 GH/s
realized, from 199 real block headers312.1 GH/s
the explorer's own /info hashRate440.4 GH/s

Three answers spread over 1.75 times, for one chain, at one moment.

They disagree because the realized block time over those 199 blocks was 210.2 seconds, not the 120 the chain aims for. Ergo's retarget lags on a chain whose hashrate is falling, so difficulty is set for a network that has already gone.

None of those three numbers is a lie. They measure different things.

How the 75% error happens

Take an RTX 5080 at 294 MH/s and compute it three ways.

InputsResult
difficulty form, no block time1.161 ERG/day
matched pair: 546.8 GH/s and 720 blocks/day1.161 ERG/day
mixed pair: realized 312.1 GH/s and 720 blocks/day2.03 ERG/day

The third one is 75% too high.

And it is the natural thing to build. You take the hashrate from the explorer, because the explorer measures reality. You take blocks per day from the spec sheet, because that is the chain's stated block time.

One measures what is happening. The other measures what is intended. Multiply them together and the mismatch becomes revenue.

BE WARNED: THIS ERROR HAS NO SYMPTOM. There is no exception and no warning. You get a plausible number that is too flattering, on the one calculation you were going to use to decide whether to spend money on hardware. It only surfaces when the payouts do not match, weeks later.

Use difficulty and drop block time entirely

coins_per_day = (my_hashrate_H_per_s * 86400 / D) * block_reward

D is the expected number of hashes needed to find one block, counted in the same hash your miner counts.

The derivation is short. A miner runs independent trials. Each succeeds with probability p equal to the target over 2^256. Define D as 1 over p. Over 86400 seconds you get h times 86400 trials, so the expected blocks found is that divided by D. Multiply by the reward.

Block time never enters it. How often the whole network finds a block is not a term in the question of how often you find one.

The two correct rows in the table above are algebraically the same as this. Network hashrate is D over T, and blocks per day is 86400 over T, so T cancels. The mixed pair breaks that cancellation by using two different values of T without noticing.

So the rule is not "be careful pairing your inputs". It is simpler. Never let network hashrate into the arithmetic. Display it if you like. Compute with D.

Take D from the header, not from the difficulty float

Now the second trap. You need D, and every chain hands you a field called difficulty.

They do not mean the same thing by it.

Difficulty is a presentation field. Each project picked a divisor when it wrote its RPC layer. The target is not a presentation field. It is consensus, it is in the block header, and D equals 2^256 over target plus one, everywhere, always.

Here is Ravencoin proved from one block header and nothing else. Bits are 0x1b06e29a, and the reported difficulty is 9518.294069933914.

exponent = 0x1b = 27, mantissa = 0x06e29a = 451226
target   = 451226 << 8*(27-3)   = 2.83239e63
D        = 2^256 / (target+1)   = 4.08814e13
D / difficulty                  = 4.29503e9
2^32                            = 4.29497e9    ratio 1.000015

So Ravencoin's difficulty is Bitcoin relative, and the multiplier is 2^32. That was derived without trusting anyone.

Kaspa is a different number. Its daemon defines difficulty as 2^255 minus 1, over target. That is half the expected hash count, so the multiplier is 2, not 2^32 and not 1.

Assume Bitcoin's convention there and you are wrong by 2.1 billion times. Assume the multiplier is 1 and you are wrong by exactly 2, which is far more dangerous because it looks survivable.

The four conventions

Multiplier on reported difficultyConventionSeen on
2^32Bitcoin relativeRavencoin, Raptoreum, Firo, Vertcoin, Decred, Zcash family
1difficulty already is DErgo, Monero, Ethash family, Alephium, Iron Fish, Conflux
2kaspad's 2^255 over targetKaspa, Karlsen, Pyrin, Hoosat, Nexellia, Astrix, Cryptix
nonedifficulty counts solutions, not hashesEquihash and Cuckoo Cycle coins

That last row is the one to be frightened of. On Equihash and Cuckoo Cycle chains, a solution is not a hash, so there is no multiplier that makes the equation work. If you cannot prove the unit for a coin, publish no revenue for it. An honest gap is worth more than a confident wrong number.

This also explains why pool APIs look inconsistent. A pool reporting Ravencoin difficulty around 9393 and Alephium difficulty around 2.6e15 is not confused. It is faithfully passing through two daemons that use different conventions. A pool API is a good cross-check and a bad source of truth.

Read the reward out of the coinbase

One more, quickly, because it fails the same silent way.

Do not hardcode the emission schedule. Halvings, soft forks and treasury splits all move the number, and a hardcoded constant stays confidently wrong for months after the chain changed.

Read the coinbase transaction of a recent block and take the actual value paid. It is the one number that cannot drift out of date.

Check your own calculator in five minutes

When this isn't your problem