On 21sth November 2021, Pickle finance was hacked, where an attacker was able to drain $19M DAI from the pDai jar. The attack exploited multiple inconsistencies & flaws in the logic of the pickle jar smart contract.
- Pickle Jar contract had a function swapExactJarForJar() which was meant to be generalized to bring more flexibility to the protocol. However, the attack could have been prevented if the function checked for whitelisted ones.
- The attacker’s jars contain minimalist functions to function as a jar and since the user controls Jars most of the checks can be easily bypassed.
The user-created two Jar contracts
- Attacker’s Address
- Attack transaction
- Attacker’s Contract
- Detailed transaction trace
Steps involved in exploit:
- The attacker deploys two new fake Jars.
- First Jar
- Second Jar
- The attacker calls strategyCmpdDaiV2.getSuppliedUnleveraged() which returns the amount of DAI available i.e 19728769153362174946836922 ~ 19M.728 DAI.
- The attacker calls swapExactJarForJar the first time, supplying fake Jar addresses created earlier which withdraws deleveraged invested DAI from the compound back to pDAI Jar.
- attacker calls earn() function 3 three times on pDAI (Pickling Dai) minting cDAI to StrategyCmpdDaiV2 contract.
- The attacker deploys another two fake Jars & a fake underlying.
- Third Jar
- Fourth Jar
- Fake Underlying contract
- Then the attacker calls swapExactJarForJar, this time passes in the third & fourth Jar with crafted data that makes a function call to curve proxy in the context of the controller-v4. Since the attacker has crafted the Jar to work with the contract it bypasses checks to the point where arbitrary code is executed in the context of the controller-v4 contract. Then withdraw() is called to withdraw 950,818,864 cDAI to controller-v4. The withdrawn cDAI are deposited to the fake Jar through deposit() and all cDAI is transferred to the attacker.
- The attacker calls redeemUnderlying on the compound to convert all cDAI to DAI & walks away with ~19M DAI.
Try It Yourself!
We have put together a GitHub repository to reproduce the attack. Here is the Github repo.