code-423n4 / 2022-03-prepo-findings

0 stars 0 forks source link

QA Report #104

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Low-impact Issues

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

  1. File: contracts/core/PrePOMarket.sol (line 68)
        _treasury = _governance;
  2. File: contracts/core/PrePOMarket.sol (line 176)
        _treasury = _newTreasury;
  3. File: contracts/core/SingleStrategyController.sol (line 75)
        _vault = _newVault;
  4. File: contracts/core/WithdrawHook.sol (line 30)
        _vault = _newVault;
  5. File: contracts/core/DepositHook.sol (line 40)
        _vault = _newVault;
  6. File: contracts/core/Collateral.sol (line 49)
        _treasury = _newTreasury;

abi.encodePacked() should not be used with dynamic types when passing the result to a hash function such as keccak256()

Use abi.encode() instead which will pad items to 32 bytes, which will prevent hash collisions (e.g. abi.encodePacked(0x123,0x456) => 0x123456 => abi.encodePacked(0x1,0x23456), but abi.encode(0x123,0x456) => 0x0...1230...456). If there is only one argument to abi.encodePacked() it can often be cast to bytes() or bytes32() instead.

  1. File: contracts/core/PrePOMarketFactory.sol (line 61)
        bytes32 _salt = keccak256(abi.encodePacked(_longToken, _shortToken));
  2. File: contracts/core/AccountAccessController.sol (line 66)
        bytes32 _leaf = keccak256(abi.encodePacked(msg.sender));

Upgradeable contract is missing a __gap[50] storage variable to allow for new storage variables in later versions

See this link for a description of this storage variable. While some contracts may not currently be sub-classed, adding the variable now protects against forgetting to add it in the future.

  1. File: contracts/core/PrePOMarketFactory.sol (lines 12-15)
    contract PrePOMarketFactory is
    IPrePOMarketFactory,
    OwnableUpgradeable,
    ReentrancyGuardUpgradeable
  2. File: contracts/core/Collateral.sol (lines 13-17)
    contract Collateral is
    ICollateral,
    ERC20Upgradeable,
    OwnableUpgradeable,
    ReentrancyGuardUpgradeable

Non-critical Issues

Multiple address mappings can be combined into a single mapping of an address to a struct, where appropriate

  1. File: contracts/core/CollateralDepositRecord.sol (lines 11-12)
    mapping(address => uint256) private _accountToNetDeposit;
    mapping(address => bool) private _allowedHooks;

Large multiples of ten should use scientific notation (e.g. 1e6) rather than decimal literals (e.g. 1000000), for readability

  1. File: contracts/core/PrePOMarket.sol (line 32)
    uint256 private constant FEE_DENOMINATOR = 1000000;
  2. File: contracts/core/Collateral.sol (line 35)
    uint256 private constant FEE_DENOMINATOR = 1000000;

Use a more recent version of solidity

Use a solidity version of at least 0.8.12 to get string.concat() to be used instead of abi.encodePacked(<str>,<str>)

  1. File: contracts/core/PrePOMarketFactory.sol (line 2)
    pragma solidity =0.8.7;
  2. File: contracts/core/AccountAccessController.sol (line 2)
    pragma solidity =0.8.7;

Non-exploitable reentrancies

Follow the best-practice of the Checks-Effects-Interactions pattern Reentrancy in Collateral.deposit(uint256) (contracts/core/Collateral.sol#52-93): External calls:

Reentrancy in PrePOMarketFactory.createMarket(string,string,address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256) (contracts/core/PrePOMarketFactory.sol#42-82): External calls:

ramenforbreakfast commented 2 years ago

Low-impact Missing zero address checks is duplicate of #35 abi.encodePacked() is a valid suggestion upgradeable contract gap would add additional complexity, we did not explicitly design these contracts to be inherited from.

Non-critical Multiple address mappings is not valid, the address keys for each mapping refer to different values. Large multiples of ten this is a style choice (severity 0) that we will consider Use a more recent version of solidity - duplicate of #103 Non-exploitable reentrancies - I do not think this is worth considering. We also already use nonReentrant for this purpose.

I will maintain the severity of this issue due to the valid abi.encodePacked suggestion.