code-423n4 / 2022-06-nested-findings

0 stars 1 forks source link

QA Report #76

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Note: The README lists a bunch of QA/Gas reports from prior findings, but doesn't list the specific issues found therein. Having each warden look at each report and de-dupe is just like adding more files to the scope, and I think is a bit unfair. For the ones that the sponsor has explicitly listed I've still included them because the sponsor may end up finding them useful, especially after seeing the gas amounts involved, but have the lines with strike-through, so the sponsor and judge can ignore them if they wish

Summary

Low Risk Issues

Issue Instances
1 Unused/empty receive()/fallback() function 1
2 Missing checks for address(0x0) when assigning values to address state variables 2

Total: 3 instances over 2 issues

Non-critical Issues

Issue Instances
1 Missing initializer modifier on constructor 2
2 Missing initializer modifier 2
3 Adding a return statement when the function defines a named return variable, is redundant 4
4 public functions not called by the contract should be declared external instead 2
5 constants should be defined rather than using magic numbers 25
6 Expressions for constant values such as a call to keccak256(), should use immutable rather than constant 4
7 Constant redefined elsewhere 5
8 NatSpec is incomplete 10
9 Event is missing indexed fields 8
10 Not using the named return variables anywhere in the function is confusing 8

Total: 70 instances over 10 issues Total: 66 instances over 9 issues

Low Risk Issues

1. Unused/empty receive()/fallback() function

If the intention is for the Ether to be used, the function should call another function, otherwise it should revert (e.g. require(msg.sender == address(weth)))

There is 1 instance of this issue:

File: contracts/governance/TimelockControllerEmergency.sol   #1

113:      receive() external payable {}

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L113

2. Missing checks for address(0x0) when assigning values to address state variables

There are 2 instances of this issue:

File: contracts/operators/Yearn/YearnCurveVaultOperator.sol   #1

48:           eth = _eth;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Yearn/YearnCurveVaultOperator.sol#L48

File: contracts/abstracts/OwnableProxyDelegation.sol   #2

65:           _owner = newOwner;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/abstracts/OwnableProxyDelegation.sol#L65

Non-critical Issues

1. Missing initializer modifier on constructor

OpenZeppelin recommends that the initializer modifier be applied to constructors

There are 2 instances of this issue:

File: contracts/Withdrawer.sol   #1

16:       constructor(IWETH _weth) {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/Withdrawer.sol#L16

File: contracts/NestedFactory.sol   #2

57        constructor(
58            NestedAsset _nestedAsset,
59            NestedRecords _nestedRecords,
60            NestedReserve _reserve,
61            FeeSplitter _feeSplitter,
62            IWETH _weth,
63            address _operatorResolver,
64            Withdrawer _withdrawer
65:       ) MixinOperatorResolver(_operatorResolver) {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L57-L65

2. Missing initializer modifier

The contract extends ReentrancyGuard/ReentrancyGuardUpgradeable but does not use the initializer modifier anywhere

There are 2 instances of this issue:

File: contracts/Withdrawer.sol   #1

13:   contract Withdrawer is ReentrancyGuard {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/Withdrawer.sol#L13

File: contracts/NestedFactory.sol   #2

20:   contract NestedFactory is INestedFactory, ReentrancyGuard, OwnableProxyDelegation, MixinOperatorResolver {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L20

3. Adding a return statement when the function defines a named return variable, is redundant

There are 4 instances of this issue:

File: contracts/libraries/CurveHelpers/CurveHelpers.sol   #1

25:                   return amounts;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/libraries/CurveHelpers/CurveHelpers.sol#L25

File: contracts/libraries/CurveHelpers/CurveHelpers.sol   #2

45:                   return amounts;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/libraries/CurveHelpers/CurveHelpers.sol#L45

File: contracts/libraries/CurveHelpers/CurveHelpers.sol   #3

65:                   return amounts;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/libraries/CurveHelpers/CurveHelpers.sol#L65

File: contracts/libraries/CurveHelpers/CurveHelpers.sol   #4

89:                   return success;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/libraries/CurveHelpers/CurveHelpers.sol#L89

4. public functions not called by the contract should be declared external instead

Contracts are allowed to override their parents' functions and change the visibility from external to public.

There are 2 instances of this issue:

File: contracts/governance/OwnerProxy.sol   #1

16:       function execute(address _target, bytes memory _data) public payable onlyOwner returns (bytes memory response) {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/OwnerProxy.sol#L16

File: contracts/governance/TimelockControllerEmergency.sol   #2

295       function executeEmergency(
296           address target,
297           uint256 value,
298           bytes calldata data
299:      ) public payable onlyRole(EMERGENCY_ROLE) {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L295-L299

5. constants should be defined rather than using magic numbers

Even assembly can benefit from using readable constants instead of hex/numeric literals

There are 25 instances of this issue:

File: contracts/operators/Beefy/lp/BeefyZapBiswapLPVaultOperator.sol

/// @audit 1000
271:          require(reserveA > 1000, "BLVO: PAIR_RESERVE_TOO_LOW");

/// @audit 1000
272:          require(reserveB > 1000, "BLVO: PAIR_RESERVE_TOO_LOW");

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Beefy/lp/BeefyZapBiswapLPVaultOperator.sol#L271

File: contracts/operators/Beefy/lp/BeefyZapUniswapLPVaultOperator.sol

/// @audit 1000
269:          require(reserveA > 1000, "BLVO: PAIR_RESERVE_TOO_LOW");

/// @audit 1000
270:          require(reserveB > 1000, "BLVO: PAIR_RESERVE_TOO_LOW");

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Beefy/lp/BeefyZapUniswapLPVaultOperator.sol#L269

File: contracts/governance/OwnerProxy.sol

/// @audit 0x20
21:               let succeeded := delegatecall(sub(gas(), 5000), _target, add(_data, 0x20), mload(_data), 0, 0)

/// @audit 0x40
24:               response := mload(0x40)

/// @audit 0x40
25:               mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))

/// @audit 0x20
25:               mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))

/// @audit 0x1f
25:               mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))

/// @audit 0x1f
25:               mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))

/// @audit 0x20
27:               returndatacopy(add(response, 0x20), 0, size)

/// @audit 0x20
32:                   revert(add(response, 0x20), size)

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/OwnerProxy.sol#L21

File: contracts/governance/scripts/OperatorScripts.sol

/// @audit 0x20
59:               deployedAddress := create(0, add(bytecode, 0x20), mload(bytecode))

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/scripts/OperatorScripts.sol#L59

File: contracts/NestedFactory.sol

/// @audit 10000
161:          require(_entryFees <= 10000, "NF: FEES_OVERFLOW");

/// @audit 10000
169:          require(_exitFees <= 10000, "NF: FEES_OVERFLOW");

/// @audit 10000
264:          uint256 amountFees = (amountBought * exitFees) / 10000; // Exit Fees

/// @audit 10000
378:          feesAmount = (amountSpent * entryFees) / 10000; // Entry Fees

/// @audit 10000
443:              feesAmount = (amountBought * (_toReserve ? entryFees : exitFees)) / 10000;

/// @audit 10000
629:          uint256 feeAmount = (_amount * exitFees) / 10000; // Exit Fee

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L161

File: contracts/libraries/StakingLPVaultHelpers.sol

/// @audit 3
38:           } else if (poolCoinAmount == 3) {

/// @audit 3
70:           } else if (poolCoinAmount == 3) {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/libraries/StakingLPVaultHelpers.sol#L38

File: contracts/libraries/CurveHelpers/CurveHelpers.sol

/// @audit 3
41:       ) internal view returns (uint256[3] memory amounts) {

/// @audit 3
42:           for (uint256 i; i < 3; i++) {

/// @audit 4
61:       ) internal view returns (uint256[4] memory amounts) {

/// @audit 4
62:           for (uint256 i; i < 4; i++) {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/libraries/CurveHelpers/CurveHelpers.sol#L41

6. Expressions for constant values such as a call to keccak256(), should use immutable rather than constant

There are 4 instances of this issue:

File: contracts/governance/TimelockControllerEmergency.sol   #1

25:       bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE");

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L25

File: contracts/governance/TimelockControllerEmergency.sol   #2

26:       bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L26

File: contracts/governance/TimelockControllerEmergency.sol   #3

27:       bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L27

File: contracts/governance/TimelockControllerEmergency.sol   #4

28:       bytes32 public constant EMERGENCY_ROLE = keccak256("EMERGENCY_ROLE");

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L28

7. Constant redefined elsewhere

Consider defining in only one contract so that values cannot become out of sync when only one location is updated. A cheap way to store constants in a single location is to create an internal constant in a library. If the variable is a local cache of another contract's value, consider making the cache variable internal or private, which will require external users to query the contract with the source of truth, so that callers don't get out of sync.

There are 5 instances of this issue:

File: contracts/operators/Beefy/lp/BeefyZapBiswapLPVaultOperator.sol

/// @audit seen in contracts/operators/Beefy/BeefyVaultOperator.sol 
19:       BeefyVaultStorage public immutable operatorStorage;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Beefy/lp/BeefyZapBiswapLPVaultOperator.sol#L19

File: contracts/operators/Beefy/lp/BeefyZapUniswapLPVaultOperator.sol

/// @audit seen in contracts/operators/Beefy/lp/BeefyZapBiswapLPVaultOperator.sol 
19:       BeefyVaultStorage public immutable operatorStorage;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Beefy/lp/BeefyZapUniswapLPVaultOperator.sol#L19

File: contracts/operators/Yearn/YearnCurveVaultOperator.sol

/// @audit seen in contracts/operators/Beefy/lp/BeefyZapUniswapLPVaultOperator.sol 
20:       YearnVaultStorage public immutable operatorStorage;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Yearn/YearnCurveVaultOperator.sol#L20

File: contracts/abstracts/MixinOperatorResolver.sol

/// @audit seen in contracts/governance/scripts/OperatorScripts.sol 
17:       OperatorResolver public immutable resolver;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/abstracts/MixinOperatorResolver.sol#L17

File: contracts/NestedFactory.sol

/// @audit seen in contracts/Withdrawer.sol 
39:       IWETH public immutable weth;

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/NestedFactory.sol#L39

8. NatSpec is incomplete

There are 10 instances of this issue:

File: contracts/operators/Beefy/lp/BeefyZapBiswapLPVaultOperator.sol

/// @audit Missing: '@return'
230       /// @param path An array of the two paired token addresses
231       /// @param biswapRouter The uniswapV2 router to be used for swap and liquidity addition
232       function _swapAndAddLiquidity(
233           uint256 amount,
234           uint256 swapAmountIn,
235           address[] memory path,
236           IBiswapRouter02 biswapRouter
237:      ) private returns (uint256 mintedLpAmount) {

/// @audit Missing: '@param reserveA'
258       /// @dev Calculate the optimal amount of tokenA to swap to obtain
259       ///         the same market value of tokenB after the trade.
260       ///         This allows to add as many tokensA and tokensB as possible
261       ///         to the liquidity to minimize the remaining amount.
262       /// @param investmentA The total amount of tokenA to invest
263       /// @param pair The IBiswapPair to be used
264       function _getOptimalSwapAmount(
265           uint256 investmentA,
266           uint256 reserveA,
267           uint256 reserveB,
268           IBiswapRouter02 router,
269           IBiswapPair pair
270:      ) private view returns (uint256 swapAmount) {

/// @audit Missing: '@param reserveB'
258       /// @dev Calculate the optimal amount of tokenA to swap to obtain
259       ///         the same market value of tokenB after the trade.
260       ///         This allows to add as many tokensA and tokensB as possible
261       ///         to the liquidity to minimize the remaining amount.
262       /// @param investmentA The total amount of tokenA to invest
263       /// @param pair The IBiswapPair to be used
264       function _getOptimalSwapAmount(
265           uint256 investmentA,
266           uint256 reserveA,
267           uint256 reserveB,
268           IBiswapRouter02 router,
269           IBiswapPair pair
270:      ) private view returns (uint256 swapAmount) {

/// @audit Missing: '@param router'
258       /// @dev Calculate the optimal amount of tokenA to swap to obtain
259       ///         the same market value of tokenB after the trade.
260       ///         This allows to add as many tokensA and tokensB as possible
261       ///         to the liquidity to minimize the remaining amount.
262       /// @param investmentA The total amount of tokenA to invest
263       /// @param pair The IBiswapPair to be used
264       function _getOptimalSwapAmount(
265           uint256 investmentA,
266           uint256 reserveA,
267           uint256 reserveB,
268           IBiswapRouter02 router,
269           IBiswapPair pair
270:      ) private view returns (uint256 swapAmount) {

/// @audit Missing: '@return'
258       /// @dev Calculate the optimal amount of tokenA to swap to obtain
259       ///         the same market value of tokenB after the trade.
260       ///         This allows to add as many tokensA and tokensB as possible
261       ///         to the liquidity to minimize the remaining amount.
262       /// @param investmentA The total amount of tokenA to invest
263       /// @param pair The IBiswapPair to be used
264       function _getOptimalSwapAmount(
265           uint256 investmentA,
266           uint256 reserveA,
267           uint256 reserveB,
268           IBiswapRouter02 router,
269           IBiswapPair pair
270:      ) private view returns (uint256 swapAmount) {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Beefy/lp/BeefyZapBiswapLPVaultOperator.sol#L230-L237

File: contracts/operators/Beefy/lp/BeefyZapUniswapLPVaultOperator.sol

/// @audit Missing: '@return'
230       /// @param path An array of the two paired token addresses
231       /// @param uniswapRouter The uniswapV2 router to be used for swap and liquidity addition
232       function _swapAndAddLiquidity(
233           uint256 amount,
234           uint256 swapAmountIn,
235           address[] memory path,
236           IUniswapV2Router02 uniswapRouter
237:      ) private returns (uint256 mintedLpAmount) {

/// @audit Missing: '@param reserveA'
258       /// @dev Calculate the optimal amount of tokenA to swap to obtain
259       ///         the same market value of tokenB after the trade.
260       ///         This allows to add as many tokensA and tokensB as possible
261       ///         to the liquidity to minimize the remaining amount.
262       /// @param investmentA The total amount of tokenA to invest
263       function _getOptimalSwapAmount(
264           uint256 investmentA,
265           uint256 reserveA,
266           uint256 reserveB,
267           IUniswapV2Router02 router
268:      ) private pure returns (uint256 swapAmount) {

/// @audit Missing: '@param reserveB'
258       /// @dev Calculate the optimal amount of tokenA to swap to obtain
259       ///         the same market value of tokenB after the trade.
260       ///         This allows to add as many tokensA and tokensB as possible
261       ///         to the liquidity to minimize the remaining amount.
262       /// @param investmentA The total amount of tokenA to invest
263       function _getOptimalSwapAmount(
264           uint256 investmentA,
265           uint256 reserveA,
266           uint256 reserveB,
267           IUniswapV2Router02 router
268:      ) private pure returns (uint256 swapAmount) {

/// @audit Missing: '@param router'
258       /// @dev Calculate the optimal amount of tokenA to swap to obtain
259       ///         the same market value of tokenB after the trade.
260       ///         This allows to add as many tokensA and tokensB as possible
261       ///         to the liquidity to minimize the remaining amount.
262       /// @param investmentA The total amount of tokenA to invest
263       function _getOptimalSwapAmount(
264           uint256 investmentA,
265           uint256 reserveA,
266           uint256 reserveB,
267           IUniswapV2Router02 router
268:      ) private pure returns (uint256 swapAmount) {

/// @audit Missing: '@return'
258       /// @dev Calculate the optimal amount of tokenA to swap to obtain
259       ///         the same market value of tokenB after the trade.
260       ///         This allows to add as many tokensA and tokensB as possible
261       ///         to the liquidity to minimize the remaining amount.
262       /// @param investmentA The total amount of tokenA to invest
263       function _getOptimalSwapAmount(
264           uint256 investmentA,
265           uint256 reserveA,
266           uint256 reserveB,
267           IUniswapV2Router02 router
268:      ) private pure returns (uint256 swapAmount) {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Beefy/lp/BeefyZapUniswapLPVaultOperator.sol#L230-L237

9. Event is missing indexed fields

Each event should use three indexed fields if there are three or more fields

There are 8 instances of this issue:

File: contracts/operators/Beefy/BeefyVaultStorage.sol

12:       event VaultAdded(address vault, address tokenOrZapper);

16:       event VaultRemoved(address vault);

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Beefy/BeefyVaultStorage.sol#L12

File: contracts/operators/Yearn/YearnVaultStorage.sol

17:       event VaultAdded(address vault, CurvePool pool);

21:       event VaultRemoved(address vault);

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/operators/Yearn/YearnVaultStorage.sol#L17

File: contracts/governance/TimelockControllerEmergency.sol

37        event CallScheduled(
38            bytes32 indexed id,
39            uint256 indexed index,
40            address target,
41            uint256 value,
42            bytes data,
43            bytes32 predecessor,
44            uint256 delay
45:       );

50:       event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);

60:       event MinDelayChange(uint256 oldDuration, uint256 newDuration);

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L37-L45

File: contracts/abstracts/MixinOperatorResolver.sol

14:       event CacheUpdated(bytes32 name, IOperatorResolver.Operator destination);

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/abstracts/MixinOperatorResolver.sol#L14

10. Not using the named return variables anywhere in the function is confusing

Consider changing the variable to be an unnamed one

There are 8 instances of this issue:

File: contracts/governance/TimelockControllerEmergency.sol

/// @audit pending
119:      function isOperation(bytes32 id) public view virtual returns (bool pending) {

/// @audit pending
126:      function isOperationPending(bytes32 id) public view virtual returns (bool pending) {

/// @audit ready
133:      function isOperationReady(bytes32 id) public view virtual returns (bool ready) {

/// @audit done
141:      function isOperationDone(bytes32 id) public view virtual returns (bool done) {

/// @audit timestamp
149:      function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp) {

/// @audit duration
158:      function getMinDelay() public view virtual returns (uint256 duration) {

/// @audit hash
166       function hashOperation(
167           address target,
168           uint256 value,
169           bytes calldata data,
170           bytes32 predecessor,
171           bytes32 salt
172:      ) public pure virtual returns (bytes32 hash) {

/// @audit hash
180       function hashOperationBatch(
181           address[] calldata targets,
182           uint256[] calldata values,
183           bytes[] calldata datas,
184           bytes32 predecessor,
185           bytes32 salt
186:      ) public pure virtual returns (bytes32 hash) {

https://github.com/code-423n4/2022-06-nested/blob/b4a153c943d54755711a2f7b80cbbf3a5bb49d76/contracts/governance/TimelockControllerEmergency.sol#L119

obatirou commented 2 years ago

1. Missing initializer modifier on constructor (disputed)

We do not understand the problem

2. Missing initializer modifier (disputed)

We do not understand the problem

7. Constant redefined elsewhere (disputed)

If in a lib, it will cost more to retrieve the data It is less gas efficient, hence we prefer in contract byte code

Yashiru commented 2 years ago

10. Not using the named return variables anywhere in the function is confusing (Acknowledged)

We prefer to name our return variables even if they are not used, this allows to add an additional information about the nature of the returned variable by giving it a name.

obatirou commented 2 years ago

4. public functions not called by the contract should be declared external instead (confirmed)

obatirou commented 2 years ago

3. Adding a return statement when the function defines a named return variable, is redundant (duplicated)

Duplicate point 3 of qa report https://github.com/code-423n4/2022-06-nested-findings/issues/61

Yashiru commented 2 years ago

5. constants should be defined rather than using magic numbers (Confirmed)

Quality assurance confirmed

Missing occurances (finded in #61):

obatirou commented 2 years ago

9. Event is missing indexed fields (duplicate)

Duplicate from https://github.com/code-423n4/2022-06-nested-findings/issues/11#issuecomment-1165618378

maximebrugel commented 2 years ago

1. Unused/empty receive()/fallback() function (Disputed)

We want to be able to receive ether this way. But if neither a receive Ether nor a payable fallback function is present, the contract cannot receive Ether through regular transactions and throws an exception.

obatirou commented 2 years ago

8. NatSpec is incomplete (duplicate)

https://github.com/code-423n4/2022-06-nested-findings/issues/84#issuecomment-1165712399

jack-the-pug commented 2 years ago

L-1: Unused/empty receive()/fallback() function

This is invalids per comment pointed out: Contract might receive/hold ETH as part of the maintenance process.

L-2: Missing checks for address(0x0) when assigning values to address state variables

Non-critical.

N-1: Missing initializer modifier on constructor

Invalid, this is not an upgradeable contract.

N-2: Missing initializer modifier

Invalid. Not upgradeable contracts.

N-3: Adding a return statement when the function defines a named return variable, is redundant

Valid, but prefer not making changes, redundant return is better for readability.

N-4: public functions not called by the contract should be declared external instead

Valid, no need to make changes.

N-5: constants should be defined rather than using magic numbers

Valid, best practices, make changes when you see fit.

N-6: Expressions for constant values such as a call to keccak256(), should use immutable rather than constant

Invalid.

N-7: Constant redefined elsewhere

Seems invalid.

N-8: NatSpec is incomplete

Non-critical.

N-9: Event is missing indexed fields

Non-critical.

N-10: Not using the named return variables anywhere in the function is confusing

Seems fine with me, not sure why this is an issue.