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: 112/131
Findings: 1
Award: $0.06
🌟 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.0606 USDC - $0.06
The combination of modifiers for WildcatMarket.closeMarket
and the implementation of WildcatMarketController
creates
a situation where closeMarket
can never actually be successfully invoked.
The condition for closing the market is there are no unpaid withdrawal batches (the market may still have capital from lenders), with the result being the APR is set to zero.
If a borrower cannot have their market closed, that exit condition is still possible, yet additionally requires lender participation, time, interest accrual and a greater number of transactions to achieve.
WildcatMarket,closeMarket
uses the onlyController
modifier from WildcatMarketBase
, which will revert unless the msg.sender
is the controller
address. The controller
address is set in the constructor, being the WildcatMarketController
that deploys the market.
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarket.sol#L142
function closeMarket() external onlyController nonReentrant {
modifier onlyController() { if (msg.sender != controller) revert NotController(); _; }
MarketParameters memory parameters = IWildcatMarketController(msg.sender).getMarketParameters(); ... controller = parameters.controller; }
function getMarketParameters() external view returns (MarketParameters memory parameters) { ... parameters.controller = address(this); }
As the WildcatMarketController
contains zero methods that have a function call to closeMarket
, and it can only be
invoked by the controller successfully (i.e. without reverting), it can never be called.
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatMarketController.sol#L1-L516
WildcatMarket.t.sol
contains closeMarket
tests that are using a modifier that pranks the address to be
the controller, but they demonstrate that only the controller address can successfully invoke closeMarket
.
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/test/market/WildcatMarket.t.sol#L198-L246
Manual review
The appropriate level of the change will depend on the desired behaviour for a closed market in the future,
specifically whether a closed market is ever allowed to be re-opened, or another market from the same controller and salt (asset
, namePrefix
, symbolPrefix
).
Suggestions:
1) Swap the modifier
Quickest choice, replace onlyController
with onlyBorrower
, accepting it means the borrower can control closing down the market and
as state.isClosed
is only set a false
on construction then that market will be permanently closed.
2) Add a close market function to the controller
3) Enable market reuse In addition to providing the ability to close the market, add a function to open the market, allowing reuse of a previously deployed contract.
Access Control
#0 - c4-pre-sort
2023-10-27T07:31:22Z
minhquanym marked the issue as duplicate of #147
#1 - c4-judge
2023-11-07T14:08:27Z
MarioPoneder marked the issue as partial-50
#2 - c4-judge
2023-11-07T14:16:53Z
MarioPoneder changed the severity to 3 (High Risk)