xanoutas/solidity-security-findings huggingface dataset:
OFAC sanctioned lender can frontrun nukeFromOrbit with a transfer of his funds
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketConfig.sol#L74-L81
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketBase.sol#L163
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketToken.sol#L64-L82
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketBase.sol#L152-L153


# Vulnerability details

## Impact
In order to prevent a sanctioned lender (for example by OFAC) to poison an entire market, a function has been developed to block and transfer the sanctionned user's funds to an escrow contract. This escrow contract can be released if borrower decides so (by setting up an override), or if sanctioned lender is removed from the sanction lists.
To do that, the borrower (or any actor) can call [`nukeFromOrbit`](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketConfig.sol#L74-L81), which will change authentication role of user to `AuthRole.Blocked` which basically disallow him any action on the market, and as said before, by calling `_blockAccount` [seize and transfer the funds to an escrow contract](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketBase.sol#L170-L183), waiting for more clarity on the situation.
But there is a way for the sanctionned lender to avoid this situation.

The requirement are:
1) a non-zero scaledBalance (cannot be applied if already in queue)
2) a second authorized lender address in the market (as borrower is responsible for the verification, he could be tricked)

## Proof of Concept

1) sanctionned lender monitor the mempool for future call to [`nukeFromOrbit`](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketConfig.sol#L74-L81)
2) sanctioned lender see the call and transfer its scaledBalance to the 2nd address by calling `[WildcatMarketToken::transfer](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketToken.sol#L36-L39)`
3) [Even if `_transfer`](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketToken.sol#L64-L82), through `_getAccount` [ensure lender isn't blocked](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketBase.sol#L152-L153), this check pass as he is not blocked yet, only sanctionned
4) using the 2nd address he can either:
	a. wait (only sanction list make it possible to block an account, and only blocked account balances can be escrowed) 
	b. or directly queue the scaledBalance into the current batch 

Once the balance has been queued, while borro
closeMarket() can only be called by the market controller but the controller has no function to close a market.
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

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


# Vulnerability details

## Description
Due to the restriction on the closeMarket() function, only the controller is able to use it, but the controller contract has no way to call it.

## Impact
Since the borrower becomes unable to close a market once it opened, it becomes a big issue as the lenders can accrue interest even when the borrower no longer wishes to borrow asset.

## Proof of Concept

Borrower creates a market.

Alice, who is authorized by Borrower to be a lender, deposits 10,000 of asset.

Alice gets 10,000 of market tokens.

Borrower no longer wishes to borrow money, but is unable to close the market since no function is created on the marketController.

scaleFactor keeps increasing and borrower can not do anything to prevent it.

Alice has the 10,000 market tokens and is able to accrue interest for an infinite amount of time, making borrower liable for the interest.

## Recommended Mitigation Steps

Add a closeMarket function to the WildcatMarketController contract.


## Assessed type

Context
Borrower cannot close their market
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

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


# Vulnerability details

The `WildcatMarket::closeMarket()` cannot be executed by a borrower because the `WildcatMarketController` contract does not implement any function calling it.

## Proof of Concept

The `closeMarket()` is supposed to be called by a borrower to close their market, set the market's `annualInterestBips` (APR) to 0%, disallow lenders from depositing asset tokens to the market, and transfer the remaining debts to the market for all lenders to retrieve.

A borrower must execute the `closeMarket()` through the `WildcatMarketController` contract, as the function is attached to the [`onlyController` modifier](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarket.sol#L142). However, I discovered that the `WildcatMarketController` contract does not implement any function calling the `closeMarket()`.

Therefore, a borrower cannot execute the `closeMarket()` to close their market.

```solidity
@>  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);
    }
```

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

## Impact

A borrower will be unable to execute the `closeMarket()` to close their market. Consequently, the borrower cannot disallow lenders from depositing asset tokens (via the [`depositUpTo()`](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarket.sol#L48) and [`deposit()`](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarket.sol#L87)) to the market, and the borrower will be forced to pay the lending interest.

## Tools Used

Manual Review

## Recommended Mitigation Steps

Implement a function (in the `WildcatMarketController` contract) for handling the execution of the `WildcatMarket::closeMarket()`.


## Assessed type

Other
Delinquency status for a borrower may not recorded correctly due to the use of outdated state.isDelinquent
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/libraries/FeeMath.sol#L89-L123
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarket.sol#L26-L29
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/libraries/FeeMath.sol#L142-L174


# Vulnerability details

## Impact
In _getUpdatedState(), updateScaleFactorAndFees() will be called and updateTimeDelinquentAndGetPenaltyTime() will be used to calculate the timeWithPenalty, however, it will always use an outdated state.isDelinquent, so the result is incorrect.

## Proof of Concept
First let us take updateState() in WildcatMarket.sol as an example to illustrate why the state.isDelinquent used is outdated.

    function updateState() external nonReentrant {
        MarketState memory state = _getUpdatedState();
        _writeState(state);
    }

As we can see, when updating the state, _getUpdatedState() will first be called. let's see what it will do.

    function _getUpdatedState() internal returns (MarketState memory state) {
    state = _state;
    // Handle expired withdrawal batch
    if (state.hasPendingExpiredBatch()) {
      uint256 expiry = state.pendingWithdrawalExpiry;
      // Only accrue interest if time has passed since last update.
      // This will only be false if withdrawalBatchDuration is 0.
      if (expiry != state.lastInterestAccruedTimestamp) {
        (uint256 baseInterestRay, uint256 delinquencyFeeRay, uint256 protocolFee) = state
          .updateScaleFactorAndFees(
            protocolFeeBips,
            delinquencyFeeBips,
            delinquencyGracePeriod,
            expiry
          );
        emit ScaleFactorUpdated(state.scaleFactor, baseInterestRay, delinquencyFeeRay, protocolFee);
      }
      _processExpiredWithdrawalBatch(state);
    }
    // Apply interest and fees accrued since last update (expiry or previous tx)
    if (block.timestamp != state.lastInterestAccruedTimestamp) {
      (uint256 baseInterestRay, uint256 delinquencyFeeRay, uint256 protocolFee) = state
        .updateScaleFactorAndFees(
          protocolFeeBips,
          delinquencyFeeBips,
          delinquencyGracePeriod,
          block.timestamp
        );
      emit ScaleFactorUpdated(state.scaleFactor, baseInterestRay, delinquencyFeeRay, protocolFee);
    }
  }

We can assume that there is no pendingWithdrawalBatch and time has passed since lastInterestAccruedTimestamp, so updateScaleFactorAndFees() will be used to update the accrued baseInterest, delinquent and protocol fee. 

Within updateScaleFactorAndFees() it call updateDelinquency() to update the related delinquency variables.

    if (delinquencyFeeBips > 0) {
      delinquencyFeeRay = state.updateDelinquency(
        timestamp,
        delinquencyFeeBips,
        delinquencyGracePeriod
      );
    }

And updateDelinquency() will call updateTimeDelinquentAndGetPenal
potential revert on deployMarket 
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatMarketController.sol#L346


# Vulnerability details

## Impact
potential revert on deployMarket if originationFeeAmount is set to 0.

## Proof of Concept
    bool hasOriginationFee = originationFeeAmount > 0;
    bool nullFeeRecipient = feeRecipient == address(0);
    bool nullOriginationFeeAsset = originationFeeAsset == address(0);
    if (
      (protocolFeeBips > 0 && nullFeeRecipient) ||
      (hasOriginationFee && nullFeeRecipient) ||
      (hasOriginationFee && nullOriginationFeeAsset)
    ) {
      revert InvalidProtocolFeeConfiguration();

this how setProtocolFee work .and it can be origination fee set to zero , if that fee is set to zero ,
    
     originationFeeAsset.safeTransferFrom(borrower, parameters.feeRecipient, originationFeeAmount);



If orginationFeeAsset is ERC20 that revert on 0 amount , that deployMarket transaction will be revert .
## Tools Used
manual view
## Recommended Mitigation Steps
add function if originationFeeAmount > 0 , do the safeTransfer


## Assessed type

DoS
Borrower can't close the market 
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

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


# Vulnerability details

## Summary 
There is no way to close a market 
## Impact
borrower can't close the market 

## Vulnerability Details 
closeMarket function in WildcatMarket use onlyController modifier but there is no way to call closeMarket through MarketController 

## Tools Used
Manual Review 
## Recommended Mitigation Steps
add a closeMarket function with onlyBorrower modifier in MarketConroller that calls closeMarket of WildcatMarket





## Assessed type

Other
Borrower can steal all blocked lender's underlying assets
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketConfig.sol#L79
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketBase.sol#L173-L174
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketBase.sol#L178
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatSanctionsSentinel.sol#L96-L97
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatSanctionsSentinel.sol#L108
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatSanctionsSentinel.sol#L110
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketWithdrawals.sol#L165
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketWithdrawals.sol#L167-L168
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketWithdrawals.sol#L171
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatSanctionsEscrow.sol#L38


# Vulnerability details

The `WildcatMarketConfig::nukeFromOrbit()` and the `WildcatMarketWithdrawals::executeWithdrawal()` create incorrect Escrows for locking the blocked lender's asset tokens (underlying assets) and market tokens.

## Impact

A borrower can steal all asset tokens and market tokens of the blocked lender. Eventually, the borrower can burn the stolen market tokens and withdraw all underlying asset tokens from the market.

## Proof of Concept

This PoC section is divided into three sub-sections:
- **Explaining how the nukeFromOrbit() creates an incorrect Escrow for the market tokens**
- **Explaining how the executeWithdrawal() creates incorrect Escrows for the market tokens and the asset tokens**
- **Step-by-step exploit scenarios**

### Explaining how the nukeFromOrbit() creates an incorrect Escrow for the market tokens

Once a lender gets sanctioned by Chainalysis, anyone can trigger the `WildcatMarketConfig::nukeFromOrbit()` to block the lender from interacting with the market and transfer all lender's market tokens to an Escrow contract.

The `nukeFromOrbit()` invokes the [`WildcatMarketBase::_blockAccount()`](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketConfig.sol#L79) to block the lender. The `_blockAccount()` will create the Escrow for holding the blocked lender's market tokens. However, the `_blockAccount()` will pass the [`accountAddress` and `borrower` arguments](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketBase.sol#L173-L174) into the `WildcatSanctionsSent
Deployment of the escrow contract with wrong inputs against the actual signature.
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketBase.sol#L163-L187
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketWithdrawals.sol#L137-L188
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatSanctionsSentinel.sol#L95-L120


# Vulnerability details

## Impact
While calling `createEscrow` in `WildcatMarketBase` and `WildcatMarketWithdrawl` wrong order of inputs is passed instead of the correct signature of the `createEscrowFunction` which leads to setting the escrow address against the lender in `sanctionOverrides` instead of the borrower and also the deployed address is different from what it should have been due to wrong salt.
## Proof of Concept
Lets look at the function signature of the the `createEscrow`

```solidity
  function createEscrow(
    address borrower,
    address account,
    address asset
  ) public override returns (address escrowContract) {
    if (!IWildcatArchController(archController).isRegisteredMarket(msg.sender)) {
      revert NotRegisteredMarket();
    }

    escrowContract = getEscrowAddress(borrower, account, asset);

    if (escrowContract.codehash != bytes32(0)) return escrowContract;

    tmpEscrowParams = TmpEscrowParams(borrower, account, asset);

    new WildcatSanctionsEscrow{ salt: keccak256(abi.encode(borrower, account, asset)) }();

    emit NewSanctionsEscrow(borrower, account, asset);

    sanctionOverrides[borrower][escrowContract] = true;

    emit SanctionOverride(borrower, escrowContract);

    _resetTmpEscrowParams();
  }
}
```

We can see the first argument is borrower, second is lender and third one and last is the asset being lent.

But the problem is this function is called at two places and in both places first two arguments are switched and in one case third argument is passed as the calling contract instead of the asset in scope.

First in the `WildcatMarketBase.sol`

```solidity
  function _blockAccount(MarketState memory state, address accountAddress) internal {
    Account memory account = _accounts[accountAddress];
    if (account.approval != AuthRole.Blocked) {
      uint104 scaledBalance = account.scaledBalance;
      account.approval = AuthRole.Blocked;
      emit AuthorizationStatusUpdated(accountAddress, AuthRole.Blocked);

      if (scaledBalance > 0) {
        account.scaledBalance = 0;
        address escrow = IWildcatSanctionsSentinel(sentinel).createEscrow(
          accountAddress,
          borrower,
          address(this)
        );
        emit Transfer(accountAddress, escrow, state.normalizeAmount(scaledBalance));
        _accounts[escrow].scaledBalance += scaledBalance;
        emit SanctionedAccountAssetsSentToEscrow(
          accountAddress,
          escrow,
          state.normalizeAmount(scaledBalance)
        );
      }
      _accounts[accountAddress] = account;
Markets cannot be closed
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

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


# Vulnerability details

## Impact
The inability to close markets has the following consequences:

* Excess assets in the market (e.g. sent to the market in excess of the required payment by the borrower) cannot be recovered as closing a market is the only way to transfer excess assets out of the market. This causes those assets to be stuck in the market forever.
* If the interest rate constraints were enforced by the controller, the borrower might be forced to pay interest on assets that the borrower no longer wants to utilize but that are not withdrawn by the lender(s) (in the current version of the code the borrower can change the market's interest rate to 0% via the controller, however I believe that this is a bug and that the interest rate constraints are supposed to be applied, which would make the borrower unable the change the interest rate below the minimum interest rate).

## Proof of Concept

The `WildcatMarket.closeMarket()` function has the `onlyController` modifier. Thus, it can only be called by the controller. The controller, however, has no code to call this function, making it effectively uncallable.

```solidity
function closeMarket() external onlyController nonReentrant {
```

## Tools Used

Manual review.

## Recommended Mitigation Steps

A `closeMarket()` function should be added to `WildcatMarketController` that is callable by the borrower and calls the `WildcatMarket.closeMarket()` function to close a market.





## Assessed type

Other
check transfer success
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-10-wildcat/blob/main/src/WildcatSanctionsEscrow.sol#L38


# Vulnerability details

## Impact
Detailed description of the impact of this finding.

## Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.

## Tools Used

## Recommended Mitigation Steps


 IERC20(asset).transfer(account, amount)

we are not testing the success of this transfer. we should use the call as there is no gas limit of 21000 units.


Recommended Mitigation Steps
(success,)= IERC20(asset).transfer(account, amount);
require(success,"cannot transfer the amount");





## Assessed type

ERC20
Privilege escalation enables a sanctioned lender to exit assets without a permit
Audit: 2023-10-wildcat-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatMarketController.sol#L182
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatMarketController.sol#L188
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketConfig.sol#L121
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketToken.sol#L36
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketWithdrawals.sol#L77
https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketWithdrawals.sol#L137


# Vulnerability details

The current implementation of the `WildcatMarketController::updateLenderAuthorization()` leads to the privilege escalation vulnerability, enabling an unauthorized account with `AuthRole.Null` approval status to be able to escalate its privilege to `AuthRole.WithdrawOnly`.

## Impact

When combining the privilege escalation vulnerability with the front-running and Sybil attacks, a sanctioned lender can evacuate and exit their underlying assets from a market without a permit.

Moreover, the market's borrower or `Wildcat` protocol owner cannot block the (sanctioned) lender from exiting their asset tokens.

## Proof of Concept

This PoC section is divided into two sub-sections:
- **Explaining how an unauthorized account can escalate its privilege**
- **Step-by-step asset evacuation and exiting process**

### Explaining how an unauthorized account can escalate its privilege

The [`WildcatMarketController::updateLenderAuthorization()`](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatMarketController.sol#L182) applies a specific lender's current authorization status (set by a borrower) to target markets. Anyone can call this function.

Once the function is executed, it will validate the validity of each target market and then run the [`WildcatMarketConfig::updateAccountAuthorization()`](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/WildcatMarketController.sol#L188) on the target market to update the given lender's current authorization status. If the borrower has authorized the given lender, the lender's approval status will be assigned with [`AuthRole.DepositAndWithdraw`](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketConfig.sol#L119). Otherwise, the lender's approval status will be set to [`AuthRole.WithdrawOnly`](https://github.com/code-423n4/2023-10-wildcat/blob/c5df665f0bc2ca5df6f06938d66494b11e7bdada/src/market/WildcatMarketConfig.sol#L121) -- This design choice allows deauthorized lenders to withdraw their underlying assets from the market.

However, this