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 #174

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

Gas Optimizations #174

code423n4 opened this issue May 28, 2022 · 1 comment
Labels
bug Something isn't working G (Gas Optimization)

Comments

@code423n4
Copy link
Contributor

code423n4 commented May 28, 2022

GAS OPTIMIZATION:

  1. There are two places where we increment the state variable first and then return it as a function output. This is wasting gas.
    For example:
    last_stratTrade_id++;
    return last_stratTrade_id;

can be rewritten as:

   return ++last_stratTrade_id;

a. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathPair.sol#L206
b. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/RubiconMarket.sol#L436
2. There are lot of places where we could avoid reading multiple times from storage by just using a temporary variable in memory to hold the storage value.
For example:
(totalSupply == 0) ? shares = assets : shares = (
assets.mul(totalSupply)
).div(totalAssets());

Can be written as:
uint256 ts = totalSupply;
(ts == 0) ? shares = assets : shares = (
assets.mul(ts)
).div(totalAssets());
This particular example saves one extra storage read. Storage read is 100 gas while memory read is only 3 gas!

See the below reference links and the storage location we are reading multiple times.
a. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathPair.sol#L177 for IBathHouse(bathHouse).reserveRatio()
b. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathToken.sol#L399 for totalSupply.
c. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathToken.sol#L457 for totalSupply.
d. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathToken.sol#L569 for totalSupply.
e. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathToken.sol#L703 for allowance[from][msg.sender].
f. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/RubiconMarket.sol#L829 for offers[offerId].buy_amt, offers[offerId].pay_amt
g. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/RubiconMarket.sol#L868 for offers[offerId].buy_amt, offers[offerId].pay_amt
h. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/RubiconMarket.sol#L909 for offers[offerId].buy_amt, offers[offerId].pay_amt
i. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/RubiconMarket.sol#L933 for offers[offerId].buy_amt, offers[offerId].pay_amt
j. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/RubiconMarket.sol#L1170 for _rank[id].
k. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/peripheral_contracts/BathBuddy.sol#L149 for "start".

  1. Emit the function input instead of the storage variable. See references below:
    a. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/RubiconMarket.sol#L749
    b. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/RubiconMarket.sol#L766

  2. The if block can be outside the for loop. And the for loop can start with an "index" value of 1. This reduces the gas for checking "index == 0" in every iteration.
    https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/RubiconRouter.sol#L86

  3. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathPair.sol#L236 to Line 241 can be changed like this(see Line 226 for the equation):

    if (offer1.pay_amt != 0) { //changed here
    IBathToken(bathAssetAddress).cancel(
    info.askId,
    offer1.pay_amt //changed here
    );
    }
    Same logic can be applied line 256 line 261. Modified if statement will look like this(see Line 227 for the equation):

    if (offer2.pay_amt != 0) {
    IBathToken(bathQuoteAddress).cancel(
    info.bidId,
    offer2.pay_amt
    );
    }

https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathHouse.sol#L52
right under line 38 of the same file, to save one slot of storage.

c. https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathHouse.sol#L43
reserveRatio(as its max value is 100) can be declared as uint64 or even uint8, and combine with the declarations mentioned in the above point(b) to save one slot of storage.

@code423n4 code423n4 added bug Something isn't working G (Gas Optimization) labels May 28, 2022
code423n4 added a commit that referenced this issue May 28, 2022
@itsmetechjay
Copy link

Warden wanted to submit an updated gas optimization report removing some items per help desk request. Updated the report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working G (Gas Optimization)
Projects
None yet
Development

No branches or pull requests

2 participants