diff --git a/packages/protocol/contracts/L1/TaikoErrors.sol b/packages/protocol/contracts/L1/TaikoErrors.sol deleted file mode 100644 index b9a405ad8c..0000000000 --- a/packages/protocol/contracts/L1/TaikoErrors.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -/// @title TaikoErrors -/// @notice This abstract contract provides custom error declarations used in -/// the Taiko protocol. Each error corresponds to specific situations where -/// exceptions might be thrown. -/// @dev The errors defined here must match the definitions in the corresponding -/// L1 libraries. -/// @custom:security-contact security@taiko.xyz -abstract contract TaikoErrors { - error L1_ALREADY_CONTESTED(); - error L1_ALREADY_PROVED(); - error L1_BATCH_TRANSFER_FAILED(); - error L1_BLOB_NOT_AVAILABLE(); - error L1_BLOB_NOT_FOUND(); - error L1_BLOCK_MISMATCH(); - error L1_CANNOT_CONTEST(); - error L1_INVALID_BLOCK_ID(); - error L1_INVALID_CONFIG(); - error L1_INVALID_GENESIS_HASH(); - error L1_INVALID_PARAM(); - error L1_INVALID_PAUSE_STATUS(); - error L1_INVALID_SIG(); - error L1_INVALID_TIER(); - error L1_INVALID_TRANSITION(); - error L1_LIVENESS_BOND_NOT_RECEIVED(); - error L1_NOT_ASSIGNED_PROVER(); - error L1_NO_HOOKS(); - error L1_PROVING_PAUSED(); - error L1_RECEIVE_DISABLED(); - error L1_TOO_LATE(); - error L1_TOO_MANY_BLOCKS(); - error L1_TRANSITION_ID_ZERO(); - error L1_TRANSITION_NOT_FOUND(); - error L1_UNEXPECTED_PARENT(); - error L1_UNEXPECTED_TRANSITION_ID(); -} diff --git a/packages/protocol/contracts/L1/TaikoEvents.sol b/packages/protocol/contracts/L1/TaikoEvents.sol deleted file mode 100644 index 5801111a4c..0000000000 --- a/packages/protocol/contracts/L1/TaikoEvents.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -import "./TaikoData.sol"; - -/// @title TaikoEvents -/// @notice This abstract contract provides event declarations for the Taiko -/// protocol, which are emitted during block proposal, proof, verification, and -/// Ethereum deposit processes. -/// @dev The events defined here must match the definitions in the corresponding -/// L1 libraries. -/// @custom:security-contact security@taiko.xyz -abstract contract TaikoEvents { - /// @dev Emitted when token is credited back to a user's bond balance. - event BondCredited(address indexed user, uint256 amount); - - /// @dev Emitted when token is debited from a user's bond balance. - event BondDebited(address indexed user, uint256 amount); - - /// @dev Emitted when a block is proposed. - /// @param blockId The ID of the proposed block. - /// @param assignedProver The block's assigned prover. - /// @param livenessBond The bond in Taiko token from the assigned prover. - /// @param meta The block metadata containing information about the proposed - /// block. - /// @param depositsProcessed Ether deposits processed. - event BlockProposed( - uint256 indexed blockId, - address indexed assignedProver, - uint96 livenessBond, - TaikoData.BlockMetadata meta, - TaikoData.EthDeposit[] depositsProcessed - ); - - /// @notice Emitted when a block's txList is in the calldata. - /// @param blockId The ID of the proposed block. - /// @param txList The txList. - event CalldataTxList(uint256 indexed blockId, bytes txList); - - /// @dev Emitted when a block is verified. - /// @param blockId The ID of the verified block. - /// @param prover The prover whose transition is used for verifying the - /// block. - /// @param blockHash The hash of the verified block. - /// @param stateRoot Deprecated and is always zero. - /// @param tier The tier ID of the proof. - event BlockVerified( - uint256 indexed blockId, - address indexed prover, - bytes32 blockHash, - bytes32 stateRoot, - uint16 tier - ); - - /// @notice Emitted when some state variable values changed. - /// @dev This event is currently used by Taiko node/client for block proposal/proving. - /// @param slotB The SlotB data structure. - event StateVariablesUpdated(TaikoData.SlotB slotB); - - /// @dev Emitted when a block transition is proved or re-proved. - /// @param blockId The ID of the proven block. - /// @param tran The verified transition. - /// @param prover The prover address. - /// @param validityBond The validity bond amount. - /// @param tier The tier ID of the proof. - event TransitionProved( - uint256 indexed blockId, - TaikoData.Transition tran, - address prover, - uint96 validityBond, - uint16 tier - ); - - /// @dev Emitted when a block transition is contested. - /// @param blockId The ID of the proven block. - /// @param tran The verified transition. - /// @param contester The contester address. - /// @param contestBond The contesting bond amount. - /// @param tier The tier ID of the proof. - event TransitionContested( - uint256 indexed blockId, - TaikoData.Transition tran, - address contester, - uint96 contestBond, - uint16 tier - ); - - /// @dev Emitted when proving has been paused - /// @param paused True if paused, false if unpaused. - event ProvingPaused(bool paused); -} diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index 3a28c9fc2c..7115cbd087 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -6,8 +6,6 @@ import "./libs/LibProposing.sol"; import "./libs/LibProving.sol"; import "./libs/LibVerifying.sol"; import "./ITaikoL1.sol"; -import "./TaikoErrors.sol"; -import "./TaikoEvents.sol"; /// @title TaikoL1 /// @notice This contract serves as the "base layer contract" of the Taiko protocol, providing @@ -18,14 +16,21 @@ import "./TaikoEvents.sol"; /// by the Bridge contract. /// @dev Labeled in AddressResolver as "taiko" /// @custom:security-contact security@taiko.xyz -contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { +contract TaikoL1 is EssentialContract, ITaikoL1 { /// @notice The TaikoL1 state. TaikoData.State public state; uint256[50] private __gap; + /// @notice Emitted when some state variable values changed. + /// @dev This event is currently used by Taiko node/client for block proposal/proving. + /// @param slotB The SlotB data structure. + event StateVariablesUpdated(TaikoData.SlotB slotB); + + error L1_RECEIVE_DISABLED(); + modifier whenProvingNotPaused() { - if (state.slotB.provingPaused) revert L1_PROVING_PAUSED(); + if (state.slotB.provingPaused) revert LibProving.L1_PROVING_PAUSED(); _; } diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 56137845a3..d5d9a28141 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -23,7 +23,6 @@ library LibProposing { bytes32 parentMetaHash; } - // Warning: Any events defined here must also be defined in TaikoEvents.sol. /// @notice Emitted when a block is proposed. /// @param blockId The ID of the proposed block. /// @param assignedProver The address of the assigned prover. @@ -44,7 +43,6 @@ library LibProposing { /// @param txList The txList. event CalldataTxList(uint256 indexed blockId, bytes txList); - // Warning: Any errors defined here must also be defined in TaikoErrors.sol. error L1_BLOB_NOT_AVAILABLE(); error L1_BLOB_NOT_FOUND(); error L1_INVALID_SIG(); diff --git a/packages/protocol/contracts/L1/libs/LibProving.sol b/packages/protocol/contracts/L1/libs/LibProving.sol index 3072e99f8a..a0afe0ad19 100644 --- a/packages/protocol/contracts/L1/libs/LibProving.sol +++ b/packages/protocol/contracts/L1/libs/LibProving.sol @@ -30,7 +30,6 @@ library LibProving { bool sameTransition; } - // Warning: Any events defined here must also be defined in TaikoEvents.sol. /// @notice Emitted when a transition is proved. /// @param blockId The block ID. /// @param tran The transition data. @@ -63,16 +62,14 @@ library LibProving { /// @param paused The pause status. event ProvingPaused(bool paused); - // Warning: Any errors defined here must also be defined in TaikoErrors.sol. error L1_ALREADY_CONTESTED(); error L1_ALREADY_PROVED(); - error L1_BLOCK_MISMATCH(); error L1_CANNOT_CONTEST(); - error L1_INVALID_BLOCK_ID(); error L1_INVALID_PAUSE_STATUS(); error L1_INVALID_TIER(); error L1_INVALID_TRANSITION(); error L1_NOT_ASSIGNED_PROVER(); + error L1_PROVING_PAUSED(); /// @notice Pauses or unpauses the proving process. /// @param _state Current TaikoData.State. @@ -110,7 +107,7 @@ library LibProving { TaikoData.TierProof memory proof ) = abi.decode(_input, (TaikoData.BlockMetadata, TaikoData.Transition, TaikoData.TierProof)); - if (_blockId != meta.id) revert L1_INVALID_BLOCK_ID(); + if (_blockId != meta.id) revert LibUtils.L1_INVALID_BLOCK_ID(); // Make sure parentHash is not zero // To contest an existing transition, simply use any non-zero value as @@ -124,7 +121,7 @@ library LibProving { // Check that the block has been proposed but has not yet been verified. if (meta.id <= local.b.lastVerifiedBlockId || meta.id >= local.b.numBlocks) { - revert L1_INVALID_BLOCK_ID(); + revert LibUtils.L1_INVALID_BLOCK_ID(); } local.slot = meta.id % _config.blockRingBufferSize; @@ -148,7 +145,7 @@ library LibProving { // theory, this check may be skipped, but it's included for added // caution. if (local.blockId != meta.id || local.metaHash != LibUtils.hashMetadata(meta)) { - revert L1_BLOCK_MISMATCH(); + revert LibUtils.L1_BLOCK_MISMATCH(); } // Each transition is uniquely identified by the parentHash, with the diff --git a/packages/protocol/contracts/L1/libs/LibUtils.sol b/packages/protocol/contracts/L1/libs/LibUtils.sol index fe0de80b4f..b564bbda9d 100644 --- a/packages/protocol/contracts/L1/libs/LibUtils.sol +++ b/packages/protocol/contracts/L1/libs/LibUtils.sol @@ -31,7 +31,6 @@ library LibUtils { uint16 tier ); - // Warning: Any errors defined here must also be defined in TaikoErrors.sol. error L1_BLOCK_MISMATCH(); error L1_INVALID_BLOCK_ID(); error L1_INVALID_GENESIS_HASH(); diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol index 5e2c11e449..4981117353 100644 --- a/packages/protocol/contracts/L1/libs/LibVerifying.sol +++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.24; import "../../signal/ISignalService.sol"; -import "./LibUtils.sol"; import "./LibBonds.sol"; +import "./LibUtils.sol"; /// @title LibVerifying /// @notice A library for handling block verification in the Taiko protocol. @@ -27,7 +27,6 @@ library LibVerifying { ITierRouter tierRouter; } - // Warning: Any errors defined here must also be defined in TaikoErrors.sol. error L1_BLOCK_MISMATCH(); error L1_INVALID_CONFIG(); error L1_TRANSITION_ID_ZERO(); diff --git a/packages/protocol/contracts/tko/TaikoToken.sol b/packages/protocol/contracts/tko/TaikoToken.sol index dd275d79f5..7bb9d38086 100644 --- a/packages/protocol/contracts/tko/TaikoToken.sol +++ b/packages/protocol/contracts/tko/TaikoToken.sol @@ -27,28 +27,4 @@ contract TaikoToken is TaikoTokenBase { // Mint 1 billion tokens _mint(_recipient, 1_000_000_000 ether); } - - /// @notice Batch transfers tokens - /// @param recipients The list of addresses to transfer tokens to. - /// @param amounts The list of amounts for transfer. - /// @return true if the transfer is successful. - function batchTransfer( - address[] calldata recipients, - uint256[] calldata amounts - ) - external - returns (bool) - { - if (recipients.length != amounts.length) revert TT_INVALID_PARAM(); - for (uint256 i; i < recipients.length; ++i) { - _transfer(msg.sender, recipients[i], amounts[i]); - } - return true; - } - - function delegates(address account) public view virtual override returns (address) { - // Special checks to avoid reading from storage slots - if (account == _TAIKO_L1 || account == _ERC20_VAULT) return address(0); - else return super.delegates(account); - } } diff --git a/packages/protocol/test/L1/TaikoL1.t.sol b/packages/protocol/test/L1/TaikoL1.t.sol index 0715e5acc8..b91b26886b 100644 --- a/packages/protocol/test/L1/TaikoL1.t.sol +++ b/packages/protocol/test/L1/TaikoL1.t.sol @@ -156,7 +156,7 @@ contract TaikoL1Test is TaikoL1TestBase { secondTransitionHash, stateRoot, meta.minTier, - TaikoErrors.L1_NOT_ASSIGNED_PROVER.selector + LibProving.L1_NOT_ASSIGNED_PROVER.selector ); // Only guardian or assigned prover is allowed @@ -205,7 +205,7 @@ contract TaikoL1Test is TaikoL1TestBase { bytes32("01"), bytes32("02"), meta.minTier, - TaikoErrors.L1_PROVING_PAUSED.selector + LibProving.L1_PROVING_PAUSED.selector ); } diff --git a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol index 62c0963333..6bdc973936 100644 --- a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol +++ b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol @@ -72,7 +72,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { blockHash, stateRoot, meta.minTier, - TaikoErrors.L1_ALREADY_PROVED.selector + LibProving.L1_ALREADY_PROVED.selector ); vm.roll(block.number + 15 * 12); @@ -265,7 +265,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { 0, stateRoot, LibTiers.TIER_GUARDIAN, - TaikoErrors.L1_INVALID_TRANSITION.selector + LibProving.L1_INVALID_TRANSITION.selector ); } @@ -305,7 +305,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { blockHash, stateRoot, meta.minTier, - TaikoErrors.L1_NOT_ASSIGNED_PROVER.selector + LibProving.L1_NOT_ASSIGNED_PROVER.selector ); vm.roll(block.number + 15 * 12); @@ -398,7 +398,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { 0, stateRoot, LibTiers.TIER_GUARDIAN, - TaikoErrors.L1_INVALID_TRANSITION.selector + LibProving.L1_INVALID_TRANSITION.selector ); vm.roll(block.number + 15 * 12); @@ -452,7 +452,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { blockHash, stateRoot, LibTiers.TIER_GUARDIAN, - TaikoErrors.L1_ALREADY_PROVED.selector + LibProving.L1_ALREADY_PROVED.selector ); } blockHash = bytes32(1_000_000 + blockId + 200); @@ -495,7 +495,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { blockHash, stateRoot, LibTiers.TIER_SGX, - TaikoErrors.L1_INVALID_BLOCK_ID.selector + LibUtils.L1_INVALID_BLOCK_ID.selector ); parentHash = blockHash; @@ -532,7 +532,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { blockHash, stateRoot, LibTiers.TIER_SGX, - TaikoErrors.L1_BLOCK_MISMATCH.selector + LibUtils.L1_BLOCK_MISMATCH.selector ); parentHash = blockHash; @@ -569,7 +569,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { stateRoot, stateRoot, LibTiers.TIER_SGX, - TaikoErrors.L1_INVALID_TIER.selector + LibProving.L1_INVALID_TIER.selector ); vm.roll(block.number + 15 * 12); @@ -607,7 +607,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { blockHash, stateRoot, LibTiers.TIER_SGX, - TaikoErrors.L1_INVALID_TIER.selector + LibProving.L1_INVALID_TIER.selector ); printVariables(""); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol index 6f36f4a4d4..3aa82a5773 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol @@ -50,7 +50,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { blockHash, stateRoot, meta.minTier, - TaikoErrors.L1_NOT_ASSIGNED_PROVER.selector + LibProving.L1_NOT_ASSIGNED_PROVER.selector ); console2.log("====== Alice proves the block"); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol index df449095b8..f9b6311e3c 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol @@ -58,7 +58,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { blockHash, stateRoot, LibTiers.TIER_GUARDIAN, - TaikoErrors.L1_ALREADY_PROVED.selector + LibProving.L1_ALREADY_PROVED.selector ); console2.log("====== Guardian re-approve with a different transition"); @@ -97,7 +97,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { blockHash, stateRoot, LibTiers.TIER_SGX, - TaikoErrors.L1_INVALID_TIER.selector + LibProving.L1_INVALID_TIER.selector ); console2.log("====== Verify the block"); @@ -157,7 +157,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { blockHash, stateRoot, LibTiers.TIER_GUARDIAN, - TaikoErrors.L1_ALREADY_PROVED.selector + LibProving.L1_ALREADY_PROVED.selector ); console2.log("====== Guardian re-approve with a different transition"); @@ -247,7 +247,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { blockHash, stateRoot, LibTiers.TIER_GUARDIAN, - TaikoErrors.L1_ALREADY_PROVED.selector + LibProving.L1_ALREADY_PROVED.selector ); console2.log("====== Guardian re-approve with a different transition"); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup7.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup7.t.sol index 9bf9c1570b..7e48985ea9 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup7.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup7.t.sol @@ -36,7 +36,7 @@ contract TaikoL1TestGroup7 is TaikoL1TestGroupBase { blockHash2, stateRoot2, meta.minTier, - TaikoErrors.L1_CANNOT_CONTEST.selector + LibProving.L1_CANNOT_CONTEST.selector ); printBlockAndTrans(meta.id); } @@ -79,7 +79,7 @@ contract TaikoL1TestGroup7 is TaikoL1TestGroupBase { blockHash3, stateRoot3, meta.minTier, - TaikoErrors.L1_ALREADY_CONTESTED.selector + LibProving.L1_ALREADY_CONTESTED.selector ); printBlockAndTrans(meta.id); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup8.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup8.t.sol index 57916bff58..7c71c246c3 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup8.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup8.t.sol @@ -87,7 +87,7 @@ contract TaikoL1TestGroup8 is TaikoL1TestGroupBase { blockHash, stateRoot, meta.minTier, - TaikoErrors.L1_PROVING_PAUSED.selector + LibProving.L1_PROVING_PAUSED.selector ); console2.log("====== Alice tries to propose another block after L1 proving paused"); @@ -106,16 +106,16 @@ contract TaikoL1TestGroup8 is TaikoL1TestGroupBase { // 1. Gets a block that doesn't exist // 2. Gets a transition by ID & hash that doesn't exist. function test_taikoL1_group_8_case_3() external { - vm.expectRevert(TaikoErrors.L1_INVALID_BLOCK_ID.selector); + vm.expectRevert(LibUtils.L1_INVALID_BLOCK_ID.selector); L1.getBlock(2); - vm.expectRevert(TaikoErrors.L1_TRANSITION_NOT_FOUND.selector); + vm.expectRevert(LibUtils.L1_TRANSITION_NOT_FOUND.selector); L1.getTransition(0, 2); - vm.expectRevert(TaikoErrors.L1_TRANSITION_NOT_FOUND.selector); + vm.expectRevert(LibUtils.L1_TRANSITION_NOT_FOUND.selector); L1.getTransition(0, randBytes32()); - vm.expectRevert(TaikoErrors.L1_INVALID_BLOCK_ID.selector); + vm.expectRevert(LibUtils.L1_INVALID_BLOCK_ID.selector); L1.getTransition(3, randBytes32()); } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup9.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup9.t.sol index 16bd04a3f5..a7bf18acab 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup9.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup9.t.sol @@ -80,7 +80,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { blockHash, stateRoot, LibTiers.TIER_GUARDIAN, - TaikoErrors.L1_ALREADY_PROVED.selector + LibProving.L1_ALREADY_PROVED.selector ); console2.log("====== Guardian re-approve with a different transition"); @@ -120,7 +120,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { blockHash, stateRoot, LibTiers.TIER_SGX, - TaikoErrors.L1_INVALID_TIER.selector + LibProving.L1_INVALID_TIER.selector ); console2.log("====== Verify the block"); @@ -181,7 +181,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { blockHash, stateRoot, LibTiers.TIER_GUARDIAN, - TaikoErrors.L1_ALREADY_PROVED.selector + LibProving.L1_ALREADY_PROVED.selector ); console2.log("====== Guardian re-approve with a different transition"); @@ -273,7 +273,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { blockHash, stateRoot, LibTiers.TIER_GUARDIAN, - TaikoErrors.L1_ALREADY_PROVED.selector + LibProving.L1_ALREADY_PROVED.selector ); console2.log("====== Guardian re-approve with a different transition");