Platform: Code4rena
Start Date: 16/10/2023
Pot Size: $60,500 USDC
Total HM: 16
Participants: 131
Period: 10 days
Judge: 0xTheC0der
Total Solo HM: 3
Id: 296
League: ETH
Rank: 84/131
Findings: 2
Award: $10.29
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xpiken
Also found by: 0xCiphky, 0xComfyCat, 0xStalin, 0xhegel, 0xkazim, 3docSec, AM, Aymen0909, CaeraDenoir, DeFiHackLabs, Drynooo, Eigenvectors, Fulum, HALITUS, HChang26, Jiamin, Juntao, LokiThe5th, Mike_Bello90, MiloTruck, QiuhaoLi, Silvermist, SovaSlava, SpicyMeatball, T1MOH, Toshii, TrungOre, TuringConsulting, Vagner, Yanchuan, ZdravkoHr, _nd_koo, almurhasan, audityourcontracts, ayden, cartlex_, circlelooper, crunch, cu5t0mpeo, deth, erictee, ggg_ttt_hhh, gizzy, gumgumzum, hash, jasonxiale, josephdara, ke1caM, kodyvim, lanrebayode77, marqymarq10, max10afternoon, nirlin, nonseodion, osmanozdemir1, peter, radev_sw, rvierdiiev, said, serial-coder, sl1, smiling_heretic, squeaky_cactus, stackachu, tallo, trachev, zaevlad
0.1213 USDC - $0.12
https://github.com/code-423n4/2023-10-wildcat/blob/main/src/market/WildcatMarket.sol#L142 https://github.com/code-423n4/2023-10-wildcat/blob/main/src/market/WildcatMarketConfig.sol#L134
Both the closeMarket
and setMaxTotalSupply
functions have the onlyController
restriction. However, it is impossible to invoke these two functions in the WildcatMarketController
contract. Consequently, this situation prevents borrowers from closing a market or adjusting state.maxTotalSupply
. As a result, there is no way to close the market even if the borrower wants to do so, resulting in constant interest accruing and losses to the borrower.
Searching for these two functions throughout the project did not find a call to either function somewhere. https://github.com/search?q=repo%3Acode-423n4%2F2023-10-wildcat%20closeMarket&type=code https://github.com/search?q=repo%3Acode-423n4%2F2023-10-wildcat+setMaxTotalSupply&type=code
Although these two functions are called in the test, that's due to forcing the caller to be set to controller
, which is clearly not feasible in a real-world situation.
function test_closeMarket_TransferRemainingDebt() external asAccount(address(controller)) { // Borrow 80% of deposits then request withdrawal of 100% of deposits _depositBorrowWithdraw(alice, 1e18, 8e17, 1e18); startPrank(borrower); asset.approve(address(market), 8e17); stopPrank(); vm.expectEmit(address(asset)); emit Transfer(borrower, address(market), 8e17); market.closeMarket(); } modifier asAccount(address prank) { startPrank(prank); _; stopPrank(); }
Vscode
It is recommended to add the call logic for the relevant functions in the WildcatMarketController
.
Error
#0 - c4-pre-sort
2023-10-27T07:02:25Z
minhquanym marked the issue as duplicate of #147
#1 - c4-judge
2023-11-07T13:53:20Z
MarioPoneder changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-11-07T13:57:45Z
MarioPoneder marked the issue as satisfactory
#3 - c4-judge
2023-11-07T14:16:53Z
MarioPoneder changed the severity to 3 (High Risk)
🌟 Selected for report: J4X
Also found by: 0x3b, 0xCiphky, 0xComfyCat, 0xStalin, 0xbepresent, 3docSec, DavidGiladi, DeFiHackLabs, Drynooo, Fulum, GREY-HAWK-REACH, InAllHonesty, MatricksDeCoder, Mike_Bello90, MiloTruck, Phantom, SHA_256, T1MOH, Udsen, VAD37, YusSecurity, ZdravkoHr, ast3ros, caventa, deepkin, deth, devival, ggg_ttt_hhh, inzinko, jasonxiale, josieg_74497, karanctf, ke1caM, nisedo, nobody2018, nonseodion, osmanozdemir1, radev_sw, rvierdiiev, serial-coder, t0x1c
10.1663 USDC - $10.17
https://github.com/code-423n4/2023-10-wildcat/blob/main/src/market/WildcatMarketToken.sol#L41-L57
If sender==from when calling transferFrom function, it will also deduct allowances, which should not be deducted. In many protocols only transferFrom is used, this design will break the compatibility with many protocols.
The trasnferFrom method always uses allowance even if spender = from. https://github.com/code-423n4/2023-10-wildcat/blob/main/src/market/WildcatMarketToken.sol#L41-L57
function transferFrom( address from, address to, uint256 amount ) external virtual nonReentrant returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for unlimited approvals. if (allowed != type(uint256).max) { uint256 newAllowance = allowed - amount; _approve(from, msg.sender, newAllowance); } _transfer(from, to, amount); return true; }
Vscode
Only use allowance when spender != from
ERC20
#0 - c4-pre-sort
2023-10-27T10:04:15Z
minhquanym marked the issue as low quality report
#1 - minhquanym
2023-10-27T10:04:16Z
QA
#2 - MarioPoneder
2023-11-08T19:34:09Z
No malicious impact, but definitely a good QA suggestion
#3 - c4-judge
2023-11-08T19:34:15Z
MarioPoneder changed the severity to QA (Quality Assurance)
#4 - c4-judge
2023-11-09T16:02:24Z
MarioPoneder marked the issue as grade-b