-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AUTO-8804: create chain specific modules for l1 gas calculations #11896
Changes from all commits
93908bb
38cbca8
e5a1bd7
75a8a30
76d22eb
f70c770
91e0856
8e486d6
6533ae4
d253968
4495a08
66d140d
efb2e02
c0dfbc9
e285b03
5db66dc
125c20d
0f35ee5
fedf5cb
4c04799
2dae7dc
73f7880
f83a90d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity 0.8.19; | ||
|
||
import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol"; | ||
import {ArbGasInfo} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol"; | ||
import {ChainModuleBase} from "./ChainModuleBase.sol"; | ||
|
||
contract ArbitrumModule is ChainModuleBase { | ||
/// @dev ARB_SYS_ADDR is the address of the ArbSys precompile on Arbitrum. | ||
/// @dev reference: https://github.com/OffchainLabs/nitro/blob/v2.0.14/contracts/src/precompiles/ArbSys.sol#L10 | ||
address private constant ARB_SYS_ADDR = 0x0000000000000000000000000000000000000064; | ||
ArbSys private constant ARB_SYS = ArbSys(ARB_SYS_ADDR); | ||
|
||
/// @dev ARB_GAS_ADDR is the address of the ArbGasInfo precompile on Arbitrum. | ||
/// @dev reference: https://github.com/OffchainLabs/nitro/blob/v2.0.14/contracts/src/precompiles/ArbGasInfo.sol#L10 | ||
address private constant ARB_GAS_ADDR = 0x000000000000000000000000000000000000006C; | ||
ArbGasInfo private constant ARB_GAS = ArbGasInfo(ARB_GAS_ADDR); | ||
|
||
function blockHash(uint256 n) external view override returns (bytes32) { | ||
uint256 blockNum = ARB_SYS.arbBlockNumber(); | ||
if (n >= blockNum || blockNum - n > 256) { | ||
return ""; | ||
} | ||
return ARB_SYS.arbBlockHash(n); | ||
} | ||
|
||
function blockNumber() external view override returns (uint256) { | ||
return ARB_SYS.arbBlockNumber(); | ||
} | ||
|
||
function getCurrentL1Fee() external view override returns (uint256) { | ||
return ARB_GAS.getCurrentTxL1GasFees(); | ||
} | ||
|
||
function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { | ||
(, uint256 perL1CalldataUnit, , , , ) = ARB_GAS.getPricesInWei(); | ||
return perL1CalldataUnit * dataSize * 16; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity 0.8.19; | ||
|
||
import {IChainModule} from "../interfaces/v2_2/IChainModule.sol"; | ||
|
||
contract ChainModuleBase is IChainModule { | ||
function blockNumber() external view virtual returns (uint256) { | ||
return block.number; | ||
} | ||
|
||
function blockHash(uint256 n) external view virtual returns (bytes32) { | ||
if (n >= block.number || block.number - n > 256) { | ||
return ""; | ||
} | ||
return blockhash(n); | ||
} | ||
|
||
function getCurrentL1Fee() external view virtual returns (uint256) { | ||
return 0; | ||
} | ||
|
||
function getMaxL1Fee(uint256) external view virtual returns (uint256) { | ||
return 0; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity 0.8.19; | ||
|
||
import {OVM_GasPriceOracle} from "../../../vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol"; | ||
import {ChainModuleBase} from "./ChainModuleBase.sol"; | ||
|
||
contract OptimismModule is ChainModuleBase { | ||
/// @dev OP_L1_DATA_FEE_PADDING includes 35 bytes for L1 data padding for Optimism and BASE | ||
bytes private constant OP_L1_DATA_FEE_PADDING = | ||
hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; | ||
/// @dev OVM_GASPRICEORACLE_ADDR is the address of the OVM_GasPriceOracle precompile on Optimism. | ||
/// @dev reference: https://community.optimism.io/docs/developers/build/transaction-fees/#estimating-the-l1-data-fee | ||
address private constant OVM_GASPRICEORACLE_ADDR = 0x420000000000000000000000000000000000000F; | ||
OVM_GasPriceOracle private constant OVM_GASPRICEORACLE = OVM_GasPriceOracle(OVM_GASPRICEORACLE_ADDR); | ||
|
||
function getCurrentL1Fee() external view override returns (uint256) { | ||
return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(msg.data, OP_L1_DATA_FEE_PADDING)); | ||
} | ||
|
||
function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { | ||
// fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. | ||
// Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. | ||
bytes memory txCallData = new bytes(4 * dataSize); | ||
return OVM_GASPRICEORACLE.getL1Fee(bytes.concat(txCallData, OP_L1_DATA_FEE_PADDING)); | ||
Comment on lines
+21
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not implement similar to arbitrum to get per unit fee and multiply by data size? That will be cheaper? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if optimism exposes the per-unit fee? If so, can we create a ticket and explore in a separate thread? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sg, we can refine all chain modules in separate PRs |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity 0.8.19; | ||
|
||
import {IScrollL1GasPriceOracle} from "../../../vendor/@scroll-tech/contracts/src/L2/predeploys/IScrollL1GasPriceOracle.sol"; | ||
import {ChainModuleBase} from "./ChainModuleBase.sol"; | ||
|
||
contract ScrollModule is ChainModuleBase { | ||
/// @dev SCROLL_L1_FEE_DATA_PADDING includes 120 bytes for L1 data padding for Optimism | ||
/// @dev according to testing, this padding allows automation registry to properly estimates L1 data fee with 3-5% buffer | ||
/// @dev this MAY NOT work for a different product and this may get out of date if transmit function is changed | ||
bytes private constant SCROLL_L1_FEE_DATA_PADDING = | ||
hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; | ||
/// @dev SCROLL_ORACLE_ADDR is the address of the L1GasPriceOracle precompile on Optimism. | ||
/// @dev reference: https://docs.scroll.io/en/developers/transaction-fees-on-scroll/#estimating-the-l1-data-fee | ||
address private constant SCROLL_ORACLE_ADDR = 0x5300000000000000000000000000000000000002; | ||
IScrollL1GasPriceOracle private constant SCROLL_ORACLE = IScrollL1GasPriceOracle(SCROLL_ORACLE_ADDR); | ||
|
||
function getCurrentL1Fee() external view override returns (uint256) { | ||
return SCROLL_ORACLE.getL1Fee(bytes.concat(msg.data, SCROLL_L1_FEE_DATA_PADDING)); | ||
} | ||
|
||
function getMaxL1Fee(uint256 dataSize) external view override returns (uint256) { | ||
// fee is 4 per 0 byte, 16 per non-zero byte. Worst case we can have all non zero-bytes. | ||
// Instead of setting bytes to non-zero, we initialize 'new bytes' of length 4*dataSize to cover for zero bytes. | ||
FelixFan1992 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// this is the same as OP. | ||
bytes memory txCallData = new bytes(4 * dataSize); | ||
return SCROLL_ORACLE.getL1Fee(bytes.concat(txCallData, SCROLL_L1_FEE_DATA_PADDING)); | ||
} | ||
} |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity ^0.8.0; | ||
|
||
interface IChainModule { | ||
// retrieve the native block number of a chain. e.g. L2 block number on Arbitrum | ||
function blockNumber() external view returns (uint256); | ||
|
||
// retrieve the native block hash of a chain. | ||
function blockHash(uint256) external view returns (bytes32); | ||
|
||
// retrieve the L1 data fee for a L2 transaction. it should return 0 for L1 chains and | ||
// L2 chains which don't have L1 fee component. it uses msg.data to estimate L1 data so | ||
// it must be used with a transaction. | ||
function getCurrentL1Fee() external view returns (uint256); | ||
|
||
// retrieve the L1 data fee for a L2 simulation. it should return 0 for L1 chains and | ||
// L2 chains which don't have L1 fee component. | ||
function getMaxL1Fee(uint256 dataSize) external view returns (uint256); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the multiplication by 16 here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will add a comment, this is ARB specific.
fee is 4 per 0 byte, 16 per non-zero byte - we assume all non-zero and
max data size to calculate max payment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add that comment back in here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's refine all chain modules in separate PRs, I think this can be improved further by multiplying by the scalar value, will investigate more