Skip to main content
The risk an exchange takes on a deposit is that it is reversed: the deposit’s block is replaced by a competing chain, after the coins have been credited and withdrawn as something else. Confirmations are the defence. How many are enough depends on one thing above all: how much of the mining power the largest miner controls. That changes over time, so on Parallax the right number is something you measure, not a constant you set once. The network status page measures it continuously and publishes the result, with the evidence behind it, as JSON. This page explains the method and how to turn it into a deposit policy. The Network status API page is the reference for reading the data, and ends with the policy below written as code.
Parallax is a young network, and its hashrate has at times been concentrated in a single pool, including periods when one pool found most of the blocks. While that is so, no number of confirmations is safe in the usual sense (see Half the hashrate or more). Check the live Decentralization and Recommended confirmations tiles before you set your policy, and build it so it reacts when they change.

The threat

To reverse a payment, a miner builds a competing chain in secret, one that leaves the payment out. Once that chain is longer than the public one, the miner publishes it. Nodes always follow the chain with the most work, so they switch to it, and the payment is gone, along with every confirmation it had. Each confirmation is one more block the secret chain must overtake. A pool counts as one miner, because it decides what all its miners work on. What matters is the share of blocks found by the largest pool, not the number of individual miners.

How the wait is worked out

The status page works out the wait against the largest miner of the last 7 days, from its share of those 7 days’ blocks.

Below half the hashrate

A miner with less than half the hashrate falls behind on average, so it can only catch up by luck, and its odds shrink with every confirmation. The status page works them out exactly, as in Rosenfeld (2014), not with the approximation in section 11 of the Bitcoin paper, which understates them: against 30% of the hashrate, 99.9% safety takes 32 blocks, not the paper’s 24. Those odds assume the miner was mining in secret the whole time the payment was being confirmed, which gives it a head start. But hashrate cannot be in two places at once. If the miner’s blocks keep arriving on the public chain at the rate its share says they should, it was not mining in secret. It could only start after the payment is accepted, from as far behind as the payment is deep, and that needs far fewer confirmations to defend against. It could still hide part of its hashrate and pass the gap off as bad luck, up to about a quarter of it, so the shorter waits allow for that. They hold for deposits credited while the miner is seen mining in the open (see Hidden mining). Confirmations needed against the largest miner’s share, worked out with the status page’s own code: At 10 minutes a block, 6 confirmations is about an hour, 32 about 5 hours, and 133 about a day. Below a 25% share the two columns agree, because the open-mining check only watches a miner with 25% of the blocks or more.

Half the hashrate or more

A miner with a majority finds blocks faster than everyone else together, so it always catches up eventually, however long the wait. Watching it does not help either: it can start a secret chain after the payment is accepted, beginning below it. What protects a payment then is cost. The blocks the miner replaces are mostly its own, and their rewards are lost with them: about its share of each block’s pay, for every confirmation. Wait until reversing the deposit would cost the miner more than the deposit is worth:
This leaves out what cannot be counted, such as the pool’s miners leaving it, or the price falling once an attack is seen, which cut both ways. It is the weakest protection on this page. While a majority exists, also cap how much you accept (see Building a policy).

Not counted

Neither method sees hashrate that is rented or brought in from elsewhere for an attack, because it never shows on the chain beforehand, nor pools that work together. Large deposits deserve a margin above what the status page says. As a rough guide to rented hashrate: matching the whole network’s hashrate costs about what miners earn, which the status page reports as securityBudget.laxPerDay. Divided by 144, that is roughly what an attacker pays per block it mines. A deposit worth more than your confirmation count times that figure is worth renting hashrate to attack, and should wait longer or be reviewed by hand. Majority attacks are not only theory. Ethereum Classic lost about 219,500 ETC to repeated reorganizations in January 2019, and attackers double-spent about 388,000 BTG at exchanges on Bitcoin Gold in May 2018. In both cases it was exchanges crediting deposits that lost the funds.

Hidden mining

Hashrate spent on a secret chain is missing from the public one. So a miner mining in secret stops publishing blocks, or publishes fewer than its share says it should. The status page watches the largest miner’s last 144 blocks, once it has 25% of the blocks or more, and asks: how likely is it that a miner mining openly, at this share, would publish this few blocks in this long? The answer sets a status dot and the confirmations.watch object in the API. How quickly the dot changes depends on the share. At 60% of the blocks it turns amber after about 2.6 hours without one of the miner’s blocks and red after about 3.8 hours. At 94% it takes about 1 hour 20 minutes and 2 hours.

What a quiet miner does and does not mean

A hidden-mining signal is not, by itself, an attack. A pool that is offline looks exactly the same: hashrate spent on nothing is as absent from the public chain as hashrate spent on a secret chain. Pools go down for maintenance, lose their node, have network trouble, or have miners move elsewhere for a while. And at 1 in 100, the grey dot shows up by chance from time to time even when nothing at all is wrong. A quiet stretch that ends with the miner simply resuming, and no block replaced, was not an attack. What the signal tells you is where a reversal would come from, and which blocks it could reach: those after watch.fromHeight. That makes the right response narrow. Hold the deposits it could affect, and let the rest of the data decide whether anything happened:
1

Hold only what is exposed

While watch.level is "critical", hold deposits in blocks above watch.fromHeight. Deposits in earlier blocks are not exposed by this stretch and follow your normal rules. At "warn", stop using the shorter open-mining waits and hold large deposits.
2

Wait for the miner to come back

The quiet stretch ends when the miner’s blocks appear again. Either they extend the public chain, or they replace part of it.
3

Check whether anything was replaced

Look at staleBlocks.lastReorg and staleBlocks.reorgEvents on the status page, and at your own scanner’s reorganization log. If there is no reorganization reaching down to fromHeight or below, the blocks after fromHeight stood: the miner was offline or unlucky, not mining a secret chain. Release the held deposits; they have their full count of confirmations. If a reorganization did reach that far, the blocks were replaced: rescan, and treat it as an incident.
4

Look for corroboration while you wait

The other figures help tell an outage from an attack before it resolves. A pool that is visibly down (its own website or dashboard, which the status page links from decentralization.topMiners[].website, or an announcement) points to an outage. So does a propagation or slow-miner alert, which points to network trouble rather than deliberate withholding. Unexplained silence from a pool that otherwise looks healthy, in a period where a large deposit is pending, is the case that deserves the most caution.
The incident history helps calibrate this. The status page records every quiet stretch as a withholding incident, kept for 90 days. Comparing those incidents with staleBlocks.reorgEvents over the same periods shows how often a quiet miner has been followed by a reorganization on Parallax, and how long its quiet stretches usually last. That record, together with your own reorganization log, is what lets you hold briefly and precisely instead of pausing all deposits whenever a pool hiccups.

Building a policy

A workable policy has four parts. 1. A required count per deposit, from live data. Choose a confidence by deposit size, for example 99.9% for ordinary deposits and 99.99% for large ones, and read the count from confirmations.levels, or from openLevels when watch.open is true at the moment you credit. While majority is true, use the cost formula instead, with a safety margin. Never go below a floor of your choosing. 2. Exposure limits. Cap the value credited per deposit, per account and per hour, lower while decentralization.grade is concentrated or critical. While a majority exists, the cap is what actually bounds your loss. 3. Halt conditions. A short list of signals that hold or pause deposits, below. The fields they name are described in Fields for a deposit policy. 4. Withdrawals stay open. These risks are to deposits. A reorganization can also drop a withdrawal you sent, but that is recovered by rebroadcasting the same signed transaction (see Withdrawals).

Halt conditions

A policy in code puts these rules together in Python.