First Flight #21: KittyFi

First Flight #21
Beginner FriendlyDeFiFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

KittyVault::executeWhiskdrawal reverts when user withdraws from an "insolvent" vault

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;
// meowntainer transfers collateral in eth vault to Aave to earn interest
uint256 toSupply = 5.0003 ether;
vm.prank(meowntainer);
wethVault.purrrCollateralToAave(toSupply);
//user withdraws all his deposit
vm.startPrank(user);
vm.expectRevert();
kittyPool.whiskdrawMeowllateral(weth, totalDepositedInVault);
vm.stopPrank();
}

Impact

  • DoS and as a result user assets get stuck in the protocol

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) } );
}
Updates

Lead Judging Commences

shikhar229169 Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Users can't withdraw meowllateral if requested amount is not present in vault as it is supplied to Aave

Support

FAQs

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