packages/contracts-core/test/suite/GasOracle.GasData.t.sol
// 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());
}
}