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

0 stars 0 forks source link

Using immutable variables rather than local variables is cheaper #180

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Handle

WatchPug

Vulnerability details

https://github.com/livepeer/arbitrum-lpt-bridge/blob/ebf68d11879c2798c5ec0735411b08d0bea4f287/contracts/L1/gateway/L1LPTGateway.sol#L136-L159

function finalizeInboundTransfer(
    address l1Token,
    address from,
    address to,
    uint256 amount,
    bytes calldata data
) external override onlyL2Counterpart(l2Counterpart) {
    require(l1Token == l1Lpt, "TOKEN_NOT_LPT");
    (uint256 exitNum, ) = abi.decode(data, (uint256, bytes));

    uint256 escrowBalance = TokenLike(l1Token).balanceOf(l1LPTEscrow);

    // mint additional tokens if requested amount exceeds escrowed amount
    if (amount <= escrowBalance) {
        TokenLike(l1Token).transferFrom(l1LPTEscrow, to, amount);
    } else {
        if (escrowBalance > 0) {
            TokenLike(l1Token).transferFrom(l1LPTEscrow, to, escrowBalance);
        }
        IMinter(minter).bridgeMint(to, amount - escrowBalance);
    }

    emit WithdrawalFinalized(l1Token, from, to, exitNum, amount);
}

As L143 already assured that l1Token equals immutable variable l1Lpt, therefore l1Token can be replaced with immutable variable l1Lpt, to avoid local variable reads (MLOAD) to save some gas.

kautukkundan commented 2 years ago

Immutable translates to a PUSH32 opcode costs 3 gas and CALLDATALOAD opcode also costs 3 gas. So, the cost for reading l1Token and reading l1Lpt should be the same.