Skip to content

@4x13 4x13 released this Aug 30, 2019 · 38 commits to master since this release


This is a mandatory upgrade, and has consensus enforcement that requires immediate upgrading of the wallet. Note that was the original mandatory version to have, but because of a miscode in the new stake modifier protocol it resulted in the chain becoming stuck. An upgrade to v1.0.4.4, which fixes the miscode, is required to be in sync with the blockchain.


Version is a mandatory update. It includes the patching of a vulnerability in Veil's zerocoin implementation that allowed malformed transactions to claim a different zerocoin denomination than was being redeemed. This update adds a banlist to remaining coins that were not shuffled through Veil's RingCt protocol.

Protocol Changes:

Light Zerocoin

Zerocoin will now have its reliance on zero knowledge proofs completely disabled. A zerocoin will now behave much more like a normal UTXO based transaction does. This results in a large reduction in transaction size, much quicker transaction validation, and fast transaction creation.

New Budget Addresses

The multisignature addresses that the general budget and the foundation budget get paid to have been updated to reflect a group of key holders that are more active in the community.

Zerocoin Overspend Attack and an Updated Inflation Schedule (Removed Founders Reward After 13th Payment)

The overspending of zerocoin denominations occurred slowly and over several months. The attacker did not spend other people's coins, they overspent their own coins and were able to redeem more value than the zerocoins were worth. This overspending attack inflated the supply by 12,441,690 coins. Through cooperation with exchanges that trade Veil, we were able to learn that around 9 million coins had been sold through several anonymous accounts. Overtime the rest of the coins were washed through the RingCt protocol in a way that was not easily traced and not easily able to be blacklisted. We were able to blacklist 282,125 basecoin and 46,810 in zerocoin. We also blacklisted 29 unspent stealth outputs that have a blinded value, so we cannot be sure of their total value. RingCt had over 5,000 outputs blacklisted, but we do not know if any of those coins have already been spent or the value of the coins.

To offset the inflation that was added by the malicious overspending of zerocoin denominations, it has been offered (and accepted) that the founder's reward be removed after payment 13. This removes approximately 10.02 million coins from being added to the supply, offsetting much of the inflation added by the overspend attack. Furthermore, Veil plans to publicly burn excess funds that are being held in the general budget address to offset the remaining 2.1 million coins (counting the blacklist offset). The inflation created by the overspend attack is something that alters coin emission schedule in a way that was much more rapid than designed, but offsetting the inflation is the best way to get the emission schedule close to its original design.

The overspend attack is a reminder that Veil needs to be diligent and continue to make rapid progress replacing the zerocoin based staking protocol with a RingCt based staking protocol.

Stake Modifier Redesigned

To prevent an issue called "stake grinding", the stake modifier code for Veil has been rewritten to make any type of stake grinding much more difficult. A stake modifier is a source of deterministic entropy that is added into the inputs that are hashed to create the proof of stake proof hash. The modifier effectively is in place to prevent the ability to see what a stake hash will be in the future and resend coins until there is a favourable amount of potential stake at some point in the future.

Make Modifier Entropy Bound To Sources That Do Not Grind Well

In order to make it more difficult to have influence over what the stake modifier will be at a point in the future, the entropy collected for the stake modifier has to be something that can't be "ground" easily. For example if the modifier were to be based on transaction hashes, then someone could just keep changing arbitrary parts of the transaction until the transaction hash results in a value that changes the modifier in a favourable way for the grinder. Veil's new modifier protocol now will use the proof-of-work hash (which is bound by computation) when entropy is collected from a PoW block and will use the proof-of-stake hash (which is bound by time and competition) for entropy collected from a PoS block.

Multi-Source Deterministic Entropy Collection

Many Proof of Stake cryptocurrencies have changed their protocol to collect the stake modifier entropy from a one or two places. For example PIVX recently updated their modifier to the same stake modifier protocol that QTUM uses, which grabs the modifier from the previous block and hashes it with the proof hash from next block. Before this update, Veil's modifier code was grabbed by a single source, and that was the accumulator value of a particular block in relation to the block being staked.

If not enough sources of entropy are collected it can create the ability to grind an entropy source. For example if a wallet has significant enough stake weight (for QTUM and PIVX this would just mean a few very very large UTXO's) then a grinder could find many proof hashes that would work for a particular block, the grinder would withhold from submitting a block that would not result in a modifier that makes them also win the next block. Although this grinding would require significant funds, it could potentially lead to a situation where a grinder could get a large amount of consecutive blocks and perform a double spend attack by causing chain reorganizations.

Veil's new modifier collects its entropy from 10 different blocks over the last 370 blocks. For example the modifier of block 1001 would first sample from the block that is 100 blocks from the chain tip, block 900. The next block is the height of the last sampled block 900 minus the sampled count (1) multiplied by 6. That would give the second sampling a block height of 894. The third would be 882. And so on. The end result is a modifier that is collected from many blocks, all of which are below the chain reorganization depth so cannot be changed, and have a very small chance of all being determined by a single source that could grind the entropy.

Use a Curved Entropy Selection Based on Height

Even if entropy is collected from multiple block sources, if the last block that the entropy comes from has a large amount of entropy bits sampled, then it allows from a grinder to have a large amount of entropy to grind. For example say that each block has 256 bits of entropy sampled from it (the full proof hash), and that the entropy is hashed to create the final modifier value. In the example above, the only real entropy that would matter is the entropy from block 900, since 2^256 has so many possibilities. This number would still be bound to a hard to grind source (as mentioned above), but at this point there would be no purpose of having multi-source entropy collection.

To solve this issue, Veil samples a small amount of entropy from the more recent blocks and gradually more bits from each sampling until the 7th sampling. After the 7th sampling the 8th-10th sampling reduce the number of bits sampled. Using Veil's scheme, if a grinder were going to grind a block to make their modifier favourable for their next stake (which would occur 101 block in the future), the grinder would only be able to grind it to 4 different values because only 2 bits are collected as entropy from that block (which can hold 4 possible values).

Why reduce the sampling at the end? Reducing the sampling on sources 8-10 makes longer range prediction of the modifier more difficult. If you are trying to predict what a modifier will look like at the chain tip + 370, you will know only a smaller portion of the entropy collected for the modifier, there will still be so much entropy added to the final modifier that you could not brute force computation of all of the potential results. If you are trying to predict what the modifier of the chain tip + 101 would be, you would have all of the modifier except for 4 of the bits, at which point you could see all 4 potential modifiers. In this regard, Veil's new protocol makes the final modifier become clearer and clearer the closer it gets (which is why we made the minimum stake age 1,000 blocks).

An example of a modifier for block 1001:

Initialize Modifier to 0.
Block 900 -> Hash(proofhash) -> Take 2 bits from result.
Modifier = Hash(Modifier and 2 sample bits)
Block 894 -> Hash(proofhash) -> Take 4 bits from result.
Modifier = Hash(Modifier and 4 sample bits)
Block 882 -> Hash(proofhash) -> Take 8 bits from result.
Modifier = Hash(Modifier and 8 sample bits)
Block 864 -> Hash(proofhash) -> Take 16 bits from result.
Modifier = Hash(Modifier and 16 sample bits)
Block 840 -> Hash(proofhash) -> Take 32 bits from result.
Modifier = Hash(Modifier and 32 sample bits)
Block 810 -> Hash(proofhash) -> Take 64 bits from result.
Modifier = Hash(Modifier and 64 sample bits)
Block 774 -> Hash(proofhash) -> Take 128 bits from result.
Modifier = Hash(Modifier and 128 sample bits)
Block 732 -> Hash(proofhash) -> Take 64 bits from result.
Modifier = Hash(Modifier and 64 sample bits)
Block 684 -> Hash(proofhash) -> Take 32 bits from result.
Modifier = Hash(Modifier and 32 sample bits)
Block 630 -> Hash(proofhash) -> Take 16 bits from result.
Assets 20
You can’t perform that action at this time.