code-423n4 / 2022-04-backd-findings

6 stars 4 forks source link

Gas Optimizations #188

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago
GAS

G-01: Unnecessary if statement in processExpiredLocks

CvxCrvRewardsLocker.processExpiredLocks; L133-L145

Gas could be saved by changing:

    function processExpiredLocks(bool relock) external override returns (bool) {
        if (relock) {
            require(!prepareWithdrawal, Error.PREPARED_WITHDRAWAL);
        }

        if (relock) {
            ICvxLocker(CVX_LOCKER).processExpiredLocks(relock);
        } else {
            ICvxLocker(CVX_LOCKER).withdrawExpiredLocksTo(treasury);
        }

        return true;
    }

To:

    function processExpiredLocks(bool relock) external override returns (bool) {
        if (relock) {
            require(!prepareWithdrawal, Error.PREPARED_WITHDRAWAL);
            ICvxLocker(CVX_LOCKER).processExpiredLocks(relock);
        } else {
            ICvxLocker(CVX_LOCKER).withdrawExpiredLocksTo(treasury);
        }

        return true;
    }

G-02: Changing parameters order could save some gas

TopUpActionFeeHandler.payFees#L81-L109

If lpToken.safeTransferFrom reverts keeperAmount and treasuryAmount will be unnecessarily calculated.

uint256 keeperAmount = amount.scaledMul(getKeeperFeeFraction());
uint256 treasuryAmount = amount.scaledMul(getTreasuryFeeFraction());
LpToken lpToken = LpToken(lpTokenAddress);

lpToken.safeTransferFrom(msg.sender, address(this), amount);

I suggest setting keeperAmount and treasuryAmount after lpToken.safeTransferFrom as seen below.


LpToken lpToken = LpToken(lpTokenAddress);

lpToken.safeTransferFrom(msg.sender, address(this), amount);

uint256 keeperAmount = amount.scaledMul(getKeeperFeeFraction());
uint256 treasuryAmount = amount.scaledMul(getTreasuryFeeFraction());

Ga-03: For loop in hasAnyRole can be more gas efficient

RoleManager.hasAnyRole#L73-L86

In summary I suggest changing it from:

for (uint256 i = 0; i < roles.length; i++) {
    if (hasRole(roles[i], account)) {
        return true;
    }
}

To:

size = roles.length;
for (uint256 i; i < size; ++i) {
    if (hasRole(roles[i], account)) {
        return true;
    }
}

Also valid for(list not exhaustive):