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

6 stars 4 forks source link

Gas Optimizations #127

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

> 0 is less efficient than != 0 for uint in require condition

Ref: https://twitter.com/GalloDaSballo/status/1485430908165443590

contracts/strategies/StrategySwapper.sol:111:        require(slippageTolerance_ > 0.8e18, Error.INVALID_SLIPPAGE_TOLERANCE);
contracts/BkdLocker.sol:90:        require(amount > 0, Error.INVALID_AMOUNT);
contracts/BkdLocker.sol:91:        require(totalLockedBoosted > 0, Error.NOT_ENOUGH_FUNDS);
contracts/BkdLocker.sol:136:        require(length > 0, "No entries");
contracts/testing/MockVotingEscrow.sol:35:        require(_balances[msg.sender] > 0, "a lock needs to first be created");
contracts/testing/MockErc20Strategy.sol:65:        require(currentBalance > 0, "Invalid amount to withdraw");
contracts/testing/MockErc20Strategy.sol:75:        require(amount > 0, "Invalid amount to transfer");
contracts/testing/Curve/MockCurveSwapETH.vy:255:            assert amounts[i] > 0  # dev: initial deposit requires all coins
contracts/testing/Curve/MockCurveSwap.vy:289:            assert in_amount > 0  # dev: initial deposit requires all coins
contracts/testing/MockEthStrategy.sol:66:        require(currentBalance > 0, "Invalid amount to withdraw");
contracts/actions/topup/TopUpActionFeeHandler.sol:123:        require(totalClaimable > 0, Error.NOTHING_TO_CLAIM);
contracts/actions/topup/TopUpAction.sol:210:        require(record.singleTopUpAmount > 0, Error.INVALID_AMOUNT);
contracts/actions/topup/TopUpAction.sol:554:        require(position.totalTopUpAmount > 0, Error.INSUFFICIENT_BALANCE);
contracts/tokenomics/AmmConvexGauge.sol:159:        require(amount > 0, Error.INVALID_AMOUNT);
contracts/tokenomics/AmmConvexGauge.sol:172:        require(amount > 0, Error.INVALID_AMOUNT);
contracts/tokenomics/VestedEscrow.sol:83:        require(unallocatedSupply > 0, "No reward tokens in contract");
contracts/tokenomics/KeeperGauge.sol:138:        require(totalClaimable > 0, Error.ZERO_TRANSFER_NOT_ALLOWED);
contracts/tokenomics/AmmGauge.sol:104:        require(amount > 0, Error.INVALID_AMOUNT);
contracts/tokenomics/AmmGauge.sol:125:        require(amount > 0, Error.INVALID_AMOUNT);
contracts/pool/LiquidityPool.sol:401:        require(_depositCap > 0, Error.INVALID_AMOUNT);
contracts/pool/LiquidityPool.sol:471:        require(underlyingAmount > 0, Error.INVALID_AMOUNT);
contracts/pool/LiquidityPool.sol:473:        require(lpToken_.balanceOf(account) > 0, Error.INSUFFICIENT_BALANCE);
contracts/pool/LiquidityPool.sol:549:        require(redeemLpTokens > 0, Error.INVALID_AMOUNT);
contracts/vault/Vault.sol:164:        require(amount > 0, Error.INVALID_AMOUNT);

Float multiplication optimization

We can use the following function to save gas on float multiplications

// out = x * y unchecked{/} z
function fmul(uint256 x, uint256 y, uint256 z) internal pure returns(uint256 out){
assembly{
if iszero(eq(div(mul(x,y),x),y)) {revert(0,0)}
out := div(mul(x,y),z)
}
}

https://github.com/code-423n4/2022-04-backd/blob/c856714a50437cb33240a5964b63687c9876275b/backd/libraries/ScaledMath.sol#L19

For loop optimization

for(uint256 i; i < length; ){
  ...
  unchecked{ ++i; }
}
contracts/access/RoleManager.sol:80:        for (uint256 i = 0; i < roles.length; i++) {
contracts/Controller.sol:117:        for (uint256 i = 0; i < numActions; i++) {
contracts/strategies/ConvexStrategyBase.sol:313:        for (uint256 i = 0; i < _rewardTokens.length(); i++) {
contracts/strategies/ConvexStrategyBase.sol:380:        for (uint256 i = 0; i < _rewardTokens.length(); i++) {
contracts/StakerVault.sol:260:        for (uint256 i = 0; i < actions.length; i++) {
contracts/BkdLocker.sol:310:            for (uint256 i = 0; i < length; i++) {
contracts/actions/topup/TopUpKeeperHelper.sol:43:            for (uint256 i = 0; i < users.length; i++) {
contracts/actions/topup/TopUpKeeperHelper.sol:46:                for (uint256 j = 0; j < positions.length; j++) {
contracts/actions/topup/TopUpKeeperHelper.sol:72:        for (uint256 i = 0; i < keys.length; i++) {
contracts/actions/topup/TopUpKeeperHelper.sol:93:        for (uint256 i = 0; i < length; i++) {
contracts/actions/topup/TopUpKeeperHelper.sol:165:        for (uint256 i = 0; i < length; i++) {
contracts/actions/topup/TopUpAction.sol:188:        for (uint256 i = 0; i < protocols.length; i++) {
contracts/actions/topup/TopUpAction.sol:456:        for (uint256 i = 0; i < length; i++) {
contracts/actions/topup/TopUpAction.sol:479:        for (uint256 i = 0; i < length; i++) {
contracts/actions/topup/TopUpAction.sol:506:        for (uint256 i = 0; i < howMany; i++) {
contracts/actions/topup/TopUpAction.sol:891:        for (uint256 i = 0; i < length; i++) {
contracts/actions/topup/handlers/CTokenRegistry.sol:61:        for (uint256 i = 0; i < ctokens.length; i++) {
contracts/actions/topup/handlers/CompoundHandler.sol:135:        for (uint256 i = 0; i < assets.length; i++) {
gzeoneth commented 2 years ago

Submitted by contest judge.