code-423n4 / 2022-05-aura-findings

0 stars 1 forks source link

Gas Optimizations #317

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

gas

1. Title: Unnecessary math operation and SLOAD in mint()

https://github.com/code-423n4/2022-05-aura/blob/main/contracts/Aura.sol#L101

minterMinted is a variable which set to 0 when init() is called. The mint() function checks that totalSupply() != 0 at L67 (which mean this function only able to be call after init() was executes and set minterMinted = 0). So subtraction at L101 is an unnecessary math operation and SLOAD. I recommend to remove minterMinted var at L101

2. Title: Do math operation directly

Occurrence: https://github.com/code-423n4/2022-05-aura/blob/main/contracts/Aura.sol#L52 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/Aura.sol#L104 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/Aura.sol#L111 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/Aura.sol#L115 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/Aura.sol#L117 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/AuraBalRewardPool.sol#L109

Calling auraMath.function to do a simple math (add, sub, mul, and div) is not an effective way. Using simple math operator (+, -, *, /) is way more efficient and increase the readability of the code.

3. Title: Initialization var with default value

Occurrences: https://github.com/code-423n4/2022-05-aura/blob/main/contracts/AuraBalRewardPool.sol#L35 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/AuraBalRewardPool.sol#L38-L39 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/AuraLocker.sol#L72

Set a storage with default value (0 for uint) is gas consuming. Declaring without value can save gas RECOMMENDATION MITIGATION STEP

    uint pendingPenalty; //@audit-info: Remove = 0

4. Title: Using != operator instead <

Occurrences: https://github.com/code-423n4/2022-05-aura/blob/main/contracts/Aura.sol#L68 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/AuraBalRewardPool.sol#L121 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/AuraBalRewardPool.sol#L139 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/AuraBalRewardPool.sol#L210 https://github.com/code-423n4/2022-05-aura/blob/main/contracts/AuraLocker.sol#L210

Using != to validate var is not zero is way more effective than using < operator.

5. Title: Var can be set immutable

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

_name and _symbol are set once in the constructor. Set it immutable can save gas

6. Title: Saving 1 storage slot in AuraLocker contract

https://github.com/code-423n4/2022-05-aura/blob/main/contracts/AuraLocker.sol#L114

Each 1 storage slot in solidity can store 32 bytes size. Address has 20 bytes size and 1 bytes for bool data type. By locating bool next to address can save 1 slot (instead put bool next to uint in current implementation). Change to:

address public immutable cvxcrvStaking;
bool public isShutdown = false; // @audit-info: Move isShutdown next to any address in the contract

7. Title: Using prefix increment and unchecked for i inside the for() loop

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

Using prefix increment and unchecked can save gas each we doing loop Change to:

            for (uint256 i = 0; i < rewardTokensLength;) {
                address token = rewardTokens[i];
                uint256 newRewardPerToken = _rewardPerToken(token);
                rewardData[token].rewardPerTokenStored = newRewardPerToken.to96();
                rewardData[token].lastUpdateTime = _lastTimeRewardApplicable(rewardData[token].periodFinish).to32();
                if (_account != address(0)) {
                    userData[_account][token] = UserData({
                        rewardPerTokenPaid: newRewardPerToken.to128(),
                        rewards: _earned(_account, token, userBalance.locked).to128()
                    });
                }
        unchecked{++i;}
            }

8. Title: Use only 1 SafeApprove call

https://github.com/code-423n4/2022-05-aura/blob/main/contracts/AuraLocker.sol#L239-L242

Doing two approve calls when we could just use one. Doing two safeApprove calls with value = 0 and after value = max doesn't seem to provide any extra feature.