Sorry for the mega post, but I’m a bit out of time to day and wanted to get this out.
Today was an interesting morning. The YC @CigDao_ has been going through some growing pains and in an attempt to stabilize some things we’ve had a number of serious proposals lately that have been very lightly voted on. This is due to the fact that you have to burn your tokens to vote. A cool feature in most scenarios, but with the small size of the dao and the significant size of changes I’ve been looking for easy ways to implement non-burnable voting so we can get a better view on what the DAO wants.
I had some code I was considering and went to check out the core contract. As a developer is want to do, you mess around. The temptation to click mint(Canister: onxlw-tiaaa-aaaan-qedoq-cai - ICP Dashboard) just to see what happens is always there and as light indulgence, I jammed in a 1 with a bunch of 0s and hit mint. This is not supposed to work. But it did. And now I’m in a conundrum.
Someone is going to notice this issue very soon and the ramifications are going to be unpredictable. One of the biggest things that saved ETH in the early days was the quick thinking during the DAO and the withdrawal by white hats of significant tokens that allowed the hack to be minimized. In that same spirit, I started doing all I could to remove as much ‘capturable’ value as possible before someone else saw a very unexpected mint and went to try it themselves.
It appeared the mint was at least gated by a max supply so I probed this limit to get up to the max. I wasn’t sure what to do next, but feared a panic would lead to significant selling. In hindsight perhaps my decision wasn’t the best, but after poking around it looked like the only liquidity pool was on sonic.
I had minted 273 Billion YC, which I think was like over 25% of the supply and I was hoping that I could get all the ICP out. And then any fallout would be fixable on the YC canister side. The 273 B didn’t go as far as I expected and I was only able to get most of the ICP out. A few users bought up some cheap YC and we may need to figure out what to do there as it may have supply issues.
I tried a few more things to see if I could get the rest of the ICP out but I was just competing against myself and couldn’t mint any more YC as the bug was tapped out. At this point, I contacted the current and previous leaders of CigDAO(@ALLiDoizCode , @Nihilor2 , and @accumulatingicp ) to start mitigation of the issue and get it fixed. We also knew the code had been used elsewhere so we did some penetration testing on STACKED and OLD @icsneed and confirmed they did not have the same vulnerability.
At this point, all the ICP has been returned to the CIGDAO treasury and the bug has been patched. I’ll let the contract author give a better description as to what and why the bug was there.
The couple of hanging threads are what to do about any fees generated by my massive trade on Sonic(if anything can be done) and what to do about the excess YC that may be out there as a few people bought up cheap YC that shouldn’t exist. I’ll leave that up to the DAO leadership to work through.
This begs a number of questions.
What should we do about these kinds of vulnerabilities on the IC?
Auditing is hella expensive (I do audits on the IC if you need one) and since we have upgradeable contracts, audits need to be evergreen. This is even more expensive.
When canisters change we need to know. This bug isn’t in the YC codebase that I could find and I expect that it was a one off change for a governance issue, but am not sure.
Can we ensure somehow that code doesn’t get deployed that doesn’t have public code?
On the Motoko side we’d need a motoko compiler on the IC that can check with GitHub on hashes. Azel might actually be able to do this if we could somehow make the Motoko compiler continuable across rounds. Not sure about rust…does rust compile rust?
For dexs, should @sonic_ooo , @ICPSwap , @HelixMarkets , and @ICLighthouse they be checking total supply on each transaction and not letting the transaction through if they detect a massive change in total supply?
More to dig into here when I have more time. In the meantime I hope I’ve minimized the damage and we can get YC back online.
Along those lines I did set up https://utiy3-bqaaa-aaaam-abe7a-cai.ic0.app/axon/6 which is a VOIC canister(GitHub - icdevsorg/VoIC) pointed at the newish YC canister.
It is in the process of syncing, but when done, it should track ongoing activity and update votes accordingly. People can make proposals and everyone can vote without burning.
It even has some treasury functions should we decide to use them. I’d suggest we move all YC decisions over there until we get this DAO transition stuff figured out.
If it looks like your balance is out of whack, let me know and I’ll investigate.
Since this is a bit more technical forum, I’ll be happy to answer any more technical questions here. In the mean time: MAKE SURE YOUR MINT FUNCTION IS SECURED