code-423n4 / 2024-05-arbitrum-foundation-validation

0 stars 0 forks source link

Potential Theft of Funds Due to Static Salt in Contract Creation During Reorgs #371

Open c4-bot-1 opened 4 months ago

c4-bot-1 commented 4 months ago

Lines of code

https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/main/src/assertionStakingPool/EdgeStakingPoolCreator.sol#L19

Vulnerability details

Impact

The use of a static salt (0) in the createPool function of AssertionStakingPoolCreator and EdgeStakingPoolCreator alike can lead to predictable contract addresses. This poses a significant security risk, as attackers can exploit this predictability during blockchain reorganizations. Attacker can deploy a malicious contract at the same address where funds are expected to be sent, they can then redirect these funds to their control. This vulnerability threatens the security of user funds. This is particularly pertinent in l2 rollups like Arbitrum.

Proof of Concept

https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/main/src/assertionStakingPool/EdgeStakingPoolCreator.sol#L19

EdgeStakingPool pool = new EdgeStakingPool{salt: 0}(challengeManager, edgeId);

Steps to Reproduce

  1. An attacker observes the transaction deploying a new EdgeStakingPool.
  2. The attacker prepares a malicious contract with the same bytecode and waits for a re-org.
  3. During a re-org, the attacker deploys the malicious contract using the predictable salt (0), thus ensuring the contract is deployed at the same address.
  4. Funds sent to this address by legitimate users are now under the control of the attacker.

Tools Used

Manual analysis

Recommended Mitigation Steps

function createPool(
    address challengeManager,
    bytes32 edgeId
) external returns (IEdgeStakingPool) {
    // Generate a unique salt based on sender and other parameters
    bytes32 salt = keccak256(abi.encodePacked(msg.sender, challengeManager, edgeId, block.timestamp));

    EdgeStakingPool pool = new EdgeStakingPool{salt: salt}(challengeManager, edgeId);
    emit NewEdgeStakingPoolCreated(challengeManager, edgeId);
    return pool;
}

This change implements the use of create2 with a dynamically generated salt that incorporates the msg.sender, the parameters of the pool, and the current timestamp. This modification ensures that each contract deployment results in a unique address, significantly reducing the risk of address collisions and preventing the reorg attack vector.

Assessed type

Invalid Validation