diff --git a/README.md b/README.md
index e17a4c90afe..970d1b96508 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,6 @@ taiko-mono/
│ ├── relayer: Bridge backend relayer in Go
│ ├── starter-dapp: Template for Taiko dapps
│ ├── status-page: Taiko protocol status page
-│ ├── tokenomics: Taiko tokenomics simulations
│ ├── website: Main documentation website at taiko.xyz (https://taiko.xyz/)
│ └── whitepaper: Whitepaper source files with automated publishing
...
diff --git a/packages/protocol/.solhintignore b/packages/protocol/.solhintignore
index 35e56e7003c..7b6a5611295 100644
--- a/packages/protocol/.solhintignore
+++ b/packages/protocol/.solhintignore
@@ -3,4 +3,5 @@ lib/
contracts/test/TestLibRLPReader.sol
contracts/test/TestLibRLPWriter.sol
**/contracts/thirdparty/**/*.sol
-test2/GasComparison.t.sol
\ No newline at end of file
+test2/GasComparison.t.sol
+test2/TestLn.sol
\ No newline at end of file
diff --git a/packages/protocol/contracts/L1/TaikoConfig.sol b/packages/protocol/contracts/L1/TaikoConfig.sol
index d67233a67ee..fde54c2de58 100644
--- a/packages/protocol/contracts/L1/TaikoConfig.sol
+++ b/packages/protocol/contracts/L1/TaikoConfig.sol
@@ -31,26 +31,15 @@ library TaikoConfig {
// transactions list calldata, 8K for the remaining tx fields.
maxBytesPerTxList: 120000,
minTxGasLimit: 21000,
- slotSmoothingFactor: 946649,
- // 100 basis points or 1%
- rewardBurnBips: 100,
- proposerDepositPctg: 25, // - 25%
// Moving average factors
- feeBaseMAF: 1024,
txListCacheExpiry: 0,
+ proofTimeTarget: 1800, // 85s based on A2 testnet status, or set to 1800 for 30mins (mainnet mock)
+ adjustmentQuotient: 16,
relaySignalRoot: false,
enableSoloProposer: false,
enableOracleProver: true,
enableTokenomics: true,
- skipZKPVerification: false,
- proposingConfig: TaikoData.FeeConfig({
- avgTimeMAF: 1024,
- dampingFactorBips: 2500 // [125% -> 75%]
- }),
- provingConfig: TaikoData.FeeConfig({
- avgTimeMAF: 1024,
- dampingFactorBips: 2500 // [75% -> 125%]
- })
+ skipZKPVerification: false
});
}
}
diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol
index 5497dfe351f..e147bbdbfa5 100644
--- a/packages/protocol/contracts/L1/TaikoData.sol
+++ b/packages/protocol/contracts/L1/TaikoData.sol
@@ -7,11 +7,6 @@
pragma solidity ^0.8.18;
library TaikoData {
- struct FeeConfig {
- uint16 avgTimeMAF;
- uint16 dampingFactorBips;
- }
-
struct Config {
uint256 chainId;
uint256 maxNumProposedBlocks;
@@ -24,29 +19,26 @@ library TaikoData {
uint256 maxTransactionsPerBlock;
uint256 maxBytesPerTxList;
uint256 minTxGasLimit;
- uint256 slotSmoothingFactor;
- uint256 rewardBurnBips;
- uint256 proposerDepositPctg;
// Moving average factors
- uint256 feeBaseMAF;
uint256 txListCacheExpiry;
+ uint64 proofTimeTarget;
+ uint8 adjustmentQuotient;
bool relaySignalRoot;
bool enableSoloProposer;
bool enableOracleProver;
bool enableTokenomics;
bool skipZKPVerification;
- FeeConfig proposingConfig;
- FeeConfig provingConfig;
}
struct StateVariables {
- uint64 feeBase;
+ uint64 basefee;
+ uint64 accBlockFees;
uint64 genesisHeight;
uint64 genesisTimestamp;
uint64 numBlocks;
+ uint64 proofTimeIssued;
uint64 lastVerifiedBlockId;
- uint64 avgBlockTime;
- uint64 avgProofTime;
+ uint64 accProposedAt;
uint64 lastProposedAt;
}
@@ -142,24 +134,26 @@ library TaikoData {
mapping(uint256 blockId => mapping(bytes32 parentHash => mapping(uint32 parentGasUsed => uint256 forkChoiceId))) forkChoiceIds;
mapping(address account => uint256 balance) balances;
mapping(bytes32 txListHash => TxListInfo) txListInfo;
- // Never or rarely changed
+ // Slot 5: never or rarely changed
uint64 genesisHeight;
uint64 genesisTimestamp;
- uint64 __reserved1;
- uint64 __reserved2;
- // Changed when a block is proposed or proven/verified
- // Changed when a block is proposed
+ uint64 __reserved51;
+ uint64 __reserved52;
+ // Slot 6: changed by proposeBlock
+ uint64 lastProposedAt;
uint64 numBlocks;
- uint64 lastProposedAt; // Timestamp when the last block is proposed.
- uint64 avgBlockTime; // miliseconds
- uint64 __reserved3;
- // Changed when a block is proven/verified
+ uint64 accProposedAt; // also by verifyBlocks
+ uint64 accBlockFees; // also by verifyBlocks
+ // Slot 7: changed by proveBlock
+ // uint64 __reserved71;
+ // uint64 __reserved72;
+ // uint64 __reserved73;
+ // uint64 __reserved74;
+ // Slot 8: changed by verifyBlocks
+ uint64 basefee;
+ uint64 proofTimeIssued;
uint64 lastVerifiedBlockId;
- uint64 __reserved4;
- // the proof time moving average, note that for each block, only the
- // first proof's time is considered.
- uint64 avgProofTime; // miliseconds
- uint64 feeBase;
+ uint64 __reserved81;
// Reserved
uint256[43] __gap;
}
diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol
index 656a75543f5..8e5f0d7a6c3 100644
--- a/packages/protocol/contracts/L1/TaikoL1.sol
+++ b/packages/protocol/contracts/L1/TaikoL1.sol
@@ -29,20 +29,23 @@ contract TaikoL1 is EssentialContract, IXchainSync, TaikoEvents, TaikoErrors {
* Initialize the rollup.
*
* @param _addressManager The AddressManager address.
- * @param _feeBase The initial value of the proposer-fee/prover-reward feeBase.
* @param _genesisBlockHash The block hash of the genesis block.
+ * @param _initBasefee Initial (reasonable) basefee value.
+ * @param _initProofTimeIssued Initial proof time which keeps the inflow/outflow in balance
*/
function init(
address _addressManager,
- uint64 _feeBase,
- bytes32 _genesisBlockHash
+ bytes32 _genesisBlockHash,
+ uint64 _initBasefee,
+ uint64 _initProofTimeIssued
) external initializer {
EssentialContract._init(_addressManager);
LibVerifying.init({
state: state,
config: getConfig(),
- feeBase: _feeBase,
- genesisBlockHash: _genesisBlockHash
+ genesisBlockHash: _genesisBlockHash,
+ initBasefee: _initBasefee,
+ initProofTimeIssued: _initProofTimeIssued
});
}
@@ -155,27 +158,19 @@ contract TaikoL1 is EssentialContract, IXchainSync, TaikoEvents, TaikoErrors {
return state.balances[addr];
}
- function getBlockFee()
- public
- view
- returns (uint256 feeAmount, uint256 depositAmount)
- {
- (, feeAmount, depositAmount) = LibTokenomics.getBlockFee(
- state,
- getConfig()
- );
+ function getBlockFee() public view returns (uint64) {
+ return state.basefee;
}
function getProofReward(
uint64 provenAt,
uint64 proposedAt
- ) public view returns (uint256 reward) {
- (, reward, ) = LibTokenomics.getProofReward({
- state: state,
- config: getConfig(),
- provenAt: provenAt,
- proposedAt: proposedAt
- });
+ ) public view returns (uint64) {
+ return
+ LibTokenomics.getProofReward({
+ state: state,
+ proofTime: provenAt - proposedAt
+ });
}
function getBlock(
@@ -256,4 +251,8 @@ contract TaikoL1 is EssentialContract, IXchainSync, TaikoEvents, TaikoErrors {
function getConfig() public pure virtual returns (TaikoData.Config memory) {
return TaikoConfig.getConfig();
}
+
+ function getVerifierName(uint16 id) public pure returns (string memory) {
+ return LibUtils.getVerifierName(id);
+ }
}
diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol
index e8337b00099..265e6c0729d 100644
--- a/packages/protocol/contracts/L1/libs/LibProposing.sol
+++ b/packages/protocol/contracts/L1/libs/LibProposing.sol
@@ -90,45 +90,20 @@ library LibProposing {
blk.metaHash = LibUtils.hashMetadata(meta);
blk.proposer = msg.sender;
- if (config.enableTokenomics) {
- (uint256 newFeeBase, uint256 fee, uint64 deposit) = LibTokenomics
- .getBlockFee(state, config);
-
- uint256 burnAmount = fee + deposit;
- if (state.balances[msg.sender] < burnAmount)
- revert L1_INSUFFICIENT_TOKEN();
-
- unchecked {
- state.balances[msg.sender] -= burnAmount;
- }
-
- // Update feeBase and avgBlockTime
- state.feeBase = LibUtils
- .movingAverage({
- maValue: state.feeBase,
- newValue: newFeeBase,
- maf: config.feeBaseMAF
- })
- .toUint64();
-
- blk.deposit = uint64(deposit);
- }
+ if (state.balances[msg.sender] < state.basefee)
+ revert L1_INSUFFICIENT_TOKEN();
unchecked {
- state.avgBlockTime = LibUtils
- .movingAverage({
- maValue: state.avgBlockTime,
- newValue: (meta.timestamp - state.lastProposedAt) * 1000,
- maf: config.proposingConfig.avgTimeMAF
- })
- .toUint64();
- state.lastProposedAt = meta.timestamp;
+ state.balances[msg.sender] -= state.basefee;
+ state.accBlockFees += state.basefee;
+ state.accProposedAt += meta.timestamp;
}
emit BlockProposed(state.numBlocks, meta);
unchecked {
++state.numBlocks;
}
+ state.lastProposedAt = meta.timestamp;
}
function getBlock(
diff --git a/packages/protocol/contracts/L1/libs/LibProving.sol b/packages/protocol/contracts/L1/libs/LibProving.sol
index f262842dfbf..086ce3ca84a 100644
--- a/packages/protocol/contracts/L1/libs/LibProving.sol
+++ b/packages/protocol/contracts/L1/libs/LibProving.sol
@@ -201,13 +201,11 @@ library LibProving {
}
}
- bytes memory verifierId = abi.encodePacked(
- "verifier_",
- evidence.zkproof.verifierId
- );
-
(bool verified, bytes memory ret) = resolver
- .resolve(string(verifierId), false)
+ .resolve(
+ LibUtils.getVerifierName(evidence.zkproof.verifierId),
+ false
+ )
.staticcall(bytes.concat(instance, evidence.zkproof.data));
if (
diff --git a/packages/protocol/contracts/L1/libs/LibTokenomics.sol b/packages/protocol/contracts/L1/libs/LibTokenomics.sol
index 2e034569d39..8ec38cfd1a2 100644
--- a/packages/protocol/contracts/L1/libs/LibTokenomics.sol
+++ b/packages/protocol/contracts/L1/libs/LibTokenomics.sol
@@ -13,6 +13,9 @@ import {
} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol";
import {TaikoData} from "../TaikoData.sol";
import {TaikoToken} from "../TaikoToken.sol";
+import {
+ LibFixedPointMath as Math
+} from "../../thirdparty/LibFixedPointMath.sol";
library LibTokenomics {
using LibMath for uint256;
@@ -52,108 +55,73 @@ library LibTokenomics {
}
}
- function getBlockFee(
- TaikoData.State storage state,
- TaikoData.Config memory config
- )
- internal
- view
- returns (uint64 newFeeBase, uint64 fee, uint64 depositAmount)
- {
- (newFeeBase, ) = getTimeAdjustedFee({
- feeConfig: config.proposingConfig,
- feeBase: state.feeBase,
- isProposal: true,
- timeUsed: block.timestamp - state.lastProposedAt,
- timeAverage: state.avgBlockTime
- });
- fee = getSlotsAdjustedFee({
- state: state,
- config: config,
- isProposal: true,
- feeBase: newFeeBase
- });
-
- unchecked {
- depositAmount = uint64((config.proposerDepositPctg * fee) / 100);
- }
- }
-
+ /**
+ * Update the baseFee for proofs
+ *
+ * @param state The actual state data
+ * @param proofTime The actual proof time
+ * @return reward Amount of reward given - if blocked is proved and verified
+ */
function getProofReward(
TaikoData.State storage state,
- TaikoData.Config memory config,
- uint64 provenAt,
- uint64 proposedAt
- )
- internal
- view
- returns (uint64 newFeeBase, uint64 reward, uint64 premiumRate)
- {
- if (proposedAt > provenAt) revert L1_INVALID_PARAM();
-
- (newFeeBase, premiumRate) = getTimeAdjustedFee({
- feeConfig: config.provingConfig,
- feeBase: state.feeBase,
- isProposal: false,
- timeUsed: provenAt - proposedAt,
- timeAverage: state.avgProofTime
- });
- reward = getSlotsAdjustedFee({
- state: state,
- config: config,
- isProposal: false,
- feeBase: newFeeBase
- });
+ uint64 proofTime
+ ) internal view returns (uint64) {
+ uint64 numBlocksUnverified = state.numBlocks -
+ state.lastVerifiedBlockId -
+ 1;
+
+ if (numBlocksUnverified == 0) {
+ return 0;
+ } else {
+ uint64 totalNumProvingSeconds = uint64(
+ uint256(numBlocksUnverified) *
+ block.timestamp -
+ state.accProposedAt
+ );
+ // If block timestamp is equal to state.accProposedAt (not really, but theoretically possible)
+ // there will be division by 0 error
+ if (totalNumProvingSeconds == 0) {
+ totalNumProvingSeconds = 1;
+ }
- unchecked {
- reward = uint64((reward * (10000 - config.rewardBurnBips)) / 10000);
+ return
+ uint64(
+ (uint256(state.accBlockFees) * proofTime) /
+ totalNumProvingSeconds
+ );
}
}
- // Implement "Slot-availability Multipliers", see the whitepaper.
- function getSlotsAdjustedFee(
+ /**
+ * Calculate the newProofTimeIssued and newBasefee
+ *
+ * @param state The actual state data
+ * @param config Config data
+ * @param proofTime The actual proof time
+ * @return newProofTimeIssued Accumulated proof time
+ * @return newBasefee New basefee
+ */
+ function getNewBaseFeeandProofTimeIssued(
TaikoData.State storage state,
TaikoData.Config memory config,
- bool isProposal,
- uint64 feeBase
- ) internal view returns (uint64) {
- unchecked {
- // m is the `n'` in the whitepaper
- uint256 m = 1000 *
- config.maxNumProposedBlocks +
- config.slotSmoothingFactor;
- // n is the number of unverified blocks
- uint256 n = 1000 *
- (state.numBlocks - state.lastVerifiedBlockId - 1);
- // k is `m − n + 1` or `m − n - 1`in the whitepaper
- uint256 k = isProposal ? m - n - 1000 : m - n + 1000;
- return uint64((feeBase * (m - 1000) * m) / (m - n) / k);
- }
- }
-
- // Implement "Incentive Multipliers", see the whitepaper.
- function getTimeAdjustedFee(
- TaikoData.FeeConfig memory feeConfig,
- uint64 feeBase,
- bool isProposal,
- uint256 timeUsed, // seconds
- uint256 timeAverage // milliseconds
- ) internal pure returns (uint64 newFeeBase, uint64 premiumRate) {
- if (timeAverage == 0) {
- return (feeBase, 0);
+ uint64 proofTime
+ ) internal view returns (uint64 newProofTimeIssued, uint64 newBasefee) {
+ newProofTimeIssued = (state.proofTimeIssued > config.proofTimeTarget)
+ ? state.proofTimeIssued - config.proofTimeTarget
+ : uint64(0);
+ newProofTimeIssued += proofTime;
+
+ uint256 x = (newProofTimeIssued * Math.SCALING_FACTOR_1E18) /
+ (config.proofTimeTarget * config.adjustmentQuotient);
+
+ if (Math.MAX_EXP_INPUT <= x) {
+ x = Math.MAX_EXP_INPUT;
}
- unchecked {
- uint256 p = feeConfig.dampingFactorBips; // [0-10000]
- uint256 a = timeAverage;
- uint256 t = (timeUsed * 1000).min(a * 2); // millisconds
- newFeeBase = uint64((feeBase * (10000 + (t * p) / a - p)) / 10000);
+ uint256 result = (uint256(Math.exp(int256(x))) /
+ Math.SCALING_FACTOR_1E18) /
+ (config.proofTimeTarget * config.adjustmentQuotient);
- if (isProposal) {
- newFeeBase = (feeBase * 2) - newFeeBase;
- } else if (p > 0) {
- premiumRate = uint64(((t.max(a) - a) * 10000) / a);
- }
- }
+ newBasefee = uint64(result.min(type(uint64).max));
}
}
diff --git a/packages/protocol/contracts/L1/libs/LibUtils.sol b/packages/protocol/contracts/L1/libs/LibUtils.sol
index 720f3de3459..b88ad8bf95b 100644
--- a/packages/protocol/contracts/L1/libs/LibUtils.sol
+++ b/packages/protocol/contracts/L1/libs/LibUtils.sol
@@ -42,6 +42,7 @@ library LibUtils {
uint256 fcId = state.forkChoiceIds[blk.blockId][parentHash][
parentGasUsed
];
+
if (fcId >= blk.nextForkChoiceId) return 0;
return fcId;
@@ -52,14 +53,15 @@ library LibUtils {
) internal view returns (TaikoData.StateVariables memory) {
return
TaikoData.StateVariables({
- feeBase: state.feeBase,
+ basefee: state.basefee,
+ accBlockFees: state.accBlockFees,
genesisHeight: state.genesisHeight,
genesisTimestamp: state.genesisTimestamp,
numBlocks: state.numBlocks,
- lastProposedAt: state.lastProposedAt,
- avgBlockTime: state.avgBlockTime,
+ proofTimeIssued: state.proofTimeIssued,
lastVerifiedBlockId: state.lastVerifiedBlockId,
- avgProofTime: state.avgProofTime
+ accProposedAt: state.accProposedAt,
+ lastProposedAt: state.lastProposedAt
});
}
@@ -130,4 +132,8 @@ library LibUtils {
mstore(0x40, add(ptr, 64))
}
}
+
+ function getVerifierName(uint16 id) public pure returns (string memory) {
+ return string(bytes.concat(bytes("verifier_"), bytes2(id)));
+ }
}
diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol
index 86475195b10..457e88e166f 100644
--- a/packages/protocol/contracts/L1/libs/LibVerifying.sol
+++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol
@@ -32,15 +32,18 @@ library LibVerifying {
function init(
TaikoData.State storage state,
TaikoData.Config memory config,
- uint64 feeBase,
- bytes32 genesisBlockHash
+ bytes32 genesisBlockHash,
+ uint64 initBasefee,
+ uint64 initProofTimeIssued
) internal {
_checkConfig(config);
uint64 timeNow = uint64(block.timestamp);
state.genesisHeight = uint64(block.number);
state.genesisTimestamp = timeNow;
- state.feeBase = feeBase;
+
+ state.basefee = initBasefee;
+ state.proofTimeIssued = initProofTimeIssued;
state.numBlocks = 1;
TaikoData.Block storage blk = state.blocks[0];
@@ -66,7 +69,6 @@ library LibVerifying {
uint256 fcId = blk.verifiedForkChoiceId;
assert(fcId > 0);
-
bytes32 blockHash = blk.forkChoices[fcId].blockHash;
uint32 gasUsed = blk.forkChoices[fcId].gasUsed;
bytes32 signalRoot;
@@ -94,7 +96,6 @@ library LibVerifying {
fcId: uint24(fcId),
fc: fc
});
-
blockHash = fc.blockHash;
gasUsed = fc.gasUsed;
signalRoot = fc.signalRoot;
@@ -128,48 +129,25 @@ library LibVerifying {
TaikoData.ForkChoice storage fc,
uint24 fcId
) private {
- if (config.enableTokenomics) {
- (
- uint256 newFeeBase,
- uint256 amount,
- uint256 premiumRate
- ) = LibTokenomics.getProofReward({
- state: state,
- config: config,
- provenAt: fc.provenAt,
- proposedAt: blk.proposedAt
- });
+ if (config.proofTimeTarget != 0) {
+ uint64 proofTime;
+ unchecked {
+ proofTime = uint64(fc.provenAt - blk.proposedAt);
+ }
- // reward the prover
- _addToBalance(state, fc.prover, amount);
+ uint64 reward = LibTokenomics.getProofReward(state, proofTime);
+
+ (state.proofTimeIssued, state.basefee) = LibTokenomics
+ .getNewBaseFeeandProofTimeIssued(state, config, proofTime);
unchecked {
- // premiumRate in [0-10000]
- amount = (blk.deposit * (10000 - premiumRate)) / 10000;
+ state.accBlockFees -= reward;
+ state.accProposedAt -= blk.proposedAt;
}
- _addToBalance(state, blk.proposer, amount);
-
- // Update feeBase and avgProofTime
- state.feeBase = LibUtils
- .movingAverage({
- maValue: state.feeBase,
- newValue: newFeeBase,
- maf: config.feeBaseMAF
- })
- .toUint64();
- }
- uint256 proofTime;
- unchecked {
- proofTime = (fc.provenAt - blk.proposedAt) * 1000;
+ // reward the prover
+ _addToBalance(state, fc.prover, reward);
}
- state.avgProofTime = LibUtils
- .movingAverage({
- maValue: state.avgProofTime,
- newValue: proofTime,
- maf: config.provingConfig.avgTimeMAF
- })
- .toUint64();
blk.nextForkChoiceId = 1;
blk.verifiedForkChoiceId = fcId;
@@ -204,20 +182,10 @@ library LibVerifying {
// EIP-4844 blob size up to 128K
config.maxBytesPerTxList > 128 * 1024 ||
config.minTxGasLimit == 0 ||
- config.slotSmoothingFactor == 0 ||
// EIP-4844 blob deleted after 30 days
config.txListCacheExpiry > 30 * 24 hours ||
- config.rewardBurnBips >= 10000
+ config.proofTimeTarget == 0 ||
+ config.adjustmentQuotient == 0
) revert L1_INVALID_CONFIG();
-
- _checkFeeConfig(config.proposingConfig);
- _checkFeeConfig(config.provingConfig);
- }
-
- function _checkFeeConfig(
- TaikoData.FeeConfig memory feeConfig
- ) private pure {
- if (feeConfig.avgTimeMAF <= 1 || feeConfig.dampingFactorBips > 10000)
- revert L1_INVALID_CONFIG();
}
}
diff --git a/packages/protocol/contracts/test/L1/TestTaikoL1.sol b/packages/protocol/contracts/test/L1/TestTaikoL1.sol
index 1459e0ed17c..5c1111b1c65 100644
--- a/packages/protocol/contracts/test/L1/TestTaikoL1.sol
+++ b/packages/protocol/contracts/test/L1/TestTaikoL1.sol
@@ -28,23 +28,9 @@ contract TestTaikoL1 is TaikoL1 {
config.maxTransactionsPerBlock = 20;
config.maxBytesPerTxList = 120000;
config.minTxGasLimit = 21000;
- config.slotSmoothingFactor = 590000;
- config.rewardBurnBips = 100; // 100 basis points or 1%
- config.proposerDepositPctg = 25; // 25%
config.enableTokenomics = false;
config.skipZKPVerification = true;
- config.feeBaseMAF = 1024;
-
- config.proposingConfig = TaikoData.FeeConfig({
- avgTimeMAF: 64,
- dampingFactorBips: 5000
- });
-
- config.provingConfig = TaikoData.FeeConfig({
- avgTimeMAF: 64,
- dampingFactorBips: 5000
- });
}
// The old implementation that is also used in hardhat tests.
diff --git a/packages/protocol/contracts/test/L1/TestTaikoL1EnableTokenomics.sol b/packages/protocol/contracts/test/L1/TestTaikoL1EnableTokenomics.sol
index 56afe3ca244..0ef3f7343aa 100644
--- a/packages/protocol/contracts/test/L1/TestTaikoL1EnableTokenomics.sol
+++ b/packages/protocol/contracts/test/L1/TestTaikoL1EnableTokenomics.sol
@@ -28,25 +28,9 @@ contract TestTaikoL1EnableTokenomics is TaikoL1 {
config.maxTransactionsPerBlock = 20;
config.maxBytesPerTxList = 120000;
config.minTxGasLimit = 21000;
- config.slotSmoothingFactor = 590000;
- config.rewardBurnBips = 100; // 100 basis points or 1%
- config.proposerDepositPctg = 25; // 25%
-
- // Moving average factors
- config.feeBaseMAF = 1024;
config.enableTokenomics = true;
config.skipZKPVerification = true;
-
- config.proposingConfig = TaikoData.FeeConfig({
- avgTimeMAF: 64,
- dampingFactorBips: 5000
- });
-
- config.provingConfig = TaikoData.FeeConfig({
- avgTimeMAF: 64,
- dampingFactorBips: 5000
- });
}
// The old implementation that is also used in hardhat tests.
diff --git a/packages/protocol/contracts/thirdparty/LibFixedPointMath.sol b/packages/protocol/contracts/thirdparty/LibFixedPointMath.sol
index 1bae4223d96..a056e09f44f 100644
--- a/packages/protocol/contracts/thirdparty/LibFixedPointMath.sol
+++ b/packages/protocol/contracts/thirdparty/LibFixedPointMath.sol
@@ -4,6 +4,7 @@ pragma solidity ^0.8.18;
library LibFixedPointMath {
uint128 public constant MAX_EXP_INPUT = 135305999368893231588;
+ uint256 public constant SCALING_FACTOR_1E18 = 1e18; // For fixed point representation factor
error Overflow();
diff --git a/packages/protocol/foundry.toml b/packages/protocol/foundry.toml
index 5d09b63e585..376e95994b9 100644
--- a/packages/protocol/foundry.toml
+++ b/packages/protocol/foundry.toml
@@ -12,6 +12,10 @@ gas_limit = '18446744073709551615'
# Do not change the block_gas_limit value, TaikoL2.t.sol depends on it.
block_gas_limit = 30000000 #30M
+# For mainnet_mock tokenomics test we need a huge value to run lots of iterations.
+# Use the above 30M for TaikoL2.t.sol related tests, only use this number with mainnet simulation.
+#block_gas_limit = 3000000000 #3000M
+
fs_permissions = [
{ access = "read", path = "./out"},
diff --git a/packages/protocol/script/DeployOnL1.s.sol b/packages/protocol/script/DeployOnL1.s.sol
index c0f442bd553..9609502dba0 100644
--- a/packages/protocol/script/DeployOnL1.s.sol
+++ b/packages/protocol/script/DeployOnL1.s.sol
@@ -19,12 +19,14 @@ import "../contracts/signal/SignalService.sol";
import "../contracts/thirdparty/AddressManager.sol";
import "../contracts/test/erc20/FreeMintERC20.sol";
import "../contracts/test/erc20/MayFailFreeMintERC20.sol";
+import "../test2/LibLn.sol";
contract DeployOnL1 is Script, AddressResolver {
using SafeCastUpgradeable for uint256;
+
uint256 public l2ChainId = vm.envUint("L2_CHAIN_ID");
- bytes32 public gensisHash = vm.envBytes32("L2_GENESIS_HASH");
+ bytes32 public genesisHash = vm.envBytes32("L2_GENESIS_HASH");
uint256 public deployerPrivateKey = vm.envUint("PRIVATE_KEY");
@@ -46,8 +48,13 @@ contract DeployOnL1 is Script, AddressResolver {
uint256 public taikoTokenPremintAmount =
vm.envUint("TAIKO_TOKEN_PREMINT_AMOUNT");
+ TaikoL1 taikoL1;
address public addressManagerProxy;
+ // New fee/reward related variables
+ uint16 public constant PROOF_TIME_TARGET = 1800; // For mainnet it is around 30 mins, but choose carefully ! (Testnet is different !)
+ uint8 public constant ADJUSTMENT_QUOTIENT = 16;
+
error FAILED_TO_DEPLOY_PLONK_VERIFIER(string contractPath);
function run() external {
@@ -112,15 +119,30 @@ contract DeployOnL1 is Script, AddressResolver {
console.log("BullToken", bullToken);
// TaikoL1
- TaikoL1 taikoL1 = new TaikoL1();
+ taikoL1 = new TaikoL1();
uint64 feeBase = 1 ** 8; // Taiko Token's decimals is 8, not 18
+
+ // Calculating it for our needs based on testnet/mainnet. We need it in
+ // order to make the fees on the same level - in ideal circumstences.
+ // See Brecht's comment https://github.com/taikoxyz/taiko-mono/pull/13564
+ uint64 initProofTimeIssued = LibLn.calcInitProofTimeIssued(
+ feeBase,
+ PROOF_TIME_TARGET,
+ ADJUSTMENT_QUOTIENT
+ );
+
address taikoL1Proxy = deployProxy(
"taiko",
address(taikoL1),
bytes.concat(
taikoL1.init.selector,
- abi.encode(addressManagerProxy, feeBase, gensisHash)
+ abi.encode(
+ addressManagerProxy,
+ genesisHash,
+ feeBase,
+ initProofTimeIssued
+ )
)
);
setAddress("proto_broker", taikoL1Proxy);
@@ -179,10 +201,7 @@ contract DeployOnL1 is Script, AddressResolver {
);
for (uint16 i = 0; i < plonkVerifiers.length; ++i) {
- setAddress(
- string(abi.encodePacked("verifier_", i)),
- plonkVerifiers[i]
- );
+ setAddress(taikoL1.getVerifierName(i), plonkVerifiers[i]);
}
}
diff --git a/packages/protocol/test/tokenomics/blockFee.test.ts b/packages/protocol/test/tokenomics/blockFee.test.ts
index 75529c54aa5..602d97d5971 100644
--- a/packages/protocol/test/tokenomics/blockFee.test.ts
+++ b/packages/protocol/test/tokenomics/blockFee.test.ts
@@ -43,7 +43,7 @@ describe("tokenomics: blockFee", function () {
afterEach(() => clearInterval(interval));
- it("expects getBlockFee to return the initial feeBase at time of contract deployment", async function () {
+ it("expects getBlockFee to return the initial basefee at time of contract deployment", async function () {
// deploy a new instance of TaikoL1 so no blocks have passed.
const tL1 = await deployTaikoL1(l1AddressManager, genesisHash, true);
const blockFee = await tL1.getBlockFee();
diff --git a/packages/protocol/test/utils/fixture.ts b/packages/protocol/test/utils/fixture.ts
index ea9ca26d145..2b924eec910 100644
--- a/packages/protocol/test/utils/fixture.ts
+++ b/packages/protocol/test/utils/fixture.ts
@@ -10,7 +10,7 @@ import {
getL2Provider,
} from "./provider";
import { createAndSeedWallets, sendTinyEtherToZeroAddress } from "./seed";
-import { defaultFeeBase, deployTaikoL1 } from "./taikoL1";
+import { defaultBasefee, deployTaikoL1 } from "./taikoL1";
import { deployTaikoL2 } from "./taikoL2";
import deployTaikoToken from "./taikoToken";
@@ -51,7 +51,7 @@ async function initIntegrationFixture(
l1AddressManager,
genesisHash,
enableTokenomics,
- defaultFeeBase
+ defaultBasefee
);
const { chainId } = await l1Provider.getNetwork();
diff --git a/packages/protocol/test/utils/taikoL1.ts b/packages/protocol/test/utils/taikoL1.ts
index 71974305b20..3d205800320 100644
--- a/packages/protocol/test/utils/taikoL1.ts
+++ b/packages/protocol/test/utils/taikoL1.ts
@@ -2,13 +2,13 @@ import { BigNumber } from "ethers";
import { ethers } from "hardhat";
import { AddressManager, TaikoL1 } from "../../typechain";
-const defaultFeeBase = BigNumber.from(10).pow(18);
+const defaultBasefee = BigNumber.from(10).pow(18);
async function deployTaikoL1(
addressManager: AddressManager,
genesisHash: string,
enableTokenomics: boolean,
- feeBase?: BigNumber
+ basefee?: BigNumber
): Promise {
// const libProposing = await (
// await ethers.getContractFactory("LibProposing")
@@ -39,11 +39,11 @@ async function deployTaikoL1(
await taikoL1.init(
addressManager.address,
genesisHash,
- feeBase ?? defaultFeeBase
+ basefee ?? defaultBasefee
)
).wait(1);
return taikoL1 as TaikoL1;
}
-export { deployTaikoL1, defaultFeeBase };
+export { deployTaikoL1, defaultBasefee };
diff --git a/packages/protocol/test2/LibLn.sol b/packages/protocol/test2/LibLn.sol
new file mode 100644
index 00000000000..bcb8ff552d8
--- /dev/null
+++ b/packages/protocol/test2/LibLn.sol
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.18;
+
+// Taken from: https://github.com/recmo/experiment-solexp/blob/main/src/FixedPointMathLib.sol
+import {LibFixedPointMath} from "../contracts/thirdparty/LibFixedPointMath.sol";
+
+library LibLn {
+ error Overflow();
+ error LnNegativeUndefined();
+
+ // Integer log2 (alternative implementation)
+ // @returns floor(log2(x)) if x is nonzero, otherwise 0.
+ // Consumes 317 gas. This could have been an 3 gas EVM opcode though.
+ function ilog2_alt(uint256 x) internal pure returns (uint256 r) {
+ unchecked {
+ // Repeat first zero all the way to the right
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ x |= x >> 32;
+ x |= x >> 64;
+ x |= x >> 128;
+
+ // Count 32 bit chunks
+ r = x & 0x100000001000000010000000100000001000000010000000100000001;
+ r *= 0x20000000200000002000000020000000200000002000000020;
+ r >>= 224;
+
+ // Extract highest bit
+ x ^= x >> 1;
+
+ // Copy to lowest 32 bit chunk
+ x |= x >> 32;
+ x |= x >> 64;
+ x |= x >> 128;
+ // No need to clear the other chunks
+
+ // Map to 0-31 using the B(2, 5) de Bruijn sequence 0x077CB531.
+ // See
+ x = ((x * 0x077CB531) >> 27) & 0x1f;
+
+ // Use a bytes32 32 entry lookup table
+ assembly {
+ // Need assembly here because solidity introduces an uncessary bounds
+ // check.
+ r := add(
+ r,
+ byte(
+ x,
+ 0x11c021d0e18031e16140f191104081f1b0d17151310071a0c12060b050a09
+ )
+ )
+ }
+ }
+ }
+
+ // Integer log2
+ // @returns floor(log2(x)) if x is nonzero, otherwise 0. This is the same
+ // as the location of the highest set bit.
+ // Consumes 232 gas. This could have been an 3 gas EVM opcode though.
+ function ilog2(uint256 x) internal pure returns (uint256 r) {
+ assembly {
+ r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
+ r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
+ r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
+ r := or(r, shl(4, lt(0xffff, shr(r, x))))
+ r := or(r, shl(3, lt(0xff, shr(r, x))))
+ r := or(r, shl(2, lt(0xf, shr(r, x))))
+ r := or(r, shl(1, lt(0x3, shr(r, x))))
+ r := or(r, lt(0x1, shr(r, x)))
+ }
+ }
+
+ function ln_pub(int256 x) public pure returns (int256 r) {
+ return ln(x);
+ }
+
+ // Computes ln(x) in 1e18 fixed point.
+ // Reverts if x is negative or zero.
+ // Consumes 670 gas.
+ function ln(int256 x) internal pure returns (int256 r) {
+ unchecked {
+ if (x < 1) {
+ if (x < 0) revert LnNegativeUndefined();
+ revert Overflow();
+ }
+
+ // We want to convert x from 10**18 fixed point to 2**96 fixed point.
+ // We do this by multiplying by 2**96 / 10**18.
+ // But since ln(x * C) = ln(x) + ln(C), we can simply do nothing here
+ // and add ln(2**96 / 10**18) at the end.
+
+ // Reduce range of x to (1, 2) * 2**96
+ // ln(2^k * x) = k * ln(2) + ln(x)
+ // Note: inlining ilog2 saves 8 gas.
+ int256 k = int256(ilog2(uint256(x))) - 96;
+ x <<= uint256(159 - k);
+ x = int256(uint256(x) >> 159);
+
+ // Evaluate using a (8, 8)-term rational approximation
+ // p is made monic, we will multiply by a scale factor later
+ int256 p = x + 3273285459638523848632254066296;
+ p = ((p * x) >> 96) + 24828157081833163892658089445524;
+ p = ((p * x) >> 96) + 43456485725739037958740375743393;
+ p = ((p * x) >> 96) - 11111509109440967052023855526967;
+ p = ((p * x) >> 96) - 45023709667254063763336534515857;
+ p = ((p * x) >> 96) - 14706773417378608786704636184526;
+ p = p * x - (795164235651350426258249787498 << 96);
+ //emit log_named_int("p", p);
+ // We leave p in 2**192 basis so we don't need to scale it back up for the division.
+ // q is monic by convention
+ int256 q = x + 5573035233440673466300451813936;
+ q = ((q * x) >> 96) + 71694874799317883764090561454958;
+ q = ((q * x) >> 96) + 283447036172924575727196451306956;
+ q = ((q * x) >> 96) + 401686690394027663651624208769553;
+ q = ((q * x) >> 96) + 204048457590392012362485061816622;
+ q = ((q * x) >> 96) + 31853899698501571402653359427138;
+ q = ((q * x) >> 96) + 909429971244387300277376558375;
+ assembly {
+ // Div in assembly because solidity adds a zero check despite the `unchecked`.
+ // The q polynomial is known not to have zeros in the domain. (All roots are complex)
+ // No scaling required because p is already 2**96 too large.
+ r := sdiv(p, q)
+ }
+ // r is in the range (0, 0.125) * 2**96
+
+ // Finalization, we need to
+ // * multiply by the scale factor s = 5.549…
+ // * add ln(2**96 / 10**18)
+ // * add k * ln(2)
+ // * multiply by 10**18 / 2**96 = 5**18 >> 78
+ // mul s * 5e18 * 2**96, base is now 5**18 * 2**192
+ r *= 1677202110996718588342820967067443963516166;
+ // add ln(2) * k * 5e18 * 2**192
+ r +=
+ 16597577552685614221487285958193947469193820559219878177908093499208371 *
+ k;
+ // add ln(2**96 / 10**18) * 5e18 * 2**192
+ r += 600920179829731861736702779321621459595472258049074101567377883020018308;
+ // base conversion: mul 2**18 / 2**192
+ r >>= 174;
+ }
+ }
+
+ // Computes e^x in 1e18 fixed point.
+ function exp(int256 x) internal pure returns (int256 r) {
+ unchecked {
+ // Input x is in fixed point format, with scale factor 1/1e18.
+
+ // When the result is < 0.5 we return zero. This happens when
+ // x <= floor(log(0.5e18) * 1e18) ~ -42e18
+ if (x <= -42139678854452767551) {
+ return 0;
+ }
+
+ // When the result is > (2**255 - 1) / 1e18 we can not represent it
+ // as an int256. This happens when x >= floor(log((2**255 -1) / 1e18) * 1e18) ~ 135.
+ if (x >= 135305999368893231589) revert Overflow();
+
+ // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96
+ // for more intermediate precision and a binary basis. This base conversion
+ // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.
+ x = (x << 78) / 5 ** 18;
+
+ // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers of two
+ // such that exp(x) = exp(x') * 2**k, where k is an integer.
+ // Solving this gives k = round(x / log(2)) and x' = x - k * log(2).
+ int256 k = ((x << 96) / 54916777467707473351141471128 + 2 ** 95) >>
+ 96;
+ x = x - k * 54916777467707473351141471128;
+ // k is in the range [-61, 195].
+
+ // Evaluate using a (6, 7)-term rational approximation
+ // p is made monic, we will multiply by a scale factor later
+ int256 p = x + 2772001395605857295435445496992;
+ p = ((p * x) >> 96) + 44335888930127919016834873520032;
+ p = ((p * x) >> 96) + 398888492587501845352592340339721;
+ p = ((p * x) >> 96) + 1993839819670624470859228494792842;
+ p = p * x + (4385272521454847904632057985693276 << 96);
+ // We leave p in 2**192 basis so we don't need to scale it back up for the division.
+ // Evaluate using using Knuth's scheme from p. 491.
+ int256 z = x + 750530180792738023273180420736;
+ z = ((z * x) >> 96) + 32788456221302202726307501949080;
+ int256 w = x - 2218138959503481824038194425854;
+ w = ((w * z) >> 96) + 892943633302991980437332862907700;
+ int256 q = z + w - 78174809823045304726920794422040;
+ q = ((q * w) >> 96) + 4203224763890128580604056984195872;
+ assembly {
+ // Div in assembly because solidity adds a zero check despite the `unchecked`.
+ // The q polynomial is known not to have zeros in the domain. (All roots are complex)
+ // No scaling required because p is already 2**96 too large.
+ r := sdiv(p, q)
+ }
+ // r should be in the range (0.09, 0.25) * 2**96.
+
+ // We now need to multiply r by
+ // * the scale factor s = ~6.031367120...,
+ // * the 2**k factor from the range reduction, and
+ // * the 1e18 / 2**96 factor for base converison.
+ // We do all of this at once, with an intermediate result in 2**213 basis
+ // so the final right shift is always by a positive amount.
+ r = int(
+ (uint(r) * 3822833074963236453042738258902158003155416615667) >>
+ uint256(195 - k)
+ );
+ }
+ }
+
+ function calcInitProofTimeIssued(
+ uint64 basefee,
+ uint16 proofTimeTarget,
+ uint8 adjustmentQuotient
+ ) public pure returns (uint64 initProofTimeIssued) {
+ uint256 scale = uint256(proofTimeTarget) * adjustmentQuotient;
+ // ln_pub() expects 1e18 fixed format
+ uint256 lnReq = scale * basefee * LibFixedPointMath.SCALING_FACTOR_1E18;
+ require(lnReq <= uint256(type(int256).max));
+ int256 log_result = ln_pub(int256(lnReq));
+ initProofTimeIssued = uint64(
+ ((scale * (uint256(log_result))) /
+ (LibFixedPointMath.SCALING_FACTOR_1E18))
+ );
+ }
+}
diff --git a/packages/protocol/test2/LibTokenomics.t.sol b/packages/protocol/test2/LibTokenomics.t.sol
deleted file mode 100644
index bcdcc197d76..00000000000
--- a/packages/protocol/test2/LibTokenomics.t.sol
+++ /dev/null
@@ -1,298 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.18;
-
-import {Test} from "forge-std/Test.sol";
-import {console2} from "forge-std/console2.sol";
-import {TaikoData} from "../contracts/L1/TaikoData.sol";
-import {LibTokenomics} from "../contracts/L1/libs/LibTokenomics.sol";
-import {
- SafeCastUpgradeable
-} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol";
-
-contract TestLibTokenomics is Test {
- using SafeCastUpgradeable for uint256;
-
- struct FeeConfig {
- uint64 avgTimeMAF;
- uint64 avgTimeCap;
- uint64 gracePeriodPctg;
- uint64 maxPeriodPctg;
- // extra fee/reward on top of baseFee
- uint64 multiplerPctg;
- }
-
- function testTokenomicsFeeCalcWithNonZeroStartBips() public {
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 0 seconds,
- isProposal: true,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 140 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 20 seconds,
- isProposal: true,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 120 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 40 seconds,
- isProposal: true,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 60 seconds,
- isProposal: true,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 80 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 80 seconds,
- isProposal: true,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 60 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 81 seconds,
- isProposal: true,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 60 * 1E8,
- expectedPreimumRate: 0
- });
- }
-
- function testTokenomicsFeeCalcWithZeroStartBips() public {
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 0 seconds,
- isProposal: true,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 20 seconds,
- isProposal: true,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 40 seconds,
- isProposal: true,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 60 seconds,
- isProposal: true,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 80 seconds,
- isProposal: true,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 81 seconds,
- isProposal: true,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
- }
-
- function testTokenomicsRewardCalcWithNonZeroStartBips() public {
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 0 seconds,
- isProposal: false,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 60 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 20 seconds,
- isProposal: false,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 80 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 40 seconds,
- isProposal: false,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 60 seconds,
- isProposal: false,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 120 * 1E8,
- expectedPreimumRate: 5000
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 80 seconds,
- isProposal: false,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 140 * 1E8,
- expectedPreimumRate: 10000
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 81 seconds,
- isProposal: false,
- dampingFactorBips: 4000, // 40%
- expectedFeeBase: 140 * 1E8,
- expectedPreimumRate: 10000
- });
- }
-
- function testTokenomicsRewardCalcWithZeroStartBips() public {
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 0 seconds,
- isProposal: false,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 20 seconds,
- isProposal: false,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 40 seconds,
- isProposal: false,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 60 seconds,
- isProposal: false,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 80 seconds,
- isProposal: false,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
-
- testTimeAdjustedFee({
- feeBase: 100 * 1E8,
- timeAverageSec: 40 seconds,
- timeUsedSec: 81 seconds,
- isProposal: false,
- dampingFactorBips: 0, // 0%
- expectedFeeBase: 100 * 1E8,
- expectedPreimumRate: 0
- });
- }
-
- function testTimeAdjustedFee(
- uint256 feeBase,
- uint256 timeAverageSec,
- uint256 timeUsedSec,
- bool isProposal,
- uint16 dampingFactorBips,
- uint256 expectedFeeBase,
- uint256 expectedPreimumRate
- ) private {
- TaikoData.FeeConfig memory feeConfig = TaikoData.FeeConfig({
- avgTimeMAF: 1024,
- dampingFactorBips: dampingFactorBips
- });
-
- (uint256 _feeBase, uint256 _premiumRate) = LibTokenomics
- .getTimeAdjustedFee(
- feeConfig,
- feeBase.toUint64(),
- isProposal,
- timeUsedSec,
- timeAverageSec * 1000
- );
-
- assertEq(_premiumRate, expectedPreimumRate);
- assertEq(_feeBase, expectedFeeBase);
- }
-}
diff --git a/packages/protocol/test2/TaikoL1.sim.sol b/packages/protocol/test2/TaikoL1.sim.sol
index 3fdac21cdcb..4861f9887c3 100644
--- a/packages/protocol/test2/TaikoL1.sim.sol
+++ b/packages/protocol/test2/TaikoL1.sim.sol
@@ -9,6 +9,7 @@ import {TaikoData} from "../contracts/L1/TaikoData.sol";
import {TaikoL1} from "../contracts/L1/TaikoL1.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {TaikoL1TestBase} from "./TaikoL1TestBase.t.sol";
+import {LibLn} from "./LibLn.sol";
/// @dev Warning: this test will take 7-10 minutes and require 1GB memory.
/// `pnpm test:sim`
@@ -23,11 +24,11 @@ contract TaikoL1_b is TaikoL1 {
config.enableTokenomics = true;
config.txListCacheExpiry = 0;
- config.proposerDepositPctg = 0;
config.enableSoloProposer = false;
config.enableOracleProver = false;
config.maxNumProposedBlocks = 36;
config.ringBufferSize = 40;
+ config.proofTimeTarget = 200;
}
}
@@ -43,18 +44,23 @@ contract TaikoL1Simulation is TaikoL1TestBase, FoundryRandom {
}
function setUp() public override {
- TaikoL1TestBase.setUp();
- _registerAddress(
- string(abi.encodePacked("verifier_", uint16(100))),
- address(new Verifier())
+ uint16 proofTimeTarget = 200; // Approx. value which close to what is in the simulation
+
+ initProofTimeIssued = LibLn.calcInitProofTimeIssued(
+ feeBase,
+ proofTimeTarget,
+ ADJUSTMENT_QUOTIENT
);
+
+ TaikoL1TestBase.setUp();
+ registerAddress(L1.getVerifierName(100), address(new Verifier()));
}
function testGeneratingManyRandomBlocks() external {
uint256 time = block.timestamp;
assertEq(time, 1);
- _depositTaikoToken(Alice, 1E6 * 1E8, 10000 ether);
+ depositTaikoToken(Alice, 1E6 * 1E8, 10000 ether);
bytes32 parentHash = GENESIS_BLOCK_HASH;
uint32 parentGasUsed;
@@ -86,6 +92,19 @@ contract TaikoL1Simulation is TaikoL1TestBase, FoundryRandom {
gasLimit,
txListSize
);
+ // Here we need to have some time elapsed between propose and prove
+ // Realistically lets make it somewhere 160-240 sec, it is realistic
+ // for a testnet. Created this function because randomNumber seems to
+ // be non-working properly.
+ uint8 proveTimeCnt = pickRandomProveTime(
+ uint256(
+ keccak256(
+ abi.encodePacked(time, msg.sender, block.timestamp)
+ )
+ )
+ );
+
+ mine(proveTimeCnt);
proveBlock(
Bob,
@@ -111,10 +130,10 @@ contract TaikoL1Simulation is TaikoL1TestBase, FoundryRandom {
"\nlogCount,",
"time,",
"lastVerifiedBlockId,",
- "numBlocks,"
- // "feeBase,",
- // "fee,",
- // "lastProposedAt"
+ "numBlocks,",
+ "baseFee,",
+ "accProposedAt,",
+ "lastProposedAt"
);
console2.log(str);
}
@@ -129,14 +148,23 @@ contract TaikoL1Simulation is TaikoL1TestBase, FoundryRandom {
",",
Strings.toString(vars.lastVerifiedBlockId),
",",
- Strings.toString(vars.numBlocks)
- // ",",
- // Strings.toString(vars.feeBase),
- // ",",
- // Strings.toString(fee),
- // ",",
- // Strings.toString(vars.lastProposedAt)
+ Strings.toString(vars.numBlocks),
+ ",",
+ Strings.toString(vars.basefee),
+ ",",
+ Strings.toString(vars.accProposedAt),
+ ",",
+ Strings.toString(vars.lastProposedAt)
);
console2.log(str);
}
+
+ function pickRandomProveTime(
+ uint256 randomNum
+ ) internal pure returns (uint8) {
+ // Result shall be between 8-12 (inclusive)
+ // so that it will result in a 160-240s proof time
+ // while the proof time target is 200s
+ return uint8(8 + (randomNum % 5));
+ }
}
diff --git a/packages/protocol/test2/TaikoL1.t.sol b/packages/protocol/test2/TaikoL1.t.sol
index bc71b94d024..48b1cbc790b 100644
--- a/packages/protocol/test2/TaikoL1.t.sol
+++ b/packages/protocol/test2/TaikoL1.t.sol
@@ -23,30 +23,12 @@ contract TaikoL1_a is TaikoL1 {
config.enableTokenomics = true;
config.txListCacheExpiry = 5 minutes;
- config.proposerDepositPctg = 0;
config.maxVerificationsPerTx = 0;
config.enableSoloProposer = false;
config.enableOracleProver = false;
config.maxNumProposedBlocks = 10;
config.ringBufferSize = 12;
// this value must be changed if `maxNumProposedBlocks` is changed.
- config.slotSmoothingFactor = 4160;
-
- config.proposingConfig = TaikoData.FeeConfig({
- avgTimeMAF: 64,
- dampingFactorBips: 5000
- });
-
- config.provingConfig = TaikoData.FeeConfig({
- avgTimeMAF: 64,
- dampingFactorBips: 5000
- });
- }
-}
-
-contract Verifier {
- fallback(bytes calldata) external returns (bytes memory) {
- return bytes.concat(keccak256("taiko"));
}
}
@@ -57,17 +39,13 @@ contract TaikoL1Test is TaikoL1TestBase {
function setUp() public override {
TaikoL1TestBase.setUp();
- _registerAddress(
- string(abi.encodePacked("verifier_", uint16(100))),
- address(new Verifier())
- );
}
/// @dev Test we can propose, prove, then verify more blocks than 'maxNumProposedBlocks'
function test_more_blocks_than_ring_buffer_size() external {
- _depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
- _depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
- _depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
bytes32 parentHash = GENESIS_BLOCK_HASH;
uint32 parentGasUsed = 0;
@@ -109,7 +87,7 @@ contract TaikoL1Test is TaikoL1TestBase {
/// @dev Test more than one block can be proposed, proven, & verified in the
/// same L1 block.
function test_multiple_blocks_in_one_L1_block() external {
- _depositTaikoToken(Alice, 1000 * 1E8, 1000 ether);
+ depositTaikoToken(Alice, 1000 * 1E8, 1000 ether);
bytes32 parentHash = GENESIS_BLOCK_HASH;
uint32 parentGasUsed = 0;
@@ -144,7 +122,7 @@ contract TaikoL1Test is TaikoL1TestBase {
/// @dev Test verifying multiple blocks in one transaction
function test_verifying_multiple_blocks_once() external {
- _depositTaikoToken(Alice, 1E6 * 1E8, 1000 ether);
+ depositTaikoToken(Alice, 1E6 * 1E8, 1000 ether);
bytes32 parentHash = GENESIS_BLOCK_HASH;
uint32 parentGasUsed = 0;
@@ -183,90 +161,4 @@ contract TaikoL1Test is TaikoL1TestBase {
verifyBlock(Alice, conf.maxNumProposedBlocks);
printVariables("after verify");
}
-
- /// @dev Test block time increases and fee decreases.
- function test_block_time_increases_and_fee_decreases() external {
- _depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
- _depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
- _depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
-
- bytes32 parentHash = GENESIS_BLOCK_HASH;
- uint32 parentGasUsed = 0;
- uint32 gasUsed = 1000000;
-
- for (
- uint256 blockId = 1;
- blockId < conf.maxNumProposedBlocks * 10;
- blockId++
- ) {
- printVariables("before propose");
- TaikoData.BlockMetadata memory meta = proposeBlock(
- Alice,
- 1000000,
- 1024
- );
- mine(1);
-
- bytes32 blockHash = bytes32(1E10 + blockId);
- bytes32 signalRoot = bytes32(1E9 + blockId);
- proveBlock(
- Bob,
- meta,
- parentHash,
- parentGasUsed,
- gasUsed,
- blockHash,
- signalRoot
- );
- parentHash = blockHash;
- parentGasUsed = gasUsed;
-
- verifyBlock(Carol, 1);
- mine(blockId);
- parentHash = blockHash;
- }
- printVariables("");
- }
-
- /// @dev Test block time decreases and the fee increases
- function test_block_time_decreases_but_fee_remains() external {
- _depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
- _depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
- _depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
-
- bytes32 parentHash = GENESIS_BLOCK_HASH;
- uint32 parentGasUsed = 0;
- uint32 gasUsed = 1000000;
-
- uint256 total = conf.maxNumProposedBlocks * 10;
-
- for (uint256 blockId = 1; blockId < total; blockId++) {
- printVariables("before propose");
- TaikoData.BlockMetadata memory meta = proposeBlock(
- Alice,
- 1000000,
- 1024
- );
- mine(1);
-
- bytes32 blockHash = bytes32(1E10 + blockId);
- bytes32 signalRoot = bytes32(1E9 + blockId);
- proveBlock(
- Bob,
- meta,
- parentHash,
- parentGasUsed,
- gasUsed,
- blockHash,
- signalRoot
- );
- parentHash = blockHash;
- parentGasUsed = gasUsed;
-
- verifyBlock(Carol, 1);
- mine(total + 1 - blockId);
- parentHash = blockHash;
- }
- printVariables("");
- }
}
diff --git a/packages/protocol/test2/TaikoL1LibTokenomicsMainnet.t.sol b/packages/protocol/test2/TaikoL1LibTokenomicsMainnet.t.sol
new file mode 100644
index 00000000000..f866ff488d8
--- /dev/null
+++ b/packages/protocol/test2/TaikoL1LibTokenomicsMainnet.t.sol
@@ -0,0 +1,295 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.18;
+
+// Uncomment if you want to compare fee/vs reward
+import {Test} from "forge-std/Test.sol";
+import {console2} from "forge-std/console2.sol";
+import {FoundryRandom} from "foundry-random/FoundryRandom.sol";
+import {AddressManager} from "../contracts/thirdparty/AddressManager.sol";
+import {TaikoConfig} from "../contracts/L1/TaikoConfig.sol";
+import {TaikoData} from "../contracts/L1/TaikoData.sol";
+import {TaikoL1} from "../contracts/L1/TaikoL1.sol";
+import {TaikoToken} from "../contracts/L1/TaikoToken.sol";
+import {SignalService} from "../contracts/signal/SignalService.sol";
+import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
+import {TaikoL1TestBase} from "./TaikoL1TestBase.t.sol";
+import {LibLn} from "./LibLn.sol";
+
+contract TaikoL1MainnetMockConfig is TaikoL1 {
+ function getConfig()
+ public
+ pure
+ override
+ returns (TaikoData.Config memory config)
+ {
+ config = TaikoConfig.getConfig();
+
+ config.txListCacheExpiry = 5 minutes;
+ config.maxVerificationsPerTx = 1;
+ config.enableSoloProposer = false;
+ config.enableOracleProver = false;
+ config.maxNumProposedBlocks = 200;
+ config.ringBufferSize = 240;
+ config.proofTimeTarget = 2160;
+ }
+}
+
+contract TaikoL1LibTokenomicsMainnet is TaikoL1TestBase, FoundryRandom {
+ // To avoid stack too deep error
+ // Can play to adjust
+ uint32 iterationCnt = 5000;
+ uint8 proofTime = 180; // When proofs are coming, 180 means 180 sec
+ // Check balances
+ uint256 Alice_start_balance;
+ uint256 Bob_start_balance;
+
+ function deployTaikoL1() internal override returns (TaikoL1 taikoL1) {
+ taikoL1 = new TaikoL1MainnetMockConfig();
+ }
+
+ function setUp() public override {
+ uint16 proofTimeTarget = 2160; // Approx. mainnet value
+ // Calculating it for our needs based on testnet/mainnet proof vars.
+ // See Brecht's comment https://github.com/taikoxyz/taiko-mono/pull/13564
+ initProofTimeIssued = LibLn.calcInitProofTimeIssued(
+ feeBase,
+ proofTimeTarget,
+ ADJUSTMENT_QUOTIENT
+ );
+
+ TaikoL1TestBase.setUp();
+
+ depositTaikoToken(Alice, 1E8 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E8 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E8 * 1E8, 100 ether);
+
+ Alice_start_balance = L1.getBalance(Alice);
+ Bob_start_balance = L1.getBalance(Bob);
+ }
+
+ /// @dev A possible (close to) mainnet scenarios is the following:
+ //// - Blocks ever 10 seconds proposed
+ //// - Proofs coming shifted slightly below 30 min / proposed block afterwards
+ //// Expected result: Withdrawals and deposits are in balance but keep shrinking since quicker proofTime
+ function xtest_possible_mainnet_scenario_proof_time_below_target()
+ external
+ {
+ vm.pauseGasMetering();
+ mine(1);
+
+ depositTaikoToken(Alice, 1E8 * 1E8, 1000 ether);
+ depositTaikoToken(Bob, 1E8 * 1E8, 1000 ether);
+ depositTaikoToken(Carol, 1E8 * 1E8, 1000 ether);
+
+ // Check balances
+ Alice_start_balance = L1.getBalance(Alice);
+ Bob_start_balance = L1.getBalance(Bob);
+
+ // Can play to adjust
+ proofTime = 179; // When proofs are coming, 179 means 1790 sec
+
+ TaikoData.BlockMetadata[] memory meta = new TaikoData.BlockMetadata[](
+ iterationCnt
+ );
+ uint64[] memory proposedAt = new uint64[](iterationCnt);
+ bytes32[] memory parentHashes = new bytes32[](iterationCnt);
+ bytes32[] memory blockHashes = new bytes32[](iterationCnt);
+ bytes32[] memory signalRoots = new bytes32[](iterationCnt);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+ console2.logBytes32(parentHash);
+
+ // Run another session with huge times
+ for (uint256 blockId = 1; blockId < iterationCnt; blockId++) {
+ meta[blockId] = proposeBlock(Alice, 1000000, 1024);
+ proposedAt[blockId] = (uint64(block.timestamp));
+ printVariables("after propose");
+ blockHashes[blockId] = bytes32(1E10 + blockId);
+ signalRoots[blockId] = bytes32(1E9 + blockId);
+
+ if (blockId > proofTime) {
+ //Start proving with an offset
+ proveBlock(
+ Bob,
+ meta[blockId - proofTime],
+ parentHashes[blockId - proofTime],
+ (blockId - proofTime == 1) ? 0 : 1000000, // Genesis block has 0 gas used
+ 1000000,
+ blockHashes[blockId - proofTime],
+ signalRoots[blockId - proofTime]
+ );
+
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt[blockId - proofTime])
+ );
+ verifyBlock(Carol, 1);
+ }
+
+ mine_every_12_sec();
+
+ parentHashes[blockId] = parentHash;
+ parentHash = blockHashes[blockId];
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ //Check end balances
+ deposits = Alice_start_balance - L1.getBalance(Alice);
+ withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+ // Assert their balance changed relatively the same way
+ // 1e18 == within 100 % delta -> 1e17 10%, let's see if this is within that range
+ assertApproxEqRel(deposits, withdrawals, 1e17);
+ }
+
+ /// @dev A possible (close to) mainnet scenarios is the following:
+ //// - Blocks ever 10 seconds proposed
+ //// - Proofs coming shifted slightly below 30 min / proposed block afterwards
+ //// Expected result: Withdrawals and deposits are in balance but keep shrinking since quicker proofTime
+ function xtest_possible_mainnet_scenario_proof_time_at_target() external {
+ vm.pauseGasMetering();
+ mine(1);
+
+ TaikoData.BlockMetadata[] memory meta = new TaikoData.BlockMetadata[](
+ iterationCnt
+ );
+ uint64[] memory proposedAt = new uint64[](iterationCnt);
+ bytes32[] memory parentHashes = new bytes32[](iterationCnt);
+ bytes32[] memory blockHashes = new bytes32[](iterationCnt);
+ bytes32[] memory signalRoots = new bytes32[](iterationCnt);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Run another session with huge times
+ for (uint256 blockId = 1; blockId < iterationCnt; blockId++) {
+ {
+ meta[blockId] = proposeBlock(Alice, 100000, 10);
+ proposedAt[blockId] = (uint64(block.timestamp));
+ printVariables("after propose");
+ blockHashes[blockId] = bytes32(1E10 + blockId); //blockHash;
+ signalRoots[blockId] = bytes32(1E9 + blockId); //signalRoot;
+
+ if (blockId > proofTime) {
+ //Start proving with an offset
+ proveBlock(
+ Bob,
+ meta[blockId - proofTime],
+ parentHashes[blockId - proofTime],
+ (blockId - proofTime == 1) ? 0 : 1000000,
+ 1000000,
+ blockHashes[blockId - proofTime],
+ signalRoots[blockId - proofTime]
+ );
+
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(
+ provenAt,
+ proposedAt[blockId - proofTime]
+ )
+ );
+ }
+
+ mine_every_12_sec();
+
+ parentHashes[blockId] = parentHash;
+ parentHash = blockHashes[blockId];
+ }
+ }
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ //Check end balances
+ deposits = Alice_start_balance - L1.getBalance(Alice);
+ withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+ // Assert their balance changed relatively the same way
+ // 1e18 == within 100 % delta -> 1e17 10%, let's see if this is within that range
+ assertApproxEqRel(deposits, withdrawals, 1e17);
+ }
+
+ /// @dev A possible (close to) mainnet scenarios is the following:
+ //// - Blocks ever 10 seconds proposed
+ //// - Proofs coming shifted slightly above 30 min / proposed block afterwards
+ //// Expected result: Withdrawals and deposits are in balance but fees keep growing bc of above target
+ function xtest_possible_mainnet_scenario_proof_time_above_target()
+ external
+ {
+ vm.pauseGasMetering();
+ mine(1);
+
+ proofTime = 181; // When proofs are coming, 181 means 1810 sec
+
+ TaikoData.BlockMetadata[] memory meta = new TaikoData.BlockMetadata[](
+ iterationCnt
+ );
+ uint64[] memory proposedAt = new uint64[](iterationCnt);
+ bytes32[] memory parentHashes = new bytes32[](iterationCnt);
+ bytes32[] memory blockHashes = new bytes32[](iterationCnt);
+ bytes32[] memory signalRoots = new bytes32[](iterationCnt);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ for (uint256 blockId = 1; blockId < iterationCnt; blockId++) {
+ meta[blockId] = proposeBlock(Alice, 1000000, 1024);
+ proposedAt[blockId] = (uint64(block.timestamp));
+ printVariables("after propose");
+ blockHashes[blockId] = bytes32(1E10 + blockId);
+ signalRoots[blockId] = bytes32(1E9 + blockId);
+
+ if (blockId > proofTime) {
+ //Start proving with an offset
+ proveBlock(
+ Bob,
+ meta[blockId - proofTime],
+ parentHashes[blockId - proofTime],
+ (blockId - proofTime == 1) ? 0 : 1000000,
+ 1000000,
+ blockHashes[blockId - proofTime],
+ signalRoots[blockId - proofTime]
+ );
+
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt[blockId - proofTime])
+ );
+ verifyBlock(Carol, 1);
+ }
+
+ mine_every_12_sec();
+
+ parentHashes[blockId] = parentHash;
+ parentHash = blockHashes[blockId];
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ //Check end balances
+ deposits = Alice_start_balance - L1.getBalance(Alice);
+ withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+ // Assert their balance changed relatively the same way
+ // 1e18 == within 100 % delta -> 1e17 10%, let's see if this is within that range
+ assertApproxEqRel(deposits, withdrawals, 1e17);
+ }
+
+ function mine_every_12_sec() internal {
+ vm.warp(block.timestamp + 12);
+ vm.roll(block.number + 1);
+ }
+}
diff --git a/packages/protocol/test2/TaikoL1LibTokenomicsTestnet.t.sol b/packages/protocol/test2/TaikoL1LibTokenomicsTestnet.t.sol
new file mode 100644
index 00000000000..6399411a295
--- /dev/null
+++ b/packages/protocol/test2/TaikoL1LibTokenomicsTestnet.t.sol
@@ -0,0 +1,950 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.18;
+
+// Uncomment if you want to compare fee/vs reward
+import {Test} from "forge-std/Test.sol";
+import {console2} from "forge-std/console2.sol";
+import {AddressManager} from "../contracts/thirdparty/AddressManager.sol";
+import {TaikoConfig} from "../contracts/L1/TaikoConfig.sol";
+import {TaikoData} from "../contracts/L1/TaikoData.sol";
+import {TaikoL1} from "../contracts/L1/TaikoL1.sol";
+import {TaikoToken} from "../contracts/L1/TaikoToken.sol";
+import {SignalService} from "../contracts/signal/SignalService.sol";
+import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
+import {TaikoL1TestBase} from "./TaikoL1TestBase.t.sol";
+import {LibLn} from "./LibLn.sol";
+
+contract TaikoL1WithTestnetConfig is TaikoL1 {
+ function getConfig()
+ public
+ pure
+ override
+ returns (TaikoData.Config memory config)
+ {
+ config = TaikoConfig.getConfig();
+
+ config.txListCacheExpiry = 5 minutes;
+ config.maxVerificationsPerTx = 0;
+ config.enableSoloProposer = false;
+ config.enableOracleProver = false;
+ config.maxNumProposedBlocks = 40;
+ config.ringBufferSize = 48;
+ config.proofTimeTarget = 120; // Testnet example
+ }
+}
+
+// Testing the base "math" and directions if all is good
+contract TaikoL1LibTokenomicsTestnet is TaikoL1TestBase {
+ function deployTaikoL1() internal override returns (TaikoL1 taikoL1) {
+ taikoL1 = new TaikoL1WithTestnetConfig();
+ }
+
+ function setUp() public override {
+ uint16 proofTimeTarget = 120; // Approx. testnet value
+ // Calculating it for our needs based on testnet/mainnet proof vars.
+ // See Brecht's comment https://github.com/taikoxyz/taiko-mono/pull/13564
+ initProofTimeIssued = LibLn.calcInitProofTimeIssued(
+ feeBase,
+ proofTimeTarget,
+ ADJUSTMENT_QUOTIENT
+ );
+
+ TaikoL1TestBase.setUp();
+
+ depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
+ }
+
+ /// @dev Test what happens when proof time increases
+ function test_balanced_state_reward_and_fee_if_proof_time_increases_slowly_then_drastically()
+ external
+ {
+ mine(1);
+ depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Check balances
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+ console2.log("Alice balance:", Alice_start_balance);
+ console2.log("Bob balance:", Bob_start_balance);
+
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ TaikoData.BlockMetadata memory meta = proposeBlock(
+ Alice,
+ 1000000,
+ 1024
+ );
+ uint64 proposedAt = uint64(block.timestamp);
+ mine(blockId);
+
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ meta,
+ parentHash,
+ blockId == 1 ? 0 : 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt)
+ );
+
+ verifyBlock(Carol, 1);
+ // This is where new fee evaluated
+ printVariables("after verify");
+
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+
+ assertEq(deposits, withdrawals);
+
+ // Run another session with huge times
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ TaikoData.BlockMetadata memory meta = proposeBlock(
+ Alice,
+ 1000000,
+ 1024
+ );
+ uint64 proposedAt = uint64(block.timestamp);
+ mine_huge();
+
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+
+ proveBlock(
+ Bob,
+ meta,
+ parentHash,
+ 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt)
+ );
+ verifyBlock(Carol, 1);
+ // This is where new fee evaluated
+ printVariables("after verify");
+
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ deposits = Alice_start_balance - L1.getBalance(Alice);
+ withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ assertEq(deposits, withdrawals);
+ }
+
+ /// @dev Test what happens when proof time hectic couple of proposes, without prove, then some proofs
+ function test_balanced_state_reward_and_fee_if_proof_time_hectic()
+ external
+ {
+ mine(1);
+ //Needs lot of token here - because there is lots of time elapsed between 2 'propose' blocks, which will raise the fee
+ depositTaikoToken(Alice, 1E8 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E8 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E8 * 1E8, 100 ether);
+
+ TaikoData.BlockMetadata[] memory metas = new TaikoData.BlockMetadata[](
+ 20
+ );
+ uint64[] memory proposedAtArr = new uint64[](20);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Check balances
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+ console2.log("Alice balance:", Alice_start_balance);
+ console2.log("Bob balance:", Bob_start_balance);
+
+ // Propose blocks - but dont go above a certain iterationi count because the drastically increasing
+ // proof time will be an issue
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ //printVariables("before propose");
+ metas[blockId] = proposeBlock(Alice, 1000000, 1024);
+ proposedAtArr[blockId] = (uint64(block.timestamp));
+ printVariables("after propose");
+ mine(blockId);
+ }
+
+ // Wait random X
+ mine(6);
+ // Prove and verify
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ metas[blockId],
+ parentHash,
+ blockId == 1 ? 0 : 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAtArr[blockId])
+ );
+
+ verifyBlock(Carol, 1);
+
+ printVariables("after verify");
+ mine(blockId);
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ // Run another iteration
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ printVariables("before propose");
+ TaikoData.BlockMetadata memory meta = proposeBlock(
+ Alice,
+ 1000000,
+ 1024
+ );
+ uint64 proposedAt = uint64(block.timestamp);
+ printVariables("after propose");
+ mine_proofTime();
+
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ meta,
+ parentHash,
+ 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt)
+ );
+ verifyBlock(Carol, 1);
+
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ deposits = Alice_start_balance - L1.getBalance(Alice);
+ withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+ assertEq(deposits, withdrawals);
+ }
+
+ /// @dev Test and see what happens when proof time is stable below the target and proving consecutive
+ function test_balanced_state_reward_and_fee_if_proof_time_stable_below_target_prooving_consecutive()
+ external
+ {
+ mine(1);
+ depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Check balances
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+ console2.log("Alice balance:", Alice_start_balance);
+ console2.log("Bob balance:", Bob_start_balance);
+
+ //parentHash = prove_with_increasing_time(parentHash, 10);
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ printVariables("before propose");
+ TaikoData.BlockMetadata memory meta = proposeBlock(
+ Alice,
+ 1000000,
+ 1024
+ );
+ uint64 proposedAt = uint64(block.timestamp);
+ printVariables("after propose");
+ mine(2);
+
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ meta,
+ parentHash,
+ blockId == 1 ? 0 : 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt)
+ );
+
+ verifyBlock(Carol, 1);
+
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+
+ assertEq(deposits, withdrawals);
+ }
+
+ /// @dev Test and see what happens when proof time is stable below the target and proving non consecutive
+ function test_balanced_state_reward_and_fee_if_proof_time_stable_below_target_proving_non_consecutive()
+ external
+ {
+ mine(1);
+ depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
+
+ TaikoData.BlockMetadata[] memory meta = new TaikoData.BlockMetadata[](
+ 30
+ );
+ uint64[] memory proposedAt = new uint64[](30);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Check balances
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+ console2.log("Alice balance:", Alice_start_balance);
+ console2.log("Bob balance:", Bob_start_balance);
+
+ // Propose blocks
+ for (uint256 blockId = 1; blockId < 30; blockId++) {
+ //printVariables("before propose");
+ meta[blockId] = proposeBlock(Alice, 1000000, 1024);
+ proposedAt[blockId] = (uint64(block.timestamp));
+ printVariables("after propose");
+ mine(blockId);
+ }
+
+ // Wait random X
+ mine(6);
+ //Prove and verify
+ for (uint256 blockId = 1; blockId < 30; blockId++) {
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+
+ proveBlock(
+ Bob,
+ meta[blockId],
+ parentHash,
+ blockId == 1 ? 0 : 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt[blockId])
+ );
+
+ verifyBlock(Carol, 1);
+
+ mine(3);
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+
+ assertEq(deposits, withdrawals);
+ }
+
+ /// @dev Test what happens when proof time decreases
+ function test_balanced_state_reward_and_fee_if_proof_time_decreases()
+ external
+ {
+ mine(1);
+ depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
+
+ TaikoData.BlockMetadata[] memory meta = new TaikoData.BlockMetadata[](
+ 20
+ );
+ uint64[] memory proposedAt = new uint64[](20);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Check balances
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+ console2.log("Alice balance:", Alice_start_balance);
+ console2.log("Bob balance:", Bob_start_balance);
+
+ // Propose blocks
+ for (uint256 blockId = 1; blockId < 20; blockId++) {
+ //printVariables("before propose");
+ meta[blockId] = proposeBlock(Alice, 1000000, 1024);
+ proposedAt[blockId] = (uint64(block.timestamp));
+ printVariables("after propose");
+ mine(blockId);
+ }
+
+ // Wait random X
+ mine(6);
+ // Prove and verify
+ for (uint256 blockId = 1; blockId < 20; blockId++) {
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ meta[blockId],
+ parentHash,
+ blockId == 1 ? 0 : 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt[blockId])
+ );
+
+ verifyBlock(Carol, 1);
+ mine(21 - blockId);
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+ // console2.log("Deposits:", deposits);
+ // console2.log("withdrawals:", withdrawals);
+ assertEq(deposits, withdrawals);
+ }
+
+ /// @dev Test and see what happens when proof time is stable above the target and proving consecutive
+ function test_balanced_state_reward_and_fee_if_proof_time_stable_above_target_prooving_consecutive()
+ external
+ {
+ mine(1);
+ depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Check balances
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+ console2.log("Alice balance:", Alice_start_balance);
+ console2.log("Bob balance:", Bob_start_balance);
+
+ //parentHash = prove_with_increasing_time(parentHash, 10);
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ printVariables("before propose");
+ TaikoData.BlockMetadata memory meta = proposeBlock(
+ Alice,
+ 1000000,
+ 1024
+ );
+ uint64 proposedAt = uint64(block.timestamp);
+ printVariables("after propose");
+ mine(5);
+
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ meta,
+ parentHash,
+ blockId == 1 ? 0 : 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt)
+ );
+
+ verifyBlock(Carol, 1);
+
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+
+ assertEq(deposits, withdrawals);
+ }
+
+ /// @dev Test and see what happens when proof time is stable above the target and proving non consecutive
+ function test_balanced_state_reward_and_fee_if_proof_time_stable_above_target_proving_non_consecutive()
+ external
+ {
+ mine(1);
+ depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
+
+ TaikoData.BlockMetadata[] memory meta = new TaikoData.BlockMetadata[](
+ 30
+ );
+ uint64[] memory proposedAt = new uint64[](30);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Check balances
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+ console2.log("Alice balance:", Alice_start_balance);
+ console2.log("Bob balance:", Bob_start_balance);
+
+ // Propose blocks
+ for (uint256 blockId = 1; blockId < 30; blockId++) {
+ //printVariables("before propose");
+ meta[blockId] = proposeBlock(Alice, 1000000, 1024);
+ proposedAt[blockId] = (uint64(block.timestamp));
+ printVariables("after propose");
+ mine(blockId);
+ }
+
+ // Wait random X
+ mine(6);
+ // Prove and verify
+ for (uint256 blockId = 1; blockId < 30; blockId++) {
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+
+ proveBlock(
+ Bob,
+ meta[blockId],
+ parentHash,
+ blockId == 1 ? 0 : 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt[blockId])
+ );
+
+ verifyBlock(Carol, 1);
+ mine(5);
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+
+ assertEq(deposits, withdrawals);
+ }
+
+ /// @dev Test what happens when proof time decreases
+ function test_balanced_state_reward_and_fee_if_proof_time_decreasses_then_stabilizes_consecutive()
+ external
+ {
+ mine(1);
+ depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Check balances
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+ console2.log("Alice balance:", Alice_start_balance);
+ console2.log("Bob balance:", Bob_start_balance);
+
+ //parentHash = prove_with_increasing_time(parentHash, 10);
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ TaikoData.BlockMetadata memory meta = proposeBlock(
+ Alice,
+ 1000000,
+ 1024
+ );
+ printVariables("after propose");
+ uint64 proposedAt = uint64(block.timestamp);
+ mine(11 - blockId);
+
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ meta,
+ parentHash,
+ blockId == 1 ? 0 : 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt)
+ );
+
+ verifyBlock(Carol, 1);
+
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+
+ assertEq(deposits, withdrawals);
+
+ // Run another session with huge times
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ printVariables("before propose");
+ TaikoData.BlockMetadata memory meta = proposeBlock(
+ Alice,
+ 1000000,
+ 1024
+ );
+ uint64 proposedAt = uint64(block.timestamp);
+ printVariables("after propose");
+ mine_proofTime();
+
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ meta,
+ parentHash,
+ 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt)
+ );
+ verifyBlock(Carol, 1);
+
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ deposits = Alice_start_balance - L1.getBalance(Alice);
+ withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ assertEq(deposits, withdrawals);
+ }
+
+ /// @dev Test what happens when proof time decreases
+ function test_balanced_state_reward_and_fee_if_proof_time_decreases_then_stabilizes_non_consecutive()
+ external
+ {
+ mine(1);
+ // Requires a bit more tokens
+ depositTaikoToken(Alice, 1E8 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E8 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E8 * 1E8, 100 ether);
+
+ TaikoData.BlockMetadata[]
+ memory metaArr = new TaikoData.BlockMetadata[](20);
+ uint64[] memory proposedAtArr = new uint64[](20);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Check balances
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+ console2.log("Alice balance:", Alice_start_balance);
+ console2.log("Bob balance:", Bob_start_balance);
+
+ // Propose blocks
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ //printVariables("before propose");
+ metaArr[blockId] = proposeBlock(Alice, 1000000, 1024);
+ proposedAtArr[blockId] = (uint64(block.timestamp));
+ printVariables("after propose");
+ mine(blockId);
+ }
+
+ // Wait random X
+ mine(6);
+ // Prove and verify
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ metaArr[blockId],
+ parentHash,
+ (blockId == 1 ? 0 : 1000000),
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAtArr[blockId])
+ );
+
+ verifyBlock(Carol, 1);
+ mine(21 - blockId);
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+
+ assertEq(deposits, withdrawals);
+
+ // Run another session with huge times
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ printVariables("before propose");
+ TaikoData.BlockMetadata memory meta = proposeBlock(
+ Alice,
+ 1000000,
+ 1024
+ );
+ uint64 proposedAt = uint64(block.timestamp);
+ printVariables("after propose");
+ mine_proofTime();
+
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ meta,
+ parentHash,
+ 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt)
+ );
+ verifyBlock(Carol, 1);
+
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ deposits = Alice_start_balance - L1.getBalance(Alice);
+ withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ // console2.log("Deposits:", deposits);
+ // console2.log("withdrawals:", withdrawals);
+ assertEq(deposits, withdrawals);
+ }
+
+ /// @dev Test and see what happens when proof time is stable at the target and proving consecutive
+ function test_balanced_state_reward_and_fee_if_proof_time_stable_consecutive()
+ external
+ {
+ mine(1);
+ depositTaikoToken(Alice, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Bob, 1E6 * 1E8, 100 ether);
+ depositTaikoToken(Carol, 1E6 * 1E8, 100 ether);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+
+ // Check balances
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+ console2.log("Alice balance:", Alice_start_balance);
+ console2.log("Bob balance:", Bob_start_balance);
+
+ //parentHash = prove_with_increasing_time(parentHash, 10);
+ for (uint256 blockId = 1; blockId < 10; blockId++) {
+ printVariables("before propose");
+ TaikoData.BlockMetadata memory meta = proposeBlock(
+ Alice,
+ 1000000,
+ 1024
+ );
+ uint64 proposedAt = uint64(block.timestamp);
+ printVariables("after propose");
+ mine_proofTime();
+
+ bytes32 blockHash = bytes32(1E10 + blockId);
+ bytes32 signalRoot = bytes32(1E9 + blockId);
+ proveBlock(
+ Bob,
+ meta,
+ parentHash,
+ blockId == 1 ? 0 : 1000000,
+ 1000000,
+ blockHash,
+ signalRoot
+ );
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(provenAt, proposedAt)
+ );
+
+ verifyBlock(Carol, 1);
+
+ parentHash = blockHash;
+ }
+
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+
+ assertEq(deposits, withdrawals);
+ }
+
+ /// @dev Test a scenario which very close to a testnet behaviour
+ function test_balanced_state_reward_and_fee_if_proof_time_stable_non_consecutive()
+ external
+ {
+ uint256 Alice_start_balance = L1.getBalance(Alice);
+ uint256 Bob_start_balance = L1.getBalance(Bob);
+
+ // Need constants here and in loop counter to avoid stack too deep error
+ TaikoData.BlockMetadata[] memory meta = new TaikoData.BlockMetadata[](
+ 200
+ );
+ uint64[] memory proposedAt = new uint64[](200);
+ bytes32[] memory parentHashes = new bytes32[](200);
+ bytes32[] memory blockHashes = new bytes32[](200);
+ bytes32[] memory signalRoots = new bytes32[](200);
+
+ bytes32 parentHash = GENESIS_BLOCK_HASH;
+ uint8 proofTime = 10;
+ console2.logBytes32(parentHash);
+
+ // Run another session with huge times
+ for (uint256 blockId = 1; blockId < 150; blockId++) {
+ {
+ meta[blockId] = proposeBlock(Alice, 1000000, 1024);
+ proposedAt[blockId] = (uint64(block.timestamp));
+ printVariables("after propose");
+
+ blockHashes[blockId] = bytes32(1E10 + blockId); //blockHash;
+ signalRoots[blockId] = bytes32(1E9 + blockId); //signalRoot;
+
+ if (blockId > proofTime) {
+ //Start proving with an offset
+ proveBlock(
+ Bob,
+ meta[blockId - proofTime],
+ parentHashes[blockId - proofTime],
+ (blockId - proofTime == 1) ? 0 : 1000000,
+ 1000000,
+ blockHashes[blockId - proofTime],
+ signalRoots[blockId - proofTime]
+ );
+
+ uint64 provenAt = uint64(block.timestamp);
+ console2.log(
+ "Proof reward is:",
+ L1.getProofReward(
+ provenAt,
+ proposedAt[blockId - proofTime]
+ )
+ );
+ }
+
+ mine_every_12_sec();
+
+ parentHashes[blockId] = parentHash;
+ parentHash = blockHashes[blockId];
+ verifyBlock(Carol, 1);
+ }
+ }
+ //Check end balances
+ uint256 deposits = Alice_start_balance - L1.getBalance(Alice);
+ uint256 withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ //Check end balances
+ deposits = Alice_start_balance - L1.getBalance(Alice);
+ withdrawals = L1.getBalance(Bob) - Bob_start_balance;
+
+ console2.log("Deposits:", deposits);
+ console2.log("withdrawals:", withdrawals);
+ // Assert their balance changed relatively the same way
+ // 1e18 == within 100 % delta -> 1e17 10%, let's see if this is within that range
+ assertApproxEqRel(deposits, withdrawals, 1e17);
+ }
+
+ function mine_huge() internal {
+ vm.warp(block.timestamp + 1200);
+ vm.roll(block.number + 300);
+ }
+
+ function mine_every_12_sec() internal {
+ vm.warp(block.timestamp + 12);
+ vm.roll(block.number + 1);
+ }
+
+ function mine_proofTime() internal {
+ vm.warp(block.timestamp + 120);
+ vm.roll(block.number + 5);
+ }
+}
diff --git a/packages/protocol/test2/TaikoL1OracleProver.t.sol b/packages/protocol/test2/TaikoL1OracleProver.t.sol
index 7b7c1876055..3b0634f060e 100644
--- a/packages/protocol/test2/TaikoL1OracleProver.t.sol
+++ b/packages/protocol/test2/TaikoL1OracleProver.t.sol
@@ -23,24 +23,11 @@ contract TaikoL1_withOracleProver is TaikoL1 {
config.enableTokenomics = true;
config.txListCacheExpiry = 5 minutes;
- config.proposerDepositPctg = 0;
config.maxVerificationsPerTx = 0;
config.enableSoloProposer = false;
config.enableOracleProver = true;
config.maxNumProposedBlocks = 10;
config.ringBufferSize = 12;
- // this value must be changed if `maxNumProposedBlocks` is changed.
- config.slotSmoothingFactor = 4160;
-
- config.proposingConfig = TaikoData.FeeConfig({
- avgTimeMAF: 64,
- dampingFactorBips: 5000
- });
-
- config.provingConfig = TaikoData.FeeConfig({
- avgTimeMAF: 64,
- dampingFactorBips: 5000
- });
}
}
@@ -57,20 +44,17 @@ contract TaikoL1Test is TaikoL1TestBase {
function setUp() public override {
TaikoL1TestBase.setUp();
- _registerAddress(
- string(abi.encodePacked("verifier_", uint16(100))),
- address(new Verifier())
- );
+ registerAddress(L1.getVerifierName(100), address(new Verifier()));
- _registerAddress("oracle_prover", Alice);
+ registerAddress("oracle_prover", Alice);
}
// Test a block can be oracle-proven multiple times by the
// oracle prover
function testOracleProver() external {
- _depositTaikoToken(Alice, 1000 * 1E8, 1000 ether);
- _depositTaikoToken(Bob, 1000 * 1E8, 1000 ether);
- _depositTaikoToken(Carol, 1000 * 1E8, 1000 ether);
+ depositTaikoToken(Alice, 1000 * 1E8, 1000 ether);
+ depositTaikoToken(Bob, 1000 * 1E8, 1000 ether);
+ depositTaikoToken(Carol, 1000 * 1E8, 1000 ether);
bytes32 parentHash = GENESIS_BLOCK_HASH;
diff --git a/packages/protocol/test2/TaikoL1TestBase.t.sol b/packages/protocol/test2/TaikoL1TestBase.t.sol
index 3170a9332ef..21be8dd66c2 100644
--- a/packages/protocol/test2/TaikoL1TestBase.t.sol
+++ b/packages/protocol/test2/TaikoL1TestBase.t.sol
@@ -11,6 +11,12 @@ import {TaikoToken} from "../contracts/L1/TaikoToken.sol";
import {SignalService} from "../contracts/signal/SignalService.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
+contract Verifier {
+ fallback(bytes calldata) external returns (bytes memory) {
+ return bytes.concat(keccak256("taiko"));
+ }
+}
+
abstract contract TaikoL1TestBase is Test {
AddressManager public addressManager;
TaikoToken public tko;
@@ -36,6 +42,10 @@ abstract contract TaikoL1TestBase is Test {
address public constant Dave = 0x400147C0Eb43D8D71b2B03037bB7B31f8f78EF5F;
address public constant Eve = 0x50081b12838240B1bA02b3177153Bca678a86078;
+ // Calculation shall be done in derived contracts - based on testnet or mainnet expected proof time
+ uint64 public initProofTimeIssued;
+ uint8 public constant ADJUSTMENT_QUOTIENT = 16;
+
function deployTaikoL1() internal virtual returns (TaikoL1 taikoL1);
function setUp() public virtual {
@@ -44,7 +54,12 @@ abstract contract TaikoL1TestBase is Test {
addressManager.init();
L1 = deployTaikoL1();
- L1.init(address(addressManager), feeBase, GENESIS_BLOCK_HASH);
+ L1.init(
+ address(addressManager),
+ GENESIS_BLOCK_HASH,
+ feeBase,
+ initProofTimeIssued
+ );
conf = L1.getConfig();
tko = new TaikoToken();
@@ -62,16 +77,17 @@ abstract contract TaikoL1TestBase is Test {
ss.init(address(addressManager));
// set proto_broker to this address to mint some TKO
- _registerAddress("proto_broker", address(this));
+ registerAddress("proto_broker", address(this));
tko.mint(address(this), 1E9 * 1E8);
// register all addresses
- _registerAddress("taiko_token", address(tko));
- _registerAddress("proto_broker", address(L1));
- _registerAddress("signal_service", address(ss));
- _registerL2Address("treasure", L2Treasure);
- _registerL2Address("signal_service", address(L2SS));
- _registerL2Address("taiko_l2", address(L2TaikoL2));
+ registerAddress("taiko_token", address(tko));
+ registerAddress("proto_broker", address(L1));
+ registerAddress("signal_service", address(ss));
+ registerL2Address("treasure", L2Treasure);
+ registerL2Address("signal_service", address(L2SS));
+ registerL2Address("taiko_l2", address(L2TaikoL2));
+ registerAddress(L1.getVerifierName(100), address(new Verifier()));
printVariables("init ");
}
@@ -175,19 +191,19 @@ abstract contract TaikoL1TestBase is Test {
L1.verifyBlocks(count);
}
- function _registerAddress(string memory name, address addr) internal {
+ function registerAddress(string memory name, address addr) internal {
string memory key = L1.keyForName(block.chainid, name);
addressManager.setAddress(key, addr);
console2.log(key, unicode"→", addr);
}
- function _registerL2Address(string memory name, address addr) internal {
+ function registerL2Address(string memory name, address addr) internal {
string memory key = L1.keyForName(conf.chainId, name);
addressManager.setAddress(key, addr);
console2.log(key, unicode"→", addr);
}
- function _depositTaikoToken(
+ function depositTaikoToken(
address who,
uint256 amountTko,
uint256 amountEth
@@ -200,21 +216,18 @@ abstract contract TaikoL1TestBase is Test {
function printVariables(string memory comment) internal {
TaikoData.StateVariables memory vars = L1.getStateVariables();
- (uint256 fee, ) = L1.getBlockFee();
+
+ uint256 fee = L1.getBlockFee();
+
string memory str = string.concat(
Strings.toString(logCount++),
":[",
Strings.toString(vars.lastVerifiedBlockId),
unicode"→",
Strings.toString(vars.numBlocks),
- "] feeBase:",
- Strings.toString(vars.feeBase),
+ "]",
" fee:",
Strings.toString(fee),
- " avgBlockTime:",
- Strings.toString(vars.avgBlockTime),
- " avgProofTime:",
- Strings.toString(vars.avgProofTime),
" lastProposedAt:",
Strings.toString(vars.lastProposedAt),
" // ",
diff --git a/packages/protocol/utils/generate_config/README.md b/packages/protocol/utils/generate_config/README.md
deleted file mode 100644
index d8d3c7986e8..00000000000
--- a/packages/protocol/utils/generate_config/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# README
-
-A script to calculate `slotSmoothingFactor` in `TaikoData.Config` given:
-
-- expected block time
-- expected proof time
-- expected slot availability multiplier
- ...
-
-## How to run
-
-`python3 main.py`
diff --git a/packages/protocol/utils/generate_config/main.py b/packages/protocol/utils/generate_config/main.py
deleted file mode 100644
index 160dba63e12..00000000000
--- a/packages/protocol/utils/generate_config/main.py
+++ /dev/null
@@ -1,42 +0,0 @@
-import math
-
-
-if __name__ == "__main__":
- print("Expected block time (seconds)", end=": ")
- block_time = int(input())
-
- print("Expected proof time (minutes)", end=": ")
- proof_time = int(input()) * 60
-
- print("Max baseFee upside (5 = 5x)", end=": ")
- max_basefee_upside = int(input())
- if max_basefee_upside < 5:
- print("error: Max baseFee upside < 5")
- exit(1)
-
- min_num_slots = math.ceil(1.0 * proof_time / block_time)
-
- print("Extra slots (e.g, 50 means 50% more slots)", end=": ")
- extra_slots = int(input())
-
- print("---------")
-
- print("min num slots:", min_num_slots)
- max_num_slots = min_num_slots + math.ceil(min_num_slots * extra_slots / 100) + 1
-
- k = max_basefee_upside
- n = max_num_slots
-
- # https://www.wolframalpha.com/input?i=solve++%28n%2Bx%29%28n%2Bx-1%29%3Dk*%281%2Bx%29x+for+x
- fee_smoothing_factor = (
- k - 2 * n + 1 - math.sqrt(k * (k + 4 * n * n - 8 * n + 2) + 1.0)
- ) / (2 - 2 * k)
-
- fee_smoothing_factor = int(fee_smoothing_factor * 1000)
-
- # f = fee_smoothing_factor
- # print(1.0*(f+n*1000)*(f+n*1000-1000)/((f+1000)*f))
-
- print("---------")
- print("maxNumProposedBlocks:", max_num_slots)
- print("slotSmoothingFactor:", fee_smoothing_factor)
diff --git a/packages/relayer/TaikoL1.json b/packages/relayer/TaikoL1.json
index f9410f57423..49d131b5910 100644
--- a/packages/relayer/TaikoL1.json
+++ b/packages/relayer/TaikoL1.json
@@ -516,11 +516,6 @@
"name": "slotSmoothingFactor",
"type": "uint256"
},
- {
- "internalType": "uint256",
- "name": "rewardBurnBips",
- "type": "uint256"
- },
{
"internalType": "uint256",
"name": "proposerDepositPctg",
@@ -528,7 +523,7 @@
},
{
"internalType": "uint256",
- "name": "feeBaseMAF",
+ "name": "basefeeMAF",
"type": "uint256"
},
{
@@ -741,7 +736,7 @@
"components": [
{
"internalType": "uint256",
- "name": "feeBase",
+ "name": "basefee",
"type": "uint256"
},
{
@@ -826,7 +821,7 @@
},
{
"internalType": "uint256",
- "name": "_feeBase",
+ "name": "_basefee",
"type": "uint256"
}
],
@@ -1046,7 +1041,7 @@
},
{
"internalType": "uint256",
- "name": "feeBase",
+ "name": "basefee",
"type": "uint256"
},
{
diff --git a/packages/relayer/contracts/taikol1/TaikoL1.go b/packages/relayer/contracts/taikol1/TaikoL1.go
index e90754ac72d..f1ae8e258aa 100644
--- a/packages/relayer/contracts/taikol1/TaikoL1.go
+++ b/packages/relayer/contracts/taikol1/TaikoL1.go
@@ -31,7 +31,7 @@ var (
// LibUtilsStateVariables is an auto generated low-level Go binding around an user-defined struct.
type LibUtilsStateVariables struct {
- FeeBase *big.Int
+ Basefee *big.Int
GenesisHeight uint64
GenesisTimestamp uint64
NextBlockId uint64
@@ -72,7 +72,7 @@ type TaikoDataConfig struct {
SlotSmoothingFactor *big.Int
RewardBurnBips *big.Int
ProposerDepositPctg *big.Int
- FeeBaseMAF *big.Int
+ BasefeeMAF *big.Int
BlockTimeMAF *big.Int
ProofTimeMAF *big.Int
RewardMultiplierPctg uint64
@@ -103,7 +103,7 @@ type TaikoDataProposedBlock struct {
// TaikoL1MetaData contains all meta data concerning the TaikoL1 contract.
var TaikoL1MetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[],\"name\":\"L1_0_FEE_BASE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_CALLDATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_DEST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_GAS_LIMIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_ADDR\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_DATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_LOGS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_STATUS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_TOPICS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_SIG_R\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_SIG_S\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_TX_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_TYPE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_NUMBER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_NUMBER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_CANNOT_BE_FIRST_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_COMMITTED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_CONFLICT_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_CONTRACT_NOT_ALLOWED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_DUP_PROVERS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_EXTRA_DATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_GAS_LIMIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INPUT_SIZE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PARAM\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_METADATA_FIELD\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_META_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_COMMITTED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_PROOF_LENGTH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SOLO_PROPOSER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ZKP\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_DENIED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_INVALID_ADDR\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"commitSlot\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"}],\"name\":\"BlockCommitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1Height\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"commitHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"commitSlot\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"name\":\"BlockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"}],\"name\":\"BlockProven\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"name\":\"BlockVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"srcHeight\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"srcHash\",\"type\":\"bytes32\"}],\"name\":\"HeaderSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"commitSlot\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"}],\"name\":\"commitBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumProposedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumVerifiedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxVerificationsPerTx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"commitConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxTransactionsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxBytesPerTxList\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"anchorTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"slotSmoothingFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardBurnBips\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerDepositPctg\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeBaseMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"feeMultiplierPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeGracePeriodPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeMaxPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"bootstrapDiscountHalvingPeriod\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enableTokenomics\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enablePublicInputsCheck\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enableAnchorValidation\",\"type\":\"bool\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"}],\"name\":\"getForkChoice\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.ForkChoice\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proposedAt\",\"type\":\"uint64\"}],\"name\":\"getProofReward\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getProposedBlock\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"metaHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"proposedAt\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.ProposedBlock\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStateVariables\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"feeBase\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastProposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgBlockTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestVerifiedHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgProofTime\",\"type\":\"uint64\"}],\"internalType\":\"structLibUtils.StateVariables\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisBlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_feeBase\",\"type\":\"uint256\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"commitSlot\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"commitHeight\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"}],\"name\":\"isCommitValid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"inputs\",\"type\":\"bytes[]\"}],\"name\":\"proposeBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"inputs\",\"type\":\"bytes[]\"}],\"name\":\"proveBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"inputs\",\"type\":\"bytes[]\"}],\"name\":\"proveBlockInvalid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"k\",\"type\":\"uint8\"}],\"name\":\"signWithGoldenTouch\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"r\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reservedA1\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reservedA2\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"feeBase\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nextBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastProposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgBlockTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__avgGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestVerifiedHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgProofTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reservedC1\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxBlocks\",\"type\":\"uint256\"}],\"name\":\"verifyBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ ABI: "[{\"inputs\":[],\"name\":\"L1_0_FEE_BASE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_CALLDATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_DEST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_GAS_LIMIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_ADDR\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_DATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_LOGS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_STATUS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_RECEIPT_TOPICS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_SIG_R\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_SIG_S\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_TX_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ANCHOR_TYPE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_NUMBER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_NUMBER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_CANNOT_BE_FIRST_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_COMMITTED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_CONFLICT_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_CONTRACT_NOT_ALLOWED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_DUP_PROVERS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_EXTRA_DATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_GAS_LIMIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INPUT_SIZE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PARAM\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_METADATA_FIELD\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_META_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_COMMITTED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_PROOF_LENGTH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SOLO_PROPOSER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ZKP\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_DENIED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_INVALID_ADDR\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"commitSlot\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"}],\"name\":\"BlockCommitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1Height\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"commitHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"commitSlot\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"name\":\"BlockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"}],\"name\":\"BlockProven\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"name\":\"BlockVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"srcHeight\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"srcHash\",\"type\":\"bytes32\"}],\"name\":\"HeaderSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"commitSlot\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"}],\"name\":\"commitBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumProposedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumVerifiedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxVerificationsPerTx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"commitConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxTransactionsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxBytesPerTxList\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"anchorTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"slotSmoothingFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardBurnBips\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerDepositPctg\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"basefeeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"feeMultiplierPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeGracePeriodPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeMaxPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"bootstrapDiscountHalvingPeriod\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enableTokenomics\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enablePublicInputsCheck\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enableAnchorValidation\",\"type\":\"bool\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"}],\"name\":\"getForkChoice\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.ForkChoice\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proposedAt\",\"type\":\"uint64\"}],\"name\":\"getProofReward\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getProposedBlock\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"metaHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposer\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"proposedAt\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.ProposedBlock\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStateVariables\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"basefee\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastProposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgBlockTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestVerifiedHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgProofTime\",\"type\":\"uint64\"}],\"internalType\":\"structLibUtils.StateVariables\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisBlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_basefee\",\"type\":\"uint256\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"commitSlot\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"commitHeight\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"commitHash\",\"type\":\"bytes32\"}],\"name\":\"isCommitValid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"inputs\",\"type\":\"bytes[]\"}],\"name\":\"proposeBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"inputs\",\"type\":\"bytes[]\"}],\"name\":\"proveBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"inputs\",\"type\":\"bytes[]\"}],\"name\":\"proveBlockInvalid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"k\",\"type\":\"uint8\"}],\"name\":\"signWithGoldenTouch\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"r\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reservedA1\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reservedA2\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"basefee\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nextBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastProposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgBlockTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__avgGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"latestVerifiedHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"avgProofTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reservedC1\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxBlocks\",\"type\":\"uint256\"}],\"name\":\"verifyBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
}
// TaikoL1ABI is the input ABI used to generate the binding from.
@@ -738,13 +738,13 @@ func (_TaikoL1 *TaikoL1CallerSession) SignWithGoldenTouch(hash [32]byte, k uint8
// State is a free data retrieval call binding the contract method 0xc19d93fb.
//
-// Solidity: function state() view returns(uint64 genesisHeight, uint64 genesisTimestamp, uint64 __reservedA1, uint64 __reservedA2, uint256 feeBase, uint64 nextBlockId, uint64 lastProposedAt, uint64 avgBlockTime, uint64 __avgGasLimit, uint64 latestVerifiedHeight, uint64 lastBlockId, uint64 avgProofTime, uint64 __reservedC1)
+// Solidity: function state() view returns(uint64 genesisHeight, uint64 genesisTimestamp, uint64 __reservedA1, uint64 __reservedA2, uint256 basefee, uint64 nextBlockId, uint64 lastProposedAt, uint64 avgBlockTime, uint64 __avgGasLimit, uint64 latestVerifiedHeight, uint64 lastBlockId, uint64 avgProofTime, uint64 __reservedC1)
func (_TaikoL1 *TaikoL1Caller) State(opts *bind.CallOpts) (struct {
GenesisHeight uint64
GenesisTimestamp uint64
ReservedA1 uint64
ReservedA2 uint64
- FeeBase *big.Int
+ Basefee *big.Int
NextBlockId uint64
LastProposedAt uint64
AvgBlockTime uint64
@@ -762,7 +762,7 @@ func (_TaikoL1 *TaikoL1Caller) State(opts *bind.CallOpts) (struct {
GenesisTimestamp uint64
ReservedA1 uint64
ReservedA2 uint64
- FeeBase *big.Int
+ Basefee *big.Int
NextBlockId uint64
LastProposedAt uint64
AvgBlockTime uint64
@@ -780,7 +780,7 @@ func (_TaikoL1 *TaikoL1Caller) State(opts *bind.CallOpts) (struct {
outstruct.GenesisTimestamp = *abi.ConvertType(out[1], new(uint64)).(*uint64)
outstruct.ReservedA1 = *abi.ConvertType(out[2], new(uint64)).(*uint64)
outstruct.ReservedA2 = *abi.ConvertType(out[3], new(uint64)).(*uint64)
- outstruct.FeeBase = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int)
+ outstruct.Basefee = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int)
outstruct.NextBlockId = *abi.ConvertType(out[5], new(uint64)).(*uint64)
outstruct.LastProposedAt = *abi.ConvertType(out[6], new(uint64)).(*uint64)
outstruct.AvgBlockTime = *abi.ConvertType(out[7], new(uint64)).(*uint64)
@@ -796,13 +796,13 @@ func (_TaikoL1 *TaikoL1Caller) State(opts *bind.CallOpts) (struct {
// State is a free data retrieval call binding the contract method 0xc19d93fb.
//
-// Solidity: function state() view returns(uint64 genesisHeight, uint64 genesisTimestamp, uint64 __reservedA1, uint64 __reservedA2, uint256 feeBase, uint64 nextBlockId, uint64 lastProposedAt, uint64 avgBlockTime, uint64 __avgGasLimit, uint64 latestVerifiedHeight, uint64 lastBlockId, uint64 avgProofTime, uint64 __reservedC1)
+// Solidity: function state() view returns(uint64 genesisHeight, uint64 genesisTimestamp, uint64 __reservedA1, uint64 __reservedA2, uint256 basefee, uint64 nextBlockId, uint64 lastProposedAt, uint64 avgBlockTime, uint64 __avgGasLimit, uint64 latestVerifiedHeight, uint64 lastBlockId, uint64 avgProofTime, uint64 __reservedC1)
func (_TaikoL1 *TaikoL1Session) State() (struct {
GenesisHeight uint64
GenesisTimestamp uint64
ReservedA1 uint64
ReservedA2 uint64
- FeeBase *big.Int
+ Basefee *big.Int
NextBlockId uint64
LastProposedAt uint64
AvgBlockTime uint64
@@ -817,13 +817,13 @@ func (_TaikoL1 *TaikoL1Session) State() (struct {
// State is a free data retrieval call binding the contract method 0xc19d93fb.
//
-// Solidity: function state() view returns(uint64 genesisHeight, uint64 genesisTimestamp, uint64 __reservedA1, uint64 __reservedA2, uint256 feeBase, uint64 nextBlockId, uint64 lastProposedAt, uint64 avgBlockTime, uint64 __avgGasLimit, uint64 latestVerifiedHeight, uint64 lastBlockId, uint64 avgProofTime, uint64 __reservedC1)
+// Solidity: function state() view returns(uint64 genesisHeight, uint64 genesisTimestamp, uint64 __reservedA1, uint64 __reservedA2, uint256 basefee, uint64 nextBlockId, uint64 lastProposedAt, uint64 avgBlockTime, uint64 __avgGasLimit, uint64 latestVerifiedHeight, uint64 lastBlockId, uint64 avgProofTime, uint64 __reservedC1)
func (_TaikoL1 *TaikoL1CallerSession) State() (struct {
GenesisHeight uint64
GenesisTimestamp uint64
ReservedA1 uint64
ReservedA2 uint64
- FeeBase *big.Int
+ Basefee *big.Int
NextBlockId uint64
LastProposedAt uint64
AvgBlockTime uint64
@@ -859,23 +859,23 @@ func (_TaikoL1 *TaikoL1TransactorSession) CommitBlock(commitSlot uint64, commitH
// Init is a paid mutator transaction binding the contract method 0x9c5e9f06.
//
-// Solidity: function init(address _addressManager, bytes32 _genesisBlockHash, uint256 _feeBase) returns()
-func (_TaikoL1 *TaikoL1Transactor) Init(opts *bind.TransactOpts, _addressManager common.Address, _genesisBlockHash [32]byte, _feeBase *big.Int) (*types.Transaction, error) {
- return _TaikoL1.contract.Transact(opts, "init", _addressManager, _genesisBlockHash, _feeBase)
+// Solidity: function init(address _addressManager, bytes32 _genesisBlockHash, uint256 _basefee) returns()
+func (_TaikoL1 *TaikoL1Transactor) Init(opts *bind.TransactOpts, _addressManager common.Address, _genesisBlockHash [32]byte, _basefee *big.Int) (*types.Transaction, error) {
+ return _TaikoL1.contract.Transact(opts, "init", _addressManager, _genesisBlockHash, _basefee)
}
// Init is a paid mutator transaction binding the contract method 0x9c5e9f06.
//
-// Solidity: function init(address _addressManager, bytes32 _genesisBlockHash, uint256 _feeBase) returns()
-func (_TaikoL1 *TaikoL1Session) Init(_addressManager common.Address, _genesisBlockHash [32]byte, _feeBase *big.Int) (*types.Transaction, error) {
- return _TaikoL1.Contract.Init(&_TaikoL1.TransactOpts, _addressManager, _genesisBlockHash, _feeBase)
+// Solidity: function init(address _addressManager, bytes32 _genesisBlockHash, uint256 _basefee) returns()
+func (_TaikoL1 *TaikoL1Session) Init(_addressManager common.Address, _genesisBlockHash [32]byte, _basefee *big.Int) (*types.Transaction, error) {
+ return _TaikoL1.Contract.Init(&_TaikoL1.TransactOpts, _addressManager, _genesisBlockHash, _basefee)
}
// Init is a paid mutator transaction binding the contract method 0x9c5e9f06.
//
-// Solidity: function init(address _addressManager, bytes32 _genesisBlockHash, uint256 _feeBase) returns()
-func (_TaikoL1 *TaikoL1TransactorSession) Init(_addressManager common.Address, _genesisBlockHash [32]byte, _feeBase *big.Int) (*types.Transaction, error) {
- return _TaikoL1.Contract.Init(&_TaikoL1.TransactOpts, _addressManager, _genesisBlockHash, _feeBase)
+// Solidity: function init(address _addressManager, bytes32 _genesisBlockHash, uint256 _basefee) returns()
+func (_TaikoL1 *TaikoL1TransactorSession) Init(_addressManager common.Address, _genesisBlockHash [32]byte, _basefee *big.Int) (*types.Transaction, error) {
+ return _TaikoL1.Contract.Init(&_TaikoL1.TransactOpts, _addressManager, _genesisBlockHash, _basefee)
}
// ProposeBlock is a paid mutator transaction binding the contract method 0xa043dbdf.
diff --git a/packages/relayer/contracts/taikol2/TaikoL2.go b/packages/relayer/contracts/taikol2/TaikoL2.go
index efd19a7c899..041a57d5296 100644
--- a/packages/relayer/contracts/taikol2/TaikoL2.go
+++ b/packages/relayer/contracts/taikol2/TaikoL2.go
@@ -44,7 +44,7 @@ type TaikoDataConfig struct {
SlotSmoothingFactor *big.Int
RewardBurnBips *big.Int
ProposerDepositPctg *big.Int
- FeeBaseMAF *big.Int
+ BasefeeMAF *big.Int
BlockTimeMAF *big.Int
ProofTimeMAF *big.Int
RewardMultiplierPctg uint64
@@ -60,11 +60,11 @@ type TaikoDataConfig struct {
// TaikoL2MetaData contains all meta data concerning the TaikoL2 contract.
var TaikoL2MetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ERR_INVALID_HINT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ERR_INVALID_TX_IDX\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ERR_PARAMS_NOT_DEFAULTS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ERR_VERIFICAITON_FAILURE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L2_INVALID_CHAIN_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L2_INVALID_GAS_PRICE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L2_INVALID_SENDER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L2_PUBLIC_INPUT_HASH_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_DENIED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_INVALID_ADDR\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"}],\"name\":\"BlockInvalidated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"srcHeight\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"srcHash\",\"type\":\"bytes32\"}],\"name\":\"HeaderSynced\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"l1Height\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"}],\"name\":\"anchor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumProposedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumVerifiedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxVerificationsPerTx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"commitConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxTransactionsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxBytesPerTxList\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"anchorTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"slotSmoothingFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardBurnBips\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerDepositPctg\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeBaseMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"rewardMultiplierPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeGracePeriodPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeMaxPeriodPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"bootstrapDiscountHalvingPeriod\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enableTokenomics\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enablePublicInputsCheck\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enableAnchorValidation\",\"type\":\"bool\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"txList\",\"type\":\"bytes\"},{\"internalType\":\"enumLibInvalidTxList.Hint\",\"name\":\"hint\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"txIdx\",\"type\":\"uint256\"}],\"name\":\"invalidateBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSyncedL1Height\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ERR_INVALID_HINT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ERR_INVALID_TX_IDX\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ERR_PARAMS_NOT_DEFAULTS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ERR_VERIFICAITON_FAILURE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L2_INVALID_CHAIN_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L2_INVALID_GAS_PRICE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L2_INVALID_SENDER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L2_PUBLIC_INPUT_HASH_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_DENIED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_INVALID_ADDR\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"}],\"name\":\"BlockInvalidated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"srcHeight\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"srcHash\",\"type\":\"bytes32\"}],\"name\":\"HeaderSynced\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"l1Height\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"}],\"name\":\"anchor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumProposedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumVerifiedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxVerificationsPerTx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"commitConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxTransactionsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxBytesPerTxList\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"anchorTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"slotSmoothingFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardBurnBips\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerDepositPctg\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"basefeeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"rewardMultiplierPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeGracePeriodPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeMaxPeriodPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"bootstrapDiscountHalvingPeriod\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enableTokenomics\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enablePublicInputsCheck\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enableAnchorValidation\",\"type\":\"bool\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"txList\",\"type\":\"bytes\"},{\"internalType\":\"enumLibInvalidTxList.Hint\",\"name\":\"hint\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"txIdx\",\"type\":\"uint256\"}],\"name\":\"invalidateBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSyncedL1Height\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
}
// TaikoL2ABI is the input ABI used to generate the binding from.
-const TaikoL2ABI = "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"}],\"name\":\"BlockInvalidated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"height\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"srcHeight\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"srcHash\",\"type\":\"bytes32\"}],\"name\":\"HeaderSynced\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"l1Height\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"}],\"name\":\"anchor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumProposedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumVerifiedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"zkProofsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxVerificationsPerTx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"commitConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxProofsPerForkChoice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxTransactionsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxBytesPerTxList\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"anchorTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feePremiumLamda\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardBurnBips\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerDepositPctg\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeBaseMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"feeMultiplierPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeGracePeriodPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeMaxPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"bootstrapDiscountHalvingPeriod\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initialUncleDelay\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enableTokenomics\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enablePublicInputsCheck\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enableAnchorValidation\",\"type\":\"bool\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"txList\",\"type\":\"bytes\"},{\"internalType\":\"enumLibInvalidTxList.Reason\",\"name\":\"hint\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"txIdx\",\"type\":\"uint256\"}],\"name\":\"invalidateBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSyncedL1Height\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"publicInputHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"
+const TaikoL2ABI = "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"}],\"name\":\"BlockInvalidated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"height\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"srcHeight\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"srcHash\",\"type\":\"bytes32\"}],\"name\":\"HeaderSynced\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"l1Height\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"}],\"name\":\"anchor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumProposedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumVerifiedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"zkProofsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxVerificationsPerTx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"commitConfirmations\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxProofsPerForkChoice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxTransactionsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxBytesPerTxList\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"anchorTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feePremiumLamda\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardBurnBips\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proposerDepositPctg\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"basefeeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofTimeMAF\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"feeMultiplierPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeGracePeriodPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"feeMaxPctg\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeCap\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"bootstrapDiscountHalvingPeriod\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initialUncleDelay\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enableTokenomics\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enablePublicInputsCheck\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"enableAnchorValidation\",\"type\":\"bool\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"getSyncedHeader\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"txList\",\"type\":\"bytes\"},{\"internalType\":\"enumLibInvalidTxList.Reason\",\"name\":\"hint\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"txIdx\",\"type\":\"uint256\"}],\"name\":\"invalidateBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSyncedL1Height\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"publicInputHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"
// TaikoL2 is an auto generated Go binding around an Ethereum contract.
type TaikoL2 struct {
diff --git a/packages/status-page/src/constants/abi/TaikoL1.ts b/packages/status-page/src/constants/abi/TaikoL1.ts
index 555ddec6060..2220bc4637f 100644
--- a/packages/status-page/src/constants/abi/TaikoL1.ts
+++ b/packages/status-page/src/constants/abi/TaikoL1.ts
@@ -533,7 +533,7 @@ export default [
},
{
internalType: "uint256",
- name: "feeBaseMAF",
+ name: "basefeeMAF",
type: "uint256",
},
{
@@ -746,7 +746,7 @@ export default [
components: [
{
internalType: "uint256",
- name: "feeBase",
+ name: "basefee",
type: "uint256",
},
{
@@ -831,7 +831,7 @@ export default [
},
{
internalType: "uint256",
- name: "_feeBase",
+ name: "_basefee",
type: "uint256",
},
],
@@ -1051,7 +1051,7 @@ export default [
},
{
internalType: "uint256",
- name: "feeBase",
+ name: "basefee",
type: "uint256",
},
{
diff --git a/packages/tokenomics/.gitignore b/packages/tokenomics/.gitignore
deleted file mode 100644
index 932765aeba6..00000000000
--- a/packages/tokenomics/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-__pycache__/
-venv
diff --git a/packages/tokenomics/CHANGELOG.md b/packages/tokenomics/CHANGELOG.md
deleted file mode 100644
index 61b27a90fae..00000000000
--- a/packages/tokenomics/CHANGELOG.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Changelog
-
-## [0.1.0](https://github.com/taikoxyz/taiko-mono/compare/tokenomics-v0.0.1...tokenomics-v0.1.0) (2023-01-19)
-
-
-### Features
-
-* implement release-please workflow ([#12967](https://github.com/taikoxyz/taiko-mono/issues/12967)) ([b0c8b60](https://github.com/taikoxyz/taiko-mono/commit/b0c8b60da0af3160db758f83c1f6368a3a712593))
-* **protocol:** implement & simulate tokenomics ([#376](https://github.com/taikoxyz/taiko-mono/issues/376)) ([191eb11](https://github.com/taikoxyz/taiko-mono/commit/191eb110990d60b49883eb3f3d7841c33421d067))
diff --git a/packages/tokenomics/README.md b/packages/tokenomics/README.md
deleted file mode 100644
index fc129660dc5..00000000000
--- a/packages/tokenomics/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# README
-
-## Installation
-
-You need to install python, **salabim**, **streamlit**, and **matplotlib**.
-
-```sh
-python3 -m venv venv
-pip install salabim streamlit matplotlib
-```
-
-## Usage
-
-Then in this directory, simply run `streamlit run main.py`,
-then visit [http://localhost:8501](http://localhost:8501/) to see simulation results.
diff --git a/packages/tokenomics/main.py b/packages/tokenomics/main.py
deleted file mode 100644
index f637c36bf84..00000000000
--- a/packages/tokenomics/main.py
+++ /dev/null
@@ -1,395 +0,0 @@
-import salabim as sim
-import matplotlib.pyplot as plt
-import streamlit as st
-from enum import Enum
-from typing import NamedTuple
-from plots import plot
-from present import Config, Present
-from presents.p0 import present as p0
-from presents.cbvp1 import present as cbvp1
-from presents.cbvp2 import present as cbvp2
-from presents.vbcp1 import present as vbcp1
-from presents.vbcp2 import present as vbcp2
-from presents.vbvps1 import present as vbvps1
-from presents.vbvps2 import present as vbvps2
-
-# from presents.p7 import present as p7
-# from presents.p8 import present as p8
-# from presents.p9 import present as p9
-# from presents.p10 import present as p10
-# from presents.p11 import present as p11
-
-DAY = 24 * 3600
-K_FEE_GRACE_PERIOD = 125
-K_FEE_MAX_PERIOD = 375
-K_BLOCK_TIME_CAP = 48 # 48 seconds
-K_PROOF_TIME_CAP = 3600 * 1.5 # 1.5 hour
-
-
-class Status(Enum):
- PENDING = 1
- PROVEN = 2
- VERIFIED = 3
-
-
-class Block(NamedTuple):
- status: Status
- fee: int
- proposed_at: int
- proven_at: int
-
-
-def get_day(config):
- day = int(env.now() / DAY)
- if day >= len(config.timing):
- day = len(config.timing) - 1
- return day
-
-
-def get_block_time_avg_second(config):
- return config.timing[get_day(config)].block_time_avg_second
-
-
-def get_proof_time_avg_second(config):
- return config.timing[get_day(config)].proof_time_avg_minute * 60
-
-
-def moving_average(ma, v, maf):
- if ma == 0:
- return v
- else:
- _ma = (ma * (maf - 1) + v) * 1.0 / maf
- if _ma > 0:
- return _ma
- else:
- return ma
-
-
-class Protocol(sim.Component):
- def setup(self, config):
- self.config = config
- self.fee_base = config.fee_base
- self.last_proposed_at = env.now()
- self.last_VERIFIED_id = 0
- self.tko_supply = 0
- self.avg_block_time = 0
- self.avg_proof_time = 0
-
- genesis = Block(
- status=Status.VERIFIED,
- fee=0,
- proposed_at=env.now(),
- proven_at=env.now(),
- )
- self.blocks = [genesis]
-
- # monitors
- self.m_pending_count = sim.Monitor("m_pending_count", level=True)
- self.m_fee_base = sim.Monitor(
- "m_fee_base", level=True, initial_tally=self.fee_base
- )
- self.m_block_fee = sim.Monitor("m_block_fee", level=True)
- self.m_proof_reward = sim.Monitor("m_proof_reward", level=True)
- self.m_tko_supply = sim.Monitor("m_tko_supply", level=True)
- self.m_block_time = sim.Monitor("m_block_time", level=True)
- self.m_proof_time = sim.Monitor("m_proof_time", level=True)
-
- def get_time_adjusted_fee(self, is_proposal, t_now, t_last, t_avg, t_cap):
- # if (tAvg == 0) {
- # return s.feeBase;
- # }
- # uint256 _tAvg = tAvg > tCap ? tCap : tAvg;
- # uint256 tGrace = (LibConstants.K_FEE_GRACE_PERIOD * _tAvg) / 100;
- # uint256 tMax = (LibConstants.K_FEE_MAX_PERIOD * _tAvg) / 100;
- # uint256 a = tLast + tGrace;
- # uint256 b = tNow > a ? tNow - a : 0;
- # uint256 tRel = (b.min(tMax) * 10000) / tMax; // [0 - 10000]
- # uint256 alpha = 10000 +
- # ((LibConstants.K_REWARD_MULTIPLIER - 100) * tRel) /
- # 100;
- # if (isProposal) {
- # return (s.feeBase * 10000) / alpha; // fee
- # } else {
- # return (s.feeBase * alpha) / 10000; // reward
- # }
-
- if t_avg == 0:
- return self.fee_base
-
- if t_avg > t_cap:
- _avg = t_cap
- else:
- _avg = t_avg
-
- t_grace = K_FEE_GRACE_PERIOD * _avg / 100.0
- t_max = K_FEE_MAX_PERIOD * _avg / 100.0
- a = t_last + t_grace
-
- if t_now > a:
- b = t_now - a
- else:
- b = 0
-
- if b > t_max:
- b = t_max
-
- t_rel = 10000 * b / t_max
-
- alpha = 10000 + (self.config.reward_multiplier - 1) * t_rel
-
- if is_proposal:
- return self.fee_base * 10000 / alpha
- else:
- return self.fee_base * alpha / 10000
-
- def get_slots_adjusted_fee(self, is_proposal, fee):
- # uint256 m = LibConstants.K_MAX_NUM_BLOCKS -
- # 1 +
- # LibConstants.K_FEE_PREMIUM_LAMDA;
- # uint256 n = s.nextBlockId - s.latestVERIFIEDId - 1;
- # uint256 k = isProposal ? m - n - 1 : m - n + 1;
- # return (fee * (m - 1) * m) / (m - n) / k;
-
- m = self.config.max_blocks - 1 + self.config.lamda
- n = self.num_pending()
- if is_proposal: # fee
- k = m - n - 1
- else: # reward
- k = m - n + 1
- return fee * (m - 1) * m / (m - n) / k
-
- def get_block_fee(self):
- fee = self.get_time_adjusted_fee(
- True,
- env.now(),
- self.last_proposed_at,
- self.avg_block_time,
- K_BLOCK_TIME_CAP,
- )
-
- premium_fee = self.get_slots_adjusted_fee(True, fee)
- # bootstrap discount not simulated
- return (fee, premium_fee)
-
- def get_proof_reward(self, proven_at, proposed_at):
- reward = self.get_time_adjusted_fee(
- False, proven_at, proposed_at, self.avg_proof_time, K_PROOF_TIME_CAP
- )
- premium_reward = self.get_slots_adjusted_fee(False, reward)
- return (reward, premium_reward)
-
- def print_me(self, st):
- st.markdown("-----")
- st.markdown("##### Protocol state")
- st.write("last_VERIFIED_id = {}".format(self.last_VERIFIED_id))
- st.write("num_blocks = {}".format(self.num_pending()))
- st.write("fee_base = {}".format(self.fee_base))
- st.write("tko_supply = {}".format(self.tko_supply))
-
- def num_pending(self):
- return len(self.blocks) - self.last_VERIFIED_id - 1
-
- def can_propose(self):
- return self.num_pending() < self.config.max_blocks
-
- def propose_block(self):
- if env.now() == 0 or not self.can_propose():
- return
-
- block_time = env.now() - self.last_proposed_at
-
- (fee, premium_fee) = self.get_block_fee()
-
- self.fee_base = moving_average(self.fee_base, fee, self.config.fee_maf)
- self.avg_block_time = moving_average(
- self.avg_block_time,
- block_time,
- self.config.time_avg_maf,
- )
- self.last_proposed_at = env.now()
- self.tko_supply -= premium_fee
-
- block = Block(
- status=Status.PENDING,
- fee=premium_fee,
- proposed_at=env.now(),
- proven_at=0,
- )
- self.blocks.append(block)
-
- Prover(protocol=self, config=self.config, blockId=len(self.blocks) - 1)
- self.verify_block()
-
- self.m_fee_base.tally(self.fee_base)
- self.m_block_fee.tally(premium_fee)
- self.m_tko_supply.tally(self.tko_supply)
- self.m_block_time.tally(block_time)
- self.m_pending_count.tally(self.num_pending())
-
- def can_prove(self, id):
- return (
- id > self.last_VERIFIED_id
- and len(self.blocks) > id
- and self.blocks[id].status == Status.PENDING
- )
-
- def prove_block(self, id):
- if self.can_prove(id):
- self.blocks[id] = self.blocks[id]._replace(
- status=Status.PROVEN, proven_at=env.now()
- )
- self.verify_block()
-
- def can_verify(self):
- return (
- len(self.blocks) > self.last_VERIFIED_id + 1
- and self.blocks[self.last_VERIFIED_id + 1].status == Status.PROVEN
- and env.now()
- > self.blocks[self.last_VERIFIED_id + 1].proven_at + self.avg_proof_time
- )
-
- def verify_block(self):
- for i in range(0, 5):
- if self.can_verify():
-
- k = self.last_VERIFIED_id + 1
-
- self.blocks[k] = self.blocks[k]._replace(status=Status.VERIFIED)
-
- proof_time = self.blocks[k].proven_at - self.blocks[k].proposed_at
-
- (reward, premium_reward) = self.get_proof_reward(
- self.blocks[k].proven_at, self.blocks[k].proposed_at
- )
-
- self.fee_base = moving_average(
- self.fee_base,
- reward,
- self.config.fee_maf,
- )
-
- self.avg_proof_time = moving_average(
- self.avg_proof_time,
- proof_time,
- self.config.time_avg_maf,
- )
-
- self.tko_supply += premium_reward
- self.m_fee_base.tally(self.fee_base)
- self.m_proof_reward.tally(premium_reward)
- self.m_tko_supply.tally(self.tko_supply)
- self.m_proof_time.tally(proof_time)
-
- self.last_VERIFIED_id = k
- else:
- break
-
- self.m_pending_count.tally(self.num_pending())
-
-
-class Prover(sim.Component):
- def setup(self, protocol, config, blockId):
- self.protocol = protocol
- self.config = config
- self.blockId = blockId
-
- def process(self):
- _proof_time_avg_second = get_proof_time_avg_second(self.config)
- yield self.hold(
- sim.Bounded(
- sim.Normal(
- _proof_time_avg_second,
- _proof_time_avg_second * self.config.proof_time_sd_pctg / 100,
- ),
- lowerbound=1,
- ).sample()
- )
- self.protocol.prove_block(self.blockId)
-
-
-class Proposer(sim.Component):
- def setup(self, protocol):
- self.protocol = protocol
- self.config = protocol.config
-
- def process(self):
- while True:
- if not self.protocol.can_propose():
- yield self.hold(1)
- else:
- self.protocol.propose_block()
- _block_time_avg_second = get_block_time_avg_second(self.config)
- yield self.hold(
- sim.Bounded(
- sim.Normal(
- _block_time_avg_second,
- _block_time_avg_second
- * self.config.block_time_sd_pctg
- / 100,
- ),
- lowerbound=1,
- ).sample()
- )
-
-
-def simulate(config, days):
- st.markdown("-----")
- st.markdown("##### Block & proof time and deviation settings")
- st.caption("[block_time (seconds), proof_time (minutes)]")
- time_str = ""
- for t in config.timing:
- time_str += str(t._asdict().values())
- st.write(time_str.replace("dict_values", " ☀️").replace("(", "").replace(")", ""))
-
- st.markdown("-----")
- st.markdown("##### You can change these settings")
- cols = st.columns([1, 1, 1, 1])
- inputs = {}
- i = 0
- for (k, v) in config._asdict().items():
- if k != "timing":
- inputs[k] = cols[i % 4].number_input(k, value=v)
- i += 1
-
- st.markdown("-----")
- if st.button("Simulate {} days".format(days), key="run"):
- actual_config = Config(timing=config.timing, **inputs)
-
- protocol = Protocol(config=actual_config)
- proposer = Proposer(protocol=protocol)
-
- env.run(till=days * DAY)
-
- st.markdown("-----")
- st.markdown("##### Block/Proof Time")
- plot(days, [(protocol.m_block_time, "block time")], color="tab:blue")
- plot(days, [(protocol.m_proof_time, "proof time")], color="tab:blue")
-
- st.markdown("-----")
- st.markdown("##### Result")
- plot(days, [(protocol.m_pending_count, "num pending blocks")])
- plot(days, [(protocol.m_fee_base, "fee_base")])
- plot(days, [(protocol.m_block_fee, "block fee")], color="tab:green")
- plot(days, [(protocol.m_proof_reward, "proof reward")])
-
- plot(days, [(protocol.m_tko_supply, "tko supply")], color="tab:red")
-
- protocol.print_me(st)
-
-
-if __name__ == "__main__":
- env = sim.Environment(trace=False)
- st.title("Taiko Block Fee/Reward Simulation")
-
- presents = [p0, cbvp1, cbvp2, vbcp1, vbcp2, vbvps1, vbvps2]
- st.markdown("## Configs")
- selected = st.radio(
- "Please choose one of the following predefined configs:",
- range(0, len(presents)),
- format_func=lambda x: presents[x].title,
- )
- present = presents[selected]
- st.markdown("-----")
- st.markdown("##### Description")
- st.markdown(present.desc)
- simulate(present.config, present.days)
diff --git a/packages/tokenomics/package.json b/packages/tokenomics/package.json
deleted file mode 100644
index c7190abde75..00000000000
--- a/packages/tokenomics/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "@taiko/tokenomics",
- "version": "0.1.0",
- "private": true
-}
diff --git a/packages/tokenomics/plots.py b/packages/tokenomics/plots.py
deleted file mode 100644
index 926848d139b..00000000000
--- a/packages/tokenomics/plots.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import matplotlib.pyplot as plt
-import matplotlib.ticker as ticker
-import streamlit as st
-import numpy as np
-
-
-@ticker.FuncFormatter
-def major_formatter(x, pos):
- return "d%d" % (x / 24 / 3600)
-
-
-def plot(days, sources, color="#E28BFD"):
- fig, ax = plt.subplots(figsize=(15, 5), nrows=1, ncols=1)
- for s in sources:
- data = s[0].xt()
- ax.plot(data[1], data[0], color, label=s[1])
- ax.legend(loc="lower center", fontsize=18.0)
- ax.xaxis.set_ticks(np.arange(0, 24 * 3600 * (days + 1), 24 * 3600))
- ax.xaxis.set_tick_params(labelrotation=45)
- ax.xaxis.set_major_formatter(major_formatter)
-
- st.write(fig)
diff --git a/packages/tokenomics/present.py b/packages/tokenomics/present.py
deleted file mode 100644
index 02b2e819762..00000000000
--- a/packages/tokenomics/present.py
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import NamedTuple
-
-
-class Timing(NamedTuple):
- block_time_avg_second: int
- proof_time_avg_minute: int
-
-
-class Config(NamedTuple):
- max_blocks: int
- lamda: float
- fee_base: int
- fee_maf: int
- reward_multiplier: float
- block_time_sd_pctg: int
- proof_time_sd_pctg: int
- time_avg_maf: int
- timing: list[Timing]
-
-
-class Present(NamedTuple):
- title: str
- desc: str
- days: int
- config: Config
diff --git a/packages/tokenomics/presents/cbvp1.py b/packages/tokenomics/presents/cbvp1.py
deleted file mode 100644
index f94cb1b9027..00000000000
--- a/packages/tokenomics/presents/cbvp1.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from present import Config, Timing, Present
-
-present = Present(
- title="cbvp1: constant block time, proof time goes down, up, then restores",
- desc="""
-
-**About this config**
-
-- the block time average set to a constant.
-- the proof time average varies but eventually changes back to the initial value.
-
-**What to verify**
-- fee_base will become smaller if proof time becomes larger.
-- fee_base remains the same if proof time becomes smaller.
-
-""",
- days=21,
- config=Config(
- max_blocks=2048,
- lamda=590,
- fee_base=100.0,
- fee_maf=1024,
- reward_multiplier=4.0,
- time_avg_maf=1024,
- block_time_sd_pctg=0,
- proof_time_sd_pctg=0,
- timing=[
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45/1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45/1.3/1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45/1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45*1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45*1.3*1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45*1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- ],
- ),
-)
diff --git a/packages/tokenomics/presents/cbvp2.py b/packages/tokenomics/presents/cbvp2.py
deleted file mode 100644
index efa29142887..00000000000
--- a/packages/tokenomics/presents/cbvp2.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from present import Config, Timing, Present
-
-present = Present(
- title="cbvp2: constant block time, proof time goes up, down, then restores",
- desc="""
-
-**About this config**
-
-- the block time average set to a constant.
-- the proof time average varies but eventually changes back to the initial value.
-
-**What to verify**
-- fee_base will become smaller if proof time becomes larger.
-- fee_base remains the same if proof time becomes smaller.
-
-""",
- days=21,
- config=Config(
- max_blocks=2048,
- lamda=590,
- fee_base=100.0,
- fee_maf=1024,
- reward_multiplier=4.0,
- time_avg_maf=1024,
- block_time_sd_pctg=0,
- proof_time_sd_pctg=0,
- timing=[
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45*1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45*1.3*1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45*1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45/1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45/1.3/1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45/1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- ],
- ),
-)
diff --git a/packages/tokenomics/presents/p0.py b/packages/tokenomics/presents/p0.py
deleted file mode 100644
index 52da6756a95..00000000000
--- a/packages/tokenomics/presents/p0.py
+++ /dev/null
@@ -1,34 +0,0 @@
-from present import Config, Timing, Present
-
-present = Present(
- title="p0: block time and proof time both constant",
- desc="""
-
-**What to simulate?**
-
-The most basic model where the block time average and proof time average are both constant.
-
-**About this config**
-
-- TKO supply changes initially but stablizes.
-- fee_base remains constant
-
-""",
- days=7,
- config=Config(
- max_blocks=2048,
- lamda=590,
- fee_base=100.0,
- fee_maf=1024,
- reward_multiplier=4.0,
- time_avg_maf=1024,
- block_time_sd_pctg=0,
- proof_time_sd_pctg=0,
- timing=[
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- ],
- ),
-)
diff --git a/packages/tokenomics/presents/vbcp1.py b/packages/tokenomics/presents/vbcp1.py
deleted file mode 100644
index 476c4d05397..00000000000
--- a/packages/tokenomics/presents/vbcp1.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from present import Config, Timing, Present
-
-present = Present(
- title="vbcp1: constant proof time, block time goes down, up, then restores",
- desc="""
-
-**About this config**
-
-- the proof time average set to a constant.
-- the block time average varies but eventually changes back to the initial value.
-
-**What to verify**
-- fee_base will become smaller if block time becomes larger.
-- fee_base remains the same if block time becomes smaller.
-
-""",
- days=21,
- config=Config(
- max_blocks=2048,
- lamda=590,
- fee_base=100.0,
- fee_maf=1024,
- reward_multiplier=4.0,
- time_avg_maf=1024,
- block_time_sd_pctg=0,
- proof_time_sd_pctg=0,
- timing=[
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15/1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15/1.3/1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15/1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15*1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15*1.3*1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15*1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- ],
- ),
-)
diff --git a/packages/tokenomics/presents/vbcp2.py b/packages/tokenomics/presents/vbcp2.py
deleted file mode 100644
index c581fdb0c25..00000000000
--- a/packages/tokenomics/presents/vbcp2.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from present import Config, Timing, Present
-
-present = Present(
- title="vbcp2: constant proof time, block time goes up, down, then restores",
- desc="""
-
-**About this config**
-
-- the proof time average set to a constant.
-- the block time average varies but eventually changes back to the initial value.
-
-**What to verify**
-- fee_base will become smaller if block time becomes larger.
-- fee_base remains the same if block time becomes smaller.
-
-""",
- days=21,
- config=Config(
- max_blocks=2048,
- lamda=590,
- fee_base=100.0,
- fee_maf=1024,
- reward_multiplier=4.0,
- time_avg_maf=1024,
- block_time_sd_pctg=0,
- proof_time_sd_pctg=0,
- timing=[
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15*1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15*1.3*1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15*1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15/1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15/1.3/1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15/1.3,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- ],
- ),
-)
diff --git a/packages/tokenomics/presents/vbvps1.py b/packages/tokenomics/presents/vbvps1.py
deleted file mode 100644
index 1808d62b917..00000000000
--- a/packages/tokenomics/presents/vbvps1.py
+++ /dev/null
@@ -1,57 +0,0 @@
-from present import Config, Timing, Present
-
-present = Present(
- title="vbvps1: block time & proof time both go down, up to the SAME direction, then restores",
- desc="""
-
-""",
- days=21,
- config=Config(
- max_blocks=2048,
- lamda=590,
- fee_base=100.0,
- fee_maf=1024,
- reward_multiplier=4.0,
- time_avg_maf=1024,
- block_time_sd_pctg=0,
- proof_time_sd_pctg=0,
- timing=[
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15/1.3,
- proof_time_avg_minute=45/1.3,
- ),
- Timing(
- block_time_avg_second=15/1.3/1.3,
- proof_time_avg_minute=45/1.3/1.3,
- ),
- Timing(
- block_time_avg_second=15/1.3,
- proof_time_avg_minute=45/1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15*1.3,
- proof_time_avg_minute=45*1.3,
- ),
- Timing(
- block_time_avg_second=15*1.3*1.3,
- proof_time_avg_minute=45*1.3*1.3,
- ),
- Timing(
- block_time_avg_second=15*1.3,
- proof_time_avg_minute=45*1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- ],
- ),
-)
diff --git a/packages/tokenomics/presents/vbvps2.py b/packages/tokenomics/presents/vbvps2.py
deleted file mode 100644
index f93e04f0df8..00000000000
--- a/packages/tokenomics/presents/vbvps2.py
+++ /dev/null
@@ -1,56 +0,0 @@
-from present import Config, Timing, Present
-
-present = Present(
- title="vbvps2: block time & proof time both go up, down to the SAME direction, then restores",
- desc="""
-""",
- days=21,
- config=Config(
- max_blocks=2048,
- lamda=590,
- fee_base=100.0,
- fee_maf=1024,
- reward_multiplier=4.0,
- time_avg_maf=1024,
- block_time_sd_pctg=0,
- proof_time_sd_pctg=0,
- timing=[
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15*1.3,
- proof_time_avg_minute=45*1.3,
- ),
- Timing(
- block_time_avg_second=15*1.3*1.3,
- proof_time_avg_minute=45*1.3*1.3,
- ),
- Timing(
- block_time_avg_second=15*1.3,
- proof_time_avg_minute=45*1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- Timing(
- block_time_avg_second=15/1.3,
- proof_time_avg_minute=45/1.3,
- ),
- Timing(
- block_time_avg_second=15/1.3/1.3,
- proof_time_avg_minute=45/1.3/1.3,
- ),
- Timing(
- block_time_avg_second=15/1.3,
- proof_time_avg_minute=45/1.3,
- ),
- Timing(
- block_time_avg_second=15,
- proof_time_avg_minute=45,
- ),
- ],
- ),
-)
diff --git a/packages/website/pages/docs/reference/contract-documentation/L1/TaikoData.md b/packages/website/pages/docs/reference/contract-documentation/L1/TaikoData.md
index 36b19fe902d..a2e613033bd 100644
--- a/packages/website/pages/docs/reference/contract-documentation/L1/TaikoData.md
+++ b/packages/website/pages/docs/reference/contract-documentation/L1/TaikoData.md
@@ -1,14 +1,5 @@
## TaikoData
-### FeeConfig
-
-```solidity
-struct FeeConfig {
- uint16 avgTimeMAF;
- uint16 dampingFactorBips;
-}
-```
-
### Config
```solidity
@@ -22,18 +13,13 @@ struct Config {
uint256 maxTransactionsPerBlock;
uint256 maxBytesPerTxList;
uint256 minTxGasLimit;
- uint256 slotSmoothingFactor;
- uint256 rewardBurnBips;
- uint256 proposerDepositPctg;
- uint256 feeBaseMAF;
uint256 txListCacheExpiry;
- bool relaySignalRoot;
+ uint64 proofTimeTarget;
+ uint8 adjustmentQuotient;
bool enableSoloProposer;
bool enableOracleProver;
bool enableTokenomics;
bool skipZKPVerification;
- struct TaikoData.FeeConfig proposingConfig;
- struct TaikoData.FeeConfig provingConfig;
}
```
@@ -41,13 +27,12 @@ struct Config {
```solidity
struct StateVariables {
- uint64 feeBase;
+ uint64 basefee;
+ uint64 accBlockFees;
uint64 genesisHeight;
uint64 genesisTimestamp;
uint64 numBlocks;
uint64 lastVerifiedBlockId;
- uint64 avgBlockTime;
- uint64 avgProofTime;
uint64 lastProposedAt;
}
```
@@ -137,6 +122,7 @@ struct ForkChoice {
bytes32 blockHash;
bytes32 signalRoot;
uint64 provenAt;
+ uint32 gasUsed;
address prover;
uint32 gasUsed;
}
@@ -176,16 +162,16 @@ struct State {
mapping(bytes32 => struct TaikoData.TxListInfo) txListInfo;
uint64 genesisHeight;
uint64 genesisTimestamp;
- uint64 __reserved1;
- uint64 __reserved2;
- uint64 numBlocks;
+ uint64 __reserved51;
+ uint64 __reserved52;
uint64 lastProposedAt;
- uint64 avgBlockTime;
- uint64 __reserved3;
+ uint64 numBlocks;
+ uint64 accProposedAt;
+ uint64 accBlockFees;
+ uint64 basefee;
+ uint64 proofTimeIssued;
uint64 lastVerifiedBlockId;
- uint64 __reserved4;
- uint64 avgProofTime;
- uint64 feeBase;
+ uint64 __reserved81;
uint256[43] __gap;
}
```
diff --git a/packages/website/pages/docs/reference/contract-documentation/L1/TaikoL1.md b/packages/website/pages/docs/reference/contract-documentation/L1/TaikoL1.md
index 9cb7f6c13a3..ea1cf5aff58 100644
--- a/packages/website/pages/docs/reference/contract-documentation/L1/TaikoL1.md
+++ b/packages/website/pages/docs/reference/contract-documentation/L1/TaikoL1.md
@@ -10,6 +10,7 @@ struct TaikoData.State state
```solidity
function init(address _addressManager, uint64 _feeBase, bytes32 _genesisBlockHash) external
+
```
Initialize the rollup.
@@ -22,10 +23,11 @@ Initialize the rollup.
| \_feeBase | uint64 | The initial value of the proposer-fee/prover-reward feeBase. |
| \_genesisBlockHash | bytes32 | The block hash of the genesis block. |
+
### proposeBlock
```solidity
-function proposeBlock(bytes input, bytes txList) external
+function proposeBlock(bytes input, bytes txList) external payable
```
Propose a Taiko L2 block.
@@ -103,13 +105,13 @@ function getBalance(address addr) public view returns (uint256)
### getBlockFee
```solidity
-function getBlockFee() public view returns (uint256 feeAmount, uint256 depositAmount)
+function getBlockFee() public view returns (uint64 feeAmount)
```
### getProofReward
```solidity
-function getProofReward(uint64 provenAt, uint64 proposedAt) public view returns (uint256 reward)
+function getProofReward(uint64 provenAt, uint64 proposedAt, uint32 gasUsed) public view returns (uint256 reward)
```
### getBlock
diff --git a/packages/website/pages/docs/reference/contract-documentation/L2/LibL2Consts.md b/packages/website/pages/docs/reference/contract-documentation/L2/LibL2Consts.md
index bc1878d609a..ee2f11323a4 100644
--- a/packages/website/pages/docs/reference/contract-documentation/L2/LibL2Consts.md
+++ b/packages/website/pages/docs/reference/contract-documentation/L2/LibL2Consts.md
@@ -1,7 +1,10 @@
+---
+title: LibL2Consts
+---
## LibL2Consts
### ANCHOR_GAS_COST
```solidity
-uint64 ANCHOR_GAS_COST
+uint32 ANCHOR_GAS_COST
```
diff --git a/packages/website/pages/docs/reference/contract-documentation/L2/TaikoL2.md b/packages/website/pages/docs/reference/contract-documentation/L2/TaikoL2.md
index 382b00c1f33..423660edf2d 100644
--- a/packages/website/pages/docs/reference/contract-documentation/L2/TaikoL2.md
+++ b/packages/website/pages/docs/reference/contract-documentation/L2/TaikoL2.md
@@ -67,6 +67,7 @@ uint64 gasExcess
```solidity
uint64 __reserved1
+
```
### Anchored
@@ -83,6 +84,18 @@ error L2_BASEFEE_MISMATCH(uint64 expected, uint64 actual)
### L2_INVALID_1559_PARAMS
+```solidity
+event BlockVars(uint64 number, uint64 basefee, uint64 gaslimit, uint64 timestamp, bytes32 parentHash, uint256 prevrandao, address coinbase, uint32 chainid)
+```
+
+### L2_BASEFEE_MISMATCH
+
+```solidity
+error L2_BASEFEE_MISMATCH(uint64 expected, uint64 actual)
+```
+
+### L2_INVALID_1559_PARAMS
+
```solidity
error L2_INVALID_1559_PARAMS()
```
@@ -150,17 +163,16 @@ This transaction shall be the first transaction in every L2 block.
#### Parameters
-| Name | Type | Description |
-| ------------- | ------- | --------------------------------------------------------- |
-| l1Hash | bytes32 | The latest L1 block hash when this block was proposed. |
-| l1SignalRoot | bytes32 | The latest value of the L1 "signal service storage root". |
-| l1Height | uint64 | The latest L1 block height when this block was proposed. |
-| parentGasUsed | uint64 | the gas used in the parent block. |
+| Name | Type | Description |
+| ------------ | ------- | --------------------------------------------------------- |
+| l1Height | uint64 | The latest L1 block height when this block was proposed. |
+| l1Hash | bytes32 | The latest L1 block hash when this block was proposed. |
+| l1SignalRoot | bytes32 | The latest value of the L1 "signal service storage root". |
### getBasefee
```solidity
-function getBasefee(uint32 timeSinceParent, uint64 gasLimit, uint64 parentGasUsed) public view returns (uint256 _basefee)
+function getBasefee(uint32 timeSinceNow, uint64 gasLimit) public view returns (uint64 _basefee)
```
### getXchainBlockHash
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index eeaf03b7125..9b5850a0fd2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -639,8 +639,6 @@ importers:
specifier: ^0.12.0
version: 0.12.0(vite@3.2.4)
- packages/tokenomics: {}
-
packages/website:
dependencies:
next: