synapsecns/sanguine

View on GitHub
packages/contracts-core/test/suite/GasOracle.GasData.t.sol

Summary

Maintainability
Test Coverage
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import {InterfaceDestination} from "../../contracts/interfaces/InterfaceDestination.sol";
import {SummitTipTooHigh} from "../../contracts/libs/Errors.sol";

import {RawGasData, RawGasData256} from "../utils/libs/SynapseStructs.t.sol";
import {Random, GasOracle, GasOracleTest} from "./GasOracle.t.sol";

// solhint-disable func-name-mixedcase
// solhint-disable no-empty-blocks
// solhint-disable ordering
contract GasOracleGasDataTest is GasOracleTest {
    function test_setGasData_revert_notOwner(address caller) public {
        vm.assume(caller != GasOracle(gasOracle).owner());
        expectRevertNotOwner();
        vm.prank(caller);
        GasOracle(gasOracle).setGasData(0, 0, 0, 0, 0, 0, 0);
    }

    function test_setSummitTip_revert_notOwner(address caller) public {
        vm.assume(caller != GasOracle(gasOracle).owner());
        expectRevertNotOwner();
        vm.prank(caller);
        GasOracle(gasOracle).setSummitTip(0);
    }

    function test_setSummitTip_allowsUpperBound() public {
        GasOracle(gasOracle).setSummitTip(0.01 ether);
        assertEq(GasOracle(gasOracle).summitTipWei(), 0.01 ether);
    }

    function test_setSummitTip_emitsEvent() public {
        vm.expectEmit(gasOracle);
        emit SummitTipUpdated(1337);
        GasOracle(gasOracle).setSummitTip(1337);
    }

    function test_setSummitTip_revert_higherThanUpperBound() public {
        vm.expectRevert(SummitTipTooHigh.selector);
        GasOracle(gasOracle).setSummitTip(0.01 ether + 1 wei);
    }

    function test_getGasData(RawGasData256 memory rgd256) public {
        setGasData(localDomain(), rgd256);
        RawGasData memory rgd = rgd256.compress();
        assertEq(GasOracle(gasOracle).getGasData(), rgd.encodeGasData());
    }

    function test_getDecodedData(uint32 domain, RawGasData256 memory rgd256) public {
        setGasData(domain, rgd256);
        RawGasData256 memory expected = rgd256.compress().decompress();
        checkGasData(domain, expected);
    }

    function test_updateGasData_beforeIncreaseOptimisticPeriod(Random memory random, uint256 timePassed) public {
        uint32 domain = random.nextUint32();
        vm.assume(domain != 0 && domain != localDomain());
        timePassed = timePassed % GasOracle(gasOracle).GAS_DATA_INCREASED_OPTIMISTIC_PERIOD();
        RawGasData memory current = random.nextGasData();
        setGasData(domain, current.decompress());
        RawGasData memory updated = random.nextGasData();
        // Force getGasData(domain) to return (updated, timePassed)
        vm.mockCall(
            destination,
            abi.encodeWithSelector(InterfaceDestination.getGasData.selector, domain),
            abi.encode(updated.castToGasData(), timePassed)
        );
        address caller = random.nextAddress();
        vm.prank(caller);
        GasOracle(gasOracle).updateGasData(domain);
        checkGasData(domain, current.decompress());
    }

    function test_updateGasData_parametersOnlyIncreased(Random memory random, uint256 timePassed) public {
        uint32 domain = random.nextUint32();
        vm.assume(domain != 0 && domain != localDomain());
        timePassed = bound(
            timePassed,
            GasOracle(gasOracle).GAS_DATA_INCREASED_OPTIMISTIC_PERIOD(),
            GasOracle(gasOracle).GAS_DATA_DECREASED_OPTIMISTIC_PERIOD() - 1
        );
        RawGasData memory current = random.nextGasData();
        setGasData(domain, current.decompress());
        RawGasData memory updated = random.nextGasData();
        // Force getGasData(domain) to return (updated, timePassed)
        vm.mockCall(
            destination,
            abi.encodeWithSelector(InterfaceDestination.getGasData.selector, domain),
            abi.encode(updated.castToGasData(), timePassed)
        );
        address caller = random.nextAddress();
        vm.prank(caller);
        GasOracle(gasOracle).updateGasData(domain);
        RawGasData256 memory cur256 = current.decompress();
        RawGasData256 memory upd256 = updated.decompress();
        RawGasData256 memory expected = RawGasData256({
            gasPrice: max(cur256.gasPrice, upd256.gasPrice),
            dataPrice: max(cur256.dataPrice, upd256.dataPrice),
            execBuffer: max(cur256.execBuffer, upd256.execBuffer),
            amortAttCost: max(cur256.amortAttCost, upd256.amortAttCost),
            etherPrice: max(cur256.etherPrice, upd256.etherPrice),
            markup: max(cur256.markup, upd256.markup)
        });
        checkGasData(domain, expected);
    }

    function test_updateGasData_fullyUpdated(Random memory random, uint256 timePassed) public {
        uint32 domain = random.nextUint32();
        vm.assume(domain != 0 && domain != localDomain());
        timePassed = bound(timePassed, GasOracle(gasOracle).GAS_DATA_DECREASED_OPTIMISTIC_PERIOD(), 30 days);
        RawGasData memory current = random.nextGasData();
        setGasData(domain, current.decompress());
        RawGasData memory updated = random.nextGasData();
        // Force getGasData(domain) to return (updated, timePassed)
        vm.mockCall(
            destination,
            abi.encodeWithSelector(InterfaceDestination.getGasData.selector, domain),
            abi.encode(updated.castToGasData(), timePassed)
        );
        address caller = random.nextAddress();
        vm.prank(caller);
        GasOracle(gasOracle).updateGasData(domain);
        checkGasData(domain, updated.decompress());
    }

    function test_updateGasData_localDomain(Random memory random, uint256 timePassed) public {
        uint32 domain = localDomain();
        timePassed = timePassed % (2 * GasOracle(gasOracle).GAS_DATA_DECREASED_OPTIMISTIC_PERIOD());
        RawGasData memory current = random.nextGasData();
        setGasData(domain, current.decompress());
        RawGasData memory updated = random.nextGasData();
        // Force getGasData(domain) to return (updated, timePassed). Note that the current Destination
        // implementation will always return zero values for local domain, but it's good to have the
        // extra check in gas oracle as well.
        vm.mockCall(
            destination,
            abi.encodeWithSelector(InterfaceDestination.getGasData.selector, domain),
            abi.encode(updated.castToGasData(), timePassed)
        );
        address caller = random.nextAddress();
        vm.prank(caller);
        GasOracle(gasOracle).updateGasData(domain);
        // Should always return current values
        checkGasData(domain, current.decompress());
    }
}