Closed sherlock-admin4 closed 3 months ago
The feasibility of this attack depends on the attacker being able to brute-force all possible salt values. EIP-3607 has introduced some restrictions on the use of create2 to prevent such attacks, but the feasibility of such an attack in real-world scenarios is still debatable.
neogranicen
Medium
Create2
address collision against a to-be-deployed rewarder allows for complete draining of the rewarder.Summary
An attacker with a pre-computed exhaustive Rainbow table for all the salts that will make him deploy a proxy contract at a certain address from his wallet will be able to front run
createRewarder
andcreateBribeRewarder
, deploy a proxy that points to an implementation that approves him an infinite amount of reward token for the to-be-deployed rewarder in the address it will be deployed on and then self destruct and let the rewarder get deployed.When the rewarder receives the rewards to be distributed to the user, an attacker will be able to drain all the rewards.
Vulnerability Detail
createRewarder
uses_clone
which usescloneDeterministic
function to deploy a new rewarder using create2 and adds some values at the end of its bytecode which are called immutable arguments.The address for the contract to be deployed using Create2 is determined by the last 20 bytes of the following as mentioned in the eip-1014:
$address = Keccak256(0xff || address || salt || Keccak256(initcode))$
Now in the context of
createRewarder
the address is going to be the factories address and the salt is going to be calculated using the $(nonce+1)$ and the address of the sender of the transaction as is clear form below:Now for the init code
cloneDeterministic
provides a bytecode for a Minimal proxy preceded by the address of the implementation and followed by the immutable arguments which are the reward token and the pool id as is shown here:createBribeRewarder
uses_cloneBribe
with the only difference being that the immutable arguments passed are the reward token and the pool address instead of idNow we can see if a transaction is submitted an attacker will have access to all the data that will let him to compute the address the rewarder will be created at.
Now an attacker can keep brute force searching until he comes up with an exhaustive Rainbow table of what salt is needed to generate any address that can exist within the 20 bytes domain while having the init code as a proxy and the address as his address.
The feasibility, as well as the detailed technique and hardware requirements for doing so, are sufficiently described in multiple references:
Draining the Rewarder
Impact
With the advancement of computing hardware, the cost of an attack has been shown to be just a few million dollars, and that the current Bitcoin network hashrate allows about $2^{80}$ in about half an hour. The cost of the attack may be offsetted with longer brute force time.
Though it might seem absurd for an attacker to spend millions to steal some hundreds of thousands the twist is that once the attacker gets the rainbow list he can keep using it to excute multiple attacks which will make him at the end make a profit, and MagicSea will only be a stepping stone on his process.
Code Snippet
https://github.com/sherlock-audit/2024-06-magicsea/blob/42e799446595c542eff9519353d3becc50cdba63/magicsea-staking/src/MasterchefV2.sol#L488
Tool used
Manual Analysis
Recommendation
Use the original version of ClonesWithImmutableArgs which uses
CREATE
instead ofCREATE2
Refrences
This was inspired by this great finding