code-423n4 / 2024-04-renzo-validation

2 stars 2 forks source link

[M-11] Front-running `xRenzoDeposit::initialize` allows attackers to rugpull and leave the protocol insolvent. #213

Closed c4-bot-3 closed 5 months ago

c4-bot-3 commented 5 months ago

Lines of code

https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/Bridge/L2/xRenzoDeposit.sol?plain=1#L75-L156

Vulnerability details

Impact

The initialize() function in the xRenzoDeposit contract is marked as public, which allows any account to call this function before the intended deployer.

An attacker can front-run the intended deployer and call the initialize() function first. This would allow the attacker to set the initial state of the xRenzoDeposit contract to their advantage, including:

Manipulation of Admin Functions:

Below are functions only available to admins, and by setting themselves as an admin by frontrunning initialize they can do the following:

function recoverERC20(address _token, uint256 _amount, address _to): Allows admins to withdraw an arbitrary amount of ETH from the contract, effectively draining the protocol's funds (rugpull).

function recoverNative(uint256 _amount, address _to): Allows admins to withdraw an arbitrary amount of ERC20 tokens to the contract, effectively draining the protocol's funds (rugpull).

setOraclePriceFeed(IRenzoOracleL2 _oracle): The attacker can set the price feed oracle to one they control, allowing them to manipulate the ezETH to ETH exchange rate.

setReceiverPriceFeed(address _receiver): The attacker can set the receiver contract address to one they control, potentially intercepting or disrupting the price feed updates.

updateBridgeFeeShare(uint256 _newShare): The attacker can adjust the bridge fee share, potentially diverting funds or altering the protocol's economics.

updateSweepBatchSize(uint256 _newBatchSize): The attacker can change the sweep batch size, potentially affecting the protocol's ability to process cross-chain transfers.

Disruption of Core Functionality:

The attacker can manipulate the initial configuration of tokens, contracts, and other parameters in the initialize() function, effectively hijacking the core deposit, withdrawal, and bridging functionality of the xRenzoDeposit contract.

This could lead to significant financial losses for users, as their interactions with the protocol may be subject to the attacker's manipulations.

Proof of Concept

The attacker observes the deployment of the xRenzoDeposit contract and quickly calls the initialize() function before the intended deployer.

The attacker sets the contract addresses and other parameters to values they control, such as setting the price feed oracle to one they own, the receiver contract to an address they control, and adjusting the bridge fee share and batch size.

The attacker can now call the admin-only functions to further manipulate the protocol's state, potentially disrupting the deposit, withdrawal, and bridging mechanisms.

Users attempting to interact with the xRenzoDeposit contract will be subject to the attacker's manipulations, potentially leading to financial losses or disruption of their expected interactions.

Tools Used

Manual Review

Recommended Mitigation Steps

Use the factory pattern to allow only the factory to call the initializer or ensure it is not front-runnable by calling initialize directly in the deploy script.

Assessed type

Other

0xJuancito commented 5 months ago

@howlbot reject

0xJuancito commented 5 months ago

See #952