From d51fe1f5f491c947c06ef4dfc4629f9641117fe6 Mon Sep 17 00:00:00 2001 From: dantaik <99078276+dantaik@users.noreply.github.com> Date: Fri, 2 Dec 2022 11:32:10 +0800 Subject: [PATCH] undo tokenomics --- packages/protocol/contracts/L1/LibData.sol | 3 - packages/protocol/contracts/L1/TaikoL1.sol | 25 +---- .../protocol/contracts/L1/v1/V1Proposing.sol | 48 ---------- packages/protocol/contracts/L1/v1/V1Utils.sol | 71 -------------- .../protocol/contracts/L1/v1/V1Verifying.sol | 95 +------------------ packages/protocol/contracts/L2/V1TaikoL2.sol | 10 +- .../protocol/contracts/libs/LibConstants.sol | 17 ---- packages/protocol/test/L1/TaikoL1.test.ts | 4 +- 8 files changed, 9 insertions(+), 264 deletions(-) diff --git a/packages/protocol/contracts/L1/LibData.sol b/packages/protocol/contracts/L1/LibData.sol index 6c6094b649..d753a798a8 100644 --- a/packages/protocol/contracts/L1/LibData.sol +++ b/packages/protocol/contracts/L1/LibData.sol @@ -29,7 +29,6 @@ library LibData { // 3 slots struct ProposedBlock { bytes32 metaHash; - uint256 deposit; address proposer; uint64 proposedAt; } @@ -56,8 +55,6 @@ library LibData { uint64 genesisTimestamp; uint64 __reservedA1; uint64 statusBits; // rarely change - // Changed when a block is proposed or proven/finalized - uint256 feeBase; // Changed when a block is proposed uint64 nextBlockId; uint64 lastProposedAt; // Timestamp when the last block is proposed. diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index e776cd083d..245b49c0e4 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -30,15 +30,10 @@ contract TaikoL1 is EssentialContract, IHeaderSync, V1Events { function init( address _addressManager, - bytes32 _genesisBlockHash, - uint256 _feeBase + bytes32 _genesisBlockHash ) external initializer { EssentialContract._init(_addressManager); - V1Verifying.init({ - state: state, - genesisBlockHash: _genesisBlockHash, - feeBase: _feeBase - }); + V1Verifying.init({state: state, genesisBlockHash: _genesisBlockHash}); tentative.whitelistProposers = false; tentative.whitelistProvers = true; @@ -253,22 +248,6 @@ contract TaikoL1 is EssentialContract, IHeaderSync, V1Events { return V1Utils.isProverWhitelisted(tentative, prover); } - function getBlockFee() public view returns (uint256) { - (, uint fee, uint deposit) = V1Proposing.getBlockFee(state); - return fee + deposit; - } - - function getProofReward( - uint64 provenAt, - uint64 proposedAt - ) public view returns (uint256 reward) { - (, reward, ) = V1Verifying.getProofReward({ - state: state, - provenAt: provenAt, - proposedAt: proposedAt - }); - } - /** * Check if the L1 is halted. * @return True if halted, false otherwise. diff --git a/packages/protocol/contracts/L1/v1/V1Proposing.sol b/packages/protocol/contracts/L1/v1/V1Proposing.sol index 91544f57ca..bdd7ed9b1f 100644 --- a/packages/protocol/contracts/L1/v1/V1Proposing.sol +++ b/packages/protocol/contracts/L1/v1/V1Proposing.sol @@ -98,38 +98,10 @@ library V1Proposing { meta.mixHash = bytes32(block.difficulty); } - uint256 deposit; - if (LibConstants.K_TOKENOMICS_ENABLED) { - uint256 newFeeBase; - { - uint256 fee; - (newFeeBase, fee, deposit) = getBlockFee(state); - TkoToken(resolver.resolve("tko_token")).burn( - msg.sender, - fee + deposit - ); - } - // Update feeBase and avgBlockTime - state.feeBase = V1Utils.movingAverage({ - maValue: state.feeBase, - newValue: newFeeBase, - maf: LibConstants.K_FEE_BASE_MAF - }); - - state.avgBlockTime = V1Utils - .movingAverage({ - maValue: state.avgBlockTime, - newValue: meta.timestamp - state.lastProposedAt, - maf: LibConstants.K_BLOCK_TIME_MAF - }) - .toUint64(); - } - state.saveProposedBlock( state.nextBlockId, LibData.ProposedBlock({ metaHash: LibData.hashMetadata(meta), - deposit: deposit, proposer: msg.sender, proposedAt: meta.timestamp }) @@ -139,26 +111,6 @@ library V1Proposing { emit BlockProposed(state.nextBlockId++, meta); } - function getBlockFee( - LibData.State storage state - ) public view returns (uint256 newFeeBase, uint256 fee, uint256 deposit) { - (newFeeBase, ) = V1Utils.getTimeAdjustedFee({ - state: state, - isProposal: true, - tNow: uint64(block.timestamp), - tLast: state.lastProposedAt, - tAvg: state.avgBlockTime, - tCap: LibConstants.K_BLOCK_TIME_CAP - }); - fee = V1Utils.getSlotsAdjustedFee({ - state: state, - isProposal: true, - feeBase: newFeeBase - }); - fee = V1Utils.getBootstrapDiscountedFee(state, fee); - deposit = (fee * LibConstants.K_PROPOSER_DEPOSIT_PCTG) / 100; - } - function isCommitValid( LibData.State storage state, uint256 commitSlot, diff --git a/packages/protocol/contracts/L1/v1/V1Utils.sol b/packages/protocol/contracts/L1/v1/V1Utils.sol index 168254a4f2..b339b91189 100644 --- a/packages/protocol/contracts/L1/v1/V1Utils.sol +++ b/packages/protocol/contracts/L1/v1/V1Utils.sol @@ -93,65 +93,6 @@ library V1Utils { return tentative.provers[prover]; } - // Implement "Incentive Multipliers", see the whitepaper. - function getTimeAdjustedFee( - LibData.State storage state, - bool isProposal, - uint64 tNow, - uint64 tLast, - uint64 tAvg, - uint64 tCap - ) internal view returns (uint256 newFeeBase, uint256 tRelBp) { - if (tAvg == 0) { - newFeeBase = state.feeBase; - tRelBp = 0; - } else { - uint256 _tAvg = tAvg > tCap ? tCap : tAvg; - uint256 tGrace = (LibConstants.K_FEE_GRACE_PERIOD_PCTG * _tAvg) / - 100; - uint256 tMax = (LibConstants.K_FEE_MAX_PERIOD_PCTG * _tAvg) / 100; - uint256 a = tLast + tGrace; - uint256 b = tNow > a ? tNow - a : 0; - tRelBp = (b.min(tMax) * 10000) / tMax; // [0 - 10000] - uint256 alpha = 10000 + - ((LibConstants.K_REWARD_MULTIPLIER_PCTG - 100) * tRelBp) / - 100; - if (isProposal) { - newFeeBase = (state.feeBase * 10000) / alpha; // fee - } else { - newFeeBase = (state.feeBase * alpha) / 10000; // reward - } - } - } - - // Implement "Slot-availability Multipliers", see the whitepaper. - function getSlotsAdjustedFee( - LibData.State storage state, - bool isProposal, - uint256 feeBase - ) internal view returns (uint256) { - // m is the `n'` in the whitepaper - uint256 m = LibConstants.K_MAX_NUM_BLOCKS - - 1 + - LibConstants.K_FEE_PREMIUM_LAMDA; - // n is the number of unverified blocks - uint256 n = state.nextBlockId - state.latestVerifiedId - 1; - // k is `m − n + 1` or `m − n - 1`in the whitepaper - uint256 k = isProposal ? m - n - 1 : m - n + 1; - return (feeBase * (m - 1) * m) / (m - n) / k; - } - - // Implement "Bootstrap Discount Multipliers", see the whitepaper. - function getBootstrapDiscountedFee( - LibData.State storage state, - uint256 feeBase - ) internal view returns (uint256) { - uint256 halves = uint256(block.timestamp - state.genesisTimestamp) / - LibConstants.K_HALVING; - uint256 gamma = 1024 - (1024 >> halves); - return (feeBase * gamma) / 1024; - } - // Returns a deterministic deadline for uncle proof submission. function uncleProofDeadline( LibData.State storage state, @@ -160,18 +101,6 @@ library V1Utils { return fc.provenAt + state.avgProofTime; } - function movingAverage( - uint256 maValue, - uint256 newValue, - uint256 maf - ) internal pure returns (uint256) { - if (maValue == 0) { - return newValue; - } - uint256 _ma = (maValue * (maf - 1) + newValue) / maf; - return _ma > 0 ? _ma : maValue; - } - function setBit( LibData.State storage state, uint64 mask, diff --git a/packages/protocol/contracts/L1/v1/V1Verifying.sol b/packages/protocol/contracts/L1/v1/V1Verifying.sol index 7c0988ab66..03ea7876d9 100644 --- a/packages/protocol/contracts/L1/v1/V1Verifying.sol +++ b/packages/protocol/contracts/L1/v1/V1Verifying.sol @@ -25,14 +25,10 @@ library V1Verifying { function init( LibData.State storage state, - bytes32 genesisBlockHash, - uint256 feeBase + bytes32 genesisBlockHash ) public { - require(feeBase > 0, "L1:feeBase"); - state.genesisHeight = uint64(block.number); state.genesisTimestamp = uint64(block.timestamp); - state.feeBase = feeBase; state.nextBlockId = 1; state.lastProposedAt = uint64(block.timestamp); state.l2Hashes[0] = genesisBlockHash; @@ -58,7 +54,6 @@ library V1Verifying { uint64 latestL2Height = state.latestVerifiedHeight; bytes32 latestL2Hash = state.l2Hashes[latestL2Height]; uint64 processed = 0; - TkoToken tkoToken; for ( uint256 i = state.latestVerifiedId + 1; @@ -66,49 +61,11 @@ library V1Verifying { i++ ) { LibData.ForkChoice storage fc = state.forkChoices[i][latestL2Hash]; - LibData.ProposedBlock storage target = LibData.getProposedBlock( - state, - i - ); // Uncle proof can not take more than 2x time the first proof did. if (!_isVerifiable(state, fc)) { break; } else { - if (LibConstants.K_TOKENOMICS_ENABLED) { - uint256 newFeeBase; - { - uint256 reward; - uint256 tRelBp; // [0-10000], see the whitepaper - (newFeeBase, reward, tRelBp) = getProofReward({ - state: state, - provenAt: fc.provenAt, - proposedAt: target.proposedAt - }); - - if (address(tkoToken) == address(0)) { - tkoToken = TkoToken(resolver.resolve("tko_token")); - } - - _rewardProvers(fc, reward, tkoToken); - _refundProposerDeposit(target, tRelBp, tkoToken); - } - // Update feeBase and avgProofTime - state.feeBase = V1Utils.movingAverage({ - maValue: state.feeBase, - newValue: newFeeBase, - maf: LibConstants.K_FEE_BASE_MAF - }); - - state.avgProofTime = V1Utils - .movingAverage({ - maValue: state.avgProofTime, - newValue: fc.provenAt - target.proposedAt, - maf: LibConstants.K_PROOF_TIME_MAF - }) - .toUint64(); - } - if (fc.blockHash != LibConstants.K_BLOCK_DEADEND_HASH) { latestL2Height += 1; latestL2Hash = fc.blockHash; @@ -130,56 +87,6 @@ library V1Verifying { } } - function getProofReward( - LibData.State storage state, - uint64 provenAt, - uint64 proposedAt - ) public view returns (uint256 newFeeBase, uint256 reward, uint256 tRelBp) { - (newFeeBase, tRelBp) = V1Utils.getTimeAdjustedFee({ - state: state, - isProposal: false, - tNow: provenAt, - tLast: proposedAt, - tAvg: state.avgProofTime, - tCap: LibConstants.K_PROOF_TIME_CAP - }); - reward = V1Utils.getSlotsAdjustedFee({ - state: state, - isProposal: false, - feeBase: newFeeBase - }); - reward = (reward * (10000 - LibConstants.K_REWARD_BURN_BP)) / 10000; - } - - function _refundProposerDeposit( - LibData.ProposedBlock storage target, - uint256 tRelBp, - TkoToken tkoToken - ) private { - uint refund = (target.deposit * (10000 - tRelBp)) / 10000; - if (refund > 0) { - tkoToken.mint(target.proposer, refund); - } - } - - function _rewardProvers( - LibData.ForkChoice storage fc, - uint256 reward, - TkoToken tkoToken - ) private { - uint sum = 2 ** fc.provers.length - 1; - for (uint i = 0; i < fc.provers.length; i++) { - uint weight = (1 << (fc.provers.length - i - 1)); - uint proverReward = (reward * weight) / sum; - - if (tkoToken.balanceOf(fc.provers[i]) == 0) { - // reduce reward if the prover has 0 TKO balance. - proverReward /= 2; - } - tkoToken.mint(fc.provers[i], proverReward); - } - } - function _cleanUp(LibData.ForkChoice storage fc) private { fc.blockHash = 0; fc.provenAt = 0; diff --git a/packages/protocol/contracts/L2/V1TaikoL2.sol b/packages/protocol/contracts/L2/V1TaikoL2.sol index f562b428bd..a313c70bdf 100644 --- a/packages/protocol/contracts/L2/V1TaikoL2.sol +++ b/packages/protocol/contracts/L2/V1TaikoL2.sol @@ -56,7 +56,7 @@ contract V1TaikoL2 is AddressResolver, ReentrancyGuard, IHeaderSync { publicInputHash = _hashPublicInputs({ chainId: block.chainid, number: number, - feeBase: 0, + baseFee: 0, ancestors: ancestors }); } @@ -189,7 +189,7 @@ contract V1TaikoL2 is AddressResolver, ReentrancyGuard, IHeaderSync { _hashPublicInputs({ chainId: chainId, number: parentHeight, - feeBase: 0, + baseFee: 0, ancestors: ancestors }), "L2:publicInputHash" @@ -199,7 +199,7 @@ contract V1TaikoL2 is AddressResolver, ReentrancyGuard, IHeaderSync { publicInputHash = _hashPublicInputs({ chainId: chainId, number: number, - feeBase: 0, + baseFee: 0, ancestors: ancestors }); @@ -209,9 +209,9 @@ contract V1TaikoL2 is AddressResolver, ReentrancyGuard, IHeaderSync { function _hashPublicInputs( uint256 chainId, uint256 number, - uint256 feeBase, + uint256 baseFee, bytes32[255] memory ancestors ) private pure returns (bytes32) { - return keccak256(abi.encodePacked(chainId, number, feeBase, ancestors)); + return keccak256(abi.encodePacked(chainId, number, baseFee, ancestors)); } } diff --git a/packages/protocol/contracts/libs/LibConstants.sol b/packages/protocol/contracts/libs/LibConstants.sol index 1b6bf7e2a5..804497d523 100644 --- a/packages/protocol/contracts/libs/LibConstants.sol +++ b/packages/protocol/contracts/libs/LibConstants.sol @@ -16,7 +16,6 @@ library LibConstants { uint256 public constant K_MAX_NUM_BLOCKS = 2049; // This number is calculated from K_MAX_NUM_BLOCKS to make // the 'the maximum value of the multiplier' close to 20.0 - uint256 public constant K_FEE_PREMIUM_LAMDA = 590; uint256 public constant K_ZKPROOFS_PER_BLOCK = 1; uint256 public constant K_VERIFICATION_DELAY = 60 minutes; uint256 public constant K_MAX_VERIFICATIONS_PER_TX = 20; @@ -26,21 +25,7 @@ library LibConstants { uint256 public constant K_BLOCK_MAX_TXS = 20; // TODO uint256 public constant K_TXLIST_MAX_BYTES = 10240; // TODO uint256 public constant K_TX_MIN_GAS_LIMIT = 21000; // TODO - uint256 public constant K_REWARD_BURN_BP = 100; // 100 basis points or 1% uint256 public constant K_ANCHOR_TX_GAS_LIMIT = 250000; - uint256 public constant K_PROPOSER_DEPOSIT_PCTG = 25; // 25% - - // Moving average factors - uint256 public constant K_FEE_BASE_MAF = 1024; - uint256 public constant K_BLOCK_TIME_MAF = 1024; - uint256 public constant K_PROOF_TIME_MAF = 1024; - - uint64 public constant K_REWARD_MULTIPLIER_PCTG = 400; // 400% - uint64 public constant K_FEE_GRACE_PERIOD_PCTG = 125; // 125% - uint64 public constant K_FEE_MAX_PERIOD_PCTG = 375; // 375% - uint64 public constant K_BLOCK_TIME_CAP = 48 seconds; - uint64 public constant K_PROOF_TIME_CAP = 60 minutes; - uint64 public constant K_HALVING = 180 days; bytes4 public constant K_ANCHOR_TX_SELECTOR = bytes4(keccak256("anchor(uint256,bytes32)")); @@ -48,6 +33,4 @@ library LibConstants { bytes32 public constant K_BLOCK_DEADEND_HASH = bytes32(uint256(1)); bytes32 public constant K_INVALIDATE_BLOCK_LOG_TOPIC = keccak256("BlockInvalidated(bytes32)"); - - bool public constant K_TOKENOMICS_ENABLED = true; } diff --git a/packages/protocol/test/L1/TaikoL1.test.ts b/packages/protocol/test/L1/TaikoL1.test.ts index fa8a92d942..598dd4568e 100644 --- a/packages/protocol/test/L1/TaikoL1.test.ts +++ b/packages/protocol/test/L1/TaikoL1.test.ts @@ -1,6 +1,5 @@ import { expect } from "chai" import { ethers } from "hardhat" -import { BigNumber } from "ethers" describe("TaikoL1", function () { async function deployTaikoL1Fixture() { @@ -50,8 +49,7 @@ describe("TaikoL1", function () { const genesisHash = randomBytes32() const taikoL1 = await TaikoL1Factory.deploy() - const feeBase = BigNumber.from(10).pow(18) - await taikoL1.init(addressManager.address, genesisHash, feeBase) + await taikoL1.init(addressManager.address, genesisHash) return { taikoL1, genesisHash } }