Platform: Code4rena
Start Date: 04/03/2024
Pot Size: $88,500 USDC
Total HM: 31
Participants: 105
Period: 11 days
Judge: ronnyx2017
Total Solo HM: 7
Id: 342
League: ETH
Rank: 74/105
Findings: 1
Award: $42.78
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Bauchibred
Also found by: 0x11singh99, 0x175, 0xAlix2, 0xDemon, 0xGreyWolf, 0xPhantom, 0xspryon, 14si2o_Flint, Arabadzhiev, Aymen0909, Bigsam, BowTiedOriole, CRYP70, DanielArmstrong, FastChecker, JecikPo, KupiaSec, MohammedRizwan, Norah, Timenov, Topmark, VAD37, adeolu, btk, crypticdefense, cryptphi, givn, grearlake, jnforja, kennedy1030, kfx, ktg, lanrebayode77, n1punp, santiellena, stonejiajia, t4sk, thank_you, tpiliposian, wangxx2026, y0ng0p3, zaevlad
42.7786 USDC - $42.78
The token balances of the bellow mentioned contracts can be drained
The AutoExit
, AutoCompound
and AutoRange
contracts all extend the Automator
abstract contract. The Automator
on its part extends the Swapper
abstract contract, which implements the uniswapV3SwapCallback
function. This function looks like this:
function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external override { require(amount0Delta > 0 || amount1Delta > 0); // swaps entirely within 0-liquidity regions are not supported // check if really called from pool (address tokenIn, address tokenOut, uint24 fee) = abi.decode(data, (address, address, uint24)); if (address(_getPool(tokenIn, tokenOut, fee)) != msg.sender) { revert Unauthorized(); } // transfer needed amount of tokenIn uint256 amountToPay = amount0Delta > 0 ? uint256(amount0Delta) : uint256(amount1Delta); SafeERC20.safeTransfer(IERC20(tokenIn), msg.sender, amountToPay); }
We can see that all it does is that it first verifies that the msg.sender
is a Uniswap V3 pool and then it transfers some amount of tokens to it. And since all of the above mentioned contracts that extend Automator
are supposed to hold ERC20 tokens within them, this function can theoretically be used to drain them, if the pool verification in it is somehow managed to be bypassed.
And this is where the vulnerability comes. This scenario is actually possible, since the Uniswap V3 pool CREATE2 addresses are computed by truncating a keccak256 hash to 160 bits, which means that there will be 2^96 different hashes that will result in the same address.
This exact vulnerability has already been discussed in this report from a past Sherlock contest and in this article. In both of those resources it is explained in detail exactly how this vulnerability can be exploited. The scarry part is that in both of those resources, it is stated that the exploit will cost a few million dollars as of today. And that price will keep on getting lower and lower, due to the rapid advancement in computing capabilities. Just to put things into perspective, the Bitcoin hash rate has almost doubled since the above mentioned report was created back in September 2023 - it has raised from 4.71e20 to 7.68e20.
Additionally, since the contracts in question are computing the addresses of Uniswap V3 pools, this means that if a collision is found for any external contract that uses those in the same manner (including the official Uniswap V3 Router, which will most likely be the first target of this exploit, due to the huge amount of token allowances that it has), the same collision will be able to be used in the context of the Revert Lend protocol, which makes this exploit much more likely to happen.
Manual Review
Get the pool address using the getPool
function of the Uniswap V3 Factory instead of computing it (getPool
will return address 0 if the factory hasn't deployed a pool with the specified parameters)
Access Control
#0 - c4-pre-sort
2024-03-21T14:04:04Z
0xEVom marked the issue as duplicate of #188
#1 - c4-pre-sort
2024-03-21T14:04:22Z
0xEVom marked the issue as sufficient quality report
#2 - c4-judge
2024-04-01T10:57:50Z
jhsagd76 marked the issue as satisfactory
#3 - c4-judge
2024-04-01T11:49:22Z
jhsagd76 changed the severity to QA (Quality Assurance)
#4 - c4-judge
2024-04-01T11:50:03Z
jhsagd76 marked the issue as grade-a