Recap of the crvUSD audit findings

Author: Konstantin Nekrasov
Security researcher at MixBytes
Disclaimer
All findings described in this article were detected during the audit and fixed by the Curve team before project deployment. You can check the results of the audit here: https://github.com/mixbytes/audits_public/blob/master/Curve Finance/Curve Stablecoin (crvUSD)/README.md.
Introduction
We conducted an audit for crvUSD, an over-collateralized stablecoin by Curve. Our audit focused on the AMM and Controller contracts where we found two critical vulnerabilities which were fixed during the audit. In this article, we’ll discuss the vulnerabilities, how to identify similar ones, and their respective solutions.
Finding 1: Arbitrary Call
CrvUSD has the Controller contract that allows users to deposit collateral and receive crvUSD. The Controller has privileged functions that regular users cannot access.

The Controller contract has a function called liquidate_extended(), which accepts an arbitrary callback:
def liquidate_extended(
    user: address, min_x: uint256, frac: uint256, use_eth: bool,
    callbacker: address, 
    callback_sig: bytes32, 
    callback_args: DynArray[uint256,5]
)
This callback was executed on behalf of the Controller contract, and an attacker could specify the call’s address, signature, and arguments.
The catch was that the callback expected a 64-byte response, so the standard ERC20.approve() couldn’t be used as a callback. Moreover, these 64 bytes were read into two uint256s, which were checked against specific values. However, it was still possible to invoke the privileged AMM.withdraw(address,uint256) function as a callback, allowing an attacker to withdraw funds from the AMM without authorization:
def withdraw(user: address, frac: uint256) -> uint256[2]:
    @notice Withdraw all liquidity for the user. Only admin contract can do it
Hence, an attacker could drain all liquidity from the crvUSD AMM. The Curve team fixed this vulnerability by prohibiting the use of arbitrary callbacks.
Finding 2: Donation Attack
In crvUSD, it was possible to spread debt across different price ranges represented by ticks. Users depositing into a specific tick would receive shares of that tick.

It appeared that each tick was susceptible to a donation attack. This type of attack is detailed in our blog. In essence, the attacker could steal users’ funds across different price ranges.

How did we manage to donate funds to a specific tick without minting shares? Firstly, the AMM.exchange() function allowed movement of the active tick and trade between crvUSD and collateral. Any trade took a fee from the trader, which was left in the passed ticks. This fee acted as a donation. However, this only took fractions of a percent from the traded amount, insufficient for a full-scale attack. To overcome this limitation, an attacker had to combine the calls of the withdraw(), deposit(), and repay() functions in order to perform the same inflation attack on themselves. This increased the donation in the ticks by 1.5 times.

In the end, an attacker could initiate a single transaction that ran a loop of 120 iterations in the smart contract, inflating the donation to a value of 100_000e18. This allowed them to steal any amount from other users.

The Curve team addressed this issue by introducing virtual shares, exactly as recommended by OpenZeppelin.
General conclusions
Always pay attention to callbacks and shares in your project. For shares - check for donation attacks and for callbacks - verify their level of arbitrariness.

The problem is that sometimes it may seem that an attacker is limited in their exploitation, making it seem like there’s no vulnerability. However, an experienced auditor can often bypass apparent limitations and demonstrate exploitability. That’s why conducting external audits with knowledgeable experts is crucial.
  • Who is MixBytes?
    MixBytes is a team of expert blockchain auditors and security researchers specializing in providing comprehensive smart contract audits and technical advisory services for EVM-compatible and Substrate-based projects. Join us on X to stay up-to-date with the latest industry trends and insights.
  • Disclaimer
    The information contained in this Website is for educational and informational purposes only and shall not be understood or construed as financial or investment advice.
Other posts