Indexed event parameters are stored in the topics part of the log instead of the data part, which allows for faster indexing/querying because of the use of bloom filters for topics. Up to three parameters in every event can be indexed. While this costs a little extra gas, doing so allows for faster and more efficient/effective event lookups.
Add indexed parameter especially for address parameters where their faster lookup for security monitoring issues can be a good trade-off for the extra gas consumed.
Low Risk
L-01: initialize functions can be frontrun
Description
The initialize function used to initialize important contract state can be called by anyone.
The attacker can initialize the contract before the legitimate deployer, hoping that the victim continues to use the same contract.
In the best case for the victim, they notice it and have to redeploy their contract costing gas.
Use the constructor to initialize non-proxied contracts.
For initializing proxy (upgradable) contracts deploy contracts using a factory contract that immediately calls initialize after deployment or make sure to call it immediately after deployment and verify the transaction succeeded.
L-02: Events not emitted for important state changes
Description
When changing state variables events are not emitted. Emitting events allows monitoring activities with off-chain monitoring tools.
Zero-address checks are a best-practice for input validation of critical address parameters. While the codebase applies this to most most cases, there are many places where this is missing in constructors and setters.
Impact: Accidental use of zero-addresses may result in exceptions, burn fees/tokens or force redeployment of contracts.
QA Report
Table of Contents
initialize
functions can be frontrunDeposit
event not emitted if ETH is deposited@TODOs
left in the codeNon-Critical Findings
NC-01: Events not indexed
Description
Indexed event parameters are stored in the topics part of the log instead of the data part, which allows for faster indexing/querying because of the use of bloom filters for topics. Up to three parameters in every event can be indexed. While this costs a little extra gas, doing so allows for faster and more efficient/effective event lookups.
Findings
strategies/ConvexStrategyBase.sol#L65\ strategies/ConvexStrategyBase.sol#L70\ strategies/ConvexStrategyBase.sol#L71\ strategies/ConvexStrategyBase.sol#L72\ strategies/StrategySwapper.sol#L35\ strategies/StrategySwapper.sol#L36\ SwapperRegistry.sol#L17\ SwapperRegistry.sol#L18\ SwapperRegistry.sol#L19\ CvxCrvRewardsLocker.sol#L47\ actions/topup/TopUpActionFeeHandler.sol#L37\ tokenomics/Minter.sol#L57\ pool/PoolFactory.sol#L75\ pool/PoolFactory.sol#L76
Recommended mitigation steps
Add indexed parameter especially for address parameters where their faster lookup for security monitoring issues can be a good trade-off for the extra gas consumed.
Low Risk
L-01:
initialize
functions can be frontrunDescription
The
initialize
function used to initialize important contract state can be called by anyone.The attacker can initialize the contract before the legitimate deployer, hoping that the victim continues to use the same contract. In the best case for the victim, they notice it and have to redeploy their contract costing gas.
Findings
StakerVault.sol#L65\ AddressProvider.sol#L53\ LpToken.sol#L33\ vault/Erc20Vault.sol#L17\ vault/EthVault.sol#L20
Recommended mitigation steps
Use the constructor to initialize non-proxied contracts.
For initializing proxy (upgradable) contracts deploy contracts using a factory contract that immediately calls initialize after deployment or make sure to call it immediately after deployment and verify the transaction succeeded.
L-02: Events not emitted for important state changes
Description
When changing state variables events are not emitted. Emitting events allows monitoring activities with off-chain monitoring tools.
Findings
oracles/ChainlinkOracleProvider.sol#L42
Recommended mitigation steps
Emit events for state variable changes.
L-03:
Deposit
event not emitted if ETH is depositedDescription
A
Deposit
event is emitted if a token is deposited but if ETH (token == address(0)
) is deposited, no event is emitted.Findings
vault/VaultReserve.sol#L52
Recommended mitigation steps
Emit
Deposit
event for ETH deposits.L-04: Zero-address checks are missing
Description
Zero-address checks are a best-practice for input validation of critical address parameters. While the codebase applies this to most most cases, there are many places where this is missing in constructors and setters.
Impact: Accidental use of zero-addresses may result in exceptions, burn fees/tokens or force redeployment of contracts.
Findings
vault/Vault.sol#L92
Recommended mitigation steps
Add zero-address checks, e.g.:
L-05: Open
@TODOs
left in the codeDescription
There are several open TODOs left in the code.
Findings
strategies/ConvexStrategyBase.sol#L4\ strategies/ConvexStrategyBase.sol#L5\ actions/topup/TopUpAction.sol#L713
Recommended mitigation steps
Check, fix and remove the todos before it is deployed in production
L-06: Possible divide by zero
Description
The function
getPriceUSD()
in oracles/ChainlinkOracleProvider.sol allows the price of an asset to be 0 due to following check:Therefore, wherever
getPriceUSD()
is used as the divisor, in certain cases it could lead to a divide by zero error reverting the transaction.Findings
oracles/OracleProviderExtensions.sol#L15\ oracles/ChainlinkOracleProvider.sol#L47
Recommended mitigation steps
Consider only allowing the price to be
> 0
ingetPriceUSD()
:or check the divisor before using.