First Flight #21: KittyFi

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

G-01: `whiskdrawMeowllateral()` transfer before checking, resulting in gas wastage when revert

Summary

The whiskdrawMeowllateral() function performs the transfer of tokens first before checking if there is enough collateral. In the event if there is insufficient colleteral, the transaction will revert and causing the gas for transferring the tokens to be wasted.

Vulnerability Details

The function transfer tokens first before checking if there is enough collateral.

function whiskdrawMeowllateral(address _token, uint256 _ameownt) external tokenExists(_token) {
IKittyVault(tokenToVault[_token]).executeWhiskdrawal(msg.sender, _ameownt);
require(_hasEnoughMeowllateral(msg.sender), KittyPool__NotEnoughMeowllateralPurrrr());
}

Impact

This PoC will simulate a user depositing collateral and minting, thereafter to withdraw when there is not enough collateral and resulting in revert. This results in wasting 3297 gas.

function test_WhiskdrawMeowllateralRevertWasteGas() public {
address doggo = address(888);
uint256 initialDeposit = 5 ether;
// Setup: Fund doggo and deposit collateral
deal(weth, doggo, 10 ether);
vm.startPrank(doggo);
IERC20(weth).approve(address(wethVault), initialDeposit);
kittyPool.depawsitMeowllateral(weth, initialDeposit);
kittyPool.meowintKittyCoin(20e18);
vm.stopPrank();
// Attempt to withdraw and expecting a revert
vm.startPrank(doggo);
uint256 withdrawAmount = 5 ether;
try kittyPool.whiskdrawMeowllateral(weth, withdrawAmount) {
console.log("Withdrawal succeeded unexpectedly");
} catch {
console.log("Withdrawal reverted due to insufficient collateral");
}
vm.stopPrank();
}

Result

Ran 1 test for test/KittyFiTest.t.sol:KittyFiTest
[PASS] test_WhiskdrawMeowllateralRevertWasteGas() (gas: 454421)
Logs:
Withdrawal reverted due to insufficient collateral
Traces:
[454421] KittyFiTest::test_WhiskdrawMeowllateralRevertWasteGas()
...
...
...
[0] VM::startPrank(0x0000000000000000000000000000000000000378)
│ └─ ← [Return]
├─ [36516] KittyPool::whiskdrawMeowllateral(0xC558DBdd856501FCd9aaF1E62eae57A9F0629a3c, 5000000000000000000 [5e18])
│ ├─ [15619] KittyVault::executeWhiskdrawal(0x0000000000000000000000000000000000000378, 5000000000000000000 [5e18])
│ │ ├─ [4859] 0x6Ae43d3271ff6888e7Fc43Fd7321a503ff738951::getUserAccountData(KittyVault: [0x4a89a6cFA7bB08AeAee2B1A63cDA0CdD5720Bc91]) [staticcall]
│ │ │ ├─ [4283] 0x0562453c3DAFBB5e625483af58f4E6D668c44e19::getUserAccountData(KittyVault: [0x4a89a6cFA7bB08AeAee2B1A63cDA0CdD5720Bc91]) [delegatecall]
│ │ │ │ ├─ [402] 0x012bAC54348C0E635dCAc9D5FB99f06F24136C9A::getPriceOracle() [staticcall]
│ │ │ │ │ └─ ← [Return] 0x0000000000000000000000002da88497588bf89281816106c7259e31af45a663
│ │ │ │ ├─ [1521] 0x1ce1bA9946C30b4C505631AD9E3E0342877FdE02::26ec273f(000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000000000000004a89a6cfa7bb08aeaee2b1a63cda0cdd5720bc910000000000000000000000002da88497588bf89281816106c7259e31af45a6630000000000000000000000000000000000000000000000000000000000000000) [delegatecall]
│ │ │ │ │ └─ ← [Return] 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
│ │ │ │ └─ ← [Return] 0, 0, 0, 0, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935 [1.157e77]
│ │ │ └─ ← [Return] 0, 0, 0, 0, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935 [1.157e77]
│ │ ├─ [3543] 0x694AA1769357215DE4FAC081bf1f309aDC325306::latestRoundData() [staticcall]
│ │ │ ├─ [1612] 0x719E22E3D4b690E5d96cCb40619180B5427F14AE::latestRoundData() [staticcall]
│ │ │ │ └─ ← [Return] 14925 [1.492e4], 251894720686 [2.518e11], 1722957240 [1.722e9], 1722957240 [1.722e9], 14925 [1.492e4]
│ │ │ └─ ← [Return] 18446744073709566541 [1.844e19], 251894720686 [2.518e11], 1722957240 [1.722e9], 1722957240 [1.722e9], 18446744073709566541 [1.844e19]
+ │ │ ├─ [3297] 0xC558DBdd856501FCd9aaF1E62eae57A9F0629a3c::transfer(0x0000000000000000000000000000000000000378, 5000000000000000000 [5e18])
│ │ │ ├─ emit Transfer(from: KittyVault: [0x4a89a6cFA7bB08AeAee2B1A63cDA0CdD5720Bc91], to: 0x0000000000000000000000000000000000000378, value: 5000000000000000000 [5e18])
│ │ │ └─ ← [Return] true
│ │ └─ ← [Return]
│ ├─ [18901] KittyVault::getUserVaultMeowllateralInEuros(0x0000000000000000000000000000000000000378) [staticcall]
│ │ ├─ [3543] 0x694AA1769357215DE4FAC081bf1f309aDC325306::latestRoundData() [staticcall]
│ │ │ ├─ [1612] 0x719E22E3D4b690E5d96cCb40619180B5427F14AE::latestRoundData() [staticcall]
│ │ │ │ └─ ← [Return] 14925 [1.492e4], 251894720686 [2.518e11], 1722957240 [1.722e9], 1722957240 [1.722e9], 14925 [1.492e4]
│ │ │ └─ ← [Return] 18446744073709566541 [1.844e19], 251894720686 [2.518e11], 1722957240 [1.722e9], 1722957240 [1.722e9], 18446744073709566541 [1.844e19]
│ │ ├─ [3543] 0x1a81afB8146aeFfCFc5E50e8479e826E7D55b910::latestRoundData() [staticcall]
│ │ │ ├─ [1612] 0xD404D68e5616e9C7045be2Dc1C5865EE328B6638::latestRoundData() [staticcall]
│ │ │ │ └─ ← [Return] 1666, 109265000 [1.092e8], 1722931836 [1.722e9], 1722931836 [1.722e9], 1666
│ │ │ └─ ← [Return] 18446744073709553282 [1.844e19], 109265000 [1.092e8], 1722931836 [1.722e9], 1722931836 [1.722e9], 18446744073709553282 [1.844e19]
│ │ ├─ [4859] 0x6Ae43d3271ff6888e7Fc43Fd7321a503ff738951::getUserAccountData(KittyVault: [0x4a89a6cFA7bB08AeAee2B1A63cDA0CdD5720Bc91]) [staticcall]
│ │ │ ├─ [4283] 0x0562453c3DAFBB5e625483af58f4E6D668c44e19::getUserAccountData(KittyVault: [0x4a89a6cFA7bB08AeAee2B1A63cDA0CdD5720Bc91]) [delegatecall]
│ │ │ │ ├─ [402] 0x012bAC54348C0E635dCAc9D5FB99f06F24136C9A::getPriceOracle() [staticcall]
│ │ │ │ │ └─ ← [Return] 0x0000000000000000000000002da88497588bf89281816106c7259e31af45a663
│ │ │ │ ├─ [1521] 0x1ce1bA9946C30b4C505631AD9E3E0342877FdE02::26ec273f(000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000000000000004a89a6cfa7bb08aeaee2b1a63cda0cdd5720bc910000000000000000000000002da88497588bf89281816106c7259e31af45a6630000000000000000000000000000000000000000000000000000000000000000) [delegatecall]
│ │ │ │ │ └─ ← [Return] 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
│ │ │ │ └─ ← [Return] 0, 0, 0, 0, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935 [1.157e77]
│ │ │ └─ ← [Return] 0, 0, 0, 0, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935 [1.157e77]
│ │ ├─ [3543] 0x694AA1769357215DE4FAC081bf1f309aDC325306::latestRoundData() [staticcall]
│ │ │ ├─ [1612] 0x719E22E3D4b690E5d96cCb40619180B5427F14AE::latestRoundData() [staticcall]
│ │ │ │ └─ ← [Return] 14925 [1.492e4], 251894720686 [2.518e11], 1722957240 [1.722e9], 1722957240 [1.722e9], 14925 [1.492e4]
│ │ │ └─ ← [Return] 18446744073709566541 [1.844e19], 251894720686 [2.518e11], 1722957240 [1.722e9], 1722957240 [1.722e9], 18446744073709566541 [1.844e19]
│ │ └─ ← [Revert] panic: division or modulo by zero (0x12)
│ └─ ← [Revert] panic: division or modulo by zero (0x12)
├─ [0] console::log("Withdrawal reverted due to insufficient collateral") [staticcall]
│ └─ ← [Stop]
├─ [0] VM::stopPrank()
│ └─ ← [Return]
└─ ← [Return]
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 19.58s (14.01s CPU time)
Ran 1 test suite in 21.79s (19.58s CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)

Tools Used

Foundry

Recommendations

Perform the check first to ensure there is sufficient collateral before withdrawing.

function whiskdrawMeowllateral(address _token, uint256 _ameownt) external tokenExists(_token) {
require(_hasEnoughMeowllateral(msg.sender), KittyPool__NotEnoughMeowllateralPurrrr());
IKittyVault(tokenToVault[_token]).executeWhiskdrawal(msg.sender, _ameownt);
}
Updates

Lead Judging Commences

shikhar229169 Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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