On August 30, 2021, decentralized lending protocol CREAM Finance was the victim of a flash loan hack. The attackers stole 2804.96 ETH and 462,079,976 AMP tokens from the protocol’s vaults.
Inside the Attack
The CREAM attacker exploited a reentrancy vulnerability that arose from how CREAM integrated AMP into its protocol. The AMP protocol implements the ERC-777 token standard, which creates the potential for reentrancy. Within the AMP contract, the _callPostTransfersHook hook is designed to call the tokensReceived() fallback function within the calling smart contract. This hook is executed as part of the process of borrowing from the protocol and allows the attacker to execute code before that initial borrow is completed.
The attacker’s smart contract’s tokensReceived function includes a second call to the borrow() function. Since this call occurs before the AMP contract updates its state from the initial borrow, the attacker is able to borrow more assets than they would have otherwise. By exploiting the reentrancy vulnerability repeatedly, it is possible to drain the contract.
Two attackers carried out an attack on CREAM. After the initial exploit, a copycat attacker used the same techniques to steal a smaller amount from the protocol.
Lessons Learned From the Attack
The CREAM Finance hack is unusual in that it did not exploit a bug in the AMP contracts. AMP implements ERC-777, and the projects’ contracts worked exactly as designed. ERC-777 is designed to notify contracts that they are being sent tokens in the form of a callback. In this case, the attacker exploited this callback to perform a reentrancy attack.
This hack demonstrates the importance of performing a complete risk assessment for all code within a DeFi project. The AMP integration with CREAM made this attack possible, and the attack did not occur sooner only because there was insufficient AMP in the protocol to make it worthwhile. A complete security audit of all proposed contract modifications and integrations is essential for security.