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: