Summary
If there is an emergency migration, the USDC in the contract will not be withdrawable
Vulnerability Details
If there's an emergency migration, since the USDC will remain in the old module contract, the godfather will be unable to withdraw the USDC.
POC
function test_EmergencyMigrationAndWithdraw() public {
vm.prank(godFather);
laundrette.depositTheCrimeMoneyInATM(godFather, godFather, 100e6);
moneyVault = emergencyMigration.migrate(kernel, usdc, crimeMoney);
vm.prank(godFather);
vm.expectRevert();
laundrette.withdrawMoney(godFather, godFather, 100e6);
}
Place the PoC into test/Laundrette.t.sol.t.sol
, and execute with
forge test --mt test_EmergencyMigrationAndWithdraw -vvvv
It can be seen from the output that the withdraw was reverted.
[54614] LaundretteTest::test_EmergencyMigrationAndWithdraw()
├─ [0] VM::prank(God Father: [0xe166Ae83c3384a19498Ae0674706988DD2797489])
│ └─ ← [Return]
├─ [44212] Laundrette::depositTheCrimeMoneyInATM(God Father: [0xe166Ae83c3384a19498Ae0674706988DD2797489], God Father: [0xe166Ae83c3384a19498Ae0674706988DD2797489], 100000000 [1e8])
│ ├─ [38703] MoneyShelf::depositUSDC(God Father: [0xe166Ae83c3384a19498Ae0674706988DD2797489], God Father: [0xe166Ae83c3384a19498Ae0674706988DD2797489], 100000000 [1e8])
│ │ ├─ [2917] Kernel::modulePermissions(0x4d4f4e4559000000000000000000000000000000000000000000000000000000, Laundrette: [0xD76ffbd1eFF76C510C3a509fE22864688aC3A588], 0xd40afe7100000000000000000000000000000000000000000000000000000000) [staticcall]
│ │ │ └─ ← [Return] true
│ │ ├─ [2959] MockUSDC::transferFrom(God Father: [0xe166Ae83c3384a19498Ae0674706988DD2797489], MoneyShelf: [0xfD07C974e33dd1626640bA3a5acF0418FaacCA7a], 100000000 [1e8])
│ │ │ └─ ← [Revert] ERC20InsufficientAllowance(0xfD07C974e33dd1626640bA3a5acF0418FaacCA7a, 0, 100000000 [1e8])
│ │ └─ ← [Revert] ERC20InsufficientAllowance(0xfD07C974e33dd1626640bA3a5acF0418FaacCA7a, 0, 100000000 [1e8])
│ └─ ← [Revert] ERC20InsufficientAllowance(0xfD07C974e33dd1626640bA3a5acF0418FaacCA7a, 0, 100000000 [1e8])
└─ ← [Revert] ERC20InsufficientAllowance(0xfD07C974e33dd1626640bA3a5acF0418FaacCA7a, 0, 100000000 [1e8])
Impact
godfather will be unable to withdraw the USDC.
Tools Used
Manual review, Foundry
Recommendations
Modify the contract so that during an emergency migration, the USDC balance of the old module contract is accounted for in the new module contract's bank[godfather] mapping and the USDC is transferred to the new module contrac.