vStake Pool Incident Post-Mortem
- The vStake profit-sharing pool for vBSWAP was recently the subject of an exploit that resulted in a loss of user deposits in that pool.
- The VALUE team proposes two approaches to make affected users whole
On May 5th 2021, 3:22 AM UTC, the exploiter re-initialized the pool and set the operator role to himself and _stakeToken to HACKEDMONEY.
By doing so, the exploiter took control of the pool and called the method governanceRecoverUnsupported() and drained the original stake token (vBWAP/BUSD LP).
Then, the exploiter removed 10,839.16 vBWAP/BUSD LP, then removed liquidity and received 7342.75 vBSWAP and 205,659.22 BUSD.
The exploiter then sold all 7342.75 vBSWAP for 8790.77 BNB at 1inch. Then, the exploiter used both BNB and BUSD to buy renBTC and use renBridge to move the funds back to BTC, which is laundered to the address https://www.blockchain.com/btc/address/1Cm6WGvXQ9EgvvWX5dRsBxE2NvxFjfbcVF
The exploiter’s actions can be verified on-chain here.
The affected pool contract has an initialize() function that should have been activated after deployment.
This line: initialized = true;
is missing from the function. As such, anyone could re-initialize the pool and set himself as owner of the pool, basically taking control of it. As owner, the exploiter used the governanceRecoverUnsupported(), which is used for recovering pool funds in the event of a bug or undesired event.
Why did the line go missing?
During set up of the profit-sharing vStake pool, the code was not written from scratch but migrated from the old implementation of our Reserve Fund, which had the correct setting. Somehow when merging the code, the line was not included and escaped notice — human error during code merge. This error does not appear in any other pools.
Only the vStake profit sharing pool of vBSWAP at https://bsc.valuedefi.io was affected. All other pools and funds are SAFU.
Immediate actions and possible mitigations in the future
- We immediately looked into the issue and fixed it.
- Moving on, we will implement a 12-hour time lock for all critical functions.
- Moreover, part of the Reserve Fund will be spent to buy insurance. We will work out the details with our insurance partner Soteria to implement this as soon as possible.
Compensation Plan and Voting
We will make the community whole again by voting as a collective on the best resolution.
All vBSWAP currently within the Reserve Fund (2802.75 vBSWAP) and 205,659.22 BUSD from the ValueDeFi deployer will be used to compensate all users at the pool. The remaining 4540 vBSWAP will be compensated as following:
Mint 4540 vBSWAP to compensate all affected users immediately.
This action could be done swiftly by the dev team without causing more workload, allowing us to continue working on important tasks at hand.
Mint 2270 vBSWAP to compensate right away. The remaining balance of 2270 vBSWAP will be minted to refund the contract in 3 months. A snapshot will be taken of every affected user in the vStake profit-sharing pool. After the snapshot is taken, all affected users will be able to claim their missing vBSWAP via the refund contract.
This option will require some work for the dev team so it might delay current workload.
For both options: After the mint, the subsequent vBSWAP accumulated by the Reserve Fund will be burned over the next 6 months. At which point the extra 4540 vBSWAP will be completely burned, reducing the supply back to normal.
From our pace of innovation on the bleeding edge of cross-chain DeFi, unfortunately by definition there will always be an element of risk with new deployments. Nonetheless, as laid out in our Missions and Values along with our track record in the space, the community can rest assured that we continue to work tirelessly with our community’s economic benefit and well-being in mind.
Thank you again for being a part of the Value Defi community and our continuing journey, in good times and bad, to meet the standard of our Mission and Values.