The Wildcat Protocol - 0xkazim's results

Banking, but worse - a protocol for fixed-rate, undercollateralised credit facilities.

General Information

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

Wildcat Protocol

Findings Distribution

Researcher Performance

Rank: 123/131

Findings: 1

Award: $0.06

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarket.sol#L142 https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketBase.sol#L136-L139

Vulnerability details

Impact

The closeMarket function has the onlyController modifier, which restricts calls to the closeMarket function to the controller only. However, the controller contract does not contain a function that invokes the closeMarket function. As a result, it is currently impossible to close the market by either the borrower or the controller.

Proof of Concept

the function closeMarket have the onlyController modifier which allows calls from the controller only:

    function closeMarket() external onlyController nonReentrant {
        MarketState memory state = _getUpdatedState();
        state.annualInterestBips = 0;
        state.isClosed = true;
        state.reserveRatioBips = 0;
        if (_withdrawalData.unpaidBatches.length() > 0) {
            revert CloseMarketWithUnpaidWithdrawals();
        }
        uint256 currentlyHeld = totalAssets();
        uint256 totalDebts = state.totalDebts();
        if (currentlyHeld < totalDebts) {
            // Transfer remaining debts from borrower
            asset.safeTransferFrom(
                borrower,
                address(this),
                totalDebts - currentlyHeld
            );
        } else if (currentlyHeld > totalDebts) {
            // Transfer excess assets to borrower
            asset.safeTransfer(borrower, currentlyHeld - totalDebts);
        }
        _writeState(state);
        emit MarketClosed(block.timestamp);
    }

the onlyController modifier:

modifier onlyController() {
    if (msg.sender != controller) revert NotController();
    _;
  }

Since the controller contract does not include a function to invoke the closeMarket function, market closure is currently impossible.

Tools Used

manual review

To address this issue, it is recommended to modify the modifier to use the onlyBorrower modifier instead, or create a function inside the controller contract that invokes the closeMarket function. This adjustment will enable market closure by the borrower or the controller as intended.

Assessed type

Other

#0 - c4-pre-sort

2023-10-27T07:08:16Z

minhquanym marked the issue as duplicate of #147

#1 - c4-judge

2023-11-07T13:53:21Z

MarioPoneder changed the severity to 2 (Med Risk)

#2 - c4-judge

2023-11-07T14:00:37Z

MarioPoneder marked the issue as partial-50

#3 - c4-judge

2023-11-07T14:16:53Z

MarioPoneder changed the severity to 3 (High Risk)

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter