xanoutas/solidity-security-findings huggingface dataset:
Users can skip paying discount fees by filling up all pending discount orders and a tiny amount of a single order at oracle price
Audit: 2024-07-dittoeth-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/libraries/LibPriceDiscount.sol#L22


# Vulnerability details

## Description
When matches are done below the current oracle price on the order book, discount fee is recorded. This discount builds up and is applied as a fee to shorters. This incentivizes shorters to exit their positions and provide liquidity at the oracle price on the market.

In [handlePriceDiscount()](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/libraries/LibPriceDiscount.sol#L22) function it checks the price of the last matched order if it is less than the oracle price. If the price is less it applies a discount fee. 

**[LibPriceDiscount.sol#L37-L47](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/libraries/LibPriceDiscount.sol#L37-L47)**
```
❌      if (h.savedPrice > h.price.mul(1 ether + C.DISCOUNT_THRESHOLD)) {
            IDiamond(payable(address(this)))._matchIsDiscounted(h);
        } else {
            if (Asset.discountedErcMatched > h.ercAmount) {
                Asset.discountedErcMatched -= uint88(h.ercAmount); // @dev(safe-cast)
            } else {
                Asset.discountedErcMatched = 1 wei;
            }
            // @dev Reset iniitialDiscountTime to reset the daysElapsed multiplier
            Asset.initialDiscountTime = 1 seconds;
        }
```

A malicious shorter or user can match all the discount orders and ensure the last order matched has its price equal to the oracle price, this will prevent the discount fee from being applied.

Sellers may notice this in the market and try to sell at the oracle price. But since there is no liquidity at that price they'll still be forced to reduce their price and sell less than the oracle price.

## Impact
This may prevent the price of DUSD from recovering and the maliciouuser will get DUSD at a cheaper price which he can redeem for ETH later.

## Proof of Concept
This test can be run in AskSellOrders.t.sol .

```solidity
    function test_SkipDiscountFee() public {
        // increase ercDebt and debt threshold to pass checks in handlePriceDiscount()
        fundLimitShortOpt(DEFAULT_PRICE, uint88(C.DISCOUNT_UPDATE_THRESHOLD), receiver);
        fundLimitBidOpt(DEFAULT_PRICE, uint88(C.DISCOUNT_UPDATE_THRESHOLD), extra);

        // add discount sells
        fundLimitAskOpt(DEFAULT_PRICE / 2, DEFAULT_AMOUNT, receiver);
        fundLimitAskOpt((DEFAULT_PRICE * 7) / 10, DEFAULT_AMOUNT, receiver);

        uint88 minAskEth = diamond.getAssetStruct(asset).minAskEth * 1e18 / 1e2;
        uint88 minAskErc = minAskEth.divU88(DEFAULT_PRICE);
        // add ask order to bypass discount charge
        fundLimitAskOpt(DEFAULT_PRICE, minAskErc, sender);

        // fill all asks with a single bid
        fundLimitBidOpt(DEFAULT_PRICE, DEFAULT_AMOUNT*2 + minAskErc, sender);

        // sender g
Incorrect slippage protection checks in the `yDUSD` vault's `deposit()` and `withdraw()`
Audit: 2024-07-dittoeth-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L76-L77
https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L111-L112


# Vulnerability details

## Summary

The slippage protection checks in the `yDUSD::deposit()` and `yDUSD::withdraw()` were incorrectly implemented. Subsequently, they cannot detect even a ~99% slippage.

## Description

As you can see in [`@1`](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L76-L77) and [`@2`](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L111-L112), both the `deposit()` and `withdraw()`detect a slippage by using the following `if` statement:
> `uint256 slippage = 0.01 ether;`
> `if (newBalance < slippage.mul(amount or shares) + oldBalance) revert ...`

The intention was to detect a slippage beyond 1%. However, the calculation of the `slippage.mul(amount or shares)` part is incorrect.

Let's take into a simple math. Suppose the `oldBalance` = 10, `amount` = 5, and `newBalance` = 11 (where the `slippage` tolerant = 1%).
> `if (newBalance < slippage.mul(amount or shares) + oldBalance) revert ...`
> = `if (11 < (0.01).mul(5) + 10) revert ...`
> = `if (11 < 0.05 + 10) revert ...`
> = `if (11 < 10.05) revert ...`

As you can see, the above slippage check will not revert a transaction even if the slippage is very huge (the `newBalance` should be 15, not 11). In other words, the check cannot detect even a ~99% slippage.

```solidity
    function deposit(uint256 assets, address receiver) public override returns (uint256) {
        if (assets > maxDeposit(receiver)) revert Errors.ERC4626DepositMoreThanMax();

        uint256 shares = previewDeposit(assets);

        uint256 oldBalance = balanceOf(receiver);
        _deposit(_msgSender(), receiver, assets, shares);
        uint256 newBalance = balanceOf(receiver);

        // @dev Slippage is likely irrelevant for this. Merely for preventative purposes
@1      uint256 slippage = 0.01 ether;
@1      if (newBalance < slippage.mul(shares) + oldBalance) revert Errors.ERC4626DepositSlippageExceeded();
            //@audit @1 -- Incorrect slippage protection check

        return shares;
    }

    function withdraw(uint256 assets, address receiver, address owner) public override returns (uint256) {
        WithdrawStruct storage withdrawal = withdrawals[msg.sender];
        uint256 amountProposed = withdrawal.amountProposed;
        uint256 timeProposed = withdrawal.timeProposed;

        if (timeProposed == 0 && amountProposed <= 1) revert Errors.ERC4626ProposeWithdrawFirst();

        if (timeProposed + C.WITHDRAW_WAIT_TIME > uint40(block.timestamp)) revert Errors.ERC4626WaitLongerBeforeWithdrawing();

        // @dev After 7 days from proposing, a user has 45 days to withdraw
Users can evade the `yDUSD` vault's withdrawal timelock mechanism
Audit: 2024-07-dittoeth-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L85
https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L91
https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L107
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/4fd2f8be339e850c32206342c3f9a1a7bedbb204/contracts/token/ERC20/extensions/ERC4626.sol#L237-L239
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/4fd2f8be339e850c32206342c3f9a1a7bedbb204/contracts/token/ERC20/extensions/ERC4626.sol#L247
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/4fd2f8be339e850c32206342c3f9a1a7bedbb204/contracts/token/ERC20/extensions/ERC4626.sol#L248


# Vulnerability details

## Summary

The `yDUSD` vault's withdrawal timelock mechanism is vulnerable. An exploiter can withdraw the `DUSD` assets in their account by using another account's `proposedWithdraw` request info, breaking the vault's core invariant.

## Description

Assuming Bob is an exploiter, he can evade his account (i.e., `owner`) from the `yDUSD` vault's withdrawal timelock mechanism by using [the `proposeWithdraw` request info of another account (i.e., `msg.sender`)](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L85) (`@1` in the snippet below), which can be requested beforehand.

This way, he can withdraw his `DUSD` assets in the `owner` account from the vault without waiting for the 7-day period, breaking the invariant of the vault's timelock mechanism.

With the `msg.sender`'s `proposeWithdraw`request info, the [7-day timelock period check](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L91) (`@2`) can be passed. After passing the withdrawal timelock check in `@2`, the [`DUSD` assets in the `owner` account](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L107) (`@3`) can be withdrawn without invoking the `yDUSD::proposeWithdraw()`.

```solidity
    function withdraw(uint256 assets, address receiver, address owner) public override returns (uint256) {
        //@audit @1 -- Bob can evade his account (i.e., owner) from the vault's withdrawal timelock mechanism by using
        //             the proposeWithdraw info of another account (i.e., msg.sender), which can be requested beforehand.
        //
        //             This way, he can withdraw his DUSD assets in the 'owner' account from the vault without 
        //             waiting for the 7-day period, breaking the invariant of the vault's timelock mechanism.
@1      WithdrawStruct storage withdrawal = withdrawals[msg.sender];
        uint256 amountProposed = withdrawal.amountProposed;
        uint256 timeProposed = withdr
Impact of inactive order book on `yUSD` withdrawals
Audit: 2024-07-dittoeth-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L84
https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/tokens/yDUSD.sol#L36
https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/OrdersFacet.sol#L139
https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/libraries/LibPriceDiscount.sol#L46


# Vulnerability details

## Impact

The function `yUSD::checkDiscountWindow` is designed to check if the system has had discounted sales. Additionally, the `yDUSD::withdraw` function allows users to withdraw `dUSD` that have gone through a proposed amount process and are within a 45-day withdrawal period.

The issue arises with the call to the function `getInitialDiscountTime()` within `yUSD::checkDiscountWindow`, which will always return more than one second even when an order book becomes inactive.

```solidity
File: yDUSD.sol
36:     function checkDiscountWindow() internal {
37:         //Note: Will upgrade contract to diamond in the future
38:         bool WithinDiscountWindow = IDiamond(payable(diamond)).getTimeSinceDiscounted(dusd) < C.DISCOUNT_WAIT_TIME;
39:         bool isDiscounted = IDiamond(payable(diamond)).getInitialDiscountTime(dusd) > 1 seconds;
40:         if (isDiscounted || WithinDiscountWindow) revert Errors.ERC4626CannotWithdrawBeforeDiscountWindowExpires();
41:     }
```

An inactive order book (lacking sell/bid order matches) can create bottlenecks or delays in withdrawals since they only allow withdrawals under specific time frames. The `checkDiscountWindow` function will always revert due to `getInitialDiscountTime` not being reset during periods of inactivity in the order book.


## Proof of Concept

It can be observed that the `getInitialDiscountTime` retrieves the value of `initialDiscountTime`:

```solidity
File: ViewFacet.sol
489: 
490:     function getInitialDiscountTime(address asset) external view returns (uint32 initialDiscountTime) {
491:         return s.asset[asset].initialDiscountTime;
492:     }
```

This variable is only modified when there is activity in the order book and the `LibPriceDiscount::handlePriceDiscount` function is called in `BidOrdersFacet#L338` and `LibOrders#L659`:

```solidity
File: BidOrdersFacet.sol
336: 
337:         // @dev match price is based on the order that was already on orderbook
338:         LibPriceDiscount.handlePriceDiscount(asset, matchTotal.lastMatchPrice, matchTotal.fillErc);
339:         return (matchTotal.fillEth, incomingBid.ercAmount);
340:     }
```

```solidity
File: LibOrders.sol
658:         // @dev match price is based on the order that was already on orderbook
659:         LibPriceDiscount.handlePriceDiscount(asset, matchTotal.lastMatchPrice, matchTotal.fillErc);
660:     }
```

If this function is not called due to inactivity in the `or
Bypassing dispute timelines in claim redemption process
Audit: 2024-07-dittoeth-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/ClaimRedemptionFacet.sol#L56
https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/ClaimRedemptionFacet.sol#L77
https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/DisputeRedemptionFacet.sol#L127


# Vulnerability details

## Impact

Shorters can call `ClaimRedemptionFacet::claimRemainingCollateral` to claim `short.collateral` whenever the `timeToDispute` has passed:

```solidity
    function claimRemainingCollateral(address asset, address redeemer, uint8 claimIndex, uint8 id)
        external
        isNotFrozen(asset)
        nonReentrant
    {
        STypes.AssetUser storage redeemerAssetUser = s.assetUser[asset][redeemer];
        if (redeemerAssetUser.SSTORE2Pointer == address(0)) revert Errors.InvalidRedemption();

        // @dev Only need to read up to the position of the SR to be claimed
        (, uint32 timeToDispute,,, MTypes.ProposalData[] memory decodedProposalData) =
            LibBytes.readProposalData(redeemerAssetUser.SSTORE2Pointer, claimIndex + 1);

>>>     if (timeToDispute > LibOrders.getOffsetTime()) revert Errors.TimeToDisputeHasNotElapsed();
        MTypes.ProposalData memory claimProposal = decodedProposalData[claimIndex];

        if (claimProposal.shorter != msg.sender || claimProposal.shortId != id) revert Errors.CanOnlyClaimYourShort();

        STypes.Asset storage Asset = s.asset[asset];
        _claimRemainingCollateral({asset: asset, vault: Asset.vault, shorter: msg.sender, shortId: id});
    }
```

However, this process can be bypassed in the following manner:

1. Redeemer creates a proposal of short records with `CR=1.4` and `CR=1.7`. `timeToDispute=3hours`
2. The proposal with `CR=1.7` is disputed using a short record of `CR=1.6`, this results in their removal from the list, leaving a smaller slate [ClaimRedemptionFacet#L127](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/DisputeRedemptionFacet.sol#L127) because a portion of the list becomes subject to dispute. 3 hours has passed but the redeemer does not claim the short record `CR=1.4`.
3. Another redeemer creates a proposal with short records `CR=1.6` and `CR=1.7`. The short record `CR=1.6` can be proposed again because it was disputed in `step 2`. This new proposal has a new `timeToDispute` different from the one in step 1.
4. At this point, the shorter of the short record `CR=1.6` from `step 3` proposal can call `ClaimRedemptionFacet::claimRemainingCollateral` without any restriction on the `timeToDispute`, even when the dispute period has not yet ended.
5. Furthermore, the `CR=1.6` can now be disputed with the SR `CR=1.5`, and subsequently, the collateral will be returned to the `TAPP` [DisputeRedemptionFacet#L88-L101](https://github.com/code-423n4/2024-0
Liquidatable Short Records can be created when a Short Record in a disputed proposal is combined with its previous Short Record
Audit: 2024-07-dittoeth-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/DisputeRedemptionFacet.sol#L93-L101


# Vulnerability details

## Description
When a proposal is disputed, the Short Records (SRs) from the disputed proposal can each be [merged](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/DisputeRedemptionFacet.sol#L105-L113) with their former SR or they get [added to the TAPP](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/DisputeRedemptionFacet.sol#L93-L101). 

They will get merged with their former SR in the `else` block below if the SR is not closed. 

**[DisputeRedemptionFacet.sol#L83-L118](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/DisputeRedemptionFacet.sol#L83-L118)**
```
088:                     if (currentSR.status == SR.Closed) {
089:                         // @dev If the protocol created a new SR with the proposed amount, it would have been at or near 1:1 (1x CR), thus making it instantly liquidatable
090:                         // @dev Additionally, the shorter would not lose anything in losing the proposed collateral since they also no longer owe the debt
091:                         // @dev Thus more streamlined to give back the proposed amounts to the TAPP, and safer to consolidate risky debt into one position
092:                         STypes.ShortRecord storage tappSR = s.shortRecords[d.asset][address(this)][C.SHORT_STARTING_ID];
093:                         LibShortRecord.merge({
094:                             short: tappSR,
095:                             ercDebt: currentProposal.ercDebtRedeemed,
096:                             ercDebtSocialized: currentProposal.ercDebtRedeemed.mul(d.ercDebtRate),
097:                             collateral: currentProposal.colRedeemed,
098:                             yield: currentProposal.colRedeemed.mul(d.dethYieldRate),
099:                             creationTime: d.protocolTime,
100:                             ercDebtFee: currentProposal.ercDebtFee
101:                         });
102:                     } else {
103:                         // @dev Returns the proposed collateral and debt to the SR
104:                         // @dev Also valid in the case where a proposed SR is closed and re-used prior to disputing
105:                         LibShortRecord.merge({
106:                             short: currentSR,
107:                             ercDebt: currentProposal.ercDebtRedeemed,
108:                             ercDebtSocialized: currentProposal.ercDebtRedeemed.mul(d.ercDebtRate),
109:                             collateral: currentProposal.colRedeemed,
110:                             yield: currentProposal.colRedeemed.mul(d.dethYieldRate),
111:                             creationTime: d.protocolTime,
112:
A user can claim all his collateral before redemption time
Audit: 2024-07-dittoeth-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/ClaimRedemptionFacet.sol#L80-L87


# Vulnerability details

## Summary
A malicious user can set up a proposal on his Short Record and decide not to claim his collateral or redeemed asset when the dispute time ends. If that Short Record is proposed again he can claim the collateral before dispute time is over for the new proposal.

## Description
After a redemption is proposed, a dispute time has to pass before the redeemer can call `claimRedemption()` to collect his asset and the shorter's remaining collateral is distributed to him. If the redeemer does not collect his asset, the shorter can call `claimRemainingCollateral()` before the time expires to claim his remaining collateral.

`claimRemainingCollateral()` calls `_claimRemainingCollateral()` and the call to `_claimRemainingCollateral()` allows the user to claim all the collateral in the Short Record if the `if` condition below is satisfied.

**[ClaimRedemptionFacet.sol#L80-L87](https://github.com/code-423n4/2024-07-dittoeth/blob/ca3c5bf8e13d0df6a2c1f8a9c66ad95bbad35bce/contracts/facets/ClaimRedemptionFacet.sol#L80-L87)**
```solidity
❌      if (shortRecord.ercDebt == 0 && shortRecord.status == SR.FullyFilled) {
            // @dev Refund shorter the remaining collateral only if fully redeemed and not claimed already
c          uint88 collateral = shortRecord.collateral;
❌          s.vaultUser[vault][shorter].ethEscrowed += collateral;
            // @dev Shorter shouldn't lose any unclaimed yield because dispute time > YIELD_DELAY_SECONDS
            LibSRUtil.disburseCollateral(asset, shorter, collateral, shortRecord.dethYieldRate, shortRecord.updatedAt);
            LibShortRecord.deleteShortRecord(asset, shorter, shortId);
        }
```

The issue is, if there are other pending redemption proposals for that same Short Record, the shorter can claim all the collateral in the Short Record before the dispute times of those proposals expire. Thus, if one of the proposals gets disputed it gets sent to the (Treasury Asset Protection Pool) TAPP Short Record. This may make the TAPP liquidatable if it does not have enough collateral to cover the new debt.

All the collateral may get claimed in any of these scenarios:
1. A malicious user creates a (Short Record) SR, proposes a redemption on a portion of the debt and never claims it. If the full SR gets proposed or it is reused and gets proposed again, he can claim all the collateral before the dispute time expires.
2. The redeemer calls `claimRedemption()` to claim his asset. If any of the Short Records he proposed has another ongoing proposal but satisfies the `if` condition in `_claimRemainingCollateral()` the shorter gets all the collateral. 

## Impact
This affects the protocol in two ways:
1. A user can claim his collateral before the dispute time of a redemption proposal expires.
2. It will increase the debt in TAPP Sh
H-17 Unmitigated
Audit: 2024-05-gondi-mitigation-findings
Severity: HIGH

# Lines of code

https://github.com/pixeldaogg/florida-contracts/blob/10d48b51313496c41c886cd46e610b627ef159aa/src/lib/loans/MultiSourceLoan.sol#L1172-L1188


# Vulnerability details

## Issue

The `refinanceFull()` and `addNewTranche()` functions share the same signature. This could lead to an issue where a user signs a signature for a full refinance, but it gets used in `addNewTranche()`. This could inadvertently increase the principal amount of the loan, which may not be the user's intention.

## Mitigation

The fix did differentiating between the two functions by using the length of `trancheIndex` and the value of `trancheIndex[0]`.

- addNewTranche: The length of the `trancheIndex` must be `1`, and its value is `_totalTranches`. This should result in an out-of-bound error if it's used in refinance.
- refinanceFull: The length of `trancheIndex` must be equal to `_totalTranches`.

With this check in place, I believe the `RenegotiationOffer` for a loan with 1 tranche can still be used for both functions. This is because `trancheIndex` isn't actually used in `refinanceFull`, but only in `refinancePartial`. So the out-of-bound exception will not be raised in `refinanceFull`

```solidity
function _checkAddNewTrancheOffer(RenegotiationOffer calldata _renegotiationOffer, uint256 _totalTranches)
    private
    pure
{
    if (_renegotiationOffer.trancheIndex.length != 1 || _renegotiationOffer.trancheIndex[0] != _totalTranches) {
        revert InvalidRenegotiationOfferError();
    }
}

function _checkRefinanceFullRenegotiationOffer(
    RenegotiationOffer calldata _renegotiationOffer,
    uint256 _totalTranches
) private pure {
    if (_renegotiationOffer.trancheIndex.length != _totalTranches) {
        revert InvalidRenegotiationOfferError();
    }
}
```



## Assessed type

Other