Stake Bug Resolved: Announcing the Blocknet Bug Bounty!
22 Oct 2017 —
The Blocknet team are happy to announce that the fork was successful and the network is healthy! Bittrex wallets will be unlocked in a few days.
The Blocknet has now fully recovered from an exploit on a stake protocol bug inherited from the upstream codebases. Huge thanks to Dan, Jeff, Xenix, and especially Michael for the stellar work! The bug allowed an attacker to illicitly stake large amounts. Following this exploit, the attacker attempted unsuccessfully to obfuscate the origin of these illicit coins by sending many tiny transactions to innocent users, which, maliciously, invoked the possibility that a user may “infect” their coins by spending them in conjunction with an illicit input.
As of today, users have the opportunity to detect any illicit coins in-wallet and send them to the redeem address: BmL4hWa8T7Qi6ZZaL291jDai4Sv98opcSK
Recovered funds are proposed to become the Blocknet bug bounty (and other community budgets) which henceforth shall provide hackers with a lucrative financial incentive to report bugs instead of exploiting them.
We are especially excited to announce that, henceforth, the attacker has two options: either hold his/her illicit, unspendable coins until they are destroyed in an upcoming block, or send them to our redeem address and attempt to earn them back honestly by spotting bugs.
What We Did
On 27 Sept, we became aware of a critical staking protocol bug inherited from the PPC/Dash/PivX codebase. Furthermore, we noticed a malicious actor appeared to have exploited this bug the very day before. (which, however improbably, was that the code lacked a check on the number of coins in a stake reward). Upon discovery, we immediately contacted exchanges to block any attempts to sell hacked funds in order to contain the illicit coins and protect our investors.
On the following day, we released a fix for the bug, preventing any further exploits of this nature.
However, since a large number of illicit stake rewards now lay in the hands of attackers, it was additionally required to redress this matter. In quick succession, we released fixes for related aspects of this attack:
- A fix to track stake rewards earned with illicit coins.
- A fix to prevent modification of the 70/30 reward split between service nodes and staking nodes.
In the meantime, one of the attackers returned some of the coins he staked illicitly, upon a bounty agreement contingent on returning all funds not already sold on Bittrex. From a total of 363k, 43k were sold on Bittrex prior to the discovery of this bug, 303k were returned, and the rest were kept in the attacker’s possession. Due to not returning all the funds, the bounty agreement will not be honored. A second attacker was unwilling to return his/her coins, having staked 223k illicitly, and proceeded to attempt to “infect” innocent users’ addresses in the hope of either obfuscating the illicit coins (s)he held, or by making it difficult to lock illicit coins. This second attacker also maliciously attacked the network.
Meanwhile, our counterattack was under way — that of systematically locking the illicit coins, with an aggressive blockchain tracking algorithm even if sent to new addresses continually. This required wallets to build a realtime list of all inputs to transactions containing illicit coins. Broadly speaking, the solution is as follows:
- Generate a list of inputs, beginning with illicitly staked block generation transactions
- Exclude inputs prior to Bittrex’s wallet being disabled
- Exclude service node stake rewards originating from illicit coins but which were correctly sent to service nodes
- Exclude any unspent transactions < 0.98 BLOCK not including fake 0.7 rewards
- If illicit stake rewards are spent, add their output to list of illicit inputs
- If an input is on the list, make it unspendable in the wallet
- Enforce the above rules at block height 105512, causing a hard fork
The exploited unspent transactions list was implemented by invoking a distributed API hosted on S3 to ensure identical state and to handle high load at the time of the fork. Now that illicit coins are all locked and can no longer be spent, the list shall be hard-coded into a future wallet release.
Protection Against the Attack For Innocent Users
The fix, additionally, was finessed by our developers to avoid locking addresses that (a) existed on the blockchain prior to the exploit, with (b) inputs that hold both illicit and licit coins, protecting users from attempts by the attacker to “infect” innocent users’ coins.
Incidentally, upon analysis, this had a minimal effect on the number of coins locked, as the remainder was 98.7% of the exploited coin supply. As such, only ~3k coins were left unlocked, effectively turning the attack-payments into donations from the attacker to the community.
Cleaning Your Wallet
The current wallet version automatically detects any illicit funds at an address, and offers you the option to clean your addresses of them. It does this by sending “infected” inputs to the bug bounty address above, so that only “clean” inputs to the address remain.
Manually Clean Your Coins
If you are on v.3.7.37 or earlier, or if for any reason you would prefer to clean your coins manually, you may do so as follows:
- If on v.3.7.36 or earlier, check this list of locked funds for your address(es): https://dxlist.blocknet.co/dxlist.txt
- If it’s on the list, it’s an infected address and needs to be cleaned.
- Version 3.7.37 and later will auto-detect infected addresses and, inside Coin Control, will display an “exploited” column if you have an infected address. Infected addresses will then show the words “exploited” in red font under the “exploited” column.
- Spend the entire balance of each exploited input to BmL4hWa8T7Qi6ZZaL291jDai4Sv98opcSK Do not spend the entire address balance, only the exploited input.
- Your transaction must also include a tx fee. To pay this do not use the exploited input. Rather,
1. Select a second funding address, using coin control,
2. Add a second output to the payment (it’s simple to just use the second funding address)
3. Send the balance of the second funding address, minus a tx fee
- The transaction will then spend the exploited input to the redeem address, pay the fee with the second address, and return the balance of the coins back to your second address.
Details About the Redeem Fund and Bug Bounty:
- The redeem funds are currently held in separate addresses by Dan, Michael, and Jeff. A multisig solution is being considered.
- Some of the funds (303k BLOCK) were returned by one of the attackers. These are not locked and are already usable for bug bounty and additional budget payments.
- Some of the funds remain in an attacker’s wallet, and are unspendable. The only course of action that the attacker may take is to “clean” them using our new feature, which would result in them being sent to the redeem address.
- If you feel that you would not like to send your illicit coins to a redeem address then let your voice be heard: submit a proposal to our self-funding system that illicit coins be put to an alternative purpose: http://blocknetdx.forumotion.com/t4-blocknet-proposals-faq. The network may then vote on your proposal.
Proposal for Redeemed Funds / Community Budget
In order to support the long term goals of the Blocknet DX, the following proposal outlines the current needs. A first draft of this proposal has been presented to the community.
Thanks to the Community!
Thank you for your sticking it out with the team and project, we appreciate your patience! Keep in mind, we are not performing a task which has a set process, delivery time, and cost. We are breaking new ground and shaping the future of blockchain technology by doing something that has never been done before. Our developers have proven it’s possible to create cross-chain atomic swaps and we are now paving the way for interoperability and inter-chain services.