code-423n4 / 2022-01-trader-joe-findings

2 stars 0 forks source link

Cache external call results can save gas #236

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Handle

WatchPug

Vulnerability details

Every call to an external contract costs a decent amount of gas. For optimization of gas usage, external call results should be cached if they are being used for more than one time.

For example:

factory.getPair(wavaxAddress, tokenAddress) and factory.getPair(tokenAddress, wavaxAddress) in LaunchEvent#createPair()

https://github.com/code-423n4/2022-01-trader-joe/blob/a1579f6453bc4bf9fb0db9c627beaa41135438ed/contracts/LaunchEvent.sol#L377-L435

function createPair() external isStopped(false) atPhase(Phase.PhaseThree) {
    // ...
    require(
        factory.getPair(wavaxAddress, tokenAddress) == address(0) ||
            IJoePair(
                IJoeFactory(factory).getPair(wavaxAddress, tokenAddress)
            ).totalSupply() ==
            0,
        "LaunchEvent: liquid pair already exists"
    );
    // ...
    pair = IJoePair(factory.getPair(tokenAddress, wavaxAddress));
    // ...
}

note: factory.getPair(a, b)factory.getPair(b, a) 相同, see code at github or code at avascan

getPair[token0][token1] = pair;
getPair[token1][token0] = pair; // populate mapping in the reverse direction

IJoeFactory(factory).getPair(_token, wavax) in RocketJoeFactory#createRJLaunchEvent()

https://github.com/code-423n4/2022-01-trader-joe/blob/a1579f6453bc4bf9fb0db9c627beaa41135438ed/contracts/RocketJoeFactory.sol#L122-L128

require(
    IJoeFactory(factory).getPair(_token, wavax) == address(0) ||
        IJoePair(IJoeFactory(factory).getPair(_token, wavax))
            .totalSupply() ==
        0,
    "RJFactory: liquid pair already exists"
);

token.decimals() in LaunchEvent#createPair()

https://github.com/code-423n4/2022-01-trader-joe/blob/a1579f6453bc4bf9fb0db9c627beaa41135438ed/contracts/LaunchEvent.sol#L395-L405

if (
    floorPrice > (wavaxReserve * 10**token.decimals()) / tokenAllocated
) {
    tokenAllocated = (wavaxReserve * 10**token.decimals()) / floorPrice;
    // ...
}
cryptofish7 commented 2 years ago

Fix: https://github.com/traderjoe-xyz/rocket-joe/pull/144