Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gas Optimizations #33

Open
code423n4 opened this issue May 13, 2022 · 1 comment
Open

Gas Optimizations #33

code423n4 opened this issue May 13, 2022 · 1 comment
Labels
bug Something isn't working duplicate This issue or pull request already exists G (Gas Optimization)

Comments

@code423n4
Copy link
Contributor

code423n4 commented May 13, 2022

Summary

Gas Optimizations

Issue Instances
1 Remove or replace unused state variables 1
2 Multiple address mappings can be combined into a single mapping of an address to a struct, where appropriate 8
3 State variables only set in the constructor should be declared immutable 6
4 State variables can be packed into fewer storage slots 3
5 Using calldata instead of memory for read-only arguments in external functions saves gas 6
6 State variables should be cached in stack variables rather than re-reading them from storage 60
7 <x> += <y> costs more gas than <x> = <x> + <y> for state variables 5
8 internal functions only called once can be inlined to save gas 4
9 <array>.length should not be looked up in every loop of a for-loop 13
10 ++i/i++ should be unchecked{++i}/unchecked{i++} when it is not possible for them to overflow, as is the case when used in for- and while-loops 13
11 require()/revert() strings longer than 32 bytes cost extra gas 1
12 keccak256() should only need to be called on a specific string literal once 1
13 Not using the named return variables when a function returns, wastes deployment gas 10
14 Using bools for storage incurs overhead 18
15 Use a more recent version of solidity 28
16 Using > 0 costs more gas than != 0 when used on a uint in a require() statement 23
17 It costs more gas to initialize variables to zero than to let the default of zero be applied 26
18 ++i costs less gas than i++, especially when it's used in for-loops (--i/i-- too) 24
19 Splitting require() statements that use && saves gas 15
20 Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead 99
21 abi.encode() is less efficient than abi.encodePacked() 2
22 Using private rather than public for constants, saves gas 30
23 Don't compare boolean expressions to boolean literals 9
24 Don't use SafeMath once the solidity version is 0.8.0 or greater 2
25 Duplicated require()/revert() checks should be refactored to a modifier or function 32
26 Multiplication/division by two should use bit shifting 5
27 Stack variable used as a cheaper cache for a state variable is only used once 1
28 require() or revert() statements that check input arguments should be at the top of the function 11
29 Empty blocks should be removed or emit something 6
30 Use custom errors rather than revert()/require() strings to save deployment gas 101
31 Functions guaranteed to revert when called by normal users can be marked payable 37
32 public functions not called by the contract should be declared external instead 18

Total: 618 instances over 32 issues

Gas Optimizations

1. Remove or replace unused state variables

Saves a storage slot. If the variable is assigned a non-zero value, saves Gsset (20000 gas). If it's assigned a zero value, saves Gsreset (2900 gas). If the variable remains unassigned, there is no gas savings unless the variable is public, in which case the compiler-generated non-payable getter deployment cost is saved. If the state variable is overriding an interface's public function, mark the variable as constant or immutable so that it does not use a storage slot

There is 1 instance of this issue:

File: convex-platform/contracts/contracts/RewardFactory.sol   #1

28:       mapping(address => uint256[]) public rewardActiveList;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/RewardFactory.sol#L28

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

Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot

There are 8 instances of this issue:

File: contracts/ExtraRewardsDistributor.sol

20        mapping(address => mapping(uint256 => uint256)) public rewardData;
21        // token -> epochList
22        mapping(address => uint256[]) public rewardEpochs;
23        // token -> account -> last claimed epoch index
24:       mapping(address => mapping(address => uint256)) public userClaims;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ExtraRewardsDistributor.sol#L20-L24

File: contracts/AuraBalRewardPool.sol

44        mapping(address => uint256) public userRewardPerTokenPaid;
45        mapping(address => uint256) public rewards;
46:       mapping(address => uint256) private _balances;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraBalRewardPool.sol#L44-L46

File: contracts/AuraLocker.sol

91        mapping(address => Balances) public balances;
92        mapping(address => LockedBalance[]) public userLocks;
93    
94        // Voting
95        //     Stored delegations
96        mapping(address => address) private _delegates;
97        //     Checkpointed votes
98        mapping(address => DelegateeCheckpoint[]) private _checkpointedVotes;
99        //     Delegatee balances (user -> unlock timestamp -> amount)
100:      mapping(address => mapping(uint256 => uint256)) public delegateeUnlocks;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L91-L100

File: contracts/AuraVestedEscrow.sol

35        mapping(address => uint256) public totalLocked;
36:       mapping(address => uint256) public totalClaimed;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L35-L36

File: convex-platform/contracts/contracts/VoterProxy.sol

35        mapping (address => bool) private stashPool;
36:       mapping (address => bool) private protectedTokens;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VoterProxy.sol#L35-L36

File: convex-platform/contracts/contracts/BaseRewardPool.sol

80        mapping(address => uint256) public userRewardPerTokenPaid;
81        mapping(address => uint256) public rewards;
82:       mapping(address => uint256) private _balances;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L80-L82

File: convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol

97        mapping(address => uint256) public userRewardPerTokenPaid;
98:       mapping(address => uint256) public rewards;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol#L97-L98

File: convex-platform/contracts/contracts/RewardFactory.sol

27        mapping (address => bool) private rewardAccess;
28:       mapping(address => uint256[]) public rewardActiveList;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/RewardFactory.sol#L27-L28

3. State variables only set in the constructor should be declared immutable

Avoids a Gsset (20000 gas) in the constructor, and replaces each Gwarmacces (100 gas) with a PUSH32 (3 gas).

There are 6 instances of this issue:

File: contracts/AuraLocker.sol

117:      string private _name;

118:      string private _symbol;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L117

File: contracts/ClaimFeesHelper.sol

23:       IFeeDistributor public feeDistro;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ClaimFeesHelper.sol#L23

File: convex-platform/contracts/contracts/TokenFactory.sol

21:       string public namePostfix;

22:       string public symbolPrefix;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/TokenFactory.sol#L21

File: convex-platform/contracts/contracts/BaseRewardPool4626.sol

26:       address public override asset;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool4626.sol#L26

4. State variables can be packed into fewer storage slots

If variables occupying the same slot are both written the same function or by the constructor, avoids a separate Gsset (20000 gas). Reads of the variables can also be cheaper

There are 3 instances of this issue:

File: convex-platform/contracts/contracts/CrvDepositor.sol   #1

/// @audit Variable ordering with 5 slots instead of the current 6:
 uint256(32):lockIncentive, uint256(32):incentiveCrv, uint256(32):unlockTime, address(20):feeManager, bool(1):cooldown, address(20):daoOperator
29:       uint256 public lockIncentive = 10; //incentive to users who spend gas to lock crvBpt

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/CrvDepositor.sol#L29

File: convex-platform/contracts/contracts/ExtraRewardStashV3.sol   #2

/// @audit Variable ordering with 9 slots instead of the current 10:
 uint256(32):pid, mapping(32):historicalRewards, mapping(32):tokenInfo, address[](32):tokenList, address(20):operator, bool(1):hasRedirected, bool(1):hasCurveRewards, address(20):staker, address(20):gauge, address(20):rewardFactory, address(20):rewardHook
33:       uint256 public pid;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L33

File: convex-platform/contracts/contracts/Booster.sol   #3

/// @audit Variable ordering with 18 slots instead of the current 19:
 uint256(32):lockIncentive, uint256(32):stakerIncentive, uint256(32):earmarkIncentive, uint256(32):platformFee, mapping(32):feeTokens, user-defined[](32):poolInfo, mapping(32):gaugeMap, address(20):owner, bool(1):isShutdown, address(20):feeManager, address(20):poolManager, address(20):rewardFactory, address(20):stashFactory, address(20):tokenFactory, address(20):rewardArbitrator, address(20):voteDelegate, address(20):treasury, address(20):stakerRewards, address(20):lockRewards
26:       uint256 public lockIncentive = 825; //incentive to crv stakers

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L26

5. Using calldata instead of memory for read-only arguments in external functions saves gas

When a function with a memory array is called externally, the abi.decode() step has to use a for-loop to copy each index of the calldata to the memory index. Each iteration of this for-loop costs at least 60 gas (i.e. 60 * <mem_array>.length). Using calldata directly, obliviates the need for such a loop in the contract code and runtime execution. Structs have the same overhead as an array of length one

There are 6 instances of this issue:

File: contracts/Interfaces.sol

17:       function getTimeWeightedAverage(OracleAverageQuery[] memory queries)

79:           JoinPoolRequest memory request

83:           SingleSwap memory singleSwap,

84:           FundManagement memory funds,

93:           ExitPoolRequest memory request

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/Interfaces.sol#L17

File: convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol

68:       function setUsedAddress(address[] memory usedList) external onlyOwner{

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol#L68

6. State variables should be cached in stack variables rather than re-reading them from storage

The instances below point to the second+ access of a state variable within a function. Caching will replace each Gwarmaccess (100 gas) with a much cheaper stack read.
Less obvious fixes/optimizations include having local storage variables of mappings within state variable mappings or mappings within state variable structs, having local storage variables of structs within mappings, having local memory caches of state variable structs, or having local caches of state variable contracts/addresses.

There are 60 instances of this issue:

File: contracts/ExtraRewardsDistributor.sol

/// @audit rewardEpochs
74:               require(len == 0 || rewardEpochs[_token][len - 1] < _epoch, "Cannot backdate to this epoch");

/// @audit rewardEpochs
102:          if (len == 0 || rewardEpochs[_token][len - 1] < _epoch) {

/// @audit rewardEpochs
103:              rewardEpochs[_token].push(_epoch);

/// @audit rewardEpochs
235:              if (rewardEpochs[_token][i] < latestEpoch) {

/// @audit rewardEpochs
236:                  claimableTokens += _claimableRewards(_account, _token, rewardEpochs[_token][i]);

/// @audit userClaims
175:          userClaims[_token][msg.sender] = _index + 1;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ExtraRewardsDistributor.sol#L74

File: contracts/AuraMerkleDrop.sol

/// @audit dao
100:          aura.safeTransfer(dao, amt);

/// @audit merkleRoot
126:          require(MerkleProof.verify(_proof, merkleRoot, leaf), "invalid proof");

/// @audit auraLocker
132:              aura.safeApprove(address(auraLocker), _amount);

/// @audit auraLocker
133:              auraLocker.lock(msg.sender, _amount);

/// @audit startTime
70:           expiryTime = startTime + _expiresAfter;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L100

File: contracts/AuraLocker.sol

/// @audit rewardData
199:          rewardData[_rewardsToken].lastUpdateTime = uint32(block.timestamp);

/// @audit rewardData
200:          rewardData[_rewardsToken].periodFinish = uint32(block.timestamp);

/// @audit lockedSupply
812:                      .div(lockedSupply)

/// @audit userLocks
278:          if (idx == 0 || userLocks[_account][idx - 1].unlockTime < unlockTime) {

/// @audit kickRewardPerEpoch
422:                      uint256 rRate = AuraMath.min(kickRewardPerEpoch.mul(epochsover + 1), denominator);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L199

File: contracts/ClaimFeesHelper.sol

/// @audit feeDistro
48:           feeDistro.claimToken(voterProxy, _token);

/// @audit feeDistro
52:               feeDistro.claimToken(voterProxy, _token);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ClaimFeesHelper.sol#L48

File: contracts/AuraStakingProxy.sol

/// @audit keeper
172:              require(msg.sender == keeper, "!auth");

/// @audit crvDepositorWrapper
148:          IERC20(crv).safeApprove(crvDepositorWrapper, type(uint256).max);

/// @audit crvDepositorWrapper
179:              ICrvDepositor(crvDepositorWrapper).deposit(crvBal, minOut, true, address(0));

/// @audit rewards
151:          IERC20(cvxCrv).safeApprove(rewards, type(uint256).max);

/// @audit rewards
216:              _token.safeApprove(rewards, type(uint256).max);

/// @audit rewards
219:              IAuraLocker(rewards).notifyRewardAmount(address(_token), bal);

/// @audit pendingOwner
119:          owner = pendingOwner;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraStakingProxy.sol#L172

File: contracts/AuraVestedEscrow.sol

/// @audit admin
123:          rewardToken.safeTransfer(admin, delta);

/// @audit auraLocker
186:              rewardToken.safeApprove(address(auraLocker), claimable);

/// @audit auraLocker
187:              auraLocker.lock(_recipient, claimable);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L123

File: convex-platform/contracts/contracts/StashFactoryV2.sol

/// @audit v1Implementation
68:               address stash = IProxyFactory(proxyFactory).clone(v1Implementation);

/// @audit v2Implementation
75:               address stash = IProxyFactory(proxyFactory).clone(v2Implementation);

/// @audit v3Implementation
61:               address stash = IProxyFactory(proxyFactory).clone(v3Implementation);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/StashFactoryV2.sol#L68

File: convex-platform/contracts/contracts/CrvDepositor.sol

/// @audit incentiveCrv
146:              ITokenMinter(minter).mint(msg.sender,incentiveCrv);

/// @audit incentiveCrv
177:                  _amount = _amount.add(incentiveCrv);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/CrvDepositor.sol#L146

File: convex-platform/contracts/contracts/VoterProxy.sol

/// @audit rewardDeposit
194:          _asset.safeApprove(rewardDeposit, balance);

/// @audit rewardDeposit
195:          IRewardDeposit(rewardDeposit).addReward(address(_asset), balance);

/// @audit operator
107:          require(operator == address(0) || IDeposit(operator).isShutdown() == true, "needs shutdown");

/// @audit operator
311:              IERC20(crv).safeTransfer(operator, _balance);

/// @audit operator
337:          IERC20(_token).safeTransfer(operator, _balance);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VoterProxy.sol#L194

File: convex-platform/contracts/contracts/BoosterOwner.sol

/// @audit owner
99:           emit AcceptedOwnership(owner);

/// @audit pendingowner
97:           owner = pendingowner;

/// @audit forceTimestamp
165:          emit ShutdownStarted(forceTimestamp);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BoosterOwner.sol#L99

File: convex-platform/contracts/contracts/ExtraRewardStashV3.sol

/// @audit pid
111:              IDeposit(operator).claimRewards(pid,gauge);

/// @audit operator
104:              IDeposit(operator).setGaugeRedirect(pid);

/// @audit operator
111:              IDeposit(operator).claimRewards(pid,gauge);

/// @audit operator
209:                      IERC20(token).safeTransfer(operator, amount);

/// @audit rewardHook
116:              try IRewardHook(rewardHook).onRewardClaim(){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L111

File: convex-platform/contracts/contracts/BaseRewardPool.sol

/// @audit periodFinish
336:          uint256 elapsedTime = block.timestamp.sub(periodFinish.sub(duration));

/// @audit periodFinish
359:              uint256 remaining = periodFinish.sub(block.timestamp);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L336

File: convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol

/// @audit periodFinish
224:          uint256 elapsedTime = block.timestamp.sub(periodFinish.sub(duration));

/// @audit periodFinish
244:              uint256 remaining = periodFinish.sub(block.timestamp);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol#L224

File: convex-platform/contracts/contracts/BaseRewardPool4626.sol

/// @audit asset
40:           IERC20(asset).safeApprove(operator_, type(uint256).max);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool4626.sol#L40

File: convex-platform/contracts/contracts/Booster.sol

/// @audit platformFee
604:                  uint256 _platform = crvBal.mul(platformFee).div(FEE_DENOMINATOR);

/// @audit rewardFactory
238:                  address rewards = IRewardFactory(rewardFactory).CreateTokenRewards(_feeToken, lockRewards, address(this));

/// @audit rewardFactory
345:              IRewardFactory(rewardFactory).setAccess(stash,true);

/// @audit treasury
606:                  IERC20(crv).safeTransfer(treasury, _platform);

/// @audit lockRewards
232:                      rewards: lockRewards,

/// @audit lockRewards
235:                  emit FeeInfoUpdated(_feeDistro, lockRewards, crv);

/// @audit lockRewards
238:                  address rewards = IRewardFactory(rewardFactory).CreateTokenRewards(_feeToken, lockRewards, address(this));

/// @audit lockRewards
622:              IRewards(lockRewards).queueNewRewards(_lockIncentive);

/// @audit poolInfo
328:          poolInfo.push(

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L604

7. <x> += <y> costs more gas than <x> = <x> + <y> for state variables

There are 5 instances of this issue:

File: contracts/AuraMerkleDrop.sol

137:              pendingPenalty += penalty;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L137

File: contracts/AuraBalRewardPool.sol

184:                  pendingPenalty += penalty;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraBalRewardPool.sol#L184

File: contracts/AuraLocker.sol

363:          lockedSupply -= amt;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L363

File: contracts/Aura.sol

130:          minterMinted += _amount;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/Aura.sol#L130

File: contracts/AuraVestedEscrow.sol

66:           require(totalTime >= 16 weeks, "!short");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L66

8. internal functions only called once can be inlined to save gas

Not inlining costs 20 to 40 gas because of two extra JUMP instructions and additional stack operations needed for function calls.

There are 4 instances of this issue:

File: contracts/AuraClaimZap.sol   #1

171       function _claimExtras( // solhint-disable-line 
172           uint256 depositCrvMaxAmount,
173           uint256 minAmountOut,
174           uint256 depositCvxMaxAmount,
175           uint256 removeCrvBalance,
176           uint256 removeCvxBalance,
177:          uint256 options

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraClaimZap.sol#L171-L177

File: convex-platform/contracts/contracts/VoterProxy.sol   #2

230:      function _withdrawSome(address _gauge, uint256 _amount) internal returns (uint256) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VoterProxy.sol#L230

File: convex-platform/contracts/contracts/ExtraRewardStashV3.sol   #3

124       function checkForNewRewardTokens() internal {
125:          for(uint256 i = 0; i < maxRewards; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L124-L125

File: convex-platform/contracts/contracts/Booster.sol   #4

572:      function _earmarkRewards(uint256 _pid) internal {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L572

9. <array>.length should not be looked up in every loop of a for-loop

The overheads outlined below are PER LOOP, excluding the first loop

  • storage arrays incur a Gwarmaccess (100 gas)
  • memory arrays use MLOAD (3 gas)
  • calldata arrays use CALLDATALOAD (3 gas)

Caching the length changes each of these to a DUP<N> (3 gas), and gets rid of the extra DUP<N> needed to store the stack offset

There are 13 instances of this issue:

File: contracts/AuraClaimZap.sol

143:          for (uint256 i = 0; i < rewardContracts.length; i++) {

147:          for (uint256 i = 0; i < extraRewardContracts.length; i++) {

151:          for (uint256 i = 0; i < tokenRewardContracts.length; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraClaimZap.sol#L143

File: contracts/AuraLocker.sol

696:          for (uint256 i = nextUnlockIndex; i < locks.length; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L696

File: contracts/AuraVestedEscrow.sol

100:          for (uint256 i = 0; i < _recipient.length; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L100

File: convex-platform/contracts/contracts/ArbitartorVault.sol

49:          for(uint256 i = 0; i < _toPids.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ArbitartorVault.sol#L49

File: convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol

69:           for(uint i=0; i < usedList.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol#L69

File: convex-platform/contracts/contracts/BaseRewardPool.sol

214:          for(uint i=0; i < extraRewards.length; i++){

230:          for(uint i=0; i < extraRewards.length; i++){

262:          for(uint i=0; i < extraRewards.length; i++){

296:              for(uint i=0; i < extraRewards.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L214

File: convex-platform/contracts/contracts/Booster.sol

379:          for(uint i=0; i < poolInfo.length; i++){

538:          for(uint256 i = 0; i < _gauge.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L379

10. ++i/i++ should be unchecked{++i}/unchecked{i++} when it is not possible for them to overflow, as is the case when used in for- and while-loops

The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas PER LOOP

There are 13 instances of this issue:

File: contracts/AuraClaimZap.sol

143:          for (uint256 i = 0; i < rewardContracts.length; i++) {

147:          for (uint256 i = 0; i < extraRewardContracts.length; i++) {

151:          for (uint256 i = 0; i < tokenRewardContracts.length; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraClaimZap.sol#L143

File: contracts/ExtraRewardsDistributor.sol

233:          for (uint256 i = epochIndex; i < tokenEpochs; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ExtraRewardsDistributor.sol#L233

File: contracts/AuraLocker.sol

174:              for (uint256 i = 0; i < rewardTokensLength; i++) {

306:          for (uint256 i; i < rewardTokensLength; i++) {

410:              for (uint256 i = nextUnlockIndex; i < length; i++) {

664:          for (uint256 i = locksLength; i > 0; i--) {

696:          for (uint256 i = nextUnlockIndex; i < locks.length; i++) {

726:          for (uint256 i = epochIndex + 1; i > 0; i--) {

773:          for (uint256 i = 0; i < userRewardsLength; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L174

File: contracts/AuraVestedEscrow.sol

100:          for (uint256 i = 0; i < _recipient.length; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L100

File: contracts/BalLiquidityProvider.sol

51:           for (uint256 i = 0; i < 2; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/BalLiquidityProvider.sol#L51

11. require()/revert() strings longer than 32 bytes cost extra gas

There is 1 instance of this issue:

File: contracts/AuraLocker.sol   #1

197:          require(_rewardsToken != address(stakingToken), "Cannot add StakingToken as reward");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L197

12. keccak256() should only need to be called on a specific string literal once

It should be saved to an immutable variable, and the variable used instead. If the hash is being used as a part of a function selector, the cast to bytes4 should also only be done once

There is 1 instance of this issue:

File: convex-platform/contracts/contracts/Booster.sol   #1

562:          bytes memory data = abi.encodeWithSelector(bytes4(keccak256("set_rewards_receiver(address)")), stash);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L562

13. Not using the named return variables when a function returns, wastes deployment gas

There are 10 instances of this issue:

File: contracts/AuraLocker.sol

603:              return 0;

649:          return balanceAtEpochOf(findEpochId(block.timestamp), _user);

708:          return (userBalance.locked, unlockable, locked, lockData);

708:          return (userBalance.locked, unlockable, locked, lockData);

708:          return (userBalance.locked, unlockable, locked, lockData);

708:          return (userBalance.locked, unlockable, locked, lockData);

713:          return totalSupplyAtEpoch(findEpochId(block.timestamp));

740:          return _time.sub(epochs[0].date).div(rewardsDuration);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L603

File: contracts/AuraVestedEscrow.sol

159:              return 0;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L159

File: convex-platform/contracts/contracts/BaseRewardPool4626.sol

180:          return convertToShares(assets);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool4626.sol#L180

14. Using bools for storage incurs overhead

    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/58f635312aa21f947cae5f8578638a85aa2519f5/contracts/security/ReentrancyGuard.sol#L23-L27
Use uint256(1) and uint256(2) for true/false

There are 18 instances of this issue:

File: contracts/AuraMerkleDrop.sol

34:       mapping(address => bool) public hasClaimed;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L34

File: contracts/AuraLocker.sol

77:       mapping(address => mapping(address => bool)) public rewardDistributors;

114:      bool public isShutdown = false;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L77

File: contracts/AuraVestedEscrow.sol

33:       bool public initialised = false;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L33

File: convex-platform/contracts/contracts/PoolManagerV3.sol

22:       bool public protectAddPool;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerV3.sol#L22

File: convex-platform/contracts/contracts/CrvDepositor.sol

39:       bool public cooldown;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/CrvDepositor.sol#L39

File: convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol

24:       bool public isShutdown;

26:       mapping(address => bool) public usedMap;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol#L24

File: convex-platform/contracts/contracts/VoterProxy.sol

35:       mapping (address => bool) private stashPool;

36:       mapping (address => bool) private protectedTokens;

37:       mapping (bytes32 => bool) private votes;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VoterProxy.sol#L35

File: convex-platform/contracts/contracts/BoosterOwner.sol

49:       bool public isSealed;

53:       bool public isForceTimerStarted;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BoosterOwner.sol#L49

File: convex-platform/contracts/contracts/ExtraRewardStashV3.sol

40:       bool public hasRedirected;

41:       bool public hasCurveRewards;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L40

File: convex-platform/contracts/contracts/Booster.sol

54:       bool public isShutdown;

67:       mapping(address => bool) public gaugeMap;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L54

File: convex-platform/contracts/contracts/RewardFactory.sol

27:       mapping (address => bool) private rewardAccess;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/RewardFactory.sol#L27

15. Use a more recent version of solidity

Use a solidity version of at least 0.8.0 to get overflow protection without SafeMath
Use a solidity version of at least 0.8.2 to get compiler automatic inlining
Use a solidity version of at least 0.8.3 to get better struct packing and cheaper multiple storage reads
Use a solidity version of at least 0.8.4 to get custom errors, which are cheaper at deployment than revert()/require() strings
Use a solidity version of at least 0.8.10 to have external calls skip contract existence checks if the external call has a return value

There are 28 instances of this issue:

File: convex-platform/contracts/contracts/ConvexMasterChef.sol

3:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ConvexMasterChef.sol#L3

File: convex-platform/contracts/contracts/RewardHook.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/RewardHook.sol#L2

File: convex-platform/contracts/contracts/Interfaces.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Interfaces.sol#L2

File: convex-platform/contracts/contracts/PoolManagerProxy.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerProxy.sol#L2

File: convex-platform/contracts/contracts/DepositToken.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/DepositToken.sol#L2

File: convex-platform/contracts/contracts/cCrv.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/cCrv.sol#L2

File: convex-platform/contracts/contracts/StashFactoryV2.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/StashFactoryV2.sol#L2

File: convex-platform/contracts/contracts/PoolManagerV3.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerV3.sol#L2

File: convex-platform/contracts/contracts/ArbitartorVault.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ArbitartorVault.sol#L2

File: convex-platform/contracts/contracts/CrvDepositor.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/CrvDepositor.sol#L2

File: convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol#L2

File: convex-platform/contracts/contracts/TokenFactory.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/TokenFactory.sol#L2

File: convex-platform/contracts/contracts/VoterProxy.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VoterProxy.sol#L2

File: convex-platform/contracts/contracts/BoosterOwner.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BoosterOwner.sol#L2

File: convex-platform/contracts/contracts/interfaces/IGaugeController.sol

3:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/IGaugeController.sol#L3

File: convex-platform/contracts/contracts/interfaces/MathUtil.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/MathUtil.sol#L2

File: convex-platform/contracts/contracts/interfaces/IProxyFactory.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/IProxyFactory.sol#L2

File: convex-platform/contracts/contracts/interfaces/IERC4626.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/IERC4626.sol#L2

File: convex-platform/contracts/contracts/interfaces/IRewardHook.sol

3:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/IRewardHook.sol#L3

File: convex-platform/contracts/contracts/interfaces/BoringMath.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/BoringMath.sol#L2

File: convex-platform/contracts/contracts/interfaces/IRewarder.sol

3:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/IRewarder.sol#L3

File: convex-platform/contracts/contracts/ProxyFactory.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ProxyFactory.sol#L2

File: convex-platform/contracts/contracts/ExtraRewardStashV3.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L2

File: convex-platform/contracts/contracts/BaseRewardPool.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L2

File: convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol#L2

File: convex-platform/contracts/contracts/BaseRewardPool4626.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool4626.sol#L2

File: convex-platform/contracts/contracts/Booster.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L2

File: convex-platform/contracts/contracts/RewardFactory.sol

2:    pragma solidity 0.6.12;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/RewardFactory.sol#L2

16. Using > 0 costs more gas than != 0 when used on a uint in a require() statement

This change saves 6 gas per instance

There are 23 instances of this issue:

File: contracts/AuraMerkleDrop.sol

122:          require(_amount > 0, "!amount");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L122

File: contracts/AuraPenaltyForwarder.sol

52:           require(bal > 0, "!empty");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraPenaltyForwarder.sol#L52

File: contracts/AuraBalRewardPool.sol

121:          require(_amount > 0, "RewardPool : Cannot stake 0");

139:          require(_amount > 0, "RewardPool : Cannot stake 0");

157:          require(amount > 0, "RewardPool : Cannot withdraw 0");

210:          require(rewardsAvailable > 0, "!balance");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraBalRewardPool.sol#L121

File: contracts/AuraLocker.sol

259:          require(_amount > 0, "Cannot stake 0");

359:          require(amt > 0, "Nothing locked");

385:          require(length > 0, "no locks");

431:          require(locked > 0, "no exp locks");

471:          require(len > 0, "Nothing to delegate");

822:          require(_rewards > 0, "No reward");

851:          require(_reward > 0, "No reward");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L259

File: contracts/Aura.sol

68:           require(_amount > 0, "Must mint something");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/Aura.sol#L68

File: contracts/BalLiquidityProvider.sol

70:           require(balAfter > 0, "!mint");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/BalLiquidityProvider.sol#L70

File: convex-platform/contracts/contracts/CrvDepositor.sol

169:          require(_amount > 0,"!>0");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/CrvDepositor.sol#L169

File: convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol

104:          require(weight > 0, "must have weight");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol#L104

File: convex-platform/contracts/contracts/interfaces/BoringMath.sol

20:           require(b > 0, "BoringMath: division by zero");

102:          require(b > 0, "BoringMath: division by zero");

123:          require(b > 0, "BoringMath: division by zero");

143:          require(b > 0, "BoringMath: division by zero");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/BoringMath.sol#L20

File: convex-platform/contracts/contracts/BaseRewardPool.sol

211:          require(_amount > 0, 'RewardPool : Cannot stake 0');

227:          require(amount > 0, 'RewardPool : Cannot withdraw 0');

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L211

17. It costs more gas to initialize variables to zero than to let the default of zero be applied

There are 26 instances of this issue:

File: contracts/AuraClaimZap.sol

143:          for (uint256 i = 0; i < rewardContracts.length; i++) {

147:          for (uint256 i = 0; i < extraRewardContracts.length; i++) {

151:          for (uint256 i = 0; i < tokenRewardContracts.length; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraClaimZap.sol#L143

File: contracts/ExtraRewardsDistributor.sol

231:          uint256 claimableTokens = 0;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ExtraRewardsDistributor.sol#L231

File: contracts/AuraLocker.sol

174:              for (uint256 i = 0; i < rewardTokensLength; i++) {

381:          uint256 reward = 0;

485:          uint256 futureUnlocksSum = 0;

540:                      uint256 unlocksSinceLatestCkpt = 0;

630:          uint256 low = 0;

773:          for (uint256 i = 0; i < userRewardsLength; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L174

File: contracts/AuraVestedEscrow.sol

99:           uint256 totalAmount = 0;

100:          for (uint256 i = 0; i < _recipient.length; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L99

File: contracts/BalLiquidityProvider.sol

51:           for (uint256 i = 0; i < 2; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/BalLiquidityProvider.sol#L51

File: convex-platform/contracts/contracts/ConvexMasterChef.sol

180:          for (uint256 pid = 0; pid < length; ++pid) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ConvexMasterChef.sol#L180

File: convex-platform/contracts/contracts/ArbitartorVault.sol

49:          for(uint256 i = 0; i < _toPids.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ArbitartorVault.sol#L49

File: convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol

69:           for(uint i=0; i < usedList.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol#L69

File: convex-platform/contracts/contracts/VoterProxy.sol

308:          uint256 _balance = 0;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VoterProxy.sol#L308

File: convex-platform/contracts/contracts/BoosterOwner.sol

144:          for(uint256 i = 0; i < poolCount; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BoosterOwner.sol#L144

File: convex-platform/contracts/contracts/ExtraRewardStashV3.sol

125:          for(uint256 i = 0; i < maxRewards; i++){

199:          for(uint i=0; i < tCount; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L125

File: convex-platform/contracts/contracts/BaseRewardPool.sol

214:          for(uint i=0; i < extraRewards.length; i++){

230:          for(uint i=0; i < extraRewards.length; i++){

262:          for(uint i=0; i < extraRewards.length; i++){

296:              for(uint i=0; i < extraRewards.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L214

File: convex-platform/contracts/contracts/Booster.sol

379:          for(uint i=0; i < poolInfo.length; i++){

538:          for(uint256 i = 0; i < _gauge.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L379

18. ++i costs less gas than i++, especially when it's used in for-loops (--i/i-- too)

Saves 6 gas PER LOOP

There are 24 instances of this issue:

File: contracts/AuraClaimZap.sol

143:          for (uint256 i = 0; i < rewardContracts.length; i++) {

147:          for (uint256 i = 0; i < extraRewardContracts.length; i++) {

151:          for (uint256 i = 0; i < tokenRewardContracts.length; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraClaimZap.sol#L143

File: contracts/ExtraRewardsDistributor.sol

233:          for (uint256 i = epochIndex; i < tokenEpochs; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ExtraRewardsDistributor.sol#L233

File: contracts/AuraLocker.sol

174:              for (uint256 i = 0; i < rewardTokensLength; i++) {

306:          for (uint256 i; i < rewardTokensLength; i++) {

410:              for (uint256 i = nextUnlockIndex; i < length; i++) {

664:          for (uint256 i = locksLength; i > 0; i--) {

696:          for (uint256 i = nextUnlockIndex; i < locks.length; i++) {

726:          for (uint256 i = epochIndex + 1; i > 0; i--) {

773:          for (uint256 i = 0; i < userRewardsLength; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L174

File: contracts/AuraVestedEscrow.sol

100:          for (uint256 i = 0; i < _recipient.length; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L100

File: contracts/BalLiquidityProvider.sol

51:           for (uint256 i = 0; i < 2; i++) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/BalLiquidityProvider.sol#L51

File: convex-platform/contracts/contracts/ArbitartorVault.sol

49:          for(uint256 i = 0; i < _toPids.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ArbitartorVault.sol#L49

File: convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol

69:           for(uint i=0; i < usedList.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol#L69

File: convex-platform/contracts/contracts/BoosterOwner.sol

144:          for(uint256 i = 0; i < poolCount; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BoosterOwner.sol#L144

File: convex-platform/contracts/contracts/ExtraRewardStashV3.sol

125:          for(uint256 i = 0; i < maxRewards; i++){

199:          for(uint i=0; i < tCount; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L125

File: convex-platform/contracts/contracts/BaseRewardPool.sol

214:          for(uint i=0; i < extraRewards.length; i++){

230:          for(uint i=0; i < extraRewards.length; i++){

262:          for(uint i=0; i < extraRewards.length; i++){

296:              for(uint i=0; i < extraRewards.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L214

File: convex-platform/contracts/contracts/Booster.sol

379:          for(uint i=0; i < poolInfo.length; i++){

538:          for(uint256 i = 0; i < _gauge.length; i++){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L379

19. Splitting require() statements that use && saves gas

See this issue which describes the fact that there is a larger deployment gas cost, but with enough runtime calls, the change ends up being cheaper

There are 15 instances of this issue:

File: contracts/ExtraRewardsDistributor.sol

171:          require(_index > 0 && _index < rewardEpochs[_token].length - 1, "!past");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ExtraRewardsDistributor.sol#L171

File: contracts/AuraStakingProxy.sol

90:           require(_outputBps > 9000 && _outputBps < 10000, "Invalid output bps");

159:          require(_token != crv && _token != cvx && _token != cvxCrv, "not allowed");

203:          require(address(_token) != crv && address(_token) != cvxCrv, "not allowed");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraStakingProxy.sol#L90

File: contracts/BalLiquidityProvider.sol

48:           require(_request.assets.length == 2 && _request.maxAmountsIn.length == 2, "!valid");

57:               require(bal > 0 && bal == _request.maxAmountsIn[i], "!bal");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/BalLiquidityProvider.sol#L48

File: convex-platform/contracts/contracts/StashFactoryV2.sol

83:           require(!isV1 && !isV2 && !isV3,"stash version mismatch");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/StashFactoryV2.sol#L83

File: convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol

111:          require(!usedMap[_lptoken] && !usedMap[_gauge], "cant force used pool");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol#L111

File: convex-platform/contracts/contracts/Booster.sol

220:          require(lockRewards != address(0) && rewardFactory != address(0), "!initialised");

222:          require(_feeToken != address(0) && _feeDistro != address(0), "!addresses");

278:          require(_lockFees >= 300 && _lockFees <= 1500, "!lockFees");

279:          require(_stakerFees >= 300 && _stakerFees <= 1500, "!stakerFees");

280:          require(_callerFees >= 10 && _callerFees <= 100, "!callerFees");

313:          require(msg.sender==poolManager && !isShutdown, "!add");

314:          require(_gauge != address(0) && _lptoken != address(0),"!param");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L220

20. Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead

When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.

https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html
Use a larger size then downcast where needed

There are 99 instances of this issue:

File: contracts/AuraLocker.sol

35:           uint32 periodFinish;

37:           uint32 lastUpdateTime;

39:           uint96 rewardRate;

41:           uint96 rewardPerTokenStored;

44:           uint128 rewardPerTokenPaid;

45:           uint128 rewards;

52:           uint112 locked;

53:           uint32 nextUnlockIndex;

56:           uint112 amount;

57:           uint32 unlockTime;

60:           uint224 supply;

61:           uint32 date; //epoch start date

64:           uint224 votes;

65:           uint32 epochStart;

119:      uint8 private immutable _decimals;

268:          uint112 lockAmount = _amount.to112();

379:          uint112 locked;

409:              uint32 nextUnlockIndex = userBalance.nextUnlockIndex;

583:      function checkpoints(address account, uint32 pos) external view virtual returns (DelegateeCheckpoint memory) {

590:      function numCheckpoints(address account) external view virtual returns (uint32) {

752:      function decimals() external view returns (uint8) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L35

File: contracts/AuraMath.sol

39:       function to224(uint256 a) internal pure returns (uint224 c) {

44:       function to128(uint256 a) internal pure returns (uint128 c) {

49:       function to112(uint256 a) internal pure returns (uint112 c) {

54:       function to96(uint256 a) internal pure returns (uint96 c) {

59:       function to32(uint256 a) internal pure returns (uint32 c) {

67:       function sub(uint32 a, uint32 b) internal pure returns (uint32 c) {

67:       function sub(uint32 a, uint32 b) internal pure returns (uint32 c) {

67:       function sub(uint32 a, uint32 b) internal pure returns (uint32 c) {

74:       function add(uint112 a, uint112 b) internal pure returns (uint112 c) {

74:       function add(uint112 a, uint112 b) internal pure returns (uint112 c) {

74:       function add(uint112 a, uint112 b) internal pure returns (uint112 c) {

78:       function sub(uint112 a, uint112 b) internal pure returns (uint112 c) {

78:       function sub(uint112 a, uint112 b) internal pure returns (uint112 c) {

78:       function sub(uint112 a, uint112 b) internal pure returns (uint112 c) {

85:       function add(uint224 a, uint224 b) internal pure returns (uint224 c) {

85:       function add(uint224 a, uint224 b) internal pure returns (uint224 c) {

85:       function add(uint224 a, uint224 b) internal pure returns (uint224 c) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMath.sol#L39

File: convex-platform/contracts/contracts/Interfaces.sol

34:       function getVote(uint256) external view returns(bool,bool,uint64,uint64,uint64,uint64,uint256,uint256,uint256,bytes memory); 

34:       function getVote(uint256) external view returns(bool,bool,uint64,uint64,uint64,uint64,uint256,uint256,uint256,bytes memory); 

34:       function getVote(uint256) external view returns(bool,bool,uint64,uint64,uint64,uint64,uint256,uint256,uint256,bytes memory); 

34:       function getVote(uint256) external view returns(bool,bool,uint64,uint64,uint64,uint64,uint256,uint256,uint256,bytes memory); 

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Interfaces.sol#L34

File: convex-platform/contracts/contracts/interfaces/IGaugeController.sol

9:        function add_gauge(address,int128,uint256) external;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/IGaugeController.sol#L9

File: convex-platform/contracts/contracts/interfaces/BoringMath.sol

24:       function to128(uint256 a) internal pure returns (uint128 c) {

29:       function to64(uint256 a) internal pure returns (uint64 c) {

34:       function to32(uint256 a) internal pure returns (uint32 c) {

39:       function to40(uint256 a) internal pure returns (uint40 c) {

44:       function to112(uint256 a) internal pure returns (uint112 c) {

49:       function to224(uint256 a) internal pure returns (uint224 c) {

54:       function to208(uint256 a) internal pure returns (uint208 c) {

59:       function to216(uint256 a) internal pure returns (uint216 c) {

67:       function add(uint128 a, uint128 b) internal pure returns (uint128 c) {

67:       function add(uint128 a, uint128 b) internal pure returns (uint128 c) {

67:       function add(uint128 a, uint128 b) internal pure returns (uint128 c) {

71:       function sub(uint128 a, uint128 b) internal pure returns (uint128 c) {

71:       function sub(uint128 a, uint128 b) internal pure returns (uint128 c) {

71:       function sub(uint128 a, uint128 b) internal pure returns (uint128 c) {

78:       function add(uint64 a, uint64 b) internal pure returns (uint64 c) {

78:       function add(uint64 a, uint64 b) internal pure returns (uint64 c) {

78:       function add(uint64 a, uint64 b) internal pure returns (uint64 c) {

82:       function sub(uint64 a, uint64 b) internal pure returns (uint64 c) {

82:       function sub(uint64 a, uint64 b) internal pure returns (uint64 c) {

82:       function sub(uint64 a, uint64 b) internal pure returns (uint64 c) {

89:       function add(uint32 a, uint32 b) internal pure returns (uint32 c) {

89:       function add(uint32 a, uint32 b) internal pure returns (uint32 c) {

89:       function add(uint32 a, uint32 b) internal pure returns (uint32 c) {

93:       function sub(uint32 a, uint32 b) internal pure returns (uint32 c) {

93:       function sub(uint32 a, uint32 b) internal pure returns (uint32 c) {

93:       function sub(uint32 a, uint32 b) internal pure returns (uint32 c) {

97:       function mul(uint32 a, uint32 b) internal pure returns (uint32 c) {

97:       function mul(uint32 a, uint32 b) internal pure returns (uint32 c) {

97:       function mul(uint32 a, uint32 b) internal pure returns (uint32 c) {

101:      function div(uint32 a, uint32 b) internal pure returns (uint32) {

101:      function div(uint32 a, uint32 b) internal pure returns (uint32) {

101:      function div(uint32 a, uint32 b) internal pure returns (uint32) {

110:      function add(uint112 a, uint112 b) internal pure returns (uint112 c) {

110:      function add(uint112 a, uint112 b) internal pure returns (uint112 c) {

110:      function add(uint112 a, uint112 b) internal pure returns (uint112 c) {

114:      function sub(uint112 a, uint112 b) internal pure returns (uint112 c) {

114:      function sub(uint112 a, uint112 b) internal pure returns (uint112 c) {

114:      function sub(uint112 a, uint112 b) internal pure returns (uint112 c) {

118:      function mul(uint112 a, uint112 b) internal pure returns (uint112 c) {

118:      function mul(uint112 a, uint112 b) internal pure returns (uint112 c) {

118:      function mul(uint112 a, uint112 b) internal pure returns (uint112 c) {

122:      function div(uint112 a, uint112 b) internal pure returns (uint112) {

122:      function div(uint112 a, uint112 b) internal pure returns (uint112) {

122:      function div(uint112 a, uint112 b) internal pure returns (uint112) {

130:      function add(uint224 a, uint224 b) internal pure returns (uint224 c) {

130:      function add(uint224 a, uint224 b) internal pure returns (uint224 c) {

130:      function add(uint224 a, uint224 b) internal pure returns (uint224 c) {

134:      function sub(uint224 a, uint224 b) internal pure returns (uint224 c) {

134:      function sub(uint224 a, uint224 b) internal pure returns (uint224 c) {

134:      function sub(uint224 a, uint224 b) internal pure returns (uint224 c) {

138:      function mul(uint224 a, uint224 b) internal pure returns (uint224 c) {

138:      function mul(uint224 a, uint224 b) internal pure returns (uint224 c) {

138:      function mul(uint224 a, uint224 b) internal pure returns (uint224 c) {

142:      function div(uint224 a, uint224 b) internal pure returns (uint224) {

142:      function div(uint224 a, uint224 b) internal pure returns (uint224) {

142:      function div(uint224 a, uint224 b) internal pure returns (uint224) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/BoringMath.sol#L24

21. abi.encode() is less efficient than abi.encodePacked()

There are 2 instances of this issue:

File: contracts/CrvDepositorWrapper.sol   #1

93:                   abi.encode(IVault.JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT, maxAmountsIn, minOut),

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/CrvDepositorWrapper.sol#L93

File: convex-platform/contracts/contracts/StashFactoryV2.sol   #2

88:           bytes memory data = abi.encode(rewarded_token);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/StashFactoryV2.sol#L88

22. Using private rather than public for constants, saves gas

If needed, the value can be read from the verified contract source code. Savings are due to the compiler not having to create non-payable getter functions for deployment calldata, and not adding another entry to the method ID table

There are 30 instances of this issue:

File: contracts/AuraMinter.sol

18:       uint256 public immutable inflationProtectionTime;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMinter.sol#L18

File: contracts/AuraMerkleDrop.sol

32:       uint256 public immutable expiryTime;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L32

File: contracts/AuraPenaltyForwarder.sol

19:       uint256 public immutable distributionDelay;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraPenaltyForwarder.sol#L19

File: contracts/AuraBalRewardPool.sol

29:       uint256 public constant duration = 14 days;

36:       uint256 public immutable startTime;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraBalRewardPool.sol#L29

File: contracts/AuraLocker.sol

73:       uint256 public constant newRewardRatio = 830;

81:       uint256 public constant rewardsDuration = 86400 * 7;

83:       uint256 public constant lockDuration = rewardsDuration * 17;

107:      uint256 public constant denominator = 10000;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L73

File: contracts/CrvDepositorWrapper.sol

30:       bytes32 public immutable BAL_ETH_POOL_ID;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/CrvDepositorWrapper.sol#L30

File: contracts/Aura.sol

28:       uint256 public constant EMISSIONS_MAX_SUPPLY = 5e25; // 50m

29:       uint256 public constant totalCliffs = 500;

30:       uint256 public immutable reductionPerCliff;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/Aura.sol#L28

File: contracts/AuraStakingProxy.sol

45:       uint256 public constant denominator = 10000;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraStakingProxy.sol#L45

File: contracts/AuraVestedEscrow.sol

29:       uint256 public immutable startTime;

30:       uint256 public immutable endTime;

31:       uint256 public immutable totalTime;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L29

File: convex-platform/contracts/contracts/ConvexMasterChef.sol

54:       uint256 public immutable rewardPerBlock;

56:       uint256 public constant BONUS_MULTIPLIER = 2;

65:       uint256 public immutable startBlock;

66:       uint256 public immutable endBlock;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ConvexMasterChef.sol#L54

File: convex-platform/contracts/contracts/CrvDepositor.sol

30:       uint256 public constant FEE_DENOMINATOR = 10000;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/CrvDepositor.sol#L30

File: convex-platform/contracts/contracts/BoosterOwner.sol

51:       uint256 public constant FORCE_DELAY = 30 days;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BoosterOwner.sol#L51

File: convex-platform/contracts/contracts/BaseRewardPool.sol

65:       uint256 public constant duration = 7 days;

70:       uint256 public immutable pid;

78:       uint256 public constant newRewardRatio = 830;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L65

File: convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol

85:       uint256 public constant duration = 7 days;

96:       uint256 public constant newRewardRatio = 830;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol#L85

File: convex-platform/contracts/contracts/Booster.sol

30:       uint256 public constant MaxFees = 2500;

31:       uint256 public constant FEE_DENOMINATOR = 10000;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L30

23. Don't compare boolean expressions to boolean literals

if (<x> == true) => if (<x>), if (<x> == false) => if (!<x>)

There are 9 instances of this issue:

File: contracts/AuraMerkleDrop.sol

123:          require(hasClaimed[msg.sender] == false, "already claimed");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L123

File: convex-platform/contracts/contracts/ArbitartorVault.sol

54:           require(shutdown==false,"pool closed");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ArbitartorVault.sol#L54

File: convex-platform/contracts/contracts/VoterProxy.sol

107:          require(operator == address(0) || IDeposit(operator).isShutdown() == true, "needs shutdown");

168:          if(protectedTokens[_token] == false){

171:          if(protectedTokens[_gauge] == false){

190:          require(protectedTokens[address(_asset)] == false, "protected");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VoterProxy.sol#L107

File: convex-platform/contracts/contracts/Booster.sol

400:          require(pool.shutdown == false, "pool is closed");

574:          require(pool.shutdown == false, "pool is closed");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L400

File: convex-platform/contracts/contracts/RewardFactory.sol

72:           require(msg.sender == operator || rewardAccess[msg.sender] == true, "!auth");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/RewardFactory.sol#L72

24. Don't use SafeMath once the solidity version is 0.8.0 or greater

Version 0.8.0 introduces internal overflow checks, so using SafeMath is redundant and adds overhead

There are 2 instances of this issue:

File: contracts/AuraBalRewardPool.sol   #1

5:    import { SafeMath } from "@openzeppelin/contracts-0.8/utils/math/SafeMath.sol";

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraBalRewardPool.sol#L5

File: contracts/AuraStakingProxy.sol   #2

7:    import { SafeMath } from "@openzeppelin/contracts-0.8/utils/math/SafeMath.sol";

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraStakingProxy.sol#L7

25. Duplicated require()/revert() checks should be refactored to a modifier or function

Saves deployment costs

There are 32 instances of this issue:

File: contracts/AuraMerkleDrop.sol

84:           require(msg.sender == dao, "!auth");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L84

File: contracts/AuraBalRewardPool.sol

139:          require(_amount > 0, "RewardPool : Cannot stake 0");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraBalRewardPool.sol#L139

File: contracts/AuraLocker.sol

719:          require(epochStart < block.timestamp, "Epoch is in the future");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L719

File: contracts/AuraStakingProxy.sol

100:          require(msg.sender == owner, "!auth");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraStakingProxy.sol#L100

File: contracts/AuraVestedEscrow.sol

87:           require(msg.sender == admin, "!auth");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L87

File: convex-platform/contracts/contracts/DepositToken.sol

54:           require(msg.sender == operator, "!authorized");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/DepositToken.sol#L54

File: convex-platform/contracts/contracts/cCrv.sol

56:           require(msg.sender == operator, "!authorized");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/cCrv.sol#L56

File: convex-platform/contracts/contracts/PoolManagerV3.sol

49:           require(msg.sender == operator, "!auth");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerV3.sol#L49

File: convex-platform/contracts/contracts/ArbitartorVault.sol

47:          require(msg.sender == operator, "!auth");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ArbitartorVault.sol#L47

File: convex-platform/contracts/contracts/CrvDepositor.sol

73:           require(msg.sender==feeManager, "!auth");

81:         require(msg.sender == daoOperator, "!auth");

141:          require(!cooldown, "cooldown");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/CrvDepositor.sol#L73

File: convex-platform/contracts/contracts/VoterProxy.sol

84:           require(msg.sender == owner, "!auth");

138:          require(msg.sender == operator, "!auth");

254:          require(msg.sender == depositor, "!auth");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VoterProxy.sol#L84

File: convex-platform/contracts/contracts/BoosterOwner.sol

159:          require(IOwner(poolManager).isShutdown(),"!poolMgrShutdown");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BoosterOwner.sol#L159

File: convex-platform/contracts/contracts/interfaces/BoringMath.sol

68:           require((c = a + b) >= b, "BoringMath: Add Overflow");

72:           require((c = a - b) <= a, "BoringMath: Underflow");

98:           require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow");

102:          require(b > 0, "BoringMath: division by zero");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/interfaces/BoringMath.sol#L68

File: convex-platform/contracts/contracts/ExtraRewardStashV3.sol

196:          require(msg.sender == operator, "!operator");

147:          require(IDeposit(operator).owner() == msg.sender, "!owner");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L196

File: convex-platform/contracts/contracts/BaseRewardPool.sol

133:          require(msg.sender == rewardManager, "!authorized");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L133

File: convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol

182:          require(msg.sender == address(deposits), "!authorized");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol#L182

File: convex-platform/contracts/contracts/Booster.sol

159:          require(msg.sender == owner, "!auth");

273:          require(msg.sender==feeManager, "!auth");

357:          require(msg.sender==poolManager, "!auth");

515:          require(msg.sender == voteDelegate, "!auth");

398:          require(!isShutdown,"shutdown");

574:          require(pool.shutdown == false, "pool is closed");

560:          require(msg.sender == stash,"!auth");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L159

File: convex-platform/contracts/contracts/RewardFactory.sol

57:           require(msg.sender == operator, "!auth");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/RewardFactory.sol#L57

26. Multiplication/division by two should use bit shifting

<x> * 2 is equivalent to <x> << 1 and <x> / 2 is the same as <x> >> 1. The MUL and DIV opcodes cost 5 gas, whereas SHL and SHR only cost 3 gas

There are 5 instances of this issue:

File: contracts/AuraMerkleDrop.sol

136:              uint256 penalty = address(auraLocker) == address(0) ? 0 : (_amount * 2) / 10;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L136

File: contracts/AuraBalRewardPool.sol

183:                  uint256 penalty = (reward * 2) / 10;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraBalRewardPool.sol#L183

File: contracts/AuraMath.sol

36:           return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);

36:           return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);

36:           return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMath.sol#L36

27. Stack variable used as a cheaper cache for a state variable is only used once

If the variable is only accessed once, it's cheaper to use the state variable directly that one time

There is 1 instance of this issue:

File: contracts/AuraLocker.sol   #1

328:          uint256 epochindex = epochs.length;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L328

28. require() or revert() statements that check input arguments should be at the top of the function

Checks that involve constants should come before checks that involve state variables

There are 11 instances of this issue:

File: contracts/AuraMerkleDrop.sol

69:           require(_expiresAfter > 2 weeks, "!expiry");

122:          require(_amount > 0, "!amount");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L69

File: contracts/AuraBalRewardPool.sol

77:           require(_startDelay < 2 weeks, "!delay");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraBalRewardPool.sol#L77

File: contracts/AuraLocker.sol

472:          require(newDelegatee != address(0), "Must delegate to someone");

822:          require(_rewards > 0, "No reward");

851:          require(_reward > 0, "No reward");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L472

File: contracts/Aura.sol

68:           require(_amount > 0, "Must mint something");

69:           require(_minter != address(0), "Invalid minter");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/Aura.sol#L68

File: contracts/AuraStakingProxy.sol

129:          require(_incentive <= 100, "too high");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraStakingProxy.sol#L129

File: convex-platform/contracts/contracts/BaseRewardPool.sol

127:          require(_reward != address(0),"!reward setting");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L127

File: convex-platform/contracts/contracts/Booster.sol

281:          require(_platform <= 200, "!platform");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L281

29. Empty blocks should be removed or emit something

The code should be refactored such that they no longer exist, or the block should do something useful, such as emitting an event or reverting. If the block is an empty if-statement block to avoid doing subsequent checks in the else-if/else conditions, the else-if/else conditions should be nested under the negation of the if-statement, because they involve different classes of checks, which may lead to the introduction of errors when the code is later modified (if(x){}else if(y){...}else{...} => if(!x){if(y){...}else{...}})

There are 6 instances of this issue:

File: convex-platform/contracts/contracts/VoterProxy.sol

312:          }catch{}

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VoterProxy.sol#L312

File: convex-platform/contracts/contracts/ExtraRewardStashV3.sol

116               try IRewardHook(rewardHook).onRewardClaim(){
117:              }catch{}

117:              }catch{}

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ExtraRewardStashV3.sol#L116-L117

File: convex-platform/contracts/contracts/Booster.sol

361           try IStaker(staker).withdrawAll(pool.lptoken,pool.gauge){
362:          }catch{}

362:          }catch{}

389:              }catch{}

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L361-L362

30. Use custom errors rather than revert()/require() strings to save deployment gas

Custom errors are available from solidity version 0.8.4. The instances below match or exceed that version

There are 101 instances of this issue:

File: contracts/AuraClaimZap.sol

96:           require(msg.sender == owner, "!auth");

137:          require(tokenRewardContracts.length == tokenRewardTokens.length, "!parity");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraClaimZap.sol#L96

File: contracts/AuraMinter.sol

32:           require(block.timestamp > inflationProtectionTime, "Inflation protected for now");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMinter.sol#L32

File: contracts/ExtraRewardsDistributor.sol

68:           require(_epoch <= latestEpoch, "Cannot assign to the future");

74:               require(len == 0 || rewardEpochs[_token][len - 1] < _epoch, "Cannot backdate to this epoch");

171:          require(_index > 0 && _index < rewardEpochs[_token].length - 1, "!past");

172:          require(_index >= userClaims[_token][msg.sender], "already claimed");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ExtraRewardsDistributor.sol#L68

File: contracts/AuraMerkleDrop.sol

69:           require(_expiresAfter > 2 weeks, "!expiry");

78:           require(msg.sender == dao, "!auth");

84:           require(msg.sender == dao, "!auth");

85:           require(merkleRoot == bytes32(0), "already set");

91:           require(msg.sender == dao, "!auth");

97:           require(msg.sender == dao, "!auth");

98:           require(block.timestamp > expiryTime, "!expired");

105:          require(msg.sender == dao, "!auth");

119:          require(merkleRoot != bytes32(0), "!root");

120:          require(block.timestamp > startTime, "!started");

121:          require(block.timestamp < expiryTime, "!active");

122:          require(_amount > 0, "!amount");

123:          require(hasClaimed[msg.sender] == false, "already claimed");

126:          require(MerkleProof.verify(_proof, merkleRoot, leaf), "invalid proof");

152:          require(penaltyForwarder != address(0), "!forwarder");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L69

File: contracts/AuraPenaltyForwarder.sol

48:           require(block.timestamp > lastDistribution + distributionDelay, "!elapsed");

52:           require(bal > 0, "!empty");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraPenaltyForwarder.sol#L48

File: contracts/AuraBalRewardPool.sol

77:           require(_startDelay < 2 weeks, "!delay");

121:          require(_amount > 0, "RewardPool : Cannot stake 0");

139:          require(_amount > 0, "RewardPool : Cannot stake 0");

157:          require(amount > 0, "RewardPool : Cannot withdraw 0");

206:          require(msg.sender == rewardManager || block.timestamp > startTime, "!authorized");

207:          require(rewardRate == 0, "!one time");

210:          require(rewardsAvailable > 0, "!balance");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraBalRewardPool.sol#L77

File: contracts/AuraLocker.sol

196:          require(rewardData[_rewardsToken].lastUpdateTime == 0, "Reward already exists");

197:          require(_rewardsToken != address(stakingToken), "Cannot add StakingToken as reward");

210:          require(rewardData[_rewardsToken].lastUpdateTime > 0, "Reward does not exist");

216:          require(_rate <= 500, "over max rate"); //max 5% per epoch

217:          require(_delay >= 2, "min delay"); //minimum 2 epochs of grace

232:          require(_tokenAddress != address(stakingToken), "Cannot withdraw staking token");

233:          require(rewardData[_tokenAddress].lastUpdateTime == 0, "Cannot withdraw reward token");

259:          require(_amount > 0, "Cannot stake 0");

260:          require(!isShutdown, "shutdown");

353:          require(isShutdown, "Must be shutdown");

359:          require(amt > 0, "Nothing locked");

385:          require(length > 0, "no locks");

431:          require(locked > 0, "no exp locks");

471:          require(len > 0, "Nothing to delegate");

472:          require(newDelegatee != address(0), "Must delegate to someone");

476:          require(newDelegatee != oldDelegatee, "Must choose new delegatee");

598:          require(timestamp <= block.timestamp, "ERC20Votes: block not yet mined");

616:          require(timestamp < block.timestamp, "ERC20Votes: block not yet mined");

655:          require(epochStart < block.timestamp, "Epoch is in the future");

719:          require(epochStart < block.timestamp, "Epoch is in the future");

821:          require(rewardDistributors[cvxCrv][msg.sender], "!authorized");

822:          require(_rewards > 0, "No reward");

849:          require(_rewardsToken != cvxCrv, "Use queueNewRewards");

850:          require(rewardDistributors[_rewardsToken][msg.sender], "Must be rewardsDistributor");

851:          require(_reward > 0, "No reward");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L196

File: contracts/ClaimFeesHelper.sol

45:           require(tokenTime > lastTokenTimes[address(_token)], "not time yet");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ClaimFeesHelper.sol#L45

File: contracts/CrvDepositorWrapper.sol

42:           require(poolAddress != address(0), "!poolAddress");

119:          require(IERC20(BALANCER_POOL_TOKEN).approve(crvDeposit, type(uint256).max), "!approval");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/CrvDepositorWrapper.sol#L42

File: contracts/Aura.sol

66:           require(msg.sender == operator, "Only operator");

67:           require(totalSupply() == 0, "Only once");

68:           require(_amount > 0, "Must mint something");

69:           require(_minter != address(0), "Invalid minter");

92:           require(totalSupply() != 0, "Not initialised");

129:          require(msg.sender == minter, "Only minter");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/Aura.sol#L66

File: contracts/AuraStakingProxy.sol

89:           require(msg.sender == owner, "!auth");

90:           require(_outputBps > 9000 && _outputBps < 10000, "Invalid output bps");

100:          require(msg.sender == owner, "!auth");

108:          require(msg.sender == owner, "!auth");

116:          require(msg.sender == owner, "!auth");

117:          require(pendingOwner != address(0), "invalid owner");

128:          require(msg.sender == owner, "!auth");

129:          require(_incentive <= 100, "too high");

138:          require(msg.sender == owner, "!auth");

158:          require(msg.sender == owner, "!auth");

159:          require(_token != crv && _token != cvx && _token != cvxCrv, "not allowed");

172:              require(msg.sender == keeper, "!auth");

203:          require(address(_token) != crv && address(_token) != cvxCrv, "not allowed");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraStakingProxy.sol#L89

File: contracts/AuraMath.sol

40:           require(a <= type(uint224).max, "AuraMath: uint224 Overflow");

45:           require(a <= type(uint128).max, "AuraMath: uint128 Overflow");

50:           require(a <= type(uint112).max, "AuraMath: uint112 Overflow");

55:           require(a <= type(uint96).max, "AuraMath: uint96 Overflow");

60:           require(a <= type(uint32).max, "AuraMath: uint32 Overflow");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMath.sol#L40

File: contracts/AuraVestedEscrow.sol

56:           require(starttime_ >= block.timestamp, "start must be future");

57:           require(endtime_ > starttime_, "end must be greater");

66:           require(totalTime >= 16 weeks, "!short");

78:           require(msg.sender == admin, "!auth");

87:           require(msg.sender == admin, "!auth");

97:           require(!initialised, "initialised already");

117:          require(msg.sender == admin, "!auth");

118:          require(totalLocked[_recipient] > 0, "!funding");

185:              require(address(auraLocker) != address(0), "!auraLocker");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraVestedEscrow.sol#L56

File: contracts/BalLiquidityProvider.sol

47:           require(msg.sender == provider, "!auth");

48:           require(_request.assets.length == 2 && _request.maxAmountsIn.length == 2, "!valid");

49:           require(pairToken.balanceOf(address(this)) > minPairAmount, "!minLiq");

53:               require(asset == address(startToken) || asset == address(pairToken), "!asset");

57:               require(bal > 0 && bal == _request.maxAmountsIn[i], "!bal");

65:           require(supplyBefore == 0, "!init");

70:           require(balAfter > 0, "!mint");

79:           require(msg.sender == dao, "!auth");

89:           require(msg.sender == provider || msg.sender == dao, "!auth");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/BalLiquidityProvider.sol#L47

31. Functions guaranteed to revert when called by normal users can be marked payable

If a function modifier such as onlyOwner is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided. The extra opcodes avoided are
CALLVALUE(2),DUP1(3),ISZERO(3),PUSH2(3),JUMPI(10),PUSH1(3),DUP1(3),REVERT(0),JUMPDEST(1),POP(2), which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost

There are 37 instances of this issue:

File: contracts/AuraMinter.sol

31:       function mint(address _to, uint256 _amount) external onlyOwner {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMinter.sol#L31

File: contracts/AuraLocker.sol

195:      function addReward(address _rewardsToken, address _distributor) external onlyOwner {

205       function approveRewardDistributor(
206           address _rewardsToken,
207           address _distributor,
208           bool _approved
209:      ) external onlyOwner {

215:      function setKickIncentive(uint256 _rate, uint256 _delay) external onlyOwner {

225:      function shutdown() external onlyOwner {

231:      function recoverERC20(address _tokenAddress, uint256 _tokenAmount) external onlyOwner {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraLocker.sol#L195

File: convex-platform/contracts/contracts/ConvexMasterChef.sol

96        function add(
97            uint256 _allocPoint,
98            IERC20 _lpToken,
99            IRewarder _rewarder,
100           bool _withUpdate
101:      ) public onlyOwner {

121       function set(
122           uint256 _pid,
123           uint256 _allocPoint,
124           IRewarder _rewarder,
125           bool _withUpdate,
126           bool _updateRewarder
127:      ) public onlyOwner {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ConvexMasterChef.sol#L96-L101

File: convex-platform/contracts/contracts/PoolManagerProxy.sol

43:       function setOwner(address _owner) external onlyOwner{

48:       function setOperator(address _operator) external onlyOwner{

57:       function shutdownPool(uint256 _pid) external onlyOperator returns(bool){

66:       function addPool(address _lptoken, address _gauge, uint256 _stashVersion) external onlyOperator returns(bool){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerProxy.sol#L43

File: convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol

58:       function setOwner(address _owner) external onlyOwner{

63:       function setOperator(address _operator) external onlyOwner{

68:       function setUsedAddress(address[] memory usedList) external onlyOwner{

75:       function shutdownSystem() external onlyOwner{

84:       function shutdownPool(uint256 _pid) external onlyOperator returns(bool){

101:      function addPool(address _lptoken, address _gauge, uint256 _stashVersion) external onlyOperator returns(bool){

110:      function forceAddPool(address _lptoken, address _gauge, uint256 _stashVersion) external onlyOperator returns(bool){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/PoolManagerSecondaryProxy.sol#L58

File: convex-platform/contracts/contracts/BoosterOwner.sol

90:       function transferOwnership(address _owner) external onlyOwner{

102:      function sealOwnership() external onlyOwner{

107:      function setBoosterOwner() external onlyOwner{

115:      function setFactories(address _rfactory, address _sfactory, address _tfactory) external onlyOwner{

119:      function setArbitrator(address _arb) external onlyOwner{

123:      function setFeeInfo(address _feeToken, address _feeDistro) external onlyOwner{

127:      function updateFeeInfo(address _feeToken, bool _active) external onlyOwner{

131:      function setFeeManager(address _feeM) external onlyOwner{

135:      function setVoteDelegate(address _voteDelegate) external onlyOwner{

139:      function shutdownSystem() external onlyOwner{

158:      function queueForceShutdown() external onlyOwner{

169:      function forceShutdownSystem() external onlyOwner{

180       function execute(
181           address _to,
182           uint256 _value,
183           bytes calldata _data
184:      ) external onlyOwner returns (bool, bytes memory) {

196:      function setRescueTokenDistribution(address _distributor, address _rewardDeposit, address _treasury) external onlyOwner{

201:      function setRescueTokenReward(address _token, uint256 _option) external onlyOwner{

206:      function setStashExtraReward(address _stash, address _token) external onlyOwner{

211:      function setStashRewardHook(address _stash, address _hook) external onlyOwner{

216:      function setStashFactoryImplementation(address _v1, address _v2, address _v3) external onlyOwner{

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BoosterOwner.sol#L90

32. 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 and can save gas by doing so.

There are 18 instances of this issue:

File: contracts/ExtraRewardsDistributor.sol

117:      function getReward(address _account, address _token) public {

127       function getReward(
128           address _account,
129           address _token,
130:          uint256 _startIndex

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/ExtraRewardsDistributor.sol#L117

File: contracts/AuraMerkleDrop.sol

114       function claim(
115           bytes32[] calldata _proof,
116           uint256 _amount,
117           bool _lock
118:      ) public returns (bool) {

149       function forwardPenalty() public {
150:          uint256 toForward = pendingPenalty;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraMerkleDrop.sol#L114-L118

File: contracts/AuraPenaltyForwarder.sol

47        function forward() public {
48:           require(block.timestamp > lastDistribution + distributionDelay, "!elapsed");

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraPenaltyForwarder.sol#L47-L48

File: contracts/AuraBalRewardPool.sol

138:      function stakeFor(address _for, uint256 _amount) public updateReward(_for) returns (bool) {

152       function withdraw(
153           uint256 amount,
154           bool claim,
155           bool lock
156:      ) public updateReward(msg.sender) returns (bool) {

195       function forwardPenalty() public {
196:          uint256 toForward = pendingPenalty;

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/AuraBalRewardPool.sol#L138

File: contracts/BalLiquidityProvider.sol

46:       function provideLiquidity(bytes32 _poolId, IVault.JoinPoolRequest memory _request) public {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/contracts/BalLiquidityProvider.sol#L46

File: convex-platform/contracts/contracts/ConvexMasterChef.sol

96        function add(
97            uint256 _allocPoint,
98            IERC20 _lpToken,
99            IRewarder _rewarder,
100           bool _withUpdate
101:      ) public onlyOwner {

121       function set(
122           uint256 _pid,
123           uint256 _allocPoint,
124           IRewarder _rewarder,
125           bool _withUpdate,
126           bool _updateRewarder
127:      ) public onlyOwner {

209:      function deposit(uint256 _pid, uint256 _amount) public {

239:      function withdraw(uint256 _pid, uint256 _amount) public {

283:      function emergencyWithdraw(uint256 _pid) public {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/ConvexMasterChef.sol#L96-L101

File: convex-platform/contracts/contracts/VoterProxy.sol

151:      function isValidSignature(bytes32 _hash, bytes memory) public view returns (bytes4) {

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VoterProxy.sol#L151

File: convex-platform/contracts/contracts/BaseRewardPool.sol

191       function stakeFor(address _for, uint256 _amount)
192           public
193:          returns(bool)

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/BaseRewardPool.sol#L191-L193

File: convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol

178       function withdraw(address _account, uint256 amount)
179           public
180:          updateReward(_account)

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/VirtualBalanceRewardPool.sol#L178-L180

File: convex-platform/contracts/contracts/Booster.sol

493:      function withdrawAll(uint256 _pid) public returns(bool){

https://github.com/code-423n4/2022-05-aura/blob/4989a2077546a5394e3650bf3c224669a0f7e690/convex-platform/contracts/contracts/Booster.sol#L493

@code423n4 code423n4 added bug Something isn't working G (Gas Optimization) labels May 13, 2022
code423n4 added a commit that referenced this issue May 13, 2022
@liveactionllama
Copy link
Contributor

Warden created this issue as a placeholder, because their submission was too large for the contest form. They then emailed their md file to our team on 05/13/2022. I've updated this issue with their md file content.

@0xMaharishi 0xMaharishi added the duplicate This issue or pull request already exists label May 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working duplicate This issue or pull request already exists G (Gas Optimization)
Projects
None yet
Development

No branches or pull requests

3 participants