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

1 stars 0 forks source link

`validateWeights()` Cache length in the for loops can save gas #132

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

Handle

WatchPug

Vulnerability details

Reading array length at each iteration of the loop takes 6 gas (3 for mload and 3 to place memory_offset) in the stack.

Caching the array length in the stack saves around 3 gas per iteration.

Several instances include:

https://github.com/code-423n4/2021-09-defiProtocol/blob/main/contracts/contracts/Basket.sol#L224-L242

https://github.com/code-423n4/2021-09-defiProtocol/blob/main/contracts/contracts/Factory.sol#L103

https://github.com/code-423n4/2021-09-defiProtocol/blob/main/contracts/contracts/Auction.sol#L81

https://github.com/code-423n4/2021-09-defiProtocol/blob/main/contracts/contracts/Auction.sol#L85

https://github.com/code-423n4/2021-09-defiProtocol/blob/main/contracts/contracts/Auction.sol#L96

https://github.com/code-423n4/2021-09-defiProtocol/blob/main/contracts/contracts/Auction.sol#L142

For example:

function pushUnderlying(uint256 amount, address to) private {
    for (uint256 i = 0; i < weights.length; i++) {
        uint256 tokenAmount = amount * weights[i] * ibRatio / BASE / BASE;
        IERC20(tokens[i]).safeTransfer(to, tokenAmount);
    }
}

Can be changed to:

function pushUnderlying(uint256 amount, address to) private {
    uint256 length = weights.length;
    for (uint256 i = 0; i < length; i++) {
        uint256 tokenAmount = amount * weights[i] * ibRatio / BASE / BASE;
        IERC20(tokens[i]).safeTransfer(to, tokenAmount);
    }
}
GalloDaSballo commented 2 years ago

Duplicate of #230