immeas Q

# low

## L-1 no validation that the owner is an EOA

https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L172

https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L112

The documentation specifies that it should be EOAs that are owners but there is no validation done to ensure that.

# non crit

## NC-1 lack of events emitted on state changes

For transparency and trust, important state changes should emit events:

https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/paymasters/verifying/singleton/VerifyingSingletonPaymaster.sol#L65-L68

```javascript
File: paymasters/verifying/singleton/VerifyingSingletonPaymaster.sol

65:    function setSigner( address _newVerifyingSigner) external onlyOwner{
66:        require(_newVerifyingSigner != address(0), "VerifyingPaymaster: new signer can not be zero address");
67:        verifyingSigner = _newVerifyingSigner;
68:    }
```

https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/paymasters/BasePaymaster.sol#L24-L26

```javascript
File: paymasters/BasePaymaster.sol

24:    function setEntryPoint(IEntryPoint _entryPoint) public onlyOwner {
25:        entryPoint = _entryPoint;
26:    }
```

## NC-2 consider removing `Math.sol` (and `Strings.sol`)

`Math.sol` is mentioned to be in scope but it is not used anywhere (but in `Strings.sol` that is not in scope an also not used anywhere).

Consider removing these libraries as it is confusing with code that is not used.

## NC-3 indentation is off

https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L320-L342

Indented with extra 4 spaces

https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L85-L93

Indented with just

// Code block 1 (javascript):
File: paymasters/verifying/singleton/VerifyingSingletonPaymaster.sol

65:    function setSigner( address _newVerifyingSigner) external onlyOwner{
66:        require(_newVerifyingSigner != address(0), "VerifyingPaymaster: new signer can not be zero address");
67:        verifyingSigner = _newVerifyingSigner;
68:    }

// Code block 2 (javascript):
File: paymasters/BasePaymaster.sol

24:    function setEntryPoint(IEntryPoint _entryPoint) public onlyOwner {
25:        entryPoint = _entryPoint;
26:    }

SmartAccount.sol#L172, SmartAccount.sol#L112, VerifyingSingletonPaymaster.sol#L65-L68, BasePaymaster.sol#L24-L26, SmartAccount.sol#L320-L342, SmartAccount.sol#L85-L93


Rickard G

# [G-01] A modifier used only once and not being inherited should be inlined to save gas
[https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/EUSD.sol#L83-L86](https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/EUSD.sol#L83-L86)
````solidity
File: contracts/lybra/token/EUSD.sol

83           modifier MintPaused() {
84                require(!configurator.vaultMintPaused(msg.sender), "MPP");
85                _;
86:          }
````
The above modifier is only being called on [Line 411](https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/EUSD.sol#L411).

[https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/PeUSDMainnetStableVision.sol#L46-L53](https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/PeUSDMainnetStableVision.sol#L46-L53)
````solidity
File: contracts/lybra/token/PeUSDMainnetStableVision.sol

46           modifier MintPaused() {
47                   require(!configurator.vaultMintPaused(msg.sender), "MPP");
48                   _;
49:          }
50           modifier BurnPaused() {
51                   require(!configurator.vaultBurnPaused(msg.sender), "BPP");
52                   _;
53:          }
````
The MintPaused modifier is only being called on [Line 63](https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/PeUSDMainnetStableVision.sol#L63) and the BurnPaused modifier on [Line 69](https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/PeUSDMainnetStableVision.sol#L69).
# [G-02] Immutables should be in uppercase
````solidity
File: contracts/lybra/miner/EUSDMiningIncentives.sol
28:    Iconfigurator public immutable configurator;

30:    IEUSD public immutable EUSD;
````
[EUSDMiningIncentives.sol#L28](https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/miner/EUSDMiningIncentives.sol#L28)
````solidity
File: contracts/lybra/miner/ProtocolRewardsPool.sol

// Code block 1 (solidity):
File: contracts/lybra/token/EUSD.sol

83           modifier MintPaused() {
84                require(!configurator.vaultMintPaused(msg.sender), "MPP");
85                _;
86:          }

// Code block 2 (solidity):
File: contracts/lybra/token/PeUSDMainnetStableVision.sol

46           modifier MintPaused() {
47                   require(!configurator.vaultMintPaused(msg.sender), "MPP");
48                   _;
49:          }
50           modifier BurnPaused() {
51                   require(!configurator.vaultBurnPaused(msg.sender), "BPP");
52                   _;
53:          }

// Code block 3 (solidity):
File: contracts/lybra/miner/EUSDMiningIncentives.sol
28:    Iconfigurator public immutable configurator;

30:    IEUSD public immutable EUSD;

File: contracts/lybra/token/EUSD.sol

83           modifier MintPaused() {
84                require(!configurator.vaultMintPaused(msg.sender), "MPP");
85                _;
86:          }

File: contracts/lybra/token/PeUSDMainnetStableVision.sol

46           modifier MintPaused() {
47                   require(!configurator.vaultMintPaused(msg.sender), "MPP");
48                   _;
49:          }
50           modifier BurnPaused() {
51                   require(!configurator.vaultBurnPaused(msg.sender), "BPP");
52                   _;
53:          }

File: contracts/lybra/miner/EUSDMiningIncentives.sol
28:    Iconfigurator public immutable configurator;

30:    IEUSD public immutable EUSD;

EUSD.sol#L83-L86, EUSD.sol#L411, PeUSDMainnetStableVision.sol#L46-L53, PeUSDMainnetStableVision.sol#L63, PeUSDMainnetStableVision.sol#L69, EUSDMiningIncentives.sol#L28


Musaka Q

#### **[L-01]** Withdrawing ERC20 from the Vault does not claim the rewards
Simply, because of this false `withdrawAndUnwrap(_amount, false)`  [withdrawERC20](https://github.com/code-423n4/2023-07-amphora/blob/main/core/solidity/contracts/core/Vault.sol#L117-L133) is only withdrawing the funds from convex and leaving the rewards. For users to claim them, they need to call another function [claimRewards](https://github.com/code-423n4/2023-07-amphora/blob/main/core/solidity/contracts/core/Vault.sol#L164-L229), this is unneeded, since `withdrawERC20` can be slightly modified to claim rewards on withdraw if the user wants, executing withdraw + claim in one TX instead of two.
You can modifiy it as follows:
```jsx
  function withdrawERC20(address _tokenAddress, uint256 _amount, bool claimRewards) external override onlyMinter {
    if (CONTROLLER.tokenId(_tokenAddress) == 0) revert Vault_TokenNotRegistered();
    if (isTokenStaked[_tokenAddress]) {
+     if(claimRewards){
+       address[] rewardT = new address[](1)
+       rewardT[0] = _tokenAddress;
+       claimRewards(rewardT);
+     }else{
        if (!CONTROLLER.tokenCrvRewardsContract(_tokenAddress).withdrawAndUnwrap(_amount, false)) {
          revert Vault_WithdrawAndUnstakeOnConvexFailed();
        }
+     }
    }
```

---

#### **[L-02]** User inconvenience when calling [Vault.canStake](https://github.com/code-423n4/2023-07-amphora/blob/main/core/solidity/contracts/core/Vault.sol#L156-L159)
From the `canStake` function we can see that before returning true it checks  if the pool exists, within the controller does the vault have any balance of such tokens and where the issue is, if the token is **already staked**  -  `!isTokenStaked[_token]` - where the function reverts if there is a stake on the token. This means if a User stakes a small amount of a given token and forgets about it, and after some time when he wants to stake more of the same token he will most likely call `canStake` to check if he would be abl

---

#### **[L-02]** User inconvenience when calling [Vault.canStake](https://github.com/code-423n4/2023-07-amphora/blob/main/core/solidity/contracts/core/Vault.sol#L156-L159)
From the `canStake` function we can see that before returning true it checks  if the pool exists, within the controller does the vault have any balance of such tokens and where the issue is, if the token is **already staked**  -  `!isTokenStaked[_token]` - where the function reverts if there is a stake on the token. This means if a User stakes a small amount of a given token and forgets about it, and after some time when he wants to stake more of the same token he will most likely call `canStake` to check if he would be able to stake, but `canStake` will return false dues to this  `!isTokenStaked[_token]`.

You can remove `!isTokenStaked[_token]` from the function, since there is no need for it.

---

#### **[L-03]** If one of the tokens in `StableCurveLpOracle` is undervalued it will report less price for the whole group
Under [_get](https://github.com/code-423n4/2023-07-amphora/blob/main/core/solidity/contracts/periphery/oracles/StableCurveLpOracle.sol#L41-L49) there is a for loop and a check inside of it which uses `Math.min` to determine the lowest price for one of the tokens. This price is later send as a return by  `StableCurveLpOracle`   oracle.

// Code block 1 (jsx):
function withdrawERC20(address _tokenAddress, uint256 _amount, bool claimRewards) external override onlyMinter {
    if (CONTROLLER.tokenId(_tokenAddress) == 0) revert Vault_TokenNotRegistered();
    if (isTokenStaked[_tokenAddress]) {
+     if(claimRewards){
+       address[] rewardT = new address[](1)
+       rewardT[0] = _tokenAddress;
+       claimRewards(rewardT);
+     }else{
        if (!CONTROLLER.tokenCrvRewardsContract(_tokenAddress).withdrawAndUnwrap(_amount, false)) {
          revert Vault_WithdrawAndUnstakeOnConvexFailed();
        }
+     }
    }

Vault.sol#L117-L133, Vault.sol#L164-L229, Vault.sol#L156-L159, StableCurveLpOracle.sol#L41-L49


MohammedRizwan Q

## Summary

### Low Risk Issues
|Number|Issue|Instances| |
|-|:-|:-:|:-:|
| [L‑01] | Violation of Checks, Effect and Interactions pattern in _deposit() | 1 |
| [L‑02] | Set fee limit for changeProtocolFee() | 1 |
| [L‑03] | draft-ERC20Permit.sol is deprecated by openzeppelin | 1 |
| [L‑04] | owner must not be address(0) as per EIP-2612 in permit() | 1 |
| [L‑05] | Violation of Checks, Effect and Interactions pattern in controllerTransfer() | 1 |

### [L‑01]  Violation of Checks, Effect and Interactions pattern in _deposit()
It is always recommended to follow Checks, Effect and Interactions(CEI) pattern in contracts to prevent re-entrancy attacks. However this is violated in _deposit() of USDA.sol contract.

There is 1 instance of this issue:

```Solidity
File: core/solidity/contracts/core/USDA.sol

  function _deposit(uint256 _susdAmount, address _target) internal paysInterest whenNotPaused {
    if (_susdAmount == 0) revert USDA_ZeroAmount();
    sUSD.transferFrom(_msgSender(), address(this), _susdAmount);
    _mint(_target, _susdAmount);
    // Account for the susd received
    reserveAmount += _susdAmount;

    emit Deposit(_target, _susdAmount);
  }
```

### Recommended Mitigation steps

```Solidity

  function _deposit(uint256 _susdAmount, address _target) internal paysInterest whenNotPaused {
    if (_susdAmount == 0) revert USDA_ZeroAmount();
+    reserveAmount += _susdAmount;
    sUSD.transferFrom(_msgSender(), address(this), _susdAmount);
    _mint(_target, _susdAmount);
    // Account for the susd received
-    reserveAmount += _susdAmount;

    emit Deposit(_target, _susdAmount);
  }
```

### [L‑02]  Set fee limit for changeProtocolFee()
In VaultController.sol, changeProtocolFee() is used to update the protocol fee. This function can only be accessed by owner of contract. However in a recent hack a malicious owner had set the fee to 100% causing severe loss to users. Therefore, to prevent such hacks it is

// Code block 1 (Solidity):
File: core/solidity/contracts/core/USDA.sol

  function _deposit(uint256 _susdAmount, address _target) internal paysInterest whenNotPaused {
    if (_susdAmount == 0) revert USDA_ZeroAmount();
    sUSD.transferFrom(_msgSender(), address(this), _susdAmount);
    _mint(_target, _susdAmount);
    // Account for the susd received
    reserveAmount += _susdAmount;

    emit Deposit(_target, _susdAmount);
  }

// Code block 2 (Solidity):
function _deposit(uint256 _susdAmount, address _target) internal paysInterest whenNotPaused {
    if (_susdAmount == 0) revert USDA_ZeroAmount();
+    reserveAmount += _susdAmount;
    sUSD.transferFrom(_msgSender(), address(this), _susdAmount);
    _mint(_target, _susdAmount);
    // Account for the susd received
-    reserveAmount += _susdAmount;

    emit Deposit(_target, _susdAmount);
  }

File: core/solidity/contracts/core/USDA.sol

  function _deposit(uint256 _susdAmount, address _target) internal paysInterest whenNotPaused {
    if (_susdAmount == 0) revert USDA_ZeroAmount();
    sUSD.transferFrom(_msgSender(), address(this), _susdAmount);
    _mint(_target, _susdAmount);
    // Account for the susd received
    reserveAmount += _susdAmount;

    emit Deposit(_target, _susdAmount);
  }

function _deposit(uint256 _susdAmount, address _target) internal paysInterest whenNotPaused {
    if (_susdAmount == 0) revert USDA_ZeroAmount();
+    reserveAmount += _susdAmount;
    sUSD.transferFrom(_msgSender(), address(this), _susdAmount);
    _mint(_target, _susdAmount);
    // Account for the susd received
-    reserveAmount += _susdAmount;

    emit Deposit(_target, _susdAmount);
  }


0xDemon Q

## **[L-01] Unsafe downcast may overflow**

When a type is downcast to a smaller type, the higher order bits are discarded, resulting in the application of a modulo operation to the original value.

If the downcasted value is large enough, this may result in an overflow that will not revert.

```solidity
            instructions.feeAmount0 == type(uint128).max
                ? type(uint128).max
                : (amount0 + instructions.feeAmount0).toUint128(),
            instructions.feeAmount1 == type(uint128).max
                ? type(uint128).max
                : (amount1 + instructions.feeAmount1).toUint128()
```

*Github : [133 - 138](https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/transformers/V3Utils.sol#L133-L138)*

## [L-02] Low level call to arbitrary address may lead to gas grieffing attack

If the destination address is a contract that has a fallback function then this can cause very large gas usage or if the destination address is a malicious actor who deliberately carries out gas grieffing.

```solidity
        uint256 balance = address(this).balance;
        if (balance > 0) {
            (bool sent,) = to.call{value: balance}("");
            if (!sent) {
                revert EtherSendFailed();
            }
```

*Github : [128 - 133](https://github.com/code-423n4/2024-03-revert-lend/blob/435b054f9ad2404173f36f0f74a5096c894b12b7/src/automators/Automator.sol#L128-L133)*

// Code block 1 (solidity):
instructions.feeAmount0 == type(uint128).max
                ? type(uint128).max
                : (amount0 + instructions.feeAmount0).toUint128(),
            instructions.feeAmount1 == type(uint128).max
                ? type(uint128).max
                : (amount1 + instructions.feeAmount1).toUint128()

// Code block 2 (solidity):
uint256 balance = address(this).balance;
        if (balance > 0) {
            (bool sent,) = to.call{value: balance}("");
            if (!sent) {
                revert EtherSendFailed();
            }

instructions.feeAmount0 == type(uint128).max
                ? type(uint128).max
                : (amount0 + instructions.feeAmount0).toUint128(),
            instructions.feeAmount1 == type(uint128).max
                ? type(uint128).max
                : (amount1 + instructions.feeAmount1).toUint128()

uint256 balance = address(this).balance;
        if (balance > 0) {
            (bool sent,) = to.call{value: balance}("");
            if (!sent) {
                revert EtherSendFailed();
            }


delfin454000 Q

## Summary
### Low risk findings

| Issue | Description | Instances |
| -- | ----------- | -------- |
|1| Use `require` rather than `assert` where appropriate|19|
|2| Issues re warning should be resolved before deployment|1|
|| Total|20|

### Non-critical findings

| Issue | Description | Instances |
| -- | ----------- | -------- |
|1| Avoid redundant return statement|5|
|2| Constant definitions that include call to `keccak256` should use `immutable`|8|
|3| Invalid import syntax|1|
|4| Duplicate import statement|1|
|5| Long single-line comments|68|
|6| Update sensitive terms in both comments and code|4|
|7| Typos not included in Automated Findings output|8|
|8| Inconsistent `returns` syntax|6|
|9| Inconsistent `require` statement syntax|2|
|10| `pragma solidity` version should be upgraded to latest version|12|
|11-1| Natspec is partially missing for some `functions`|3|
|11-2| `@return` alone is missing for some `functions`|8|
|11-3| Natspec is wholly missing for some `functions`|142|
|11-4| Natspec is partially missing for some `constructors`|2|
|11-5| Natspec is wholly missing for some `constructors`|3|
|| Total|273|

### Low risk findings

| No. | Explanation + cases |
|--| ----------- |
|1|**Use `require` rather than `assert` where appropriate**|
|  |On failure, the `assert` function causes a `Panic` error and, unlike `require`, does not generate an error string. According to Solidity v0.8.18, "properly functioning code should never create a Panic." Therefore, an `assert` should be used only if, based on the relevant associated code, it is never expected to throw an exception.

Below is an example of valid use of `assert` in Ethos Reserve:

[TroveManager.sol: L1219-1224](https://github.com/code-423n4/2023-02-ethos/blob/73687f32b934c9d697b97745356cdf8a1f264955/Ethos-Core/contracts/TroveManager.sol#L1219-L1224)
```solidity
            * The following assert() holds true because:
            * - The system always contains >= 1 trove
            * - When we close

            * The following assert() holds true because:
            * - The system always contains >= 1 trove
            * - When we close or liquidate a trove, we redistribute the pending rewards, so if all troves were closed/liquidated,
            * rewards would’ve been emptied and totalCollateralSnapshot would be zero too.
            */
            assert(totalStakesSnapshot[_collateral] > 0);


Rolezn Q

## Summary<a name="Summary">

### Low Risk Issues
| |Issue|Contexts|
|-|:-|:-:|
| [LOW‑1](#LOW‑1) | IERC20 `approve()` Is Deprecated | 2 |
| [LOW‑2](#LOW‑2) | Missing Contract-existence Checks Before Low-level Calls | 5 |
| [LOW‑3](#LOW‑3) | Contracts are not using their OZ Upgradeable counterparts | 4 |
| [LOW‑4](#LOW‑4) | TransferOwnership Should Be Two Step | 4 |
| [LOW‑5](#LOW‑5) | Unused `receive()` Function Will Lock Ether In Contract  | 4 |
| [LOW‑6](#LOW‑6) | No Storage Gap For Upgradeable Contracts | 1 |
| [LOW‑7](#LOW‑7) | Upgrade OpenZeppelin Contract Dependency | 1 |
| [LOW‑8](#LOW‑8) | Use `safeTransferOwnership` instead of `transferOwnership` function | 4 |
| [LOW‑9](#LOW‑9) | Consider the case where totalsupply is 0 | 2 |

Total: 27 contexts over 9 issues

### Non-critical Issues
| |Issue|Contexts|
|-|:-|:-:|
| [NC‑1](#NC‑1) | Add a timelock to critical functions | 8 |
| [NC‑2](#NC‑2) | Avoid Floating Pragmas: The Version Should Be Locked | 4 |
| [NC‑3](#NC‑3) | No need for `== true` or `== false` checks | 2 |
| [NC‑4](#NC‑4) | Constants in comparisons should appear on the left side | 3 |
| [NC‑5](#NC‑5) | Critical Changes Should Use Two-step Procedure | 8 |
| [NC‑6](#NC‑6) | Duplicated `require()`/`revert()` Checks Should Be Refactored To A Modifier Or Function | 2 |
| [NC‑7](#NC‑7) | Event emit should emit a parameter | 1 |
| [NC‑8](#NC‑8) | Function writing that does not comply with the Solidity Style Guide  | 4 |
| [NC‑9](#NC‑9) | Imports can be grouped together | 31 |
| [NC‑10](#NC‑10) | NatSpec return parameters should be included in contracts | 1 |
| [NC‑11](#NC‑11) | No need to initialize uints to zero | 3 |
| [NC‑12](#NC‑12) | Initial value check is mis


SM3_SS G

# Summary

# Gas Optimization
no | Issue |Instances||
|-|:-|:-:|:-:|
| [G-01] |  A modifier used only once and not being inherited should be inlined to save gas | 3 |
| [G-02] |  State variables with values known at compile time should be constants  | 2 |
| [G-03] |  Using calldata instead of memory for read-only arguments in external functions saves gas | 1 |
| [G-04] |  Use assembly to check for address(0) | 17 |
| [G-05] |  Amounts should be checked for 0 before calling a transfer| 5 |
| [G-06] |  Use calldata instead of memory | 2 |
| [G-07] |  Can Make The Variable Outside The Loop To Save Gas | 1 |
| [G-08] |  Use assembly to write address storage values | 12 |
| [G-09] |  Use nested if statements instead of && | 4 |
| [G-10] |  Make 3 event parameters indexed when possible | 8 |
| [G-11] |  internal functions not called by the contract should be removed to save deployment gas | 4 |
| [G-12] |  Use hardcode address instead address(this) | 24 |
| [G-13] |  use Mappings Instead of Arrays | 2 |
| [G-14] |  Use constants instead of type(uintx).max | 1 |
| [G-15] |  State variables can be packed into fewer storage slots | 1 |

## [G-01]   A modifier used only once and not being inherited should be inlined to save gas

When you use a modifier in Solidity, Solidity generates code to check the conditions of the modifier and execute the modified function if the conditions are met. This generated code can consume gas, especially if the modifier is used frequently or if the modified function is called multiple times.

By inlining a modifier that is used only once and not being inherited, you can eliminate the overhead of the generated code and reduce the gas cost of your contract.

```solidity
file:   lybra/token/EUSD.sol

83         modifier MintPaused() {
        require(!configurator.vaultMintPaused(msg.sender), "MPP");
        _;
    }
```
https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/EUSD.sol#L83-L86

```solidity
file:   lybr

file:   lybra/token/PeUSDMainnetStableVision.sol

46    modifier MintPaused() {
        require(!configurator.vaultMintPaused(msg.sender), "MPP");
        _;
    }

50         modifier BurnPaused() {
        require(!configurator.vaultBurnPaused(msg.sender), "BPP");
        _;
    }

// Code block 1 (unknown):
https://github.com/code-423n4/2023-06-lybra/blob/main/contracts/lybra/token/EUSD.sol#L83-L86


SM3_SS G

# Summary

## Gas Optimization

|No  | Issue | Instances|
|----|-------|-------|
| [G-01] |  Remove unnecessary code: The VOTING_POWER_SNAPSHOT_DELAY constant is not used in the contract and can be removed to reduce unnecessary code. | 1 | - |
| [G-02] |  Failure to check the zero address in the constructor causes the contract to be deployed again | 1 | - |
| [G-03] |  Emit can be rearranged| 1 | - |
| [G-04] |  Change Constant to Immutable for keccak Variables| 2 | - |
| [G-05] |  Using a positive conditional flow to save a NOT opcode | 6 | - |
| [G-06] |  USE ASSEMBLY TO CHECK FOR ADDRESS(0) | 1 | - |
| [G-07] |  Use local variables: In the \_getVotesAtSnapshotBlocks function, the same result is calculated twice, which can be expensive in terms of gas usage. To avoid this, you can store the result in a local variable and reuse it. | 1 | - |
| [G-08] |  Use bytes memory instead of bytes[] memory: In the _hashProposal function, the calldatas_ parameter can be declared as a single bytes memory parameter instead of an array of bytes. This can reduce gas costs by avoiding the overhead of creating an array.| 1 | - |
| [G-09] |  The result of function calls should be cached rather than re-calling the function | 8 | - |
| [G-10] |  Combine similar functions: The \_getVotesAtSnapshotBlocks and \_validateCallDatas functions have similar structures and could potentially be combined into a single function with different parameters. This can reduce code duplication and improve gas usage. | 7 | - |
| [G-11] |  Use bitmaps to save gas | 4 | - |
| [G-12] | Splitting if() statements that use && saves gas| 6 | - |
| [G-13] | Use != 0 instead of > 0 for unsigned integer comparison | 19 | - |
| [G-14] | Use calldata instead of memory for function arguments that do not get mutated | 16 | - |
| [G-15] | Don’t initialize variables with default value | 26 | - |
| [G-16] | Do not calculate constants | 5 | - |
| [G-16] | Using delete statement can save gas | 1

file:    Funding.sol
31       uint256 internal constant VOTING_POWER_SNAPSHOT_DELAY = 33;

file:   PositionManager.sol
116     constructor(
        ERC20PoolFactory erc20Factory_,
        ERC721PoolFactory erc721Factory_
    ) PermitERC721("Ajna Positions NFT-V1", "AJNA-V1-POS", "1") {
        erc20PoolFactory  = erc20Factory_;
        erc721PoolFactory = erc721Factory_;
    }


BRONZEDISC Q

## QA
---

### Layout Order [1]

- The best-practices for layout within a contract is the following order: state variables, events, modifiers, constructor and functions.

https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/rwaOracles/RWADynamicOracle.sol

```solidity
// place this struct with the state variables.
295:  struct Range {

// place these events before the constructor
309:  event RangeSet(
326:  event RangeOverriden(

// place these errors before the constructor
334:  error InvalidPrice();
335:  error InvalidRange();
336:  error PriceNotSet();

// place this state variable with the other ones
343:  uint256 private constant ONE = 10 ** 27;
```

https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/usdy/rUSDYFactory.sol

```solidity
// place this modifier before the constructor
154:  modifier onlyGuardian() {

// place this event before the constructor
146:  event rUSDYDeployed(
```

https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/usdy/rUSDY.sol

```solidity
// place these events right after state variables.
154:  event TransferShares(
172:  event SharesBurnt(
189:  event TokensBurnt(address indexed account, uint256 tokensBurnt);
```

https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/bridge/SourceBridge.sol

```solidity
/// place these before the constructor
183:  event DestinationChainContractAddressSet(
189:  error DestinationNotSupported();
190:  error GasFeeTooLow();
```

https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/bridge/DestinationBridge.sol

```solidity
// place these structs with the other state variables
369:  struct Threshold {
374:  struct TxnThreshold {
379:  struct Transaction {

// place these events before the constructor
389:  event ApproverRemoved(address approver);
396:  event ApproverAdded(address approver);
405:  event ChainIdSupported(string srcChain, string approvedSource);
414:  event ThresholdSet(string chain, uint256[] amounts, uint256[] numOfApprovers);
422:  event

// Code block 1 (solidity):
// place this struct with the state variables.
295:  struct Range {

// place these events before the constructor
309:  event RangeSet(
326:  event RangeOverriden(

// place these errors before the constructor
334:  error InvalidPrice();
335:  error InvalidRange();
336:  error PriceNotSet();

// place this state variable with the other ones
343:  uint256 private constant ONE = 10 ** 27;

// Code block 2 (solidity):
// place this modifier before the constructor
154:  modifier onlyGuardian() {

// place this event before the constructor
146:  event rUSDYDeployed(

// Code block 3 (solidity):
// place these events right after state variables.
154:  event TransferShares(
172:  event SharesBurnt(
189:  event TokensBurnt(address indexed account, uint256 tokensBurnt);

// Code block 4 (solidity):
/// place these before the constructor
183:  event DestinationChainContractAddressSet(
189:  error DestinationNotSupported();
190:  error GasFeeTooLow();

// place this struct with the state variables.
295:  struct Range {

// place these events before the constructor
309:  event RangeSet(
326:  event RangeOverriden(

// place these errors before the constructor
334:  error InvalidPrice();
335:  error InvalidRange();
336:  error PriceNotSet();

// place this state variable with the other ones
343:  uint256 private constant ONE = 10 ** 27;

// place this modifier before the constructor
154:  modifier onlyGuardian() {

// place this event before the constructor
146:  event rUSDYDeployed(

// place these events right after state variables.
154:  event TransferShares(
172:  event SharesBurnt(
189:  event TokensBurnt(address indexed account, uint256 tokensBurnt);

/// place these before the constructor
183:  event DestinationChainContractAddressSet(
189:  error DestinationNotSupported();
190:  error GasFeeTooLow();

RWADynamicOracle.sol, rUSDYFactory.sol, rUSDY.sol, SourceBridge.sol, DestinationBridge.sol

rUSDYFactory.sol, RWADynamicOracle.sol, rUSDY.sol, SourceBridge.sol, DestinationBridge.sol


0xHelium Analysis

# Salty.io Analysis reports
![Imgur](https://i.imgur.com/0kcgGjN.png)
## Note for sponsor to contextualize the analysis
The following analysis should be taken with the following in mind:
- Most of the recommendation are after the codebase overview, so there is where you should look at.
- The following analysis reports of this codebase mainly adds lots of personal recommandation to improve said codebase.
- Sponsor can use the visual representation to improve their docs and use the recommandations to improve the codebase.

### Codebase Overview
Salty.IO is a Decentralized Exchange on Ethereum which uses Automatic Atomic Arbitrage (AAA) to generate yield and provide Zero Fees on all swaps.
![Imgur](https://i.imgur.com/4YNcJZ9.png)

With AAA, market inefficiencies are arbitraged at swap time to create profits - which are then distributed to liquidity providers and stakers and used to form Protocol Owned Liquidity (POL) for the DAO.

Additionally, Salty.IO provides USDS, an overcollateralized ERC20 stablecoin native to the protocol which uses WBTC/WETH LP as collateral.
![Imgur](https://i.imgur.com/VJIPyeC.png)

### Technical overview
The Salty.IO codebase is divided up into the following folders:
/arbitrage - handles searching for arbitrage opportunities at user swap time with the actual arbitrage swaps being done within Pools.sol itself.
![Imgur](https://i.imgur.com/gAgV19D.png)
As seen in the above image , we can conclude that swaping token1 -> token2 following the inverse route as swapping token2 -> token1 This mechanism is gas efficient in theory, but in practice it's prone to sandwich attacks by MEVs. Consider the scenario below:Arbitrage is following WETH-> WBTC-> SALT-> WETH path, A mev can just buy some WBTC to increase the price prior to swapping WETH-> WBTC and sell after the swapping to make profits.
To remediate consider adding a slippage protection to the arbitrage

/dao - handles creating governance proposals, voting, acting on successful proposals and ma

	function _aggregatePrices( uint256 price1, uint256 price2, uint256 price3 ) internal view returns (uint256)
		{
		uint256 numNonZero;

		if (price1 > 0)
			numNonZero++;

		if (price2 > 0)
			numNonZero++;

		if (price3 > 0)
			numNonZero++;

		// If less than two price sources then return zero to indicate failure
		if ( numNonZero < 2 )
			return 0;

		uint256 diff12 = _absoluteDifference(price1, price2);
		uint256 diff13 = _absoluteDifference(price1, price3);
		uint256 diff23 = _absoluteDifference(price2, price3);

		uint256 priceA;
		uint256 priceB;

		if ( ( diff12 <= diff13 ) && ( diff12 <= diff23 ) )
			(priceA, priceB) = (price1, price2);
		else if ( ( diff13 <= diff12 ) && ( diff13 <= diff23 ) )
			(priceA, priceB) = (price1, price3);
		else if ( ( diff23 <= diff12 ) && ( diff23 <= diff13 ) )
			(priceA, priceB) = (price2, price3);

		uint256 averagePrice = ( priceA + priceB ) / 2;

		// If price sources are too far apart then return zero to indicate failure
		if (  (_absoluteDifference(priceA, priceB) * 100000) / averagePrice > maximumPriceFeedPercentDifferenceTimes1000 )
			return 0;

		return averagePrice;
		}

function performUpkeep() public nonReentrant
		{
		// Perform the multiple steps of performUpkeep()
 		try this.step1() {}
		catch (bytes memory error) { emit UpkeepError("Step 1", error); }

 		try this.step2(msg.sender) {}
		catch (bytes memory error) { emit UpkeepError("Step 2", error); }

 		try this.step3() {}
		catch (bytes memory error) { emit UpkeepError("Step 3", error); }

 		try this.step4() {}
		catch (bytes memory error) { emit UpkeepError("Step 4", error); }

 		try this.step5() {}
		catch (bytes memory error) { emit UpkeepError("Step 5", error); }

 		try this.step6() {}
		catch (bytes memory error) { emit UpkeepError("Step 6", error); }

 		try this.step7() {}
		catch (bytes memory error) { emit UpkeepError("Step 7", error); }

 		try this.step8() {}
		catch (bytes memory error) { emit UpkeepError("Step 8", error); }

 		try this.step9() {}
		catch (bytes memory error) { emit UpkeepError("Step 9", error); }

 		try this.step10() {}
		catch (bytes memory error) { emit UpkeepError("Step 10", error); }

 		try this.step11() {}
		catch (bytes memory error) { emit UpkeepError("Step 11", error); }
		}


7ashraf Q

# Possible division by zero
## Instances
CDPManager.sol #621-622
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L621

LiquidationLibrary.sol #555
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L555

LiquidationLibrary.sol #558
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L558

LiquidationLibrary.sol #579
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L579

Need to validate ```_redeemColFromCdp``` to avoid  division by 0 risk
CdpManager.sol #135
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L135

## Description
by tracing the function calls, after calling decrease system debt to zero, a zero value may be passed to the function

## Mitigation
Add a ```require value > 0``` statement before diding by ```value```

# Check if cpd exists first
## Instances
* LiquidationLibrary.sol #400
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L400

* LiquidationLibrary.sol #455
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L455

* CdpManager.sol #419
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L419

* CdpManager.sol#432
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L432

* LiquidationLibrary.sol #472
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L472

* LiquidationLibrary.sol #754
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L754

* CdpManager.sol #336
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L336

# Check if cpd exists first
## Instances
* LiquidationLibrary.sol #400
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L400

* LiquidationLibrary.sol #455
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L455

* CdpManager.sol #419
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L419

* CdpManager.sol#432
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L432

* LiquidationLibrary.sol #472
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L472

* LiquidationLibrary.sol #754
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L754

* CdpManager.sol #336
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L336

* CdpManager.sol #334
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L334
# Should check if borrower and position manager exist first

## Instances
* BorrowerOperations.sol #635
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L635
* BorrowerOperations.sol #647
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L647
* BorrowerOperations.sol #653
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L653

# Unsafe subtraction
## Instances
* BorrowerOperations.sol #1062
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L1060C9-L1062C56

CdpManager.sol#L621, LiquidationLibrary.sol#L555, LiquidationLibrary.sol#L558, LiquidationLibrary.sol#L579, CdpManager.sol#L135, LiquidationLibrary.sol#L400, LiquidationLibrary.sol#L455, CdpManager.sol#L419, CdpManager.sol#L432, LiquidationLibrary.sol#L472, LiquidationLibrary.sol#L754, CdpManager.sol#L336, CdpManager.sol#L334, BorrowerOperations.sol#L635, BorrowerOperations.sol#L647, BorrowerOperations.sol#L653, BorrowerOperations.sol#L1060-L9


Bauchibred Q

# QA Report

## Table of Contents

| Issue ID                                                                                | Description                                                                                |
| --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| [QA-01](#qa-01-transfers-should-be-done-via-a-low-level-call-if-possible)                                 | Transfers should be done via a low-level call if possible                                   |
| [QA-02](#qa-02-multiple-issues-on-how-external-protocols-are-being-integrated-to-kelp)                    | Multiple issues on how external protocols are being integrated to KELP                      |
| [QA-03](#qa-03-protocol-might-break-for-a-token-with-a-proxy-and-implementation-contract-like-cbeth-reth) | Protocol might break for a token with a proxy and implementation contract (like cbETH/rETH) |
| [QA-04](#qa-04-setters-should-always-have-equality-checkers)                                              | Setters should always have equality checkers                                                |
| [QA-05](#qa-05-lrtoracle-sol-should-implement-the-whennotpaused-modifier)                                 | `LrtOracle.sol` should implement the `whenNotPaused()` modifier                             |
| [QA-06](#qa-06-lrtconfiginitialize-could-be-made-more-effective)                                          | `LRTConfig::initialize()` could be made more effective                                      |

## QA-01 Transfers should be done via a low-level call if possible

### Impact

Some tokens do not follow the normal EIP20 specification, i.e instead of returning false on trnasfer failures they revert, which means that the current interface being used wouldn't work with these tokens

### Proof of Concept

Using this search comman

    function transferAssetToNodeDelegator(
        uint256 ndcIndex,
        address asset,
        uint256 amount
    )
        external
        nonReentrant
        onlyLRTManager
        onlySupportedAsset(asset)
    {
        address nodeDelegator = nodeDelegatorQueue[ndcIndex];
        if (!IERC20(asset).transfer(nodeDelegator, amount)) {
            revert TokenTransferFailed();
        }
    }

function transfer(address recipient, uint256 amount) external returns (bool);


n0kto G

# `PoolConfig::whitelistPool` can return PoolID to save gas.

## Description

The `DAO::_finalizeTokenWhitelisting` function whitelists pools using `poolsConfig.whitelistPool`. This function already retrieves the poolID, but it doesn't return it. Modifying `PoolConfig::whitelistPool` to return the poolID can save approximately 1838 gas units per call, resulting in cost savings.

These savings can be significant, especially considering the current gas prices. With an average gas price of 20 gwei per unit and the price of Ether at \$2250, this modification can save more than \$0.08 for each call. It's important to note that `PoolConfig::whitelistPool` is only called in `DAO::_finalizeTokenWhitelisting`, which doesn’t imply a big refactor.

```javascript
    function _finalizeTokenWhitelisting(uint256 ballotID) internal {
        if (proposals.ballotIsApproved(ballotID)) {
            ...
@>            poolsConfig.whitelistPool(
@>                pools,
@>                IERC20(ballot.address1),
@>                exchangeConfig.wbtc()
@>            );
@>            poolsConfig.whitelistPool(
@>                pools,
@>                IERC20(ballot.address1),
@>                exchangeConfig.weth()
@>            );

@>            bytes32 pool1 = PoolUtils._poolID(
@>                IERC20(ballot.address1),
@>                exchangeConfig.wbtc()
@>            );
@>            bytes32 pool2 = PoolUtils._poolID(
@>                IERC20(ballot.address1),
@>               exchangeConfig.weth()
@>            );
            ...
        }
        ...
    }
```

## Impact

Optimizes gas consumption.

## Proof of Concept

### Foundry PoC added to `DAO.t.sol`

```javascript
function testWhitelistTokenApprovedGasEfficiency() public {
    vm.startPrank(alice);
    staking.stakeSALT(1000000 ether);

    IERC20 token = new TestERC20("TEST", 18);

    proposals.proposeTokenWhitelisting(token, "", "");

    uint256 ballotID = 1;
    proposals.castVote(ballotID, Vote.YES);

    // Incr

function testWhitelistTokenApprovedGasEfficiency() public {
    vm.startPrank(alice);
    staking.stakeSALT(1000000 ether);

    IERC20 token = new TestERC20("TEST", 18);

    proposals.proposeTokenWhitelisting(token, "", "");

    uint256 ballotID = 1;
    proposals.castVote(ballotID, Vote.YES);

    // Increase block time to finalize the ballot
    vm.warp(block.timestamp + 11 days);

    // Test Parameter Ballot finalization
    salt.transfer(address(dao), 399999 ether);
    salt.transfer(address(dao), 5 ether);

    uint gas_before = gasleft();
    dao.finalizeBallot(ballotID);
    uint gas_after = gasleft();
    console.log(gas_before - gas_after);
}

// Code block 1 (javascript):
function _finalizeTokenWhitelisting(uint256 ballotID) internal {
        if (proposals.ballotIsApproved(ballotID)) {
            ...
@>            poolsConfig.whitelistPool(
@>                pools,
@>                IERC20(ballot.address1),
@>                exchangeConfig.wbtc()
@>            );
@>            poolsConfig.whitelistPool(
@>                pools,
@>                IERC20(ballot.address1),
@>                exchangeConfig.weth()
@>            );

@>            bytes32 pool1 = PoolUtils._poolID(
@>                IERC20(ballot.address1),
@>                exchangeConfig.wbtc()
@>            );
@>            bytes32 pool2 = PoolUtils._poolID(
@>                IERC20(ballot.address1),
@>               exchangeConfig.weth()
@>            );
            ...
        }
        ...
    }


RaymondFam Q

## Missing setter for `changeFee`
`setChangeFee()` is missing in PrivatePool. In the event an adjustment is needed due to incorrect initialization, there is no option for that. Consider implementing a setter for `changeFee` just like it has been done so for its all other counterparts.

## Sanity checks at the constructor
Adequate zero address and zero value checks should be implemented in [`initialize()`](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L157-L200) of PrivatePool to avoid accidental error(s) that could result in non-functional calls associated with it particularly when assigning presumably immutable variables, i.e. `baseToken`, `nft`, and `changeFee`.

## Typo mistakes
[File: Factory.sol#L166](https://github.com/code-423n4/2023-04-caviar/blob/main/src/Factory.sol#L166)

```diff
-    /// @param salt The salt that will used on deployment.
+    /// @param salt The salt that will be used on deployment.
```
## Unbounded loop in `deposit()`
The [for loops](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol#L239-L241) entailed could easily run out of gas since an NFT collection usually entails thousands of tokenIds. The impact is low since the user can always retry with a smaller array size after encountering a DoS. Where possible, comment with a suggested `tokenIds.length` so users get an idea what array size to work with or better yet set an upper bound to it in the function logic .

## Inadequate NatSpec
Solidity contracts can use a special form of comments, i.e., the Ethereum Natural Language Specification Format (NatSpec) to provide rich documentation for functions, return variables and more. Please visit the following link for further details:

https://docs.soliditylang.org/en/v0.8.16/natspec-format.html

Consider fully equipping all contracts with complete set of NatSpec to better facilitate users/developers interacting with the protocol's smart contracts.

For instance, the function NatSpec of [`se

## Unbounded loop in `deposit()`
The [for loops](https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol#L239-L241) entailed could easily run out of gas since an NFT collection usually entails thousands of tokenIds. The impact is low since the user can always retry with a smaller array size after encountering a DoS. Where possible, comment with a suggested `tokenIds.length` so users get an idea what array size to work with or better yet set an upper bound to it in the function logic .

## Inadequate NatSpec
Solidity contracts can use a special form of comments, i.e., the Ethereum Natural Language Specification Format (NatSpec) to provide rich documentation for functions, return variables and more. Please visit the following link for further details:

https://docs.soliditylang.org/en/v0.8.16/natspec-format.html

Consider fully equipping all contracts with complete set of NatSpec to better facilitate users/developers interacting with the protocol's smart contracts.

For instance, the function NatSpec of [`sell()`](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L291-L306) in PrivatePool will be perfect with missing @return protocolFeeAmount added.

## Unspecific compiler version pragma
For some source-units the compiler version pragma is very unspecific, i.e. ^0.8.19. While this often makes sense for libraries to allow them to be included with multiple different versions of an application, it may be a security risk for the actual application implementation itself. A known vulnerable compiler version may accidentally be selected or security tools might fall-back to an older compiler version ending up actually checking a different EVM compilation that is ultimately deployed on the blockchain.

Avoid floating pragmas where possible. It is highly recommend pinning a concrete compiler version (latest without security issues) in at least the top-level “deployed” contracts to make it unambiguous which compiler version is bein

## Gas griefing/theft is possible on unsafe external call
`return` data (bool success,) has to be stored due to EVM architecture, if in a usage like below, ‘out’ and ‘outsize’ values are given (0,0). Thus, this storage disappears and may come from external contracts a possible gas grieving/theft problem is avoided as denoted in the link below:

https://twitter.com/pashovkrum/status/1607024043718316032?t=xs30iD6ORWtE2bTTYsCFIQ&s=19

Here is a specific instance entailed:

[File: PrivatePool.sol#L461](PrivatePool.sol#L461](https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L461)

// Code block 1 (diff):
-    /// @param salt The salt that will used on deployment.
+    /// @param salt The salt that will be used on deployment.

PrivatePool.sol#L157-L200, Factory.sol#L166, EthRouter.sol#L239-L241, PrivatePool.sol#L291-L306, PrivatePool.sol#L461


tnevler Q

# Report
## Low Risk ##
### [L-1]: Critical changes should use two-step procedure
**Context:**

1. ```function setOwner(address _newOwner) external mixedAuth {``` [L109](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L109)
1. ```function updateImplementation(address _implementation) external mixedAuth {``` [L120](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L120)
1. ```function setEntryPoint(IEntryPoint _entryPoint) public onlyOwner {``` [L24](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/paymasters/BasePaymaster.sol#L24)
1. ```function setSigner( address _newVerifyingSigner) external onlyOwner{``` [L65](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/paymasters/verifying/singleton/VerifyingSingletonPaymaster.sol#L65)

**Recommendation:**

The best practice is to use two-step procedure for critical changes to make them less error-prone.

## Non-Critical Issues ##
### [N-1]: Function defines a named return variable but then it uses return statements
**Context:**

1. ```return abi.encode(data.paymasterId);``` [L28](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/paymasters/PaymasterHelpers.sol#L28)
1. ```return (userOp.paymasterContext(paymasterData), 0);``` [L110](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/paymasters/verifying/singleton/VerifyingSingletonPaymaster.sol#L110)

**Recommendation:**

Choose named return variable or return statement. It is unnecessary to use both.

### [N-2]: Variable is unused
**Context:**

1. ```UserOperation calldata op,``` [L25](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/paymasters/PaymasterHelpers.sol#L2

### [N-4]: Wrong order of functions
**Context:**

1. ```function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, address aggregator, uint256 missingAccountFunds)``` [L60](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/BaseSmartAccount.sol#L60) (external function can not go after public function)
1. ```receive() external payable {``` [L36](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/Proxy.sol#L36) (receive() function must go before fallback() function)
1. ```function setOwner(address _newOwner) external mixedAuth {``` [L109](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L109) (external function can not go after public function)
1. ```event SmartAccountCreated(address indexed _proxy, address indexed _implementation, address indexed _owner, string version, uint256 _index);``` [L24](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccountFactory.sol#L24) (event definition can not go after constructor)
1. ```function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool) {``` [L55](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/handler/DefaultCallbackHandler.sol#L55) (external view function can not go after external pure function)
1. ```function handleOps(UserOperation[] calldata ops, address payable beneficiary) public {``` [L68](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/aa-4337/core/EntryPoint.sol#L68) (public function can not go after private function)
1. ```function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {``` [L45](https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/aa-4337/interf

SmartAccount.sol#L109, SmartAccount.sol#L120, BasePaymaster.sol#L24, VerifyingSingletonPaymaster.sol#L65, PaymasterHelpers.sol#L28, VerifyingSingletonPaymaster.sol#L110, PaymasterHelpers.sol#L2, BaseSmartAccount.sol#L60, Proxy.sol#L36, SmartAccountFactory.sol#L24, DefaultCallbackHandler.sol#L55, EntryPoint.sol#L68

DefaultCallbackHandler.sol, PaymasterHelpers.sol, VerifyingSingletonPaymaster.sol, BasePaymaster.sol, BaseSmartAccount.sol, Proxy.sol, SmartAccountFactory.sol, EntryPoint.sol, SmartAccount.sol


Matin Q

### Low-Risk Issues
| |Issue|Instances|
|-|:-|:-:|
| [L‑01] | Derivative contract addresses cannot be modified | 1 |
| [L‑02] | Wrong function natspec | 1 |

Total: 2 instances over 2 issues

Note: The table above was created considering the **automatic findings** and thus, those are not included.

## Low-Risk Issues

### [L‑01]  Derivative contract addresses cannot be modified
Any wrong, deprecated, or upgraded address of the derivative contract cannot be modified in the future. The function `addDerivative()` just adds and pushes the contract address to the last index and considers its weights in every calculation.

*There is 1 instance of this issue:*

```solidity
        function addDerivative(
        address _contractAddress,
        uint256 _weight
    ) external onlyOwner {
        derivatives[derivativeCount] = IDerivative(_contractAddress);
        weights[derivativeCount] = _weight;
        derivativeCount++;

        uint256 localTotalWeight = 0;
        for (uint256 i = 0; i < derivativeCount; i++)
            localTotalWeight += weights[i];
        totalWeight = localTotalWeight;
        emit DerivativeAdded(_contractAddress, _weight, derivativeCount);
    }
```
https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L182-L195

### [L‑02]  Wrong function natspec
Two functions `adjustWeight()` and `addDerivative()` has the same natspec comment in the @notice part:
```solidity
    @notice - Adds new derivative to the index fund
```
https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L158
https://github.com/code-423n4/2023-03-asymmetry/blob/main/contracts/SafEth/SafEth.sol#L178

// Code block 1 (solidity):
function addDerivative(
        address _contractAddress,
        uint256 _weight
    ) external onlyOwner {
        derivatives[derivativeCount] = IDerivative(_contractAddress);
        weights[derivativeCount] = _weight;
        derivativeCount++;

        uint256 localTotalWeight = 0;
        for (uint256 i = 0; i < derivativeCount; i++)
            localTotalWeight += weights[i];
        totalWeight = localTotalWeight;
        emit DerivativeAdded(_contractAddress, _weight, derivativeCount);
    }

// Code block 2 (solidity):
@notice - Adds new derivative to the index fund

function addDerivative(
        address _contractAddress,
        uint256 _weight
    ) external onlyOwner {
        derivatives[derivativeCount] = IDerivative(_contractAddress);
        weights[derivativeCount] = _weight;
        derivativeCount++;

        uint256 localTotalWeight = 0;
        for (uint256 i = 0; i < derivativeCount; i++)
            localTotalWeight += weights[i];
        totalWeight = localTotalWeight;
        emit DerivativeAdded(_contractAddress, _weight, derivativeCount);
    }

@notice - Adds new derivative to the index fund


Bauer Q

## 1.No check mint fee is 0
CashManager.sol
If the mintFee is not setted of 0 , the  ```collateral.safeTransferFrom(msg.sender, feeRecipient, feesInCollateral);```  will transfer 0 amount to feeRecipient in the requestMint(), this will waste a lot of gas.

```
function requestMint(
    uint256 collateralAmountIn
  )
    external
    override
    updateEpoch
    nonReentrant
    whenNotPaused
    checkKYC(msg.sender)
  {
    if (collateralAmountIn < minimumDepositAmount) {
      revert MintRequestAmountTooSmall();
    }

    uint256 feesInCollateral = _getMintFees(collateralAmountIn);
    uint256 depositValueAfterFees = collateralAmountIn - feesInCollateral;

    _checkAndUpdateMintLimit(depositValueAfterFees);

    collateral.safeTransferFrom(msg.sender, feeRecipient, feesInCollateral);
    collateral.safeTransferFrom(
      msg.sender,
      assetRecipient,
      depositValueAfterFees
    );

    mintRequestsPerEpoch[currentEpoch][msg.sender] += depositValueAfterFees;

    emit MintRequested(
      msg.sender,
      currentEpoch,
      collateralAmountIn,
      depositValueAfterFees,
      feesInCollateral
    );
  }

```
## Recommended Mitigation Steps：
```
if (feesInCollateral != 0)
    collateral.safeTransferFrom(msg.sender, feeRecipient, feesInCollateral);

```

## 2. whenPaused is useless in function call multiexcall()
CashManager.sol
Three functions requestMint(),claimMint(),requestRedemption() have the not pause modifier. There is whenPaused  modifier for function call multiexcall(), it means the multiexcall() can be trigger when the status is Paused, however  at this point  MANAGER_ADMIN stile not able to call function that is modified by not paused.

```
function multiexcall(
    ExCallData[] calldata exCallData
  )
    external
    payable
    override
    nonReentrant
    onlyRole(MANAGER_ADMIN)
    whenPaused
    returns (bytes[] memory results)
  {
    results = new bytes[](exCallData.length);
    for (uint256 i = 0; i < exCallData.length; ++i) {

// Code block 1 (unknown):
function requestMint(
    uint256 collateralAmountIn
  )
    external
    override
    updateEpoch
    nonReentrant
    whenNotPaused
    checkKYC(msg.sender)
  {
    if (collateralAmountIn < minimumDepositAmount) {
      revert MintRequestAmountTooSmall();
    }

    uint256 feesInCollateral = _getMintFees(collateralAmountIn);
    uint256 depositValueAfterFees = collateralAmountIn - feesInCollateral;

    _checkAndUpdateMintLimit(depositValueAfterFees);

    collateral.safeTransferFrom(msg.sender, feeRecipient, feesInCollateral);
    collateral.safeTransferFrom(
      msg.sender,
      assetRecipient,
      depositValueAfterFees
    );

    mintRequestsPerEpoch[currentEpoch][msg.sender] += depositValueAfterFees;

    emit MintRequested(
      msg.sender,
      currentEpoch,
      collateralAmountIn,
      depositValueAfterFees,
      feesInCollateral
    );
  }

// Code block 2 (unknown):
if (feesInCollateral != 0)
    collateral.safeTransferFrom(msg.sender, feeRecipient, feesInCollateral);


0xnev Q

### [Low Risk](#low-risk)
| Count | Title |
|:--:|:-------|
| [L-01]| `liquidation()`: Liquidation allowance check insufficient in `liquidatio()`|
| [L-02] |  `LybraGovernance`: Vote casters cannot change or remove vote |
| [L-03] | `LybraEUSDVaultBase.superLiquidation()`: Confusing code comments deviates from function logic |

| Total Low Risk Issues | 3 |
|:--:|:--:|

### [Non-Critical](#non-critical)
| Count | Title |
|:--:|:-------|
| [NC-01] | `rigidRedemption()`: Disallow rigid redemption of 0 value|
| [NC-02] | Add reentrancy guard to Lybra's version of synthethix contract |
| [NC-03] | `LybraStETHVault.excessIncomeDistribution()`: Use `_saveReport()` directly |
| [NC-04] | `LybraStETHVault.excessIncomeDistribution()`: Cache result of `getDutchAuctionDiscountPrice()` |
| [NC-05] | `liquidation()/superLiquidation`: Add 0 value check to prevent division by 0 in `liquidation` |
| [NC-06] | Superfluous events |

| Total Non-Critical Issues | 6 |
|:--:|:--:|

## Low Risk
## [L-01] `liquidation()`: Liquidation allowance check insufficient in `liquidatio()`

## Impact
```solidity
require(EUSD.allowance(provider, address(this)) > 0, "provider should authorize to provide liquidation EUSD");
```
Liquidation allowance check in `liquidation()` is insufficient since it only checks that allowance provided to vault contract is more than 0.

Provider should authorize to provide at least eusdAmount to repay on behalf of borrower that is undercollateralized in `liquidation()` similar to `superLiquidation()`. If not, the transaction will still revert.

## Recommendation
Consider approving token allowance similar to `superLiquidation()`
```solidity
require(EUSD.allowance(provider, address(this)) >= eusdAmount, "provider should authorize to provide liquidation EUSD");
```

## [L-02] `LybraGovernance`: Vote casters cannot change or remove vote

## Impact
```solidity
function _countVote(uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory) inte

// Code block 1 (solidity):
require(EUSD.allowance(provider, address(this)) > 0, "provider should authorize to provide liquidation EUSD");

// Code block 2 (solidity):
require(EUSD.allowance(provider, address(this)) >= eusdAmount, "provider should authorize to provide liquidation EUSD");

require(EUSD.allowance(provider, address(this)) > 0, "provider should authorize to provide liquidation EUSD");

require(EUSD.allowance(provider, address(this)) >= eusdAmount, "provider should authorize to provide liquidation EUSD");


0xkazim G

# Findings Summary

| ID     | Title                                                  | Severity |
| ------ | ------------------------------------------------------ | -------- |
| [G-01] | you can use one event instead of two event to save gas | low      |

# [G-01] you can use one event instead of two event to save gas

## Description

there is no need to use 2 event for StakingPaused/UnstakingPaused and/or Staked/Unstaked, you can use one event for pause/unpause and one event for Stake/Unstake and saving some gas.

## context

There are 5 instances of the topic.

```solidity

file: contracts/SafEth/SafEth.sol

 //@audit-info use one event for both
    event StakingPaused(bool indexed paused);
    event UnstakingPaused(bool indexed paused);
    //@audit-info use one event for both below !
     event Staked(address indexed recipient, uint ethIn, uint safEthOut);
    event Unstaked(address indexed recipient, uint ethOut, uint safEthIn);
```

https://github.com/code-423n4/2023-03-asymmetry/blob/44b5cd94ebedc187a08884a7f685e950e987261c/contracts/SafEth/SafEth.sol#L23-L27

## Recommendations

change the events above to something like this :

`event stakeState(bool indexed paused)` and same thing to staked/unstaked event can be set this way.

// Code block 1 (solidity):
file: contracts/SafEth/SafEth.sol

 //@audit-info use one event for both
    event StakingPaused(bool indexed paused);
    event UnstakingPaused(bool indexed paused);
    //@audit-info use one event for both below !
     event Staked(address indexed recipient, uint ethIn, uint safEthOut);
    event Unstaked(address indexed recipient, uint ethOut, uint safEthIn);


catwhiskeys Q

# Possible reentrancy attack and cooldown manipulation
Instances:
https://github.com/code-423n4/2024-01-salty/blob/main/src/staking/StakingRewards.sol#L57-L92
https://github.com/code-423n4/2024-01-salty/blob/main/src/staking/StakingRewards.sol#L97-L140

## PoC

Absence of reentrancy guards in the functions `_increaseUserShare` and `_decreaseUserShare`
and possibly faulty cooldown mechanism:
```
if ( msg.sender != address(exchangeConfig.dao()) ) // DAO doesn't use the cooldown
	{
@>	require( block.timestamp >= user.cooldownExpiration, "Must wait for the cooldown to expire" );

	// Update the cooldown expiration for future transactions
@>	user.cooldownExpiration = block.timestamp + stakingConfig.modificationCooldown();
	}
```
If we check interface `IStakingConfig.sol` we see that function `modificationCooldown` doesn't provide much functionality, seems like it's handled manually, by admins. This can lead to man-made risks.

There is a function below `userCooldowns`, but it seems to have nothing to do with the function above.
Probably, user cooldown mechanism should be reviewed.

Even though functions `_increaseUserShare` and `_decreaseUserShare` are internal, they handle funds,
so the reentrancy guards should contribute a lot for the function security.

## Impact
Loss of funds

## Tools:
VSCode

## Recommeded mitigation steps:
1. Consider adding reentrancy guards for the functions `_increaseUserShare` and `_decreaseUserShare`.
2. Consider making strinct comparison , just for case if `stakingConfig.modificationCooldown()` will be equal to 0:
```
function _increaseUserShare( address wallet, bytes32 poolID, uint256 increaseShareAmount, bool useCooldown ) internal
	{
	require( poolsConfig.isWhitelisted( poolID ), "Invalid pool" );
	require( increaseShareAmount != 0, "Cannot increase zero share" );

	UserShareInfo storage user = _userShareInfo[wallet][poolID];

	if ( useCooldown )
	if ( msg.sender != address(exchangeConfig.dao()) ) // DAO doesn't use the cooldown
		{

function _increaseUserShare( address wallet, bytes32 poolID, uint256 increaseShareAmount, bool useCooldown ) internal
	{
	require( poolsConfig.isWhitelisted( poolID ), "Invalid pool" );
	require( increaseShareAmount != 0, "Cannot increase zero share" );

	UserShareInfo storage user = _userShareInfo[wallet][poolID];

	if ( useCooldown )
	if ( msg.sender != address(exchangeConfig.dao()) ) // DAO doesn't use the cooldown
		{
-		require( block.timestamp >= user.cooldownExpiration, "Must wait for the cooldown to expire" );
+		require( block.timestamp > user.cooldownExpiration, "Must wait for the cooldown to expire" );

// Code block 1 (unknown):
if ( msg.sender != address(exchangeConfig.dao()) ) // DAO doesn't use the cooldown
	{
@>	require( block.timestamp >= user.cooldownExpiration, "Must wait for the cooldown to expire" );

	// Update the cooldown expiration for future transactions
@>	user.cooldownExpiration = block.timestamp + stakingConfig.modificationCooldown();
	}


LewisBroadhurst Q

## Non-Critical

### [NC-01]

Simplification of the `try catch` block to make code more readable and the function more gas efficient.

```
// PrivatePool.sol
function availableForFlashLoan(address token, uint256 tokenId) public view returns (bool) {
    // return if the NFT is owned by this contract
    try ERC721(token).ownerOf(tokenId) returns (address result) {
        return result == address(this);
    } catch {
        return false;
    }
}

// recommended change
function availableForFlashLoan(address token, uint256 tokenId) public view returns (bool) {
    // return if the NFT is owned by this contract
    address owner = ERC721(token).ownerOf(tokenId);
    return owner == address(this);
}
```

### [NC-02]

If statement can be simplified into a ternary operator. Gas savings from require.

```
// Factory.sol
if ((_baseToken == address(0) && msg.value != baseTokenAmount) || (_baseToken != address(0) && msg.value > 0)) {
    revert PrivatePool.InvalidEthAmount();
}

// recommended change
if (_baseToken == address(0) ? msg.value != baseTokenAmount : msg.value >= 0) {
    revert PrivatePool.InvalidEthAmount();
}

// Additional gas savings from merging into require
require((_baseToken == address(0) ? msg.value == baseTokenAmount : msg.value >= 0), PrivatePool.InvalidEthAmount());
```

// Code block 1 (unknown):
// PrivatePool.sol
function availableForFlashLoan(address token, uint256 tokenId) public view returns (bool) {
    // return if the NFT is owned by this contract
    try ERC721(token).ownerOf(tokenId) returns (address result) {
        return result == address(this);
    } catch {
        return false;
    }
}

// recommended change
function availableForFlashLoan(address token, uint256 tokenId) public view returns (bool) {
    // return if the NFT is owned by this contract
    address owner = ERC721(token).ownerOf(tokenId);
    return owner == address(this);
}

// Code block 2 (unknown):
// Factory.sol
if ((_baseToken == address(0) && msg.value != baseTokenAmount) || (_baseToken != address(0) && msg.value > 0)) {
    revert PrivatePool.InvalidEthAmount();
}

// recommended change
if (_baseToken == address(0) ? msg.value != baseTokenAmount : msg.value >= 0) {
    revert PrivatePool.InvalidEthAmount();
}

// Additional gas savings from merging into require
require((_baseToken == address(0) ? msg.value == baseTokenAmount : msg.value >= 0), PrivatePool.InvalidEthAmount());


codeslide G

### Gas Optimizations List

| Number | Optimization Details                               | Instances |
| :----: | :------------------------------------------------- | :-------: |
| [G-01] | Use scientific notation                            |    18     |
| [G-02] | Unnecessary computation                            |     3     |
| [G-03] | Mark functions as payable                          |    17     |
| [G-04] | Change function visibility from public to external |     2     |
| [G-05] | Use short circuiting to save gas                   |     1     |
| [G-06] | Remove unnecessary variables                       |     5     |

Total 6 issues

#### [G-01] Use scientific notation

Use scientific notation like `1e18` rather than `10 ** 18` to avoid an unnecessary arithmetic operation and save gas.

```solidity
File: contracts/SafEth/SafEth.sol

54:    minAmount = 5 * 10 ** 17; // initializing with .5 ETH as minimum

55:    maxAmount = 200 * 10 ** 18; // initializing with 200 ETH as maximum

80:    preDepositPrice = 10 ** 18; // initializes with a price of 1

81:    else preDepositPrice = (10 ** 18 * underlyingValue) / totalSupply;

94:    ) * depositAmount) / 10 ** 18;

98:    uint256 mintAmount = (totalStakeValueEth * 10 ** 18) / preDepositPrice;
```

```solidity
File: contracts/SafEth/deriviatives/Reth.sol

44:     maxSlippage = (1 * 10 ** 16); // 1%

171:    uint rethPerEth = (10 ** 36) / poolPrice();

173:    uint256 minOut = ((((rethPerEth * msg.value) / 10 ** 18) * ((10 ** 18 - maxSlippage))) / 10 ** 18);

214:    RocketTokenRETHInterface(rethAddress()).getEthValue(10 ** 18);

215:    else return (poolPrice() * 10 ** 18) / (10 ** 18);
```

```solidity
File: contracts/SafEth/deriviatives/SfrxEth.sol

38:     maxSlippage = (1 * 10 ** 16); // 1%

74:    uint256 minOut = (((ethPerDerivative(_amount) * _amount) / 10 ** 18) * (10 ** 18 - maxSlippage)) / 10 ** 18;

112:    uint256 frxAmount = IsFrxEth(SFRX_ETH_ADDRESS).convertToAssets(10 ** 18);

115:    return ((10 *

// Code block 1 (solidity):
File: contracts/SafEth/SafEth.sol

54:    minAmount = 5 * 10 ** 17; // initializing with .5 ETH as minimum

55:    maxAmount = 200 * 10 ** 18; // initializing with 200 ETH as maximum

80:    preDepositPrice = 10 ** 18; // initializes with a price of 1

81:    else preDepositPrice = (10 ** 18 * underlyingValue) / totalSupply;

94:    ) * depositAmount) / 10 ** 18;

98:    uint256 mintAmount = (totalStakeValueEth * 10 ** 18) / preDepositPrice;

// Code block 2 (solidity):
File: contracts/SafEth/deriviatives/Reth.sol

44:     maxSlippage = (1 * 10 ** 16); // 1%

171:    uint rethPerEth = (10 ** 36) / poolPrice();

173:    uint256 minOut = ((((rethPerEth * msg.value) / 10 ** 18) * ((10 ** 18 - maxSlippage))) / 10 ** 18);

214:    RocketTokenRETHInterface(rethAddress()).getEthValue(10 ** 18);

215:    else return (poolPrice() * 10 ** 18) / (10 ** 18);

File: contracts/SafEth/SafEth.sol

54:    minAmount = 5 * 10 ** 17; // initializing with .5 ETH as minimum

55:    maxAmount = 200 * 10 ** 18; // initializing with 200 ETH as maximum

80:    preDepositPrice = 10 ** 18; // initializes with a price of 1

81:    else preDepositPrice = (10 ** 18 * underlyingValue) / totalSupply;

94:    ) * depositAmount) / 10 ** 18;

98:    uint256 mintAmount = (totalStakeValueEth * 10 ** 18) / preDepositPrice;

File: contracts/SafEth/deriviatives/Reth.sol

44:     maxSlippage = (1 * 10 ** 16); // 1%

171:    uint rethPerEth = (10 ** 36) / poolPrice();

173:    uint256 minOut = ((((rethPerEth * msg.value) / 10 ** 18) * ((10 ** 18 - maxSlippage))) / 10 ** 18);

214:    RocketTokenRETHInterface(rethAddress()).getEthValue(10 ** 18);

215:    else return (poolPrice() * 10 ** 18) / (10 ** 18);


BRONZEDISC Q

## QA
---

### Layout Order [1]

- The best-practices for layout within a contract is the following order: state variables, events, modifiers, constructor and functions.

https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol

```solidity
// define these state variables before all the events
82:    address public baseToken;
85:    address public nft;
88:    uint56 public changeFee;
91:    uint16 public feeRate;
94:    bool public initialized;
97:    bool public payRoyalties;
100:    bool public useStolenNftOracle;
104:    uint128 public virtualBaseTokenReserves;
112:    uint128 public virtualNftReserves;
116:    bytes32 public merkleRoot;
119:    address public immutable stolenNftOracle;
122:    address payable public immutable factory;
125:    address public immutable royaltyRegistry;
```

https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol

```solidity
// place this state variable before all the error declarations.
86:    address public immutable royaltyRegistry;
```

---

### Function Visibility [2]

- Order of Functions: Ordering helps readers identify which functions they can call and to find the constructor and fallback definitions easier. Functions should be grouped according to their visibility and ordered: constructor, receive function (if exists), fallback function (if exists), public, external, internal, private. Within a grouping, place the view and pure functions last.

https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol

```solidity
// receive function should come right after constructor
134:    receive() external payable {}

// external function coming before public ones
623:    function flashLoan(IERC3156FlashBorrower receiver, address token, uint256 tokenId, bytes calldata data)
```

https://github.com/code-423n4/2023-04-caviar/blob/main/src/EthRouter.sol

```solidity
// receive function should come after constructor
88:    receive() external payable {}
```

---

### natSpec missing [3]

// Code block 1 (solidity):
// define these state variables before all the events
82:    address public baseToken;
85:    address public nft;
88:    uint56 public changeFee;
91:    uint16 public feeRate;
94:    bool public initialized;
97:    bool public payRoyalties;
100:    bool public useStolenNftOracle;
104:    uint128 public virtualBaseTokenReserves;
112:    uint128 public virtualNftReserves;
116:    bytes32 public merkleRoot;
119:    address public immutable stolenNftOracle;
122:    address payable public immutable factory;
125:    address public immutable royaltyRegistry;

// Code block 2 (solidity):
// place this state variable before all the error declarations.
86:    address public immutable royaltyRegistry;

// Code block 3 (solidity):
// receive function should come right after constructor
134:    receive() external payable {}

// external function coming before public ones
623:    function flashLoan(IERC3156FlashBorrower receiver, address token, uint256 tokenId, bytes calldata data)

// Code block 4 (solidity):
// receive function should come after constructor
88:    receive() external payable {}

// define these state variables before all the events
82:    address public baseToken;
85:    address public nft;
88:    uint56 public changeFee;
91:    uint16 public feeRate;
94:    bool public initialized;
97:    bool public payRoyalties;
100:    bool public useStolenNftOracle;
104:    uint128 public virtualBaseTokenReserves;
112:    uint128 public virtualNftReserves;
116:    bytes32 public merkleRoot;
119:    address public immutable stolenNftOracle;
122:    address payable public immutable factory;
125:    address public immutable royaltyRegistry;

// place this state variable before all the error declarations.
86:    address public immutable royaltyRegistry;

// receive function should come right after constructor
134:    receive() external payable {}

// external function coming before public ones
623:    function flashLoan(IERC3156FlashBorrower receiver, address token, uint256 tokenId, bytes calldata data)

// receive function should come after constructor
88:    receive() external payable {}


arialblack14 G

# GAS OPTIMIZATION REPORT

### Summary of optimizations

| Number       | Issue details                                                                                | Instances |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------: |
| [G-1](#G1)   | `++i/i++` should be `unchecked{++i}`/`unchecked{i++}` when  it is not possible for them to overflow, for example when used in `for` and `while` loops |    15    |
| [G-2](#G2)   | Multiple address mappings can be combined into a single mapping of an address to a struct, where appropriate.                                         |     5     |
| [G-3](#G3)   | Using storage instead of memory for structs/arrays saves gas.                                                                                |    12    |
| [G-4](#G4)   | Usage of`uint`s/`int`s smaller than 32 bytes (256 bits) incurs overhead.                                                                              |    31    |
| [G-5](#G5)   | `abi.encode()` is less efficient than `abi.encodePacked()`                                                                                |     2     |
| [G-6](#G6)   | Use`bytes32` instead of string.                                                                                |     9     |
| [G-7](#G7)   | Internal functions only called once can be inlined to save gas.                                                                                |    25    |
| [G-8](#G8)   | `>=` costs less gas than `>`.                                                                                |    39    |
| [G-9](#G9)   | `<x> += <y>` costs more gas than `<x> = <x> + <y>` for state variables

for (uint i = 0; i < length; i++) {
// do something that doesn't change the value of i
}

for (uint i = 0; i < length; i = unchecked_inc(i)) {
	// do something that doesn't change the value of i
}

function unchecked_inc(uint i) returns (uint) {
	unchecked {
		return i + 1;
	}
}


oyc_109 G

## [G-01] Don't Initialize Variables with Default Value

Uninitialized variables are assigned with the types default value. Explicitly initializing a variable with it's default value costs unnecesary gas.

```
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol::234 => uint256 payment = 0;
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol::310 => uint256 i = 0;
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol::468 => for (uint i = 0; i < dest.length;) {
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccountNoAuth.sol::234 => uint256 payment = 0;
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccountNoAuth.sol::305 => uint256 i = 0;
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccountNoAuth.sol::458 => for (uint i = 0; i < dest.length;) {
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/base/ModuleManager.sol::119 => uint256 moduleCount = 0;
```

## [G-02] Cache Array Length Outside of Loop

Caching the array length outside a loop saves reading it on each iteration, as long as the array's length is not changed during the loop.

```
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol::468 => for (uint i = 0; i < dest.length;) {
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccountNoAuth.sol::458 => for (uint i = 0; i < dest.length;) {
```

## [G-03] Long Revert Strings

Shortening revert strings to fit in 32 bytes will decrease gas costs for deployment and gas costs when the revert condition has been met.

If the contract(s) in scope allow using Solidity >=0.8.4, consider using Custom Errors as they are more gas efficient while allowing developers to describe the error in detail using NatSpec.

```
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol::77 => require(msg.sender == owner, "Smart Account:: Sender is not authorized"

// Code block 1 (unknown):
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol::234 => uint256 payment = 0;
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol::310 => uint256 i = 0;
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol::468 => for (uint i = 0; i < dest.length;) {
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccountNoAuth.sol::234 => uint256 payment = 0;
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccountNoAuth.sol::305 => uint256 i = 0;
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccountNoAuth.sol::458 => for (uint i = 0; i < dest.length;) {
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/base/ModuleManager.sol::119 => uint256 moduleCount = 0;

// Code block 2 (unknown):
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol::468 => for (uint i = 0; i < dest.length;) {
2023-01-biconomy/scw-contracts/contracts/smart-contract-wallet/SmartAccountNoAuth.sol::458 => for (uint i = 0; i < dest.length;) {


Awesome Q

# 1. Unspecific Compiler Version Pragma

It is generally not recommended to use floating pragmas (i.e. pragmas that do not specify a specific compiler version) in contracts that are not intended to be used as libraries.

This is because using floating pragmas in application contracts can pose a security risk.

For example, a known vulnerable compiler version may be selected by mistake, or security tools might revert to an older compiler version that produces a different EVM compilation than the one intended to be deployed on the blockchain.

To avoid these potential issues, consider specifying a specific compiler version in your pragmas.

So instead of using a floating pragma like `pragma solidity ^0.8.0;`, it is better to use a concrete compiler version like `pragma solidity 0.8.17;`.

More information can be found in the following links:

- [Consensys Audit of 1inch](https://consensys.net/diligence/audits/2020/12/1inch-liquidity-protocol/#unspecific-compiler-version-pragma)
- [Solidity docs](https://docs.soliditylang.org/en/latest/layout-of-source-files.html#version-pragma)
- [Solidity Specific](https://consensys.github.io/smart-contract-best-practices/development-recommendations/solidity-specific/locking-pragmas/)

Affected lines of code:

- [Factory.sol#L2](https://github.com/code-423n4/2023-04-caviar/blob/cd8a92667bcb6657f70657183769c244d04c015c/src/Factory.sol#L2)
- [PrivatePoolMetadata.sol#L2](https://github.com/code-423n4/2023-04-caviar/blob/cd8a92667bcb6657f70657183769c244d04c015c/src/PrivatePoolMetadata.sol#L2)
- [EthRouter.sol#L2](https://github.com/code-423n4/2023-04-caviar/blob/cd8a92667bcb6657f70657183769c244d04c015c/src/EthRouter.sol#L2)
- [PrivatePool.sol#L2](https://github.com/code-423n4/2023-04-caviar/blob/cd8a92667bcb6657f70657183769c244d04c015c/src/PrivatePool.sol#L2)

# 2. Follow the function order of the solidity style guide

The [Solidity style guide](https://docs.soliditylang.org/en/v0.8.17/style-guide.html#order-of-functions) recommends the

File: src/EthRouter.sol
line 169:    // exceute the sell against a public pool

File: src/PrivatePool.sol
line 251: // add the royalty fee amount to the net input aount

Factory.sol#L2, PrivatePoolMetadata.sol#L2, EthRouter.sol#L2, PrivatePool.sol#L2

EthRouter.sol, Factory.sol, PrivatePool.sol, PrivatePoolMetadata.sol


chaduke Q

QA1: functions _increaseUserShares() and _decreaseUserShares() fail to update user.cooldownExpiration when useCooldown = false. As a result, right after _increaseUserShares() is called with useCooldown = false, another call _increaseUserShares() can be possible since user.cooldownExpiration has not been updated in the previous calls.

[https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/staking/StakingRewards.sol#L57-L140](https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/staking/StakingRewards.sol#L57-L140)

Mitigation: Regardless of the value of useCooldown, we should always update user.cooldownExpiration as follows:

```javascript
https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/staking/StakingRewards.sol#L57-L140
```

QA2. The _decreaseUserShare() function has a rounding-down precision error for ``virtualRewardsToRemove`` that is in favor of the user instead of the protocol.

[https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/staking/StakingRewards.sol#L118C11-L118C33](https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/staking/StakingRewards.sol#L118C11-L118C33)

As a result, even when a user redeems all shares, user.virtualRewards still might be positive. Due to the rounding down precision of ``virtualRewardsToRemove``, claiming is in favor instead of the system.

Mitigation: the rounding should be in favor of the system. A rounding up should be used as follows:

```javascipt
uint256 virtualRewardsToRemove = Math.ceilDiv(user.virtualRewards * decreaseShareAmount), user.userShare);
```

QA3: _sendLiquidityRewards() might not send all ``liquidityRewardsAmount`` to the pools due to rounding down error. This is because when calculating the portion for each pool, there is a rounding down error:

[https://github.com/code-423n4/2024-01-salty/blob/535

QA3: _sendLiquidityRewards() might not send all ``liquidityRewardsAmount`` to the pools due to rounding down error. This is because when calculating the portion for each pool, there is a rounding down error:

[https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/rewards/SaltRewards.sol#L67-L68](https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/rewards/SaltRewards.sol#L67-L68)

As a result, when each time performUpKeep() is called, there might be leftover ``liquidityRewardsAmount`` that has not been distributed.

Mitigation: send the leftover either to the last pool, or better yet, send it to the staking as follows in the function ``performUpKeep()``:

// Code block 1 (javascript):
https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/staking/StakingRewards.sol#L57-L140

// Code block 2 (javascipt):
uint256 virtualRewardsToRemove = Math.ceilDiv(user.virtualRewards * decreaseShareAmount), user.userShare);


Rickard Q

# [L-01] Owner can renounce Ownership

## Vulnerability details
### Proof of Concept
[https://github.com/code-423n4/2023-02-ethos/blob/main/Ethos-Vault/contracts/abstract/ReaperBaseStrategyv4.sol#L14-L19](https://github.com/code-423n4/2023-02-ethos/blob/main/Ethos-Vault/contracts/abstract/ReaperBaseStrategyv4.sol#L14-L19)
````solidity
7 results - 7 files
/ActivePool.sol
13: import "./Dependencies/Ownable.sol";
26: contract ActivePool is Ownable, CheckContract, IActivePool {

/BorrowerOperations.sol
13: import "./Dependencies/Ownable.sol";
18: contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOperations {

/CollateralConfig.sol
6:  import "./Dependencies/Ownable.sol";
15: contract CollateralConfig is ICollateralConfig, CheckContract, Ownable {

/HintHelpers.sol
9:  import "./Dependencies/Ownable.sol";
12: contract HintHelpers is LiquityBase, Ownable, CheckContract {

/StabilityPool.sol
16: import "./Dependencies/Ownable.sol";
146:  contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool {

/CommunityIssuance.sol
9:  import "./Dependencies/Ownable.sol";
14: contract CommunityIssuance is ICommunityIssuance, Ownable, CheckContract, BaseMath {

/LQTYStaking.sol
7:  import "./Dependencies/Ownable.sol";
18: contract LQTYStaking is ILQTYStaking, Ownable, CheckContract, BaseMath {
````
Typically, the contract’s owner is the account that deploys the contract. As a result, the owner is able to perform certain privileged activities.

The OpenZeppelin’s Ownable used in this project contract implements renounceOwnership. This can represent a certain risk if the ownership is renounced for any other reason than by design.

Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.

`onlyOwner` functions:
````solidity
/ActivePool.sol
71: function setAddresses(
          address _collateralConfigAddress,
          address _borrowerOperationsAddr

/ActivePool.sol
71: function setAddresses(
          address _collateralConfigAddress,
          address _borrowerOperationsAddress,
          address _troveManagerAddress,
          address _stabilityPoolAddress,
          address _defaultPoolAddress,
          address _collSurplusPoolAddress,
          address _treasuryAddress,
          address _lqtyStakingAddress,
          address[] calldata _erc4626vaults
      )
          external
          onlyOwner
      {
125:  function setYieldingPercentage(address _collateral, uint256 _bps) external onlyOwner {

132:  function setYieldingPercentageDrift(uint256 _driftBps) external onlyOwner {

138:  function setYieldClaimThreshold(address _collateral, uint256 _threshold) external onlyOwner {

144:  function setYieldDistributionParams(uint256 _treasurySplit, uint256 _SPSplit, uint256 _stakingSplit) external onlyOwner {

214:  function manualRebalance(address _collateral, uint256 _simulatedAmountLeavingPool) external onlyOwner {

/BorrowerOperations.sol
110:  function setAddresses(
        address _collateralConfigAddress,
        address _troveManagerAddress,
        address _activePoolAddress,
        address _defaultPoolAddress,
        address _stabilityPoolAddress,
        address _gasPoolAddress,
        address _collSurplusPoolAddress,
        address _priceFeedAddress,
        address _sortedTrovesAddress,
        address _lusdTokenAddress,
        address _lqtyStakingAddress
    )
        external
        override
        onlyOwner
    {

/CollateralConfig.sol
46: function initialize(
        address[] calldata _collaterals,
        uint256[] calldata _MCRs,
        uint256[] calldata _CCRs
    ) external override onlyOwner {

85: function updateCollateralRatios(
        address _collateral,
        uint256 _MCR,
        uint256 _CCR
    ) external onlyOwner checkCollateral(_collateral) {

/HintHelpers.sol
27: function setAddresses(
        address _collateralConfigAddress,
        address _sortedTrovesAddress,

// Code block 1 (solidity):
7 results - 7 files
/ActivePool.sol
13: import "./Dependencies/Ownable.sol";
26: contract ActivePool is Ownable, CheckContract, IActivePool {

/BorrowerOperations.sol
13: import "./Dependencies/Ownable.sol";
18: contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOperations {

/CollateralConfig.sol
6:  import "./Dependencies/Ownable.sol";
15: contract CollateralConfig is ICollateralConfig, CheckContract, Ownable {

/HintHelpers.sol
9:  import "./Dependencies/Ownable.sol";
12: contract HintHelpers is LiquityBase, Ownable, CheckContract {

/StabilityPool.sol
16: import "./Dependencies/Ownable.sol";
146:  contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool {

/CommunityIssuance.sol
9:  import "./Dependencies/Ownable.sol";
14: contract CommunityIssuance is ICommunityIssuance, Ownable, CheckContract, BaseMath {

/LQTYStaking.sol
7:  import "./Dependencies/Ownable.sol";
18: contract LQTYStaking is ILQTYStaking, Ownable, CheckContract, BaseMath {


Sathish9098 Q

 # LOW FINDINGS

Low-level findings should not be ignored, as they can still pose potential risks or be indicative of vulnerabilities that could be exploited. It is recommended to address and remediate all identified issues, regardless of their severity, to enhance the overall security and reliability of the smart contract

##

| LOW COUNT| ISSUES | INSTANCES|
|-------|-----|--------|
| [L-1]| Event are missing sender information  | 1 |
| [L-2]| Prevent division by 0  | 1 |
| [L-3]| LOW LEVEL CALLS WITH SOLIDITY VERSION 0.8.14 CAN RESULT IN OPTIMISER BUG | 1 |
| [L-4]| Lack of sanity/threshold/limit checks for uint256    | 1 |
| [L-5]| Gas griefing/theft is possible on unsafe external call | 1 |
| [L-6]| Project has NPM Dependency which uses a vulnerable version : @openzeppelin  | - |
| [L-7]| Project Upgrade and Stop Scenario should be  | - |
| [L-8]| Lack of nonReentrant modifiers for critical external functions   | 4 |
| [L-9]| Missing Event for critical updates | 1 |
| [L-10]| EnumerableSet.UintSet should be avoided  | - |

# NON CRITICAL FINDINGS

| NC COUNT| ISSUES | INSTANCES|
|-------|-----|--------|
| [NC-1]| immutable should be uppercase  | 5 |
| [NC-2]| Use NATSPEC commands for all contracts   | - |
| [NC-3]| For functions,Variables follow Solidity standard naming conventions (internal function,Variable style rule) | 5 |
| [NC-4]| According to the syntax rules, use => mapping ( instead of => mapping( using spaces as keyword  | 17 |
| [NC-5]| SMT Checker  | - |
| [NC-6]| Assembly Codes Specific – Should Have Comments  | 3 |
| [NC-7]| Shorthand way to write if / else statement   | 2 |
| [NC-8]| Don't use named return variables its confusing | 14 |
| [NC-9]| Tokens accidentally sent to the contract cannot be recovered| - |
| [NC-10]| NatSpec comments should be increased in contracts  | - |

##

## [L-1] Event are missing sender information

When an action is triggered based on a user's action, not being able to filter based on who triggered the action makes

FILE: 2023-05-ajna/ajna-grants/src/grants/GrantFund.sol

64: emit FundTreasury(fundingAmount_, treasury);


Brenzee G

## No need to specify value if that value is the initial value of the type
https://github.com/code-423n4/2023-02-ethos/blob/main/Ethos-Core/contracts/CollateralConfig.sol#L18
https://github.com/code-423n4/2023-02-ethos/blob/main/Ethos-Core/contracts/ActivePool.sol#L32
https://github.com/code-423n4/2023-02-ethos/blob/main/Ethos-Core/contracts/LQTY/CommunityIssuance.sol#L21
https://github.com/code-423n4/2023-02-ethos/blob/main/Ethos-Core/contracts/LUSDToken.sol#L37

### Explanation

By default `bool` values in Solidity are `false` . By removing the `= false` gas can be saved.

CollateralConfig.sol:
Deploy gas before: 871266
Deploy gas after: 870858
Gas saved: 408

ActivePool.sol
Deploy gas before: 2391096
Deploy gas after: 2390677
Gas saved: 419

Average saved gas per smart contract deployement - 410 gas

## Suggestions

```diff
diff --git a/contracts/CollateralConfig.sol.orig b/contracts/CollateralConfig.sol
index d524f23..6ad85b1 100644
--- a/contracts/CollateralConfig.sol.orig
+++ b/contracts/CollateralConfig.sol
@@ -15,7 +15,7 @@ import "./Interfaces/ICollateralConfig.sol";
 contract CollateralConfig is ICollateralConfig, CheckContract, Ownable {
     using SafeERC20 for IERC20;

-    bool public initialized = false;
+    bool public initialized;

     // Smallest allowed value for the minimum collateral ratio for individual troves in each market (collateral)
     uint256 constant public MIN_ALLOWED_MCR = 1.1 ether; // 110%
```

```diff
diff --git a/contracts/ActivePool.sol.orig b/contracts/ActivePool.sol
index 753fcd0..868a35e 100644
--- a/contracts/ActivePool.sol.orig
+++ b/contracts/ActivePool.sol
@@ -29,7 +29,7 @@ contract ActivePool is Ownable, CheckContract, IActivePool {

     string constant public NAME = "ActivePool";

-    bool public addressesSet = false;
+    bool public addressesSet;
     address public collateralConfigAddress;
     address public borrowerOperationsAddress;
     address public troveManagerAddress;
```

```diff
diff --git a/contracts/L

```diff
diff --git a/contracts/LUSDToken.sol.orig b/contracts/LUSDToken.sol
index 9c5424d..dd470c4 100644
--- a/contracts/LUSDToken.sol.orig
+++ b/contracts/LUSDToken.sol
@@ -34,7 +34,7 @@ contract LUSDToken is CheckContract, ILUSDToken {
     string constant internal _VERSION = "1";
     uint8 constant internal _DECIMALS = 18;

-    bool public mintingPaused = false;
+    bool public mintingPaused;

     // --- Data for EIP2612 ---

// Code block 1 (diff):
diff --git a/contracts/CollateralConfig.sol.orig b/contracts/CollateralConfig.sol
index d524f23..6ad85b1 100644
--- a/contracts/CollateralConfig.sol.orig
+++ b/contracts/CollateralConfig.sol
@@ -15,7 +15,7 @@ import "./Interfaces/ICollateralConfig.sol";
 contract CollateralConfig is ICollateralConfig, CheckContract, Ownable {
     using SafeERC20 for IERC20;

-    bool public initialized = false;
+    bool public initialized;

     // Smallest allowed value for the minimum collateral ratio for individual troves in each market (collateral)
     uint256 constant public MIN_ALLOWED_MCR = 1.1 ether; // 110%

// Code block 2 (diff):
diff --git a/contracts/ActivePool.sol.orig b/contracts/ActivePool.sol
index 753fcd0..868a35e 100644
--- a/contracts/ActivePool.sol.orig
+++ b/contracts/ActivePool.sol
@@ -29,7 +29,7 @@ contract ActivePool is Ownable, CheckContract, IActivePool {

     string constant public NAME = "ActivePool";

-    bool public addressesSet = false;
+    bool public addressesSet;
     address public collateralConfigAddress;
     address public borrowerOperationsAddress;
     address public troveManagerAddress;

diff --git a/contracts/CollateralConfig.sol.orig b/contracts/CollateralConfig.sol
index d524f23..6ad85b1 100644
--- a/contracts/CollateralConfig.sol.orig
+++ b/contracts/CollateralConfig.sol
@@ -15,7 +15,7 @@ import "./Interfaces/ICollateralConfig.sol";
 contract CollateralConfig is ICollateralConfig, CheckContract, Ownable {
     using SafeERC20 for IERC20;

-    bool public initialized = false;
+    bool public initialized;

     // Smallest allowed value for the minimum collateral ratio for individual troves in each market (collateral)
     uint256 constant public MIN_ALLOWED_MCR = 1.1 ether; // 110%

diff --git a/contracts/ActivePool.sol.orig b/contracts/ActivePool.sol
index 753fcd0..868a35e 100644
--- a/contracts/ActivePool.sol.orig
+++ b/contracts/ActivePool.sol
@@ -29,7 +29,7 @@ contract ActivePool is Ownable, CheckContract, IActivePool {

     string constant public NAME = "ActivePool";

-    bool public addressesSet = false;
+    bool public addressesSet;
     address public collateralConfigAddress;
     address public borrowerOperationsAddress;
     address public troveManagerAddress;

CollateralConfig.sol#L18, ActivePool.sol#L32, CommunityIssuance.sol#L21, LUSDToken.sol#L37

LUSDToken.sol, CollateralConfig.sol, CommunityIssuance.sol, ActivePool.sol