First Flight #21: KittyFi

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

Division by Zero in `KittyPool::_hasEnoughMeowllateral` Function Leading to Unexpected Reverts

Summary

The KittyPool::_hasEnoughMeowllateral function lacks proper checks to ensure that division operations are safe, causing division by zero errors. This leads to unexpected reverts when users attempt to mint KittyCoin without having sufficient collateral, disrupting contract functionality and potentially causing harm.

Vulnerability Details

The KittyPool::_hasEnoughMeowllateral function does not include proper checks to ensure that the divisor in a division operation is non-zero. As a result, when a user attempts to mint KittyCoin without sufficient collateral, the function reverts with a panic code due to division by zero. This lack of validation allows for uncontrolled reverts, making the contract vulnerable to unexpected behavior and potential exploitation.

Quote from the solidity docs: "Properly functioning code should never create a Panic, not even on invalid external input. If this happens, then there is a bug in your contract which you should fix." (https://docs.soliditylang.org/en/latest/control-structures.html)

Impact

  • Unexpected Reverts: Users experience unexpected transaction failures, leading to a poor user experience and potential loss of trust in the contract.

  • Disruption of Functionality: The contract's functionality can be disrupted, especially if malicious users intentionally trigger these errors.

Severity: Medium

While the issue does not directly lead to financial loss, its potential to disrupt contract functionality and the user experience warrants a medium severity rating. If further analysis reveals exploitation paths causing significant harm, the severity could be elevated to high.

Tools Used

  • Manual code review

  • Foundry for testing and reproducing the issue

Add the following to KittyFiTest.t.sol:

function test_MintWithoutCollateralPanic() public {
uint256 amountToMint = 20e18; // 20 KittyCoin
// Check initial state
uint256 initialBalance = kittyCoin.balanceOf(user);
assertEq(initialBalance, 0);
// Attempt to mint KittyCoin without depositing collateral
vm.startPrank(user);
vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x12)); // Expecting division by zero panic
kittyPool.meowintKittyCoin(amountToMint);
vm.stopPrank();
// Verify no KittyCoin was minted
uint256 finalBalance = kittyCoin.balanceOf(user);
assertEq(finalBalance, 0);
}

Recommendations

  1. Input Validation: Add checks in the _hasEnoughMeowllateral function to ensure all denominators are non-zero before performing division operations. Revert with meaningful error messages for better control and clarity.

function _hasEnoughMeowllateral(
address _user
) internal view returns (bool hasEnoughCollateral) {
uint256 totalCollateralInEuros = getUserMeowllateralInEuros(_user);
+ require(totalCollateralInEuros > 0, "KittyPool__NoCollateral"); // Ensure there is collateral
uint256 collateralRequiredInEuros = kittyCoinMeownted[_user].mulDiv(
COLLATERAL_PERCENT,
COLLATERAL_PRECISION
);
return totalCollateralInEuros >= collateralRequiredInEuros;
}

By implementing this recommendation, the contract will handle errors more gracefully, avoid unexpected reverts, and enhance robustness and user experience.

Updates

Lead Judging Commences

shikhar229169 Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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