QA Report #98
Labels
bug
Something isn't working
QA (Quality Assurance)
Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
sponsor acknowledged
Technically the issue is correct, but we're not going to resolve it for XYZ reasons
valid
Overview
Table of Contents
initialize()
functionsMyStrategy.sol
is an upgradeable contract that is missing a__gap[50]
storage variable to allow for new storage variables in later versionsinitialize()
is front-runnable inMyStrategy.sol
require()
should be used for checking error conditions on inputs and return values whileassert()
should be used for invariant checkingLow Risk Issues
1. Add constructor initializers
As per OpenZeppelin’s (OZ) recommendation, “The guidelines are now to make it impossible for anyone to run
initialize
on an implementation contract, by adding an empty constructor with theinitializer
modifier. So the implementation contract gets initialized automatically upon deployment.”Note that this behaviour is also incorporated the OZ Wizard since the UUPS vulnerability discovery: “Additionally, we modified the code generated by the Wizard 19 to include a constructor that automatically initializes the implementation when deployed.”
Furthermore, this thwarts any attempts to frontrun the initialization tx of these contracts:
2. Uninitialized Upgradeable contract
Similar issue in the past: here
Upgradeable dependencies should be initialized.
While not causing any harm at the moment, suppose OZ someday decide to upgrade this contract and the sponsor uses the new version: it is possible that the contract will not work anymore.
Consider calling the
init()
here:File: MyStrategy.sol 56: function initialize(address _vault) public initializer { 57: assert(IVault(_vault).token() == address(AURA)); 58: 59: __BaseStrategy_init(_vault); + 59: __ReentrancyGuard_init(); //@audit ReentrancyGuardUpgradeable 60: 61: want = address(AURA); 62: 63: /// @dev do one off approvals here 64: // Permissions for Locker 65: AURA.safeApprove(address(LOCKER), type(uint256).max); 66: 67: AURABAL.safeApprove(address(BALANCER_VAULT), type(uint256).max); 68: WETH.safeApprove(address(BALANCER_VAULT), type(uint256).max); 69: 70: // Set Safe Defaults 71: withdrawalSafetyCheck = true; 72: 73: // Process locks on reinvest is best left false as gov can figure out if they need to save that gas 74: }
3. Deprecated safeApprove() function
Deprecated
Using this deprecated function can lead to unintended reverts and potentially the locking of funds. A deeper discussion on the deprecation of this function is in OZ issue #2219 (OpenZeppelin/openzeppelin-contracts#2219). The OpenZeppelin ERC20
safeApprove()
function has been deprecated, as seen in the comments of the OpenZeppelin code.As recommended by the OpenZeppelin comment, consider replacing
safeApprove()
withsafeIncreaseAllowance()
orsafeDecreaseAllowance()
instead:4. Lack of event emission after critical
initialize()
functionsSimilar issue in the past: here
To record the init parameters for off-chain monitoring and transparency reasons, please consider emitting an event after the
initialize()
functions:5.
MyStrategy.sol
is an upgradeable contract that is missing a__gap[50]
storage variable to allow for new storage variables in later versionsSee 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.
6. Events not indexed
7.
initialize()
is front-runnable inMyStrategy.sol
Consider adding some access control to them or deploying atomically or using constructor
initializer
Non-Critical Issues
1.
require()
should be used for checking error conditions on inputs and return values whileassert()
should be used for invariant checkingProperly functioning code should never reach a failing assert statement, unless there is a bug in your contract you should fix. Here, I believe the assert should be a require or a revert:
As the Solidity version is < 0.8.* the remaining gas would be fully used in case of failure.
2. Typos
3. Open TODOS
Consider resolving the TODOs before deploying.
The text was updated successfully, but these errors were encountered: