First Flight #21: KittyFi

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

Lack of Operation Confirmation Before State Updates

Summary

The functions purrrCollateralToAave, purrrCollateralFromAave, and purrgeBadPawsition perform critical operations involving transferring collateral to and from the Aave protocol and purging bad positions. However, these functions do not confirm the success of the operations before updating the corresponding state variables.

Vulnerability Details

The purrrCollateralToAave and purrrCollateralFromAave functions interact with the Aave protocol but do not check if the operations (supply, withdraw) succeeded before updating the contract's state variables as seen in the following code;
If the operations fail but the state variables are still updated, the contract's state will be inconsistent with the actual balances, leading to potential financial losses or vulnerabilities.

/**
* @notice Supplies collateral to Aave pool to earn interest
* @param _ameowntToSupply The amount of collateral to supply to Aave
*/
function purrrCollateralToAave(uint256 _ameowntToSupply) external onlyMeowntainer {
totalMeowllateralInVault -= _ameowntToSupply;
IERC20(i_token).approve(address(i_aavePool), _ameowntToSupply);
i_aavePool.supply( { asset: i_token, amount: _ameowntToSupply, onBehalfOf: address(this), referralCode: 0 } );
}
/**
* @notice Withdraws collateral from Aave pool
* @param _ameowntToWhiskdraw The amount of collateral to withdraw from Aave
*/
function purrrCollateralFromAave(uint256 _ameowntToWhiskdraw) external onlyMeowntainer {
totalMeowllateralInVault += _ameowntToWhiskdraw;
i_aavePool.withdraw( { asset: i_token, amount: _ameowntToWhiskdraw, to: address(this) } );
}

In purrgeBadPawsition function the user's debt is reset to zero before the burn operation as seen in the following code. If the burn operation fails, the user's debt remains zero, which could lead to inconsistencies

function purrgeBadPawsition(address _user) external returns (uint256 _totalAmountReceived) {
require(!(_hasEnoughMeowllateral(_user)), KittyPool__UserIsPurrfect());
uint256 totalDebt = kittyCoinMeownted[_user];
kittyCoinMeownted[_user] = 0;
>> i_kittyCoin.burn(msg.sender, totalDebt);
uint256 userMeowllateralInEuros = getUserMeowllateralInEuros(_user);
uint256 redeemPercent;
if (totalDebt >= userMeowllateralInEuros) {
redeemPercent = PRECISION;
}
else {
uint256 extraReward = toDistribute.mulDiv(REWARD_PERCENT, PRECISION);
extraReward = Math.min(extraReward, extraCollateral);
_totalAmountReceived += (toDistribute + extraReward); //! can cause overflow
_vault.executeWhiskdrawal(msg.sender, toDistribute + extraReward);
unchecked {
++i;
}
}
}

Impact

If the operations fail but the state is updated, it can result in an incorrect representation of collateral and debt, leading to financial discrepancies and potential insolvency issues. Also the attackers could exploit this inconsistency by triggering state updates without actually transferring collateral, resulting in losses for the protocol and its users.

Tools Used

Manual Review

Recommendations

Implement checks to confirm the success of the operations before updating the state variables

Updates

Lead Judging Commences

shikhar229169 Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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