From 169e4ee98f5c2d4b4d8cd3ae887be6a36a79b578 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 27 Jan 2024 09:50:55 +0800 Subject: [PATCH 1/4] more --- packages/protocol/contracts/L1/TaikoData.sol | 1 + packages/protocol/contracts/L1/TaikoL1.sol | 5 +++++ packages/protocol/contracts/common/OwnerUUPSUpgradable.sol | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 6877b7c11c0..bc6da1a0d85 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -177,6 +177,7 @@ library TaikoData { uint64 numBlocks; uint64 lastVerifiedBlockId; bool provingPaused; + uint64 lastUnpausedAt; } /// @dev Struct holding the state variables for the {TaikoL1} contract. diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index 405f908744e..b40e6ee1452 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -113,6 +113,11 @@ contract TaikoL1 is LibVerifying.verifyBlocks(state, getConfig(), AddressResolver(this), maxBlocksToVerify); } + function unpause() public override whenPaused onlyOwner { + OwnerUUPSUpgradable.unpause(); + state.slotB.lastUnpausedAt = uint64(block.timestamp); + } + /// @notice Pause block proving. /// @param pause True if paused. function pauseProving(bool pause) external onlyOwner { diff --git a/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol b/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol index c67d4e3b8d2..8f022ffba89 100644 --- a/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol +++ b/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol @@ -57,12 +57,12 @@ abstract contract OwnerUUPSUpgradable is UUPSUpgradeable, OwnableUpgradeable { _disableInitializers(); } - function pause() external whenNotPaused onlyOwner { + function pause() public virtual whenNotPaused onlyOwner { _paused = _TRUE; emit Paused(msg.sender); } - function unpause() external whenPaused onlyOwner { + function unpause() public virtual whenPaused onlyOwner { _paused = _FALSE; emit Unpaused(msg.sender); } From 0052453c1781828aca86309385012a7b7c8ea604 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 27 Jan 2024 10:04:44 +0800 Subject: [PATCH 2/4] fix --- packages/protocol/contracts/L1/TaikoL1.sol | 8 +++++++- packages/protocol/contracts/L1/libs/LibProving.sol | 9 ++++++++- packages/protocol/contracts/L1/libs/LibProvingAlt.sol | 9 +++++++-- packages/protocol/contracts/L1/libs/LibVerifying.sol | 5 ++++- .../protocol/contracts/common/OwnerUUPSUpgradable.sol | 9 ++++++--- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index b40e6ee1452..16b7fad5d65 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -113,7 +113,7 @@ contract TaikoL1 is LibVerifying.verifyBlocks(state, getConfig(), AddressResolver(this), maxBlocksToVerify); } - function unpause() public override whenPaused onlyOwner { + function unpause() public override { OwnerUUPSUpgradable.unpause(); state.slotB.lastUnpausedAt = uint64(block.timestamp); } @@ -247,4 +247,10 @@ contract TaikoL1 is function isConfigValid() public view returns (bool) { return LibVerifying.isConfigValid(getConfig()); } + + function _authorizePause(address) internal override { + if (msg.sender != owner() && msg.sender != resolve("rollup_watchdog", true)) { + revert L1_UNAUTHORIZED(); + } + } } diff --git a/packages/protocol/contracts/L1/libs/LibProving.sol b/packages/protocol/contracts/L1/libs/LibProving.sol index bdb1a8a6aa9..4902e2b9ec9 100644 --- a/packages/protocol/contracts/L1/libs/LibProving.sol +++ b/packages/protocol/contracts/L1/libs/LibProving.sol @@ -16,6 +16,7 @@ pragma solidity 0.8.20; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "../../common/AddressResolver.sol"; +import "../../libs/LibMath.sol"; import "../tiers/ITierProvider.sol"; import "../verifiers/IVerifier.sol"; import "../TaikoData.sol"; @@ -25,6 +26,8 @@ import "./LibUtils.sol"; /// @notice A library for handling block contestation and proving in the Taiko /// protocol. library LibProving { + using LibMath for uint256; + bytes32 public constant RETURN_LIVENESS_BOND = keccak256("RETURN_LIVENESS_BOND"); // Warning: Any events defined here must also be defined in TaikoEvents.sol. @@ -335,7 +338,11 @@ library LibProving { revert L1_ALREADY_PROVED(); } - if (tid == 1 && ts.tier == 0 && block.timestamp <= ts.timestamp + tier.provingWindow) { + if ( + tid == 1 && ts.tier == 0 + && block.timestamp + <= uint256(ts.timestamp).max(state.slotB.lastUnpausedAt) + tier.provingWindow + ) { // For the first transition, (1) if the previous prover is // still the assigned prover, we exclusively grant permission to // the assigned approver to re-prove the block, (2) unless the diff --git a/packages/protocol/contracts/L1/libs/LibProvingAlt.sol b/packages/protocol/contracts/L1/libs/LibProvingAlt.sol index 7d9bd2623a9..600d4303248 100644 --- a/packages/protocol/contracts/L1/libs/LibProvingAlt.sol +++ b/packages/protocol/contracts/L1/libs/LibProvingAlt.sol @@ -16,6 +16,7 @@ pragma solidity 0.8.20; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "../../common/AddressResolver.sol"; +import "../../libs/LibMath.sol"; import "../tiers/ITierProvider.sol"; import "../verifiers/IVerifier.sol"; import "../TaikoData.sol"; @@ -25,6 +26,8 @@ import "./LibUtils.sol"; /// @notice An alternative library for handling block contestation and proving in the Taiko /// protocol. library LibProvingAlt { + using LibMath for uint256; + bytes32 public constant RETURN_LIVENESS_BOND = keccak256("RETURN_LIVENESS_BOND"); // Warning: Any events defined here must also be defined in TaikoEvents.sol. @@ -118,7 +121,7 @@ library LibProvingAlt { ITierProvider.Tier memory tier = ITierProvider(resolver.resolve("tier_provider", false)).getTier(proof.tier); - _checkProverPermission(blk, ts, tid, tier); + _checkProverPermission(state, blk, ts, tid, tier); // We must verify the proof, and any failure in proof verification will // result in a revert. @@ -373,6 +376,7 @@ library LibProvingAlt { /// @dev Check the msg.sender (the new prover) against the block's assigned prover. function _checkProverPermission( + TaikoData.State storage state, TaikoData.Block storage blk, TaikoData.TransitionState storage ts, uint32 tid, @@ -384,7 +388,8 @@ library LibProvingAlt { // The highest tier proof can always submit new proofs if (tier.contestBond == 0) return; - bool inProvingWindow = block.timestamp <= ts.timestamp + tier.provingWindow; + bool inProvingWindow = uint256(ts.timestamp).max(state.slotB.lastUnpausedAt) + + tier.provingWindow >= block.timestamp; bool isAssignedPover = msg.sender == blk.assignedProver; // The assigned prover can only submit the very first transition. diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol index 1e41e8ec743..fb8a349f7b1 100644 --- a/packages/protocol/contracts/L1/libs/LibVerifying.sol +++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol @@ -16,6 +16,7 @@ pragma solidity 0.8.20; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "../../common/AddressResolver.sol"; +import "../../libs/LibMath.sol"; import "../../signal/ISignalService.sol"; import "../tiers/ITierProvider.sol"; import "../TaikoData.sol"; @@ -24,6 +25,8 @@ import "./LibUtils.sol"; /// @title LibVerifying /// @notice A library for handling block verification in the Taiko protocol. library LibVerifying { + using LibMath for uint256; + // Warning: Any events defined here must also be defined in TaikoEvents.sol. event BlockVerified( uint256 indexed blockId, @@ -166,7 +169,7 @@ library LibVerifying { } if ( uint256(ITierProvider(tierProvider).getTier(ts.tier).cooldownWindow) - + ts.timestamp > block.timestamp + + uint256(ts.timestamp).max(state.slotB.lastUnpausedAt) > block.timestamp ) { // If cooldownWindow is 0, the block can theoretically // be proved and verified within the same L1 block. diff --git a/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol b/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol index 8f022ffba89..a3d92b288c0 100644 --- a/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol +++ b/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol @@ -57,12 +57,14 @@ abstract contract OwnerUUPSUpgradable is UUPSUpgradeable, OwnableUpgradeable { _disableInitializers(); } - function pause() public virtual whenNotPaused onlyOwner { + function pause() public virtual whenNotPaused { + _authorizePause(msg.sender); _paused = _TRUE; emit Paused(msg.sender); } - function unpause() public virtual whenPaused onlyOwner { + function unpause() public virtual whenPaused { + _authorizePause(msg.sender); _paused = _FALSE; emit Unpaused(msg.sender); } @@ -71,7 +73,8 @@ abstract contract OwnerUUPSUpgradable is UUPSUpgradeable, OwnableUpgradeable { return _paused == _TRUE; } - function _authorizeUpgrade(address) internal override onlyOwner { } + function _authorizeUpgrade(address) internal virtual override onlyOwner { } + function _authorizePause(address) internal virtual onlyOwner { } /// @notice Initializes the contract with an address manager. // solhint-disable-next-line func-name-mixedcase From ea262e4cd7d65a697a883e2e300e391fb52b4953 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 27 Jan 2024 10:15:18 +0800 Subject: [PATCH 3/4] Update TaikoData.sol --- packages/protocol/contracts/L1/TaikoData.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index bc6da1a0d85..95d27ce31ec 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -177,6 +177,9 @@ library TaikoData { uint64 numBlocks; uint64 lastVerifiedBlockId; bool provingPaused; + uint8 __reserved1; + uint16 __reserved2; + uint32 __reserved3; uint64 lastUnpausedAt; } From f21a4763083b24bfde4a36b0e41000fc72533ef2 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 27 Jan 2024 20:16:31 +0800 Subject: [PATCH 4/4] Update LibProving.sol --- packages/protocol/contracts/L1/libs/LibProving.sol | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/protocol/contracts/L1/libs/LibProving.sol b/packages/protocol/contracts/L1/libs/LibProving.sol index 4902e2b9ec9..dea23c4058b 100644 --- a/packages/protocol/contracts/L1/libs/LibProving.sol +++ b/packages/protocol/contracts/L1/libs/LibProving.sol @@ -61,11 +61,15 @@ library LibProving { error L1_NOT_ASSIGNED_PROVER(); error L1_UNEXPECTED_TRANSITION_TIER(); - function pauseProving(TaikoData.State storage state, bool pause) external { - if (state.slotB.provingPaused == pause) revert L1_INVALID_PAUSE_STATUS(); + function pauseProving(TaikoData.State storage state, bool toPause) external { + if (state.slotB.provingPaused == toPause) revert L1_INVALID_PAUSE_STATUS(); - state.slotB.provingPaused = pause; - emit ProvingPaused(pause); + state.slotB.provingPaused = toPause; + + if (!toPause) { + state.slotB.lastUnpausedAt = uint64(block.timestamp); + } + emit ProvingPaused(toPause); } /// @dev Proves or contests a block transition.