Beginner FriendlyFoundryBridge
100 EXP
View results
Submission Details
Severity: medium
Invalid

Re-entrancy vulnerability in L1BossBridge::sendToL1 function, resulting in financial loss and disruption to the system

Summary

The vulnerability lies in the sendToL1 function. This function is responsible for sending tokens from L2 to L1. It uses the call function to send the tokens, which is a low-level function that forwards all available gas and does not throw an exception if the call fails. This can lead to a reentrancy attack.

Vulnerability Details

Reentrancy attacks occur when a malicious contract can repeatedly call a function before the first invocation of that function is finished. In this case, an attacker could potentially drain the contract's balance by repeatedly calling the sendToL1 function before the balance is updated.

Impact

Here is the vulnerable code:

function sendToL1(uint8 v, bytes32 r, bytes32 s, bytes memory message) public nonReentrant whenNotPaused {
address signer = ECDSA.recover(MessageHashUtils.toEthSignedMessageHash(keccak256(message)), v, r, s);
if (!signers[signer]) {
revert L1BossBridge__Unauthorized();
}
(address target, uint256 value, bytes memory data) = abi.decode(message, (address, uint256, bytes));
(bool success,) = target.call{ value: value }(data);
if (!success) {
revert L1BossBridge__CallFailed();
}
}

The nonReentrant modifier is used to prevent reentrancy, but it only protects against reentrancy on the same function. In this case, the sendToL1 function is calling another contract, which could potentially be reentrant.

The reentrancy vulnerability in this contract could have the following impacts:

  1. Loss of Funds: An attacker could drain all the funds from the vault contract. This could lead to significant financial loss for the users of the contract.

  2. Disruption of System: If the L1BossBridge contract is used in a larger system, a successful reentrancy attack could disrupt the entire system. This is because the vault contract could be used as a central point for storing funds in the system.

  3. Unintended Operations: The reentrancy vulnerability can change the contract’s state in unforeseen ways and trigger unintended operations. This could lead to unexpected behavior in the contract.

  4. Potential for Cross-Function Reentrancy Attacks: If the sendToL1 function shares state with another function that has a desirable effect for the attacker, a cross-function reentrancy attack could be possible. This could allow the attacker to perform operations that they should not be able to do.

Tools Used

AI tool phind.

Recommendations

To mitigate this vulnerability, you could use the Checks-Effects-Interactions pattern, which recommends that you make any state changes in your contract before calling other contracts. This would ensure that even if the called contract is reentrant, it won't be able to re-enter the calling function and cause unexpected behavior.

Here is an example of how you could refactor the sendToL1 function to use the Checks-Effects-Interactions pattern:

function sendToL1(uint8 v, bytes32 r, bytes32 s, bytes memory message) public nonReentrant whenNotPaused {
address signer = ECDSA.recover(MessageHashUtils.toEthSignedMessageHash(keccak256(message)), v, r, s);
if (!signers[signer]) {
revert L1BossBridge__Unauthorized();
}
(address target, uint256 value, bytes memory data) = abi.decode(message, (address, uint256, bytes));
// Checks
+ require(token.balanceOf(address(this)) >= value, "Insufficient balance");
// Effects
+ token.safeTransfer(target, value);
// Interactions
(bool success,) = target.call{ value: value }(data);
if (!success) {
revert L1BossBridge__CallFailed();
}
}

Here, the safeTransfer function is called before the call function, following the Checks-Effects-Interactions pattern. This ensures that the contract's state is updated before interacting with another contract, preventing a potential reentrancy attack.

Updates

Lead Judging Commences

0xnevi Lead Judge
about 2 years ago
0xnevi Lead Judge about 2 years ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.