Skip to content
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

VRFV2Plus L1 fee calculation updates for Optimism and Base #13335

Merged
merged 45 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
4cc63ce
VRFV2Plus wrapper L1 fee calculation updates for Optimism and Base
ibrajer May 27, 2024
5428624
Fixed tx revert in the wrapper deploy universe superscript
ibrajer May 27, 2024
2a42dc6
Contract fixes and new superscript command
ibrajer May 27, 2024
bcdaa9b
Updated pnpm lockfile
ibrajer May 27, 2024
ad838c2
Fixed Optimism L1 transaction padding bytes size
ibrajer May 28, 2024
c6ef9e3
Added L1 fee calculation options to coordinator and wrapper
ibrajer Jun 5, 2024
06d9c71
Updated gethwrappers
ibrajer Jun 5, 2024
104725e
Reverted s_coordinatorLinkPremiumPercentage back to private
ibrajer Jun 5, 2024
a368b76
Added more comments for different L1 fee calculations
ibrajer Jun 5, 2024
9c8a574
Added coefficient to L1 gas calculation
ibrajer Jun 5, 2024
8c08efb
Removed obsolete superscript command
ibrajer Jun 5, 2024
e0a5d5b
Updated pnpm lockfile
ibrajer Jun 5, 2024
d03df82
Solhint fixes
ibrajer Jun 5, 2024
8028733
Fixed wrapper revert issue
ibrajer Jun 5, 2024
8092e0f
Fixed superscript linter error
ibrajer Jun 5, 2024
e31ca8b
Another superscript fix
ibrajer Jun 5, 2024
e8e9ff2
Optimize remove consumer gas and bytecode. Remove redundant operations
leeyikjiun Jun 6, 2024
b7d9c8d
Revert calldata to memory for several functions in VRFCoordinator
ibrajer Jun 6, 2024
ba233f0
Fixed all nits and reverted ChainSpecificUtil
ibrajer Jun 6, 2024
bd57634
Removed unnecessary deps from package.json and reduced compiler warnings
ibrajer Jun 6, 2024
cfc1c66
Brought back semver package (removed by accident)
ibrajer Jun 6, 2024
ed934ed
Move L1_UNSIGNED_RLP_ENC_TX_DATA_BYTES_SIZE higher up
ibrajer Jun 7, 2024
25a2d89
Foundry tests for new L2 chain VRF coordinators
ibrajer Jun 7, 2024
bdb864b
Diverged wrapper contract and introduce L1GasFee event
ibrajer Jun 10, 2024
783fe02
Add tests to check emitting L1GasFee event
ibrajer Jun 11, 2024
1655358
Wrapper tests and fix for L1 gas calculation setter on the wrapper
ibrajer Jun 11, 2024
9ee8ddd
Fixed getBlockhash Foundry test for Arbitrum coordinator
ibrajer Jun 12, 2024
07e960a
Addressed more comments, minor contract fixes and test updates
ibrajer Jun 12, 2024
59f6eee
Updated VRF superscripts to support diverged contracts
ibrajer Jun 12, 2024
d73ddca
Merge branch 'develop' into bugfix/VRF-1011-wrapper-gas-calculation
ibrajer Jun 12, 2024
923b218
Updated Hardhat config and go_generate script with new contracts
ibrajer Jun 14, 2024
9e1b604
Trimmed down vendor code around Optimism GasPriceOracle contract
ibrajer Jun 17, 2024
8db302b
Update proof and rc from memory to calldata
leeyikjiun Jun 11, 2024
2a95e69
Merge 8db302b03c7a3eaf6f2962ab63744de8bdb7f5e8 into 31c0cb7c474dedcc3…
ibrajer Jun 20, 2024
e6cc972
Update gethwrappers
app-token-issuer-infra-releng[bot] Jun 20, 2024
54582fd
Merge branch 'develop' into bugfix/VRF-1011-wrapper-gas-calculation
ibrajer Jun 20, 2024
9abf16d
Fixed CI issues with formatting and gethwrapper generator
ibrajer Jun 20, 2024
d269e60
Updated VRFv2 gethwrappers
ibrajer Jun 20, 2024
24297f4
Fixed TestIntegrationVRFV2 test failure
ibrajer Jun 20, 2024
a4e2ab1
Fixed failing Foundry tests
ibrajer Jun 20, 2024
cdf0214
Merge branch 'develop' into bugfix/VRF-1011-wrapper-gas-calculation
ibrajer Jul 3, 2024
4bd9928
Fixed broken hardhat config
ibrajer Jul 3, 2024
654895d
BatchVRFCoordinatorV2Plus Foundry test fixed and added changesets
ibrajer Jul 3, 2024
8da5e5e
Merge branch 'develop' into bugfix/VRF-1011-wrapper-gas-calculation
ibrajer Jul 4, 2024
0eeeae6
Merge branch 'develop' into bugfix/VRF-1011-wrapper-gas-calculation
ibrajer Jul 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/proud-zoos-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

VRFV2Plus coordinator and wrapper split contracts between L1 and L2 chains #updated
5 changes: 5 additions & 0 deletions contracts/.changeset/proud-turkeys-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chainlink/contracts': patch
---

VRFV2Plus coordinator and wrapper split contracts between L1 and L2 chains #updated
24 changes: 24 additions & 0 deletions contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,30 @@ let config = {
},
},
},
'src/v0.8/vrf/dev/VRFCoordinatorV2_5_Arbitrum.sol': {
version: '0.8.19',
settings: {
optimizer: {
enabled: true,
runs: 500, // see native_solc_compile_all_vrf
},
metadata: {
bytecodeHash: 'none',
},
},
},
'src/v0.8/vrf/dev/VRFCoordinatorV2_5_Optimism.sol': {
version: '0.8.19',
settings: {
optimizer: {
enabled: true,
runs: 500, // see native_solc_compile_all_vrf
},
metadata: {
bytecodeHash: 'none',
},
},
},
'src/v0.8/automation/AutomationForwarderLogic.sol': {
version: '0.8.19',
settings: COMPILER_SETTINGS,
Expand Down
14 changes: 11 additions & 3 deletions contracts/scripts/native_solc_compile_all_vrf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ compileContract () {
local contract
contract=$(basename "$1" ".sol")

solc @openzeppelin/="$ROOT"/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \
solc @openzeppelin/="$ROOT"/contracts/node_modules/@openzeppelin/ \
--overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \
-o "$ROOT"/contracts/solc/v$SOLC_VERSION/"$contract" \
--abi --bin --allow-paths "$ROOT"/contracts/src/v0.8,"$ROOT"/contracts/node_modules\
"$ROOT"/contracts/src/v0.8/"$1"
Expand All @@ -31,7 +32,8 @@ compileContractAltOpts () {
local contract
contract=$(basename "$1" ".sol")

solc @openzeppelin/="$ROOT"/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs "$2" --metadata-hash none \
solc @openzeppelin/="$ROOT"/contracts/node_modules/@openzeppelin/ \
--overwrite --optimize --optimize-runs "$2" --metadata-hash none \
-o "$ROOT"/contracts/solc/v$SOLC_VERSION/"$contract" \
--abi --bin --allow-paths "$ROOT"/contracts/src/v0.8,"$ROOT"/contracts/node_modules\
"$ROOT"/contracts/src/v0.8/"$1"
Expand Down Expand Up @@ -97,8 +99,12 @@ export SOLC_VERSION=$SOLC_VERSION
compileContract vrf/dev/interfaces/IVRFCoordinatorV2PlusInternal.sol
compileContract vrf/dev/testhelpers/VRFV2PlusConsumerExample.sol
compileContractAltOpts vrf/dev/VRFCoordinatorV2_5.sol 500
compileContractAltOpts vrf/dev/VRFCoordinatorV2_5_Arbitrum.sol 500
compileContractAltOpts vrf/dev/VRFCoordinatorV2_5_Optimism.sol 500
compileContract vrf/dev/BatchVRFCoordinatorV2Plus.sol
compileContract vrf/dev/VRFV2PlusWrapper.sol
compileContract vrf/dev/VRFV2PlusWrapper_Arbitrum.sol
compileContract vrf/dev/VRFV2PlusWrapper_Optimism.sol
compileContract vrf/dev/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol
compileContract vrf/dev/testhelpers/VRFMaliciousConsumerV2Plus.sol
compileContract vrf/dev/testhelpers/VRFV2PlusExternalSubOwnerExample.sol
Expand All @@ -113,5 +119,7 @@ compileContract vrf/dev/TrustedBlockhashStore.sol
compileContract vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol
compileContractAltOpts vrf/dev/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol 5
compileContract vrf/dev/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol
compileContract vrf/testhelpers/VRFMockETHLINKAggregator.sol
compileContract vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol
compileContract vrf/BatchBlockhashStore.sol
compileContract vrf/dev/BlockhashStore.sol
compileContract vrf/dev/BlockhashStore.sol
12 changes: 9 additions & 3 deletions contracts/scripts/native_solc_compile_all_vrfv2plus
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ compileContract () {
local contract
contract=$(basename "$1" ".sol")

solc @openzeppelin/="$ROOT"/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \
solc @openzeppelin/="$ROOT"/contracts/node_modules/@openzeppelin/ \
--overwrite --optimize --optimize-runs $OPTIMIZE_RUNS --metadata-hash none \
-o "$ROOT"/contracts/solc/v$SOLC_VERSION/"$contract" \
--abi --bin --allow-paths "$ROOT"/contracts/src/v0.8,"$ROOT"/contracts/node_modules\
"$ROOT"/contracts/src/v0.8/"$1"
Expand All @@ -31,7 +32,8 @@ compileContractAltOpts () {
local contract
contract=$(basename "$1" ".sol")

solc @openzeppelin/="$ROOT"/contracts/node_modules/@openzeppelin/ --overwrite --optimize --optimize-runs "$2" --metadata-hash none \
solc @openzeppelin/="$ROOT"/contracts/node_modules/@openzeppelin/ \
--overwrite --optimize --optimize-runs "$2" --metadata-hash none \
-o "$ROOT"/contracts/solc/v$SOLC_VERSION/"$contract" \
--abi --bin --allow-paths "$ROOT"/contracts/src/v0.8,"$ROOT"/contracts/node_modules\
"$ROOT"/contracts/src/v0.8/"$1"
Expand All @@ -41,8 +43,12 @@ compileContractAltOpts () {
compileContract vrf/dev/interfaces/IVRFCoordinatorV2PlusInternal.sol
compileContract vrf/dev/testhelpers/VRFV2PlusConsumerExample.sol
compileContractAltOpts vrf/dev/VRFCoordinatorV2_5.sol 500
compileContractAltOpts vrf/dev/VRFCoordinatorV2_5_Arbitrum.sol 500
compileContractAltOpts vrf/dev/VRFCoordinatorV2_5_Optimism.sol 500
compileContract vrf/dev/BatchVRFCoordinatorV2Plus.sol
compileContract vrf/dev/VRFV2PlusWrapper.sol
compileContract vrf/dev/VRFV2PlusWrapper_Arbitrum.sol
compileContract vrf/dev/VRFV2PlusWrapper_Optimism.sol
compileContract vrf/dev/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol
compileContract vrf/dev/testhelpers/VRFMaliciousConsumerV2Plus.sol
compileContract vrf/dev/testhelpers/VRFV2PlusExternalSubOwnerExample.sol
Expand All @@ -60,4 +66,4 @@ compileContract vrf/dev/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol
compileContract vrf/testhelpers/VRFMockETHLINKAggregator.sol
compileContract vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol
compileContract vrf/BatchBlockhashStore.sol
compileContract vrf/dev/BlockhashStore.sol
compileContract vrf/dev/BlockhashStore.sol
2 changes: 1 addition & 1 deletion contracts/src/v0.8/ChainSpecificUtil.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ library ChainSpecificUtil {
* @notice Returns the L1 fees that will be paid for the current transaction, given any calldata
* @notice for the current transaction.
* @notice When on a known Arbitrum chain, it uses ArbGas.getCurrentTxL1GasFees to get the fees.
* @notice On Arbitrum, the provided calldata is not used to calculate the fees.
* @notice On Arbitrum, there's no need to pass the provided calldata
* @notice On Optimism, the provided calldata is passed to the OVM_GasPriceOracle predeploy
* @notice and getL1Fee is called to get the fees.
*/
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/v0.8/ChainSpecificUtil_v0_8_6.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ library ChainSpecificUtil {
* @notice Returns the L1 fees that will be paid for the current transaction, given any calldata
* @notice for the current transaction.
* @notice When on a known Arbitrum chain, it uses ArbGas.getCurrentTxL1GasFees to get the fees.
* @notice On Arbitrum, the provided calldata is not used to calculate the fees.
* @notice On Arbitrum, there's no need to pass the provided calldata
* @notice On Optimism, the provided calldata is passed to the OVM_GasPriceOracle predeploy
* @notice and getL1Fee is called to get the fees.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

/// @notice: IMPORTANT NOTICE for anyone who wants to use this contract
/// @notice Source: https://github.com/ethereum-optimism/optimism/blob/71b93116738ee98c9f8713b1a5dfe626ce06c1b2/packages/contracts-bedrock/src/L2/GasPriceOracle.sol
/// @notice The original code was trimmed down to include only the necessary interface elements required to interact with GasPriceOracle
/// @notice We need this file so that Solidity compiler will not complain because some functions don't exist
/// @notice In reality, we don't embed this code into our own contracts, instead we make cross-contract calls on predeployed GasPriceOracle contract

import {ISemver} from "../universal/ISemver.sol";
import {Predeploys} from "../libraries/Predeploys.sol";
import {L1Block} from "../L2/L1Block.sol";
import {Constants} from "../libraries/Constants.sol";
import {LibZip} from "../deps/LibZip.sol";

/// @custom:proxied
/// @custom:predeploy 0x420000000000000000000000000000000000000F
/// @title GasPriceOracle
/// @notice This contract maintains the variables responsible for computing the L1 portion of the
/// total fee charged on L2. Before Bedrock, this contract held variables in state that were
/// read during the state transition function to compute the L1 portion of the transaction
/// fee. After Bedrock, this contract now simply proxies the L1Block contract, which has
/// the values used to compute the L1 portion of the fee in its state.
///
/// The contract exposes an API that is useful for knowing how large the L1 portion of the
/// transaction fee will be. The following events were deprecated with Bedrock:
/// - event OverheadUpdated(uint256 overhead);
/// - event ScalarUpdated(uint256 scalar);
/// - event DecimalsUpdated(uint256 decimals);
contract GasPriceOracle is ISemver {
/// @notice Number of decimals used in the scalar.
uint256 public constant DECIMALS = 6;

/// @notice Semantic version.
/// @custom:semver 1.3.0
string public constant version = "1.3.0";

/// @notice This is the intercept value for the linear regression used to estimate the final size of the
/// compressed transaction.
int32 private constant COST_INTERCEPT = -42_585_600;

/// @notice This is the coefficient value for the linear regression used to estimate the final size of the
/// compressed transaction.
uint32 private constant COST_FASTLZ_COEF = 836_500;

/// @notice This is the minimum bound for the fastlz to brotli size estimation. Any estimations below this
/// are set to this value.
uint256 private constant MIN_TRANSACTION_SIZE = 100;

/// @notice Indicates whether the network has gone through the Ecotone upgrade.
bool public isEcotone;

/// @notice Indicates whether the network has gone through the Fjord upgrade.
bool public isFjord;

/// @notice Computes the L1 portion of the fee based on the size of the rlp encoded input
/// transaction, the current L1 base fee, and the various dynamic parameters.
/// @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.
/// @return L1 fee that should be paid for the tx
function getL1Fee(bytes memory _data) external view returns (uint256) {
if (isFjord) {
return _getL1FeeFjord(_data);
} else if (isEcotone) {
return _getL1FeeEcotone(_data);
}
return _getL1FeeBedrock(_data);
}

/// @notice returns an upper bound for the L1 fee for a given transaction size.
/// It is provided for callers who wish to estimate L1 transaction costs in the
/// write path, and is much more gas efficient than `getL1Fee`.
/// It assumes the worst case of fastlz upper-bound which covers %99.99 txs.
/// @param _unsignedTxSize Unsigned fully RLP-encoded transaction size to get the L1 fee for.
/// @return L1 estimated upper-bound fee that should be paid for the tx
function getL1FeeUpperBound(uint256 _unsignedTxSize) external view returns (uint256) {
require(isFjord, "GasPriceOracle: getL1FeeUpperBound only supports Fjord");

// Add 68 to the size to account for unsigned tx:
uint256 txSize = _unsignedTxSize + 68;
// txSize / 255 + 16 is the pratical fastlz upper-bound covers %99.99 txs.
uint256 flzUpperBound = txSize + txSize / 255 + 16;

return _fjordL1Cost(flzUpperBound);
}

/// @notice Set chain to be Ecotone chain (callable by depositor account)
function setEcotone() external {
require(
msg.sender == Constants.DEPOSITOR_ACCOUNT,
"GasPriceOracle: only the depositor account can set isEcotone flag"
);
require(isEcotone == false, "GasPriceOracle: Ecotone already active");
isEcotone = true;
}

/// @notice Set chain to be Fjord chain (callable by depositor account)
function setFjord() external {
require(
msg.sender == Constants.DEPOSITOR_ACCOUNT,
"GasPriceOracle: only the depositor account can set isFjord flag"
);
require(isEcotone, "GasPriceOracle: Fjord can only be activated after Ecotone");
require(isFjord == false, "GasPriceOracle: Fjord already active");
isFjord = true;
}

/// @notice Retrieves the current gas price (base fee).
/// @return Current L2 gas price (base fee).
function gasPrice() public view returns (uint256) {
return block.basefee;
}

/// @notice Retrieves the current base fee.
/// @return Current L2 base fee.
function baseFee() public view returns (uint256) {
return block.basefee;
}

/// @custom:legacy
/// @notice Retrieves the current fee overhead.
/// @return Current fee overhead.
function overhead() public view returns (uint256) {
require(!isEcotone, "GasPriceOracle: overhead() is deprecated");
return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead();
}

/// @custom:legacy
/// @notice Retrieves the current fee scalar.
/// @return Current fee scalar.
function scalar() public view returns (uint256) {
require(!isEcotone, "GasPriceOracle: scalar() is deprecated");
return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar();
}

/// @notice Retrieves the latest known L1 base fee.
/// @return Latest known L1 base fee.
function l1BaseFee() public view returns (uint256) {
return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).basefee();
}

/// @notice Retrieves the current blob base fee.
/// @return Current blob base fee.
function blobBaseFee() public view returns (uint256) {
return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).blobBaseFee();
}

/// @notice Retrieves the current base fee scalar.
/// @return Current base fee scalar.
function baseFeeScalar() public view returns (uint32) {
return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).baseFeeScalar();
}

/// @notice Retrieves the current blob base fee scalar.
/// @return Current blob base fee scalar.
function blobBaseFeeScalar() public view returns (uint32) {
return L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).blobBaseFeeScalar();
}

/// @custom:legacy
/// @notice Retrieves the number of decimals used in the scalar.
/// @return Number of decimals used in the scalar.
function decimals() public pure returns (uint256) {
return DECIMALS;
}

/// @notice Computes the amount of L1 gas used for a transaction. Adds 68 bytes
/// of padding to account for the fact that the input does not have a signature.
/// @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for.
/// @return Amount of L1 gas used to publish the transaction.
/// @custom:deprecated This method does not accurately estimate the gas used for a transaction.
/// If you are calculating fees use getL1Fee or getL1FeeUpperBound.
function getL1GasUsed(bytes memory _data) public view returns (uint256) {
if (isFjord) {
// Add 68 to the size to account for unsigned tx
// Assume the compressed data is mostly non-zero, and would pay 16 gas per calldata byte
// Divide by 1e6 due to the scaling factor of the linear regression
return (_fjordLinearRegression(LibZip.flzCompress(_data).length + 68) * 16) / 1e6;
}
uint256 l1GasUsed = _getCalldataGas(_data);
if (isEcotone) {
return l1GasUsed;
}
return l1GasUsed + L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead();
}

/// @notice Computation of the L1 portion of the fee for Bedrock.
/// @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.
/// @return L1 fee that should be paid for the tx
function _getL1FeeBedrock(bytes memory _data) internal view returns (uint256) {
uint256 l1GasUsed = _getCalldataGas(_data);
uint256 fee = (l1GasUsed + L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeOverhead()) *
l1BaseFee() *
L1Block(Predeploys.L1_BLOCK_ATTRIBUTES).l1FeeScalar();
return fee / (10 ** DECIMALS);
}

/// @notice L1 portion of the fee after Ecotone.
/// @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.
/// @return L1 fee that should be paid for the tx
function _getL1FeeEcotone(bytes memory _data) internal view returns (uint256) {
uint256 l1GasUsed = _getCalldataGas(_data);
uint256 scaledBaseFee = baseFeeScalar() * 16 * l1BaseFee();
uint256 scaledBlobBaseFee = blobBaseFeeScalar() * blobBaseFee();
uint256 fee = l1GasUsed * (scaledBaseFee + scaledBlobBaseFee);
return fee / (16 * 10 ** DECIMALS);
}

/// @notice L1 portion of the fee after Fjord.
/// @param _data Unsigned fully RLP-encoded transaction to get the L1 fee for.
/// @return L1 fee that should be paid for the tx
function _getL1FeeFjord(bytes memory _data) internal view returns (uint256) {
return _fjordL1Cost(LibZip.flzCompress(_data).length + 68);
}

/// @notice L1 gas estimation calculation.
/// @param _data Unsigned fully RLP-encoded transaction to get the L1 gas for.
/// @return Amount of L1 gas used to publish the transaction.
function _getCalldataGas(bytes memory _data) internal pure returns (uint256) {
uint256 total = 0;
uint256 length = _data.length;
for (uint256 i = 0; i < length; i++) {
if (_data[i] == 0) {
total += 4;
} else {
total += 16;
}
}
return total + (68 * 16);
}

/// @notice Fjord L1 cost based on the compressed and original tx size.
/// @param _fastLzSize estimated compressed tx size.
/// @return Fjord L1 fee that should be paid for the tx
function _fjordL1Cost(uint256 _fastLzSize) internal view returns (uint256) {
// Apply the linear regression to estimate the Brotli 10 size
uint256 estimatedSize = _fjordLinearRegression(_fastLzSize);
uint256 feeScaled = baseFeeScalar() * 16 * l1BaseFee() + blobBaseFeeScalar() * blobBaseFee();
return (estimatedSize * feeScaled) / (10 ** (DECIMALS * 2));
}

/// @notice Takes the fastLz size compression and returns the estimated Brotli
/// @param _fastLzSize fastlz compressed tx size.
/// @return Number of bytes in the compressed transaction
function _fjordLinearRegression(uint256 _fastLzSize) internal pure returns (uint256) {
int256 estimatedSize = COST_INTERCEPT + int256(COST_FASTLZ_COEF * _fastLzSize);
if (estimatedSize < int256(MIN_TRANSACTION_SIZE) * 1e6) {
estimatedSize = int256(MIN_TRANSACTION_SIZE) * 1e6;
}
return uint256(estimatedSize);
}
}
Loading
Loading