code-423n4 / 2022-01-timeswap-findings

2 stars 0 forks source link

Gas Optimization: Cache result of `BlockNumber.get()` #142

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Handle

gzeon

Vulnerability details

Impact

Result of BlockNumber.get() can be cached before the for loop.

        for (uint256 i; i < ids.length; i++) {
            Due storage due = dues[ids[i]];
            require(due.startBlock != BlockNumber.get(), 'E207');

to

        uint32 bn32 = BlockNumber.get();
        for (uint256 i; i < ids.length; i++) {
            Due storage due = dues[ids[i]];
            require(due.startBlock != bn32, 'E207');

Proof of Concept

https://github.com/code-423n4/2022-01-timeswap/blob/bf50d2a8bb93a5571f35f96bd74af54d9c92a210/Timeswap/Timeswap-V1-Core/contracts/TimeswapPair.sol#L361

Mathepreneur commented 2 years ago

We get stack too deep error.

0xean commented 2 years ago

ditto previous comments....

To prove the point to the sponsor this compiles currently by scoping in brackets.


        Due[] storage dues = pool.dues[owner];
        {
          uint32 bn32 = BlockNumber.get();
          for (uint256 i; i < ids.length; i++) {
              Due storage due = dues[ids[i]];
              require(due.startBlock != bn32, 'E207');
              if (owner != msg.sender) require(collateralsOut[i] == 0, 'E213');
              PayMath.checkProportional(assetsIn[i], collateralsOut[i], due);
              due.debt -= assetsIn[i];
              due.collateral -= collateralsOut[i];
              assetIn += assetsIn[i];
              collateralOut += collateralsOut[i];
          }
        }
        if (assetIn > 0) Callback.pay(asset, assetIn, data);