Summary
If the Meowntainer
supply most/all the deposited assets to Aave and totalMeowllateralInVault
is less than the amount
of asset requested for withdrawal by the user, the KittyVault::executeWhiskdrawal
reverts.
Vulnerability Details
It is required that the totalMeowllateralInVault
is checked before going on to perform withdrawal for user. if the totalMeowllateralInVault
is insufficient, sufficient amount of the asset should be withdrawn from Aave back into the vault before fufilling the withdrawal request of the user.
PoC
function test_userDepositAndWithdrawAfterSupplyToAave() public userDepositsCollateral {
uint256 totalDepositedInVault = 5.0003 ether;
uint256 toSupply = 5.0003 ether;
vm.prank(meowntainer);
wethVault.purrrCollateralToAave(toSupply);
vm.startPrank(user);
vm.expectRevert();
kittyPool.whiskdrawMeowllateral(weth, totalDepositedInVault);
vm.stopPrank();
}
Impact
Tools Used
Foundry test
manual review
Recommendations
The KittyPool
contract should be allowed to make withdrawals from Aave pool in case the totalMeowllateralInVault
is insufficient.
function executeWhiskdrawal(address _user, uint256 _cattyNipToWithdraw) external onlyPool {
uint256 _ameownt = _cattyNipToWithdraw.mulDiv(getTotalMeowllateral(), totalCattyNip);
+ if( totalMeowllateralInVault < _ameownt){
+ purrrCollateralFromAave(_ameownt - totalMeowllateralInVault);
+ }
userToCattyNip[_user] -= _cattyNipToWithdraw;
totalCattyNip -= _cattyNipToWithdraw;
totalMeowllateralInVault -= _ameownt;
IERC20(i_token).safeTransfer(_user, _ameownt);
}
function purrrCollateralFromAave(uint256 _ameowntToWhiskdraw)
external
- onlyMeowntainer
{
+ require(msg.sender == i_pool || msg.sender == meowntainer, "NOT_AUTHORIZED");
totalMeowllateralInVault += _ameowntToWhiskdraw;
i_aavePool.withdraw( { asset: i_token, amount: _ameowntToWhiskdraw, to: address(this) } );
}