From 24e8196b014487cd645559ae2907b1807047d4ec Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Tue, 2 Apr 2024 23:14:12 +0800 Subject: [PATCH 1/6] fix --- packages/protocol/contracts/bridge/Bridge.sol | 17 +++++++++++++++-- .../contracts/common/EssentialContract.sol | 3 +++ .../contracts/team/TimelockTokenPool.sol | 4 ++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/protocol/contracts/bridge/Bridge.sol b/packages/protocol/contracts/bridge/Bridge.sol index 98f133d8574..a894da57e8b 100644 --- a/packages/protocol/contracts/bridge/Bridge.sol +++ b/packages/protocol/contracts/bridge/Bridge.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import "../common/EssentialContract.sol"; import "../libs/LibAddress.sol"; +import "../libs/LibMath.sol"; import "../signal/ISignalService.sol"; import "./IBridge.sol"; @@ -13,6 +14,7 @@ import "./IBridge.sol"; /// @custom:security-contact security@taiko.xyz contract Bridge is EssentialContract, IBridge { using Address for address; + using LibMath for uint256; using LibAddress for address; using LibAddress for address payable; @@ -207,7 +209,7 @@ contract Bridge is EssentialContract, IBridge { } } - if (block.timestamp >= invocationDelay + receivedAt) { + if (_isPostInvocationDelay(receivedAt, invocationDelay)) { delete proofReceipt[msgHash]; messageStatus[msgHash] = Status.RECALLED; @@ -279,7 +281,7 @@ contract Bridge is EssentialContract, IBridge { } } - if (block.timestamp >= invocationDelay + receivedAt) { + if (_isPostInvocationDelay(receivedAt, invocationDelay)) { // If the gas limit is set to zero, only the owner can process the message. if (_message.gasLimit == 0 && msg.sender != _message.destOwner) { revert B_PERMISSION_DENIED(); @@ -598,4 +600,15 @@ contract Bridge is EssentialContract, IBridge { return false; } } + + function _isPostInvocationDelay( + uint256 _receivedAt, + uint256 _invocationDelay + ) + private + view + returns (bool) + { + return block.timestamp >= _receivedAt.max(lastUnpausedAt) + _invocationDelay; + } } diff --git a/packages/protocol/contracts/common/EssentialContract.sol b/packages/protocol/contracts/common/EssentialContract.sol index f0467bee5be..9acd5bee55f 100644 --- a/packages/protocol/contracts/common/EssentialContract.sol +++ b/packages/protocol/contracts/common/EssentialContract.sol @@ -23,6 +23,8 @@ abstract contract EssentialContract is UUPSUpgradeable, Ownable2StepUpgradeable, uint8 private __paused; + uint64 public lastUnpausedAt; + uint256[49] private __gap; /// @notice Emitted when the contract is paused. @@ -78,6 +80,7 @@ abstract contract EssentialContract is UUPSUpgradeable, Ownable2StepUpgradeable, /// @notice Unpauses the contract. function unpause() public virtual whenPaused { __paused = _FALSE; + lastUnpausedAt = uint64(block.timestamp); emit Unpaused(msg.sender); // We call the authorize function here to avoid: // Warning (5740): Unreachable code. diff --git a/packages/protocol/contracts/team/TimelockTokenPool.sol b/packages/protocol/contracts/team/TimelockTokenPool.sol index 1c28d3bd2b8..6d3ef7d0713 100644 --- a/packages/protocol/contracts/team/TimelockTokenPool.sol +++ b/packages/protocol/contracts/team/TimelockTokenPool.sol @@ -163,14 +163,14 @@ contract TimelockTokenPool is EssentialContract, EIP712Upgradeable { } /// @notice Withdraws all withdrawable tokens. - function withdraw() external nonReentrant { + function withdraw() external nonReentrant whenNotPaused { _withdraw(msg.sender, msg.sender); } /// @notice Withdraws all withdrawable tokens to a designated address. /// @param _to The address where the granted and unlocked tokens shall be sent to. /// @param _sig Signature provided by the grant recipient. - function withdraw(address _to, bytes memory _sig) external nonReentrant { + function withdraw(address _to, bytes memory _sig) external whenNotPaused nonReentrant { if (_to == address(0)) revert INVALID_PARAM(); address recipient = ECDSA.recover(getWithdrawalHash(_to), _sig); _withdraw(recipient, _to); From 5aee40aa6eda01ee5ad57b0d55863087a44f31d8 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Wed, 3 Apr 2024 17:44:04 +0800 Subject: [PATCH 2/6] fmt --- packages/protocol/contracts/bridge/Bridge.sol | 16 +++++++++------- .../contracts/team/TimelockTokenPool.sol | 10 +++++++++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/protocol/contracts/bridge/Bridge.sol b/packages/protocol/contracts/bridge/Bridge.sol index 38f4282362c..acca6bf2fe7 100644 --- a/packages/protocol/contracts/bridge/Bridge.sol +++ b/packages/protocol/contracts/bridge/Bridge.sol @@ -623,7 +623,6 @@ contract Bridge is EssentialContract, IBridge { } } - /// @notice Checks if the signal was received. /// This is the 'readonly' version of _proveSignalReceived. /// @param _signalService The signal service address. @@ -641,7 +640,6 @@ contract Bridge is EssentialContract, IBridge { view returns (bool) { - try ISignalService(_signalService).verifySignalReceived( _chainId, resolve(_chainId, "bridge", false), _signal, _proof ) { @@ -650,11 +648,15 @@ contract Bridge is EssentialContract, IBridge { return false; } } - function _isPostInvocationDelay( + + function _isPostInvocationDelay( uint256 _receivedAt, - uint256 _invocationDelay ) private + uint256 _invocationDelay + ) + private view - returns (bool) { - return block.timestamp >= _receivedAt.max(lastUnpausedAt) + _invocationDelay; - } + returns (bool) + { + return block.timestamp >= _receivedAt.max(lastUnpausedAt) + _invocationDelay; + } } diff --git a/packages/protocol/contracts/team/TimelockTokenPool.sol b/packages/protocol/contracts/team/TimelockTokenPool.sol index 0364fb2fa14..be4d491dbc7 100644 --- a/packages/protocol/contracts/team/TimelockTokenPool.sol +++ b/packages/protocol/contracts/team/TimelockTokenPool.sol @@ -176,7 +176,15 @@ contract TimelockTokenPool is EssentialContract, EIP712Upgradeable { /// @param _to The address where the granted and unlocked tokens shall be sent to. /// @param _nonce The nonce to be used. /// @param _sig Signature provided by the grant recipient. - function withdraw(address _to, uint256 _nonce, bytes memory _sig) external whenNotPaused nonReentrant { + function withdraw( + address _to, + uint256 _nonce, + bytes memory _sig + ) + external + whenNotPaused + nonReentrant + { if (_to == address(0)) revert INVALID_PARAM(); address account = ECDSA.recover(getWithdrawalHash(_to, _nonce), _sig); From f30d3b7c90869283c23b7cdebd8ab9213650d8d0 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Wed, 3 Apr 2024 17:46:54 +0800 Subject: [PATCH 3/6] Update TimelockTokenPool.sol --- packages/protocol/contracts/team/TimelockTokenPool.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/team/TimelockTokenPool.sol b/packages/protocol/contracts/team/TimelockTokenPool.sol index be4d491dbc7..c749de33964 100644 --- a/packages/protocol/contracts/team/TimelockTokenPool.sol +++ b/packages/protocol/contracts/team/TimelockTokenPool.sol @@ -179,7 +179,7 @@ contract TimelockTokenPool is EssentialContract, EIP712Upgradeable { function withdraw( address _to, uint256 _nonce, - bytes memory _sig + bytes calldata _sig ) external whenNotPaused From 854723b1d40f8a3b92b5e77ea8b09c2ce55efcb9 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Wed, 3 Apr 2024 17:47:51 +0800 Subject: [PATCH 4/6] Update Bridge.sol --- packages/protocol/contracts/bridge/Bridge.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/protocol/contracts/bridge/Bridge.sol b/packages/protocol/contracts/bridge/Bridge.sol index acca6bf2fe7..99057cc05ae 100644 --- a/packages/protocol/contracts/bridge/Bridge.sol +++ b/packages/protocol/contracts/bridge/Bridge.sol @@ -657,6 +657,8 @@ contract Bridge is EssentialContract, IBridge { view returns (bool) { - return block.timestamp >= _receivedAt.max(lastUnpausedAt) + _invocationDelay; + unchecked { + return block.timestamp >= _receivedAt.max(lastUnpausedAt) + _invocationDelay; + } } } From 11c8bd6aef34742716e5401ab7f1d3b60a34a2e3 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Wed, 3 Apr 2024 17:48:36 +0800 Subject: [PATCH 5/6] Update LibUtils.sol --- packages/protocol/contracts/L1/libs/LibUtils.sol | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L1/libs/LibUtils.sol b/packages/protocol/contracts/L1/libs/LibUtils.sol index b72bfa7e34d..484e1ae8c15 100644 --- a/packages/protocol/contracts/L1/libs/LibUtils.sol +++ b/packages/protocol/contracts/L1/libs/LibUtils.sol @@ -98,7 +98,9 @@ library LibUtils { view returns (bool) { - uint256 deadline = _tsTimestamp.max(_lastUnpausedAt) + _windowMinutes * 60; - return block.timestamp >= deadline; + unchecked { + uint256 deadline = _tsTimestamp.max(_lastUnpausedAt) + _windowMinutes * 60; + return block.timestamp >= deadline; + } } } From 1b1967621810fd18383f1ebeba43fc9b21b5459f Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Wed, 3 Apr 2024 17:49:28 +0800 Subject: [PATCH 6/6] Update TimelockTokenPool.sol --- packages/protocol/contracts/team/TimelockTokenPool.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/team/TimelockTokenPool.sol b/packages/protocol/contracts/team/TimelockTokenPool.sol index c749de33964..b6a0c37daca 100644 --- a/packages/protocol/contracts/team/TimelockTokenPool.sol +++ b/packages/protocol/contracts/team/TimelockTokenPool.sol @@ -168,7 +168,7 @@ contract TimelockTokenPool is EssentialContract, EIP712Upgradeable { } /// @notice Withdraws all withdrawable tokens. - function withdraw() external nonReentrant whenNotPaused { + function withdraw() external whenNotPaused nonReentrant { _withdraw(msg.sender, msg.sender); }