code-423n4 / 2021-12-defiprotocol-findings

0 stars 0 forks source link

`Basket.sol#pullUnderlying()` Cache and read storage variables from the stack can save gas #105

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

Handle

WatchPug

Vulnerability details

For the storage variables that will be accessed multiple times, cache and read from the stack can save ~100 gas from each extra read (SLOAD after Berlin).

For example:

ibRatio is used in for loop, cache and read from the stack can save gas.

https://github.com/code-423n4/2021-12-defiprotocol/blob/205d3766044171e325df6a8bf2e79b37856eece1/contracts/contracts/Basket.sol#L288-L294

function pullUnderlying(uint256 amount, address from) private {
        for (uint256 i = 0; i < weights.length; i++) {
            uint256 tokenAmount = amount * weights[i] * ibRatio / BASE / BASE;
            require(tokenAmount > 0);
            IERC20(tokens[i]).safeTransferFrom(from, address(this), tokenAmount);
        }
    }

Recommendation

Change to:

function pullUnderlying(uint256 amount, address from) private {
        uint256 _ibRatio = ibRatio;
        for (uint256 i = 0; i < weights.length; i++) {
            uint256 tokenAmount = amount * weights[i] * _ibRatio / BASE / BASE;
            require(tokenAmount > 0);
            IERC20(tokens[i]).safeTransferFrom(from, address(this), tokenAmount);
        }
    }
0xleastwood commented 2 years ago

Duplicate of #49