xanoutas/solidity-security-findings huggingface dataset:
Overflow in utility calculation could lead to DoS
Audit: 2023-08-shell-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L712-L718


# Vulnerability details

## Impact
An overflow condition in the utility calculation could occur as prices evolve through time, blocking further deposit, swap and withdrawal calculations. The actual impact on funds would depend on the (out of scope) accounting layer implementation.

## Proof of Concept
Deposit, swap and withdrawal operations call the internal function _getUtility(). This function involves solving a quadratic equation with four variables; in particular, at line 716, an attempt is made at raising to the power of 2 the expression bQuad = (a * y + b * y), with: 
x = token X reserve,
y = token Y reserve,
a = sqrt(1/p_max_current),
b = sqrt(p_min_current)

https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L713-L716

Note that this expression is thus proportional to p_min_current and inversely proportional to p_max_current.
Considering that p_max_current refers to the time weighted interpolation between py_init and py_final for the current block, and similarly p_min_current refers to the time weighted interpolation between px_init and px_final, the value of (a * y + b * y) will rise with time when py_init > py_final, and/or px_init < px_final.

This behavior could be blocking in the following scenario:
1. A system is set up with py_init > py_final, and/or px_init < px_final.
2. Users make large enough deposits before the system reaches its final price configuration, such that :
    - x and y parameters are significantly large
    - p_min_current and p_max_current are low and high enough, respectively, so that _getUtility() does not revert yet, and all operations succeed
3. Time passes, with p_min_current and/or p_max_current evolving adversely such that _getUtility() now reverts on overflow; the system can no longer compute deposits, swaps or withdrawals.

The following unit test can be added to the existing EvolvingProteusProperties test contract for demonstration:
```diff
diff --git a/EvolvingProteusProperties.t.sol.orig b/EvolvingProteusProperties.t.sol
index 447bf05..f2d9b41 100644
--- a/EvolvingProteusProperties.t.sol.orig
+++ b/EvolvingProteusProperties.t.sol
@@ -63,6 +63,11 @@ contract EvolvingProteusProperties is Test {
        // py_final_val = 695100000000000;
        // px_final_val = 69510000000000;
 
+       py_init_val  = 695100000000000000;
+       px_init_val  = 695100000000000;
+       py_final_val = 6951000000000000;
+       px_final_val = 695100000000000;
+
        // y constant x decreases
        // py_init_val = 6951000000000000;
        // px_init_val = 69510000000000;
@@ -82,11 +87,10 @@ contract EvolvingProteusProperties is Test {
        // px_final_val = 6951000000000;
 
        // x & y both increase
-       py_init_val = 6951000000000000;
-       px_init_val = 69510000000000;
-       py_fin
`_applyFeeByRounding` may revert while calculating absolute value
Audit: 2023-08-shell-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L829-L830


# Vulnerability details

## Impact

The implementation of absolute value in `_applyFeeByRounding` is incorrect and leads to revert.

`_applyFeeByRounding` is being used for properly calculating fees during swapping (function `_swap` calls `_applyFeeByRounding`) and withdrawing and depositing (`_reserveTokenSpecified` and `_lpTokenSpecified` call `_applyFeeByRounding`). It's important to notice, how crucial this function is - thus unintended revert affects most of the code-base. That's the main reason why I've estimated this issue as Medium.


## Proof of Concept

Calling `_applyFeeByRounding(-57896044618658097711785492504343953926634992332820282019728792003956564819968, false)` will revert.

[File: EvolvingProteus.sol](https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L829-L830)
```
829:        bool negative = amount < 0 ? true : false;
830:        uint256 absoluteValue = negative ? uint256(-amount) : uint256(amount);
```


When `amount = -57896044618658097711785492504343953926634992332820282019728792003956564819968`, at line 830 - we try to change it from negative to positive by removing `-`.

`-57896044618658097711785492504343953926634992332820282019728792003956564819968` is being changed to `-(-57896044618658097711785492504343953926634992332820282019728792003956564819968)`, which is: `57896044618658097711785492504343953926634992332820282019728792003956564819968`. This operation is being made before casting to `uint256` occurs. `amount` is still `int256` and `57896044618658097711785492504343953926634992332820282019728792003956564819968` does not fit in `int256` type, since the max value of `int256` is `57896044618658097711785492504343953926634992332820282019728792003956564819967`. This leads to revert.

## Tools Used

Manual code review

## Recommended Mitigation Steps

Add additional check before calculating absolute value:

```
require(amount != -57896044618658097711785492504343953926634992332820282019728792003956564819968)
```


## Assessed type

Math
Violation of the rule that the final amount cannot be less than the `FIXED_FEE` in `_applyFeeByRounding`
Audit: 2023-08-shell-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L831-L848


# Vulnerability details

## Impact

The comment section in `_applyFeeByRounding` defines, that `FIXED_FEE` cannot be greater than final amount:

```
831:        // FIXED_FEE * 2 because we will possibly deduct the FIXED_FEE from
832:        // this amount, and we don't want the final amount to be less than
833:        // the FIXED_FEE.
```

However, this constraint can be violated. As fee is beneficial for the pool and final amount is beneficial for the end user - fee should never be greater than the final amount. This is stated in line 832: `we don't want the final amount to be less than the FIXED_FEE`. However, this requirement is not always fulfilled. Unaware users  may get higher fee than their final amount - which exposes them to financial loss (fee shouldn't be higher than final amount).

Moreover. `_applyFeeByRounding` is being used for properly calculating fees during swapping (function `_swap` calls `_applyFeeByRounding`) and withdrawing and depositing (`_reserveTokenSpecified` and `_lpTokenSpecified` call `_applyFeeByRounding`). It's important to notice, how crucial this function is - thus improper fees' calculation affects most of the code-base. That's the additional reason why I've estimated this issue as Medium.



## Proof of Concept

Line 834 defines, that `if (absoluteValue < FIXED_FEE * 2) revert AmountError();`. This check is suppose to make sure, that final amount is not less than `FIXED_FEE`.
Let's assume that `absoluteValue = 2 * FIXED_FEE`, (function won't revert with `AmountError()`, as condition `2 * FIXED_FEE  < FIXED_FEE * 2` is not true).

Now, when `feeUp` is set to `false`, we're entering the branch at line 844:

```
843:        } else
844:            roundedAbsoluteAmount =
845:                absoluteValue -
846:                (absoluteValue / BASE_FEE) -
847:                FIXED_FEE;
```

`roundedAbsoluteAmount = absoluteValue - (absoluteValue / BASE_FEE) - FIXED_FEE`, for `absoluteValue = 2 * FIXED_FEE`:
`roundedAbsoluteAmount = 2 * FIXED_FEE - (2 * FIXED_FEE / BASE_FEE) - FIXED_FEE = FIXED_FEE - (2 * FIXED_FEE / BASE_FEE)`
Since `(2 * FIXED_FEE / BASE_FEE) > 0`, this implies, that `roundedAbsoluteAmount < FIXED_FEE` (we are subtracting fraction of `FIXED_FEE` from `FIXED_FEE`, thus the result will be smaller than `FIXED_FEE`).
This implies that `roundedAbsoluteAmount` is smaller than `FIXED_FEE`, thus the constraint: "we don't want the final amount to be less than FIXED_FEE" is violated and final amount is smaller than `FIXED_FEE`

## Tools Used

Manual code review

## Recommended Mitigation Steps

Add additional `require` check that `FIXED_FEE` is indeed less than the final amount.


## Assessed type

Math
Centralization and Sequence Down Risks Arbitrum 
Audit: 2023-08-shell-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L137


# Vulnerability details

## Impact
Arbitrum chosen as the deployment platform for contracts is still on path to decentralization 

## Proof of Concept
Arbitrum chain owners can still pause the system implying EvolvingProteus contracts and other Shell protocol aspects will not work

Arbitrum Sequencer is centralized and can decide which transactions to add, can delay transactions impacting EvolvingProteus and Shell protocol functionality 

Arbiturm Sequencer can go down. This has happened in the past and many protocols systems do checks to ensure Sequencer is up before critical logic or functionalities etc 

## Tools Used
Manual Analysis 

## Recommended Mitigation Steps
Recommended system have checks in place to protect against outages, pauses, or deploy on a more decentralized network compared to Arbitrum 


## Assessed type

Other
Lack of a `divide-by-zero` check can cause `_getUtility()` to revert.
Audit: 2023-08-shell-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L709
https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L717-L718https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L717-L718


# Vulnerability details

## Impact
The lack of a `divide-by-zero check` in the `_getUtility()` function can cause a revert leading to DOS.
## Proof of Concept
- Take a look at `_getUtility()`: [here](https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L701-L724) 
```
File: EvolvingProteus.sol
701:    function _getUtility(
702:        int256 x,
703:        int256 y
704:    ) internal view returns (int256 utility) {
---SKIP---
709:        int128 two = ABDKMath64x64.divu(uint256(2 * MULTIPLIER), uint256(MULTIPLIER));
710:        int128 one = ABDKMath64x64.divu(uint256(MULTIPLIER), uint256(MULTIPLIER));
711:
712:        int128 aQuad = (a.mul(b).sub(one));
713:        int256 bQuad = (a.muli(y) + b.muli(x));
714:        int256 cQuad = x * y;
715:
716:        int256 disc = int256(Math.sqrt(uint256((bQuad**2 - (aQuad.muli(cQuad)*4)))));
717:        int256 r0 = (-bQuad*MULTIPLIER + disc*MULTIPLIER) / aQuad.mul(two).muli(MULTIPLIER); // @audit revert if two == 0
718:        int256 r1 = (-bQuad*MULTIPLIER - disc*MULTIPLIER) / aQuad.mul(two).muli(MULTIPLIER); // @audit revert if two == 0

---SKIP---
```
- At L709, The value of `two` is calculated using the function `ABDKMath64x64.divu()` (Note `ABDKMath64x64.divu()` performs multiplication on the result of division which I mentioned in another issue). Because this function `Calculate x / y rounding towards zero` so the return value of `two` can be `0`. [see here](https://github.com/abdk-consulting/abdk-libraries-solidity/blob/5e1e7c11b35f8313d3f7ce11c1b86320d7c0b554/ABDKMath64x64.sol#L268-L283)
```
File: ABDKMath64x64.sol
269:   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
270:   * integer numbers.  Revert on overflow or when y is zero.
```
- Hence, there is no check that `two != 0` before being multiplied in the `denominator` when calculating `r0` and `r1`.
- Take a look at L717-L718, if `two == 0` ---> `aQuad.mul(two).muli(MULTIPLIER) == 0 ` ---> the calculation of `r0` and `r1` will revert due to division by `0`.
## Tools Used
Manual review
## Recommended Mitigation Steps
Add a check of `two != 0` before performing computations `r0` and `r1`.


## Assessed type

DoS
No Connection between Function and Possible intended usage of the Function
Audit: 2023-08-shell-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L534-L541
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L630-L636
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L739
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L770


# Vulnerability details

## Impact
No Connection between _getPointGivenXandUtility(...) & _getPointGivenXandUtility(...) Functions and Possible intended usage of these Functions due to missing parentheses when called at L541, L534, L630 & L636

## Proof of Concept
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L739
```solidity
function _getPointGivenXandUtility(
        int256 x,
        int256 utility
    ) internal view returns (int256 x0, int256 y0) {
      ...
    }
```
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L770
```solidity
function _getPointGivenXandUtility(
        int256 x,
        int256 utility
    ) internal view returns (int256 x0, int256 y0) {
      ...
    }
```
The Two functions above are used inside the two functions below but are not called rightly
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L534-L541
```solidity
 function _swap(
        bool feeDirection,
        int256 specifiedAmount,
        int256 xi,
        int256 yi,
        SpecifiedToken specifiedToken
    ) internal view returns (int256 computedAmount) {
       ...
                    _getPointGivenXandUtility
                );
            } else {
               ...
                    _getPointGivenYandUtility
            ...
        }
```
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L630-L636
```solidity
  function _lpTokenSpecified(
        SpecifiedToken specifiedToken,
        int256 specifiedAmount,
        bool feeDirection,
        int256 si,
        int256 xi,
        int256 yi
    ) internal view returns (int256 computedAmount) {
       ...
                _getPointGivenYandUtility
            );
        else
           ...
                _getPointGivenXandUtility
            );
```
as can be visibly seen above no parentheses is present in this function call which could cause DOS
## Tools Used
Manual Review
## Recommended Mitigation Steps
Ensure that this function calls have parentheses if that is the intended usage
```solidity
 function _swap(
        bool feeDirection,
        int256 specifiedAmount,
        int256 xi,
        int256 yi,
        SpecifiedToken specifiedToken
    ) internal view returns (int256 computedAmount) {
       ...
          ---     _getPointGivenXandUtility
          +++    _getPointGivenXandUtility(...)
                );
            } else {
               ...
           ---     _getPointGivenYandUtility
           +++    _getPointGivenYandUtility(...)
            ...
No Proper Error Handling for possible Multiplication OverFlow and DOS in _getUtility Function
Audit: 2023-08-shell-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L714


# Vulnerability details

## Impact
No Proper Error Handling for possible Multiplication OverFlow and DOS in _getUtility Function could give room for DOS due to Multiplication OverFlow in _swap(...) function, _reserveTokenSpecified(...) function, _getUtilityFinalLp(...) function and several other instances where _getUtility Function is used directly or indirectly

## Proof of Concept
The _getUtility Function seems like a very important function in the EvolvingProteus.sol contract, with many important use cases in the protocol. To avoid over complex explanation, I would be using the [L506](https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L506) _swap(...) function & [L272](https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L272) swapGivenInputAmount(...) function to proof this concept
```solidity
function swapGivenInputAmount(
        uint256 xBalance,
        uint256 yBalance,
        uint256 inputAmount,
        SpecifiedToken inputToken
    ) external view returns (uint256 outputAmount) {
        // input amount validations against the current balance
        require(
            inputAmount < INT_MAX && xBalance < INT_MAX && yBalance < INT_MAX
        );
...
        int256 result = _swap(
            FEE_DOWN,
            int256(inputAmount),
            int256(xBalance),
            int256(yBalance),
            inputToken
        );
...
}
```
The swapGivenInputAmount function above shows that a maximum allowed validation was done for xBalance and yBalance but not for the multiplication value of the two before it was passed into the _swap function
```solidity
 function _swap(
        bool feeDirection,
        int256 specifiedAmount,
        int256 xi,
        int256 yi,
        SpecifiedToken specifiedToken
    ) internal view returns (int256 computedAmount) {
       ...
            int256 utility = _getUtility(xi, yi);
      ...
    }
```
The _swap function above shows no validation was done for the incoming xBalance and yBalance for any form of multiplication OverFlow of the two before it was passed into the _getUtility(...) function
```solidity
 function _getUtility(
        int256 x,
        int256 y
    ) internal view returns (int256 utility) {
      ...
        int256 cQuad = x * y;
     ...
   }
```
Finally the _getUtility(...) function where the multiplication is carried out without any validation
## Tools Used
Manual Review
## Recommended Mitigation Steps
A proper Error handling with adequate Error Message should be added after the multiplication at L714 

```solidity
    function _getUtility(
        int256 x,
        int256 y
    ) internal view returns (int256 utility) {

      ...
        int256 cQuad = x * y;
+++ if( cQuad < x || cQuad < y){
+++   revert MiximumAllowedPriceExceededDueToMultiplicationOverFlow();
+++ }
     ...
   }
```


## Assessed t
NO MINIMUM BALANCE AMOUNT RATIO would give room for Unnecessary Errors
Audit: 2023-08-shell-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L796-L801
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L283-L303
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L322-L343


# Vulnerability details

## Impact
There is MAX_BALANCE_AMOUNT_RATIO validation but no minimum balance amount ratio validation in the _checkAmountWithBalance function at L800 of the EvolvingProteus.sol contract. This is a powerful contract which needs to be air tight from all directions, not having this validation would give room for errors that could result from having below a minimum balance amount ratio threshold.

## Proof of Concept
L800 of _checkAmountWithBalance(...) function in the EvolvingProteus.sol contract shows an important validation check to avoid precision errors but this validation is only one way, there should be a second validation to control limit in the opposite direction, having a below minimum balance amount ratio could result from the need to swap a large amount in ratio to the current balance this is in reference to the swapGivenOutputAmount(...) & swapGivenInputAmount(...) functions where the _checkAmountWithBalance function is being used, not having a proper Error handing system in case of overflow, slippage etc is not good enough.
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L796-L801
```solidity
    /**
     * @dev this limits the ratio between a starting balance and an input
     *  or output amount.
     * @dev when we swap very small amounts against a very large pool,
     *  precision errors can cause the pool to lose a small amount of value.
     */
 function _checkAmountWithBalance(uint256 balance, uint256 amount)
        private
        pure
    {
        if (balance / amount >= MAX_BALANCE_AMOUNT_RATIO) revert AmountError();
    }
```
The usage of _checkAmountWithBalance(...) function can be found at L283 & L300 of  function swapGivenInputAmount(...)
https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L283-L303

```solidity
function swapGivenInputAmount(
        uint256 xBalance,
        uint256 yBalance,
        uint256 inputAmount,
        SpecifiedToken inputToken
    ) external view returns (uint256 outputAmount) {
        // input amount validations against the current balance
        require(
            inputAmount < INT_MAX && xBalance < INT_MAX && yBalance < INT_MAX
        );

        _checkAmountWithBalance(
            (inputToken == SpecifiedToken.X) ? xBalance : yBalance,
            inputAmount
        );

       ....
        _checkAmountWithBalance(
            (inputToken == SpecifiedToken.X) ? yBalance : xBalance,
            outputAmount
        );
    }
```
The usage of _checkAmountWithBalance(...) function can also be found at two more instances at L322 & L340 of  function swapGivenOutputAmount(...)
https://github.