Beginner FriendlyFoundryBridge
100 EXP
View results
Submission Details
Severity: high
Valid

`L1BossBridge::sendToL1` allows authorized signers to make arbitrary calls

Summary

L1BossBridge::sendToL1 allows authorized signers to make arbitrary calls, as the message param is decoded into a specific target and calldata.

Vulnerability Details

L1BossBridge::sendToL1 has a function parameter bytes memory message. The function uses this param to decode:

(address target, uint256 value, bytes memory data) = abi.decode(message, (address, uint256, bytes));

and finally use these parameters to make a low level call:

(bool success,) = target.call{ value: value }(data);

This function allows authorized signers to potentially steal users funds, if the target is the token address, and the data is:

abi.encodeCall(IERC20.transferFrom, (address(vault), signer, token.balanceOf(address(vault)));

Also, the target can be any ERC20 token address.

If the contract could hold ETH, if the target is the signer address, and the data is empty, this function will actually be used to send ether:

(bool success,) = sender.call{ value: value }("");

Basically, this function is intended to be used to withdraw tokens from L2 to L1, but its actually a risky function that lets authorized signers do as they please.

Impact

Medium. Although this is considered a centralization risk, this does not mean that its should not considered as a risk, because allowing authorized signers to make arbitrary calls should not be allowed.

Tools Used

  • Manual Review

Recommendations

Remove withdrawTokensToL1 function and message param from sendToL1 function. Remove also the low level call. Make sure to only allow transferFrom from vault to msg.sender.

function sendToL1(uint8 v, bytes32 r, bytes32 s) public nonReentrant whenNotPaused {
+ bytes memory message = abi.encode(
+ address(token),
+ msg.sender,
+ amount
+ )
address signer = ECDSA.recover(MessageHashUtils.toEthSignedMessageHash(keccak256(message)), v, r, s);
if (!signers[signer]) {
revert L1BossBridge__Unauthorized();
}
token.safeTransferFrom(address(vault), msg.sender, amount);
}
Updates

Lead Judging Commences

0xnevi Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

sendToL1(): Wrong function visibility

Support

FAQs

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