First Flight #21: KittyFi

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

Race conditions in `KittyPool::purrgeBadPawsition` allow attackers to front run a user attempting to liquidate their position by minting more tokens causing the user to repay more than intended

Summary

Race conditions in KittyPool::purrgeBadPawsition allow attackers to front run a user attempting to liquidate their position by minting more tokens causing the user to repay more than intended

Vulnerability Details

When a user calls purrgeBadPawsition to repay an attackers bad debt, the attacker can monitor users attempting to liquidate their position and front run it by minting more KittyCoin. This would raise their total debt and could possibly cause the user to repay more KittyCoin than intended.

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

Impact

User calling purrgeBadPawsition could lose more KittyCoin than intended or even all of it leaving them unable to potentially pay back their debt.

POC

Alice has 1000 KittyCoin and sees that Bob has a bad debt postion with a total debt of 500 Kitty coin. She calls purrgeBadPawsition with the intention of buring 500 KittCoin and receiving a share of the reward distribution. Bob sees this transaction submitted to the mempool, front runs it and mints 500 more KittyCoin. The totalDebt amount is now 1000 instead of the 500 Alice intended, and Alice burns all of her KittyCoin.

Tools Used

Manual Review

Recommendations

Consider adding a parameter to the function that takes in an upper bound of what the maximum the user is willing to repay. This will act similar to slippage. Revert if the total debt is higher than the upper bound.

- function purrgeBadPawsition(address _user, ) external returns (uint256 _totalAmountReceived) {
+ function purrgeBadPawsition(address _user, uint256 _upperBound) external returns (uint256 _totalAmountReceived) {
require(!(_hasEnoughMeowllateral(_user)), KittyPool__UserIsPurrfect());
uint256 totalDebt = kittyCoinMeownted[_user];
+ require(totalDebt <= _upperBound, Custom_ErrorMessage());
kittyCoinMeownted[_user] = 0;
i_kittyCoin.burn(msg.sender, totalDebt);
Updates

Lead Judging Commences

shikhar229169 Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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