Or that contests remain the most effective form of audit when it comes to finding more bugs faster per dollar than any other method.
@zellic_io should open source the @code4rena platform and operational manual so projects or foundations or VCs or @ethereum or @_SEAL_Org can run these as I always felt they were: public goods. cc @samczsun
200k in 80m out
Here's how Resolve got drained and how Morpho made it worse (and how to avoid it all in your project).
---
1. No contract protection
The whole hack consisted of an attacker depositing 100k USDC (the min) and getting minted 50m USR (a few times).
There is no cap for max mint, no timelock and no invariant check to make sure that "deposit amount == minted amount"
(or at least that the whole protocol is solvent)...
---
2. Single private key
Again, everything relied on a back end that had a privileged role enabling it to mint. No multisig, no nothing, just a single PK minting whatever it likes.
---
3. 3h to pause
The team took ~3h to pause. The attacker minted 50m USR, waited 80min and minted again 30m USR.
---
4. 4 signatures for a pause
This is the opposite to a safe design.
1 PK to mint unlimited assets, 4 PKs to pause everything.
It should be the opposite. Allow anyone on the dev team to pause everything and add a multisig for the important decisions
---
5. Morpho hardcodes USR = 1$
Morpho relied on oracles who assumed 1 USR == 1 USD.
Perfect assumption 99.9% of the time, terrible in that 0.1%.
Users were able to buy 1 USR for 0.2 USD, deposit it into Morpho and borrow 1 USDC, repeat...
---
6. Asset runs in the wrong direction
Morpho vaults have off chain managers that detected a 100% utilization on USR/wUSR vaults (due to the above).
Then 12min after the hack they proceeded deposited funds into them to farm the higher yield.
That of course enabled even more assets to be siphoned out of these vaults.
Curators should be suspicious if all vaults in a given asset jump to 100% utilization in the span of a few minutes.
---
18 audits, still hacked...
Not because the auditors were bad, but because the architecture was.
I spent 10 hours writing down every weird vault bug I've found.
9 bugs in total
- 5 for building a vault
- 4 for integrating with one
Most of them sound obvious until you realize your project has them
https://t.co/V5tnePDMPU
I lost a significant amount of money due to a silent, zero-interaction dev environment exploit.
No wallet connection.
No signing.
No running the app.
Just cloning a repo and opening it in VS Code.
Malicious .vscode/tasks.json hooks can execute automatically on folder open once you trust the workspace, hidden, background execution. This is actively abused by DPRK Interview groups.
I work in Web3 and thought I was careful. This one is genuinely scary and unheard of for most devs.
Please treat untrusted repos like malware. Open in restricted mode. Inspect .vscode/ before trusting anything. 🙏
How ✨I found a critical vulnerability✨ in @zora's ERC20Z contract via a little known Uniswap v3/v4 property
When Zora put out this article: https://t.co/pyEQuVtXjD outlining their new protocol, I was intrigued and had to learn more
From a high level, the system works by allowing creators to sell NFT's where a portion of the revenue from the sale is taken and placed in a Uniswap v3 pool along with an ERC20 wrapped version of the NFT, instantly creating a liquid secondary market. Pretty cool mechanism. I had to dig deeper
Reading the contract, I quickly spotted something that set off alarm bells in my head. When minting liquidity, the amount0Min and amount1Min parameters were 0. Looks like a classic sandwich attack vulnerability, was this too good to be true? (spoiler: kinda)
I quickly wrote up a (messy) PoC realizing that I was looking at a pretty good payday for the little amount of time I'd spent on this. The PoC worked by frontrunning the liquidity mint to provide a small amount of liquidity to the pool and swap the token price to the maximum price, then backrunning the mint by selling the token into the newly placed liquidity, draining the position of its ETH and dropping the token price to near zero
I sent the PoC off to Zora's security team expecting the best, but alas they pointed out a significant flaw in the PoC. I dealt ERC20Z tokens to the contract to provide liquidity so that I could make the frontrun swap, but Zora had designed the system with this in mind, making it impossible for anyone to get the ERC20 token before liquidity was placed
Feeling dejected, I played around with the PoC to see if there was any way I could still make the attack possible. What if I try swapping with no liquidity in the pool? I run the updated test. I see green. It worked! It turns out that you can freely manipulate the price of Uniswap v3/v4 pool by swapping zero amounts when there's no liquidity in the way. This was exactly what I needed for the exploit
Zora acknowledged that this attack was indeed possible, patching the issue and ultimately awarding me a bounty of 11k USDC
To security researchers and smart contract developers: make sure to prevent price manipulation by using safe amount0Min/amount1Min parameters and beware of 0 amount swaps!
Shameless plug: this is the third high+ severity confirmed bounty I've reported on a protocol which leverages Uniswap v3, so if you'd like to get coverage on your Uniswap v3/v4 adjacent protocol, my DM's are open! And if you'd like to book me on a team audit with the best of the best, you can book me through @SpearbitDAO
Made it to top 10 in a public contest on @sherlockdefi . Thankyou God for this 🤲. Big thanks to @sherlockdefi for this opportunity, many more to come inshallah😇
How to make the most out of any codebase?
First, list every entry point a user can interact with.
Then, go through them one at a time and take note
More details:
https://t.co/zWLEvEqCxq