From abef644fe51598ed7d762a1956ae77543ac30a0a Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 00:35:37 +0800 Subject: [PATCH 01/46] Update TaikoL2.sol --- packages/protocol/contracts/L2/TaikoL2.sol | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index e0d36a4f97c..10afe923c1f 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -11,6 +11,10 @@ import "../signal/ISignalService.sol"; import "./Lib1559Math.sol"; import "./LibL2Config.sol"; +interface ISnapshot { + function snapshot() external returns (uint256); +} + /// @title TaikoL2 /// @notice Taiko L2 is a smart contract that handles cross-layer message /// verification and manages EIP-1559 gas pricing for Layer 2 (L2) operations. @@ -49,6 +53,8 @@ contract TaikoL2 is EssentialContract { /// @notice The L1's chain ID. uint64 public l1ChainId; + uint64 public lastSnapshotL1Block; + uint256[46] private __gap; /// @notice Emitted when the latest L1 block details are anchored to L2. @@ -169,6 +175,11 @@ contract TaikoL2 is EssentialContract { gasExcess = _gasExcess; emit Anchored(_parentHash, _gasExcess); + + if (_l1BlockId % 10_000 == 0) { + // lastSnapshotL1Block = _l1BlockId; + ISnapshot(resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); + } } /// @notice Withdraw token or Ether from this address From 19ceeb42ec3a17e740f6bc56af4c816c2d1d4740 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 00:45:46 +0800 Subject: [PATCH 02/46] more --- packages/protocol/contracts/L1/TaikoData.sol | 11 +++++++++-- packages/protocol/contracts/L1/libs/LibProposing.sol | 7 +++++++ packages/protocol/contracts/L2/TaikoL2.sol | 12 ++++++------ packages/protocol/contracts/common/ISnapshot.sol | 8 ++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 packages/protocol/contracts/common/ISnapshot.sol diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 5280e278a2c..555b2d4e60a 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -153,6 +153,13 @@ library TaikoData { uint64 lastUnpausedAt; } + struct SlotC { + uint64 lastSnapshotIn; + uint64 __reservedC1; + uint64 __reservedC2; + uint64 __reservedC3; + } + /// @dev Struct holding the state variables for the {TaikoL1} contract. struct State { // Ring buffer for proposed blocks and a some recent verified blocks. @@ -164,10 +171,10 @@ library TaikoData { uint64 blockId_mod_blockRingBufferSize => mapping(uint32 transitionId => TransitionState ts) ) transitions; - // Ring buffer for Ether deposits bytes32 __reserve1; SlotA slotA; // slot 5 SlotB slotB; // slot 6 - uint256[44] __gap; + SlotC slotC; // slot 7 + uint256[43] __gap; } } diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 61ad57d6994..157b761d8cf 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../../common/IAddressResolver.sol"; +import "../../common/ISnapshot.sol"; import "../../common/LibStrings.sol"; import "../../libs/LibAddress.sol"; import "../../libs/LibNetwork.sol"; @@ -228,6 +229,12 @@ library LibProposing { meta: meta_, depositsProcessed: deposits_ }); + + // Take a snapshot every week + if (block.number % 50_400 == 0 && _state.slotC.lastSnapshotIn != block.number) { + _state.slotC.lastSnapshotIn = uint64(block.number); + ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); + } } function _isProposerPermitted( diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 10afe923c1f..b26079892a5 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -5,16 +5,13 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../common/EssentialContract.sol"; +import "../common/ISnapshot.sol"; import "../common/LibStrings.sol"; import "../libs/LibAddress.sol"; import "../signal/ISignalService.sol"; import "./Lib1559Math.sol"; import "./LibL2Config.sol"; -interface ISnapshot { - function snapshot() external returns (uint256); -} - /// @title TaikoL2 /// @notice Taiko L2 is a smart contract that handles cross-layer message /// verification and manages EIP-1559 gas pricing for Layer 2 (L2) operations. @@ -55,6 +52,8 @@ contract TaikoL2 is EssentialContract { uint64 public lastSnapshotL1Block; + uint64 private _lastSnapshotIn; + uint256[46] private __gap; /// @notice Emitted when the latest L1 block details are anchored to L2. @@ -176,8 +175,9 @@ contract TaikoL2 is EssentialContract { emit Anchored(_parentHash, _gasExcess); - if (_l1BlockId % 10_000 == 0) { - // lastSnapshotL1Block = _l1BlockId; + // Every week we take a snapshot + if (_l1BlockId % 50_400 == 0 && _lastSnapshotIn != _l1BlockId) { + _lastSnapshotIn = _l1BlockId; ISnapshot(resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); } } diff --git a/packages/protocol/contracts/common/ISnapshot.sol b/packages/protocol/contracts/common/ISnapshot.sol new file mode 100644 index 00000000000..493263a9510 --- /dev/null +++ b/packages/protocol/contracts/common/ISnapshot.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +/// @title ISnapshot + +interface ISnapshot { + function snapshot() external returns (uint256); +} From 665fb1643be56d673a4c90b350744df728d26a5d Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 00:53:51 +0800 Subject: [PATCH 03/46] fix --- packages/protocol/contracts/L1/TaikoToken.sol | 2 +- packages/protocol/contracts/L1/libs/LibProposing.sol | 5 +++-- packages/protocol/contracts/L2/TaikoL2.sol | 6 ++++-- packages/protocol/contracts/tokenvault/BridgedERC20.sol | 9 ++++++--- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoToken.sol b/packages/protocol/contracts/L1/TaikoToken.sol index c02a102351f..81ffd741018 100644 --- a/packages/protocol/contracts/L1/TaikoToken.sol +++ b/packages/protocol/contracts/L1/TaikoToken.sol @@ -53,7 +53,7 @@ contract TaikoToken is EssentialContract, ERC20SnapshotUpgradeable, ERC20VotesUp } /// @notice Creates a new token snapshot. - function snapshot() public onlyFromOwnerOrNamed(LibStrings.B_SNAPSHOOTER) returns (uint256) { + function snapshot() public onlyFromOwnerOrNamed(LibStrings.B_TAIKO) returns (uint256) { return _snapshot(); } diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 157b761d8cf..0a989091ddf 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -231,8 +231,9 @@ library LibProposing { }); // Take a snapshot every week - if (block.number % 50_400 == 0 && _state.slotC.lastSnapshotIn != block.number) { - _state.slotC.lastSnapshotIn = uint64(block.number); + uint256 v = block.number / 50_400; + if (v > _state.slotC.lastSnapshotIn) { + _state.slotC.lastSnapshotIn = uint64(v); ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); } } diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index b26079892a5..d1209b66755 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -176,8 +176,10 @@ contract TaikoL2 is EssentialContract { emit Anchored(_parentHash, _gasExcess); // Every week we take a snapshot - if (_l1BlockId % 50_400 == 0 && _lastSnapshotIn != _l1BlockId) { - _lastSnapshotIn = _l1BlockId; + + uint256 v = _l1BlockId / 50_400; + if (v > _lastSnapshotIn) { + _lastSnapshotIn = uint64(v); ISnapshot(resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); } } diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20.sol b/packages/protocol/contracts/tokenvault/BridgedERC20.sol index 837f5ede72b..a4f77c5d553 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20.sol @@ -33,8 +33,11 @@ contract BridgedERC20 is error BTOKEN_CANNOT_RECEIVE(); error BTOKEN_UNAUTHORIZED(); - modifier onlyOwnerOrSnapshooter() { - if (msg.sender != owner() && msg.sender != snapshooter) { + modifier onlyOwnerOrTaikoOrSnapshooter() { + if ( + msg.sender != owner() && msg.sender != snapshooter + && msg.sender != resolve(LibStrings.B_TAIKO, false) + ) { revert BTOKEN_UNAUTHORIZED(); } _; @@ -81,7 +84,7 @@ contract BridgedERC20 is } /// @notice Creates a new token snapshot. - function snapshot() external onlyOwnerOrSnapshooter returns (uint256) { + function snapshot() external onlyOwnerOrTaikoOrSnapshooter returns (uint256) { return _snapshot(); } From de3c699d96acccec86f557bcf5246b792f9b1938 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 00:56:07 +0800 Subject: [PATCH 04/46] Update TaikoL2.sol --- packages/protocol/contracts/L2/TaikoL2.sol | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index d1209b66755..884effb8245 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -177,10 +177,13 @@ contract TaikoL2 is EssentialContract { // Every week we take a snapshot - uint256 v = _l1BlockId / 50_400; - if (v > _lastSnapshotIn) { - _lastSnapshotIn = uint64(v); - ISnapshot(resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); + address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); + if (taikoToken != address(0)) { + uint256 v = _l1BlockId / 50_400; + if (v > _lastSnapshotIn) { + _lastSnapshotIn = uint64(v); + ISnapshot(taikoToken).snapshot(); + } } } From 2b7e8e55b57a001d83616102d2d31e6aad571036 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 00:59:55 +0800 Subject: [PATCH 05/46] Update TaikoL2.sol --- packages/protocol/contracts/L2/TaikoL2.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 884effb8245..9ab495ca364 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -52,7 +52,7 @@ contract TaikoL2 is EssentialContract { uint64 public lastSnapshotL1Block; - uint64 private _lastSnapshotIn; + uint64 public lastSnapshotIn; uint256[46] private __gap; @@ -180,8 +180,8 @@ contract TaikoL2 is EssentialContract { address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); if (taikoToken != address(0)) { uint256 v = _l1BlockId / 50_400; - if (v > _lastSnapshotIn) { - _lastSnapshotIn = uint64(v); + if (v > lastSnapshotIn) { + lastSnapshotIn = uint64(v); ISnapshot(taikoToken).snapshot(); } } From e266e22b5a690e27a58d09fc0948e9557b24a2d5 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 01:00:19 +0800 Subject: [PATCH 06/46] Update TaikoL2.sol --- packages/protocol/contracts/L2/TaikoL2.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 9ab495ca364..5494ab6cc15 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -175,8 +175,7 @@ contract TaikoL2 is EssentialContract { emit Anchored(_parentHash, _gasExcess); - // Every week we take a snapshot - + // Take a snapshot every week address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); if (taikoToken != address(0)) { uint256 v = _l1BlockId / 50_400; From 4b1faf2d553d54a342587ee48448119f8420154d Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 01:01:17 +0800 Subject: [PATCH 07/46] rename --- packages/protocol/contracts/L1/TaikoData.sol | 2 +- packages/protocol/contracts/L1/libs/LibProposing.sol | 4 ++-- packages/protocol/contracts/L2/TaikoL2.sol | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 555b2d4e60a..642abb11eeb 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -154,7 +154,7 @@ library TaikoData { } struct SlotC { - uint64 lastSnapshotIn; + uint64 lastSnapshot; uint64 __reservedC1; uint64 __reservedC2; uint64 __reservedC3; diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 0a989091ddf..b86d52158b0 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -232,8 +232,8 @@ library LibProposing { // Take a snapshot every week uint256 v = block.number / 50_400; - if (v > _state.slotC.lastSnapshotIn) { - _state.slotC.lastSnapshotIn = uint64(v); + if (v > _state.slotC.lastSnapshot) { + _state.slotC.lastSnapshot = uint64(v); ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); } } diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 5494ab6cc15..7e48fcbc391 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -50,9 +50,8 @@ contract TaikoL2 is EssentialContract { /// @notice The L1's chain ID. uint64 public l1ChainId; - uint64 public lastSnapshotL1Block; - - uint64 public lastSnapshotIn; + /// @notice The last snapshot marker + uint64 public lastSnapshot; uint256[46] private __gap; @@ -179,8 +178,8 @@ contract TaikoL2 is EssentialContract { address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); if (taikoToken != address(0)) { uint256 v = _l1BlockId / 50_400; - if (v > lastSnapshotIn) { - lastSnapshotIn = uint64(v); + if (v > lastSnapshot) { + lastSnapshot = uint64(v); ISnapshot(taikoToken).snapshot(); } } From 2f810e1fdcc3b1a2e73d0336e8b6e7cc72506fa5 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 01:02:07 +0800 Subject: [PATCH 08/46] Update ISnapshot.sol --- packages/protocol/contracts/common/ISnapshot.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/common/ISnapshot.sol b/packages/protocol/contracts/common/ISnapshot.sol index 493263a9510..ac7656f8c36 100644 --- a/packages/protocol/contracts/common/ISnapshot.sol +++ b/packages/protocol/contracts/common/ISnapshot.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.24; /// @title ISnapshot - +/// @custom:security-contact security@taiko.xyz interface ISnapshot { function snapshot() external returns (uint256); } From f72055b50ade04641fd39b129ccbd82252bfe626 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 11:22:02 +0800 Subject: [PATCH 09/46] more --- packages/protocol/contracts/L1/TaikoToken.sol | 6 +++--- packages/protocol/contracts/tokenvault/BridgedERC20.sol | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoToken.sol b/packages/protocol/contracts/L1/TaikoToken.sol index 81ffd741018..a27aafaa835 100644 --- a/packages/protocol/contracts/L1/TaikoToken.sol +++ b/packages/protocol/contracts/L1/TaikoToken.sol @@ -31,7 +31,7 @@ contract TaikoToken is EssentialContract, ERC20SnapshotUpgradeable, ERC20VotesUp address _recipient, address _addressManager ) - public + external initializer { __Essential_init(_owner, _addressManager); @@ -48,12 +48,12 @@ contract TaikoToken is EssentialContract, ERC20SnapshotUpgradeable, ERC20VotesUp /// @notice Burns tokens from the specified address. /// @param _from The address to burn tokens from. /// @param _amount The amount of tokens to burn. - function burn(address _from, uint256 _amount) public onlyOwner { + function burn(address _from, uint256 _amount) external onlyOwner { return _burn(_from, _amount); } /// @notice Creates a new token snapshot. - function snapshot() public onlyFromOwnerOrNamed(LibStrings.B_TAIKO) returns (uint256) { + function snapshot() external onlyFromOwnerOrNamed(LibStrings.B_TAIKO) returns (uint256) { return _snapshot(); } diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20.sol b/packages/protocol/contracts/tokenvault/BridgedERC20.sol index a4f77c5d553..bd6a203094d 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20.sol @@ -36,7 +36,7 @@ contract BridgedERC20 is modifier onlyOwnerOrTaikoOrSnapshooter() { if ( msg.sender != owner() && msg.sender != snapshooter - && msg.sender != resolve(LibStrings.B_TAIKO, false) + && msg.sender != resolve(LibStrings.B_TAIKO, true) ) { revert BTOKEN_UNAUTHORIZED(); } From 50daa6907050a759a6fc74df57bfa78b825fdc80 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 14:01:17 +0800 Subject: [PATCH 10/46] comment --- packages/protocol/contracts/L1/libs/LibProposing.sol | 2 +- packages/protocol/contracts/L2/TaikoL2.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index b86d52158b0..477d892618c 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -230,7 +230,7 @@ library LibProposing { depositsProcessed: deposits_ }); - // Take a snapshot every week + // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. uint256 v = block.number / 50_400; if (v > _state.slotC.lastSnapshot) { _state.slotC.lastSnapshot = uint64(v); diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 7e48fcbc391..a2aad4ce9a2 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -174,7 +174,7 @@ contract TaikoL2 is EssentialContract { emit Anchored(_parentHash, _gasExcess); - // Take a snapshot every week + // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); if (taikoToken != address(0)) { uint256 v = _l1BlockId / 50_400; From 0512cb3eba842bd09ecbbda66d5babab69666ecd Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 14:07:34 +0800 Subject: [PATCH 11/46] more --- packages/protocol/contracts/L1/TaikoToken.sol | 2 +- packages/protocol/contracts/tokenvault/BridgedERC20.sol | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoToken.sol b/packages/protocol/contracts/L1/TaikoToken.sol index a27aafaa835..e5b462b399c 100644 --- a/packages/protocol/contracts/L1/TaikoToken.sol +++ b/packages/protocol/contracts/L1/TaikoToken.sol @@ -53,7 +53,7 @@ contract TaikoToken is EssentialContract, ERC20SnapshotUpgradeable, ERC20VotesUp } /// @notice Creates a new token snapshot. - function snapshot() external onlyFromOwnerOrNamed(LibStrings.B_TAIKO) returns (uint256) { + function snapshot() external onlyFromNamed(LibStrings.B_TAIKO) returns (uint256) { return _snapshot(); } diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20.sol b/packages/protocol/contracts/tokenvault/BridgedERC20.sol index bd6a203094d..5f005d3415a 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20.sol @@ -33,11 +33,8 @@ contract BridgedERC20 is error BTOKEN_CANNOT_RECEIVE(); error BTOKEN_UNAUTHORIZED(); - modifier onlyOwnerOrTaikoOrSnapshooter() { - if ( - msg.sender != owner() && msg.sender != snapshooter - && msg.sender != resolve(LibStrings.B_TAIKO, true) - ) { + modifier onlyTaikoOrSnapshooter() { + if (msg.sender != snapshooter && msg.sender != resolve(LibStrings.B_TAIKO, true)) { revert BTOKEN_UNAUTHORIZED(); } _; @@ -84,7 +81,7 @@ contract BridgedERC20 is } /// @notice Creates a new token snapshot. - function snapshot() external onlyOwnerOrTaikoOrSnapshooter returns (uint256) { + function snapshot() external onlyTaikoOrSnapshooter returns (uint256) { return _snapshot(); } From 5372314f16858666a8df1745ebbf3d282c0d9954 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 14:12:06 +0800 Subject: [PATCH 12/46] Revert "more" This reverts commit 0512cb3eba842bd09ecbbda66d5babab69666ecd. --- packages/protocol/contracts/L1/TaikoToken.sol | 2 +- packages/protocol/contracts/tokenvault/BridgedERC20.sol | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoToken.sol b/packages/protocol/contracts/L1/TaikoToken.sol index e5b462b399c..a27aafaa835 100644 --- a/packages/protocol/contracts/L1/TaikoToken.sol +++ b/packages/protocol/contracts/L1/TaikoToken.sol @@ -53,7 +53,7 @@ contract TaikoToken is EssentialContract, ERC20SnapshotUpgradeable, ERC20VotesUp } /// @notice Creates a new token snapshot. - function snapshot() external onlyFromNamed(LibStrings.B_TAIKO) returns (uint256) { + function snapshot() external onlyFromOwnerOrNamed(LibStrings.B_TAIKO) returns (uint256) { return _snapshot(); } diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20.sol b/packages/protocol/contracts/tokenvault/BridgedERC20.sol index 5f005d3415a..bd6a203094d 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20.sol @@ -33,8 +33,11 @@ contract BridgedERC20 is error BTOKEN_CANNOT_RECEIVE(); error BTOKEN_UNAUTHORIZED(); - modifier onlyTaikoOrSnapshooter() { - if (msg.sender != snapshooter && msg.sender != resolve(LibStrings.B_TAIKO, true)) { + modifier onlyOwnerOrTaikoOrSnapshooter() { + if ( + msg.sender != owner() && msg.sender != snapshooter + && msg.sender != resolve(LibStrings.B_TAIKO, true) + ) { revert BTOKEN_UNAUTHORIZED(); } _; @@ -81,7 +84,7 @@ contract BridgedERC20 is } /// @notice Creates a new token snapshot. - function snapshot() external onlyTaikoOrSnapshooter returns (uint256) { + function snapshot() external onlyOwnerOrTaikoOrSnapshooter returns (uint256) { return _snapshot(); } From fa95bda85a12b73ffe7dcc2b812892cd4581bf6e Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 14:23:01 +0800 Subject: [PATCH 13/46] Update TaikoL2.sol --- packages/protocol/contracts/L2/TaikoL2.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index a2aad4ce9a2..5ff1f92eee1 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -109,6 +109,7 @@ contract TaikoL2 is EssentialContract { /// @notice Anchors the latest L1 block details to L2 for cross-layer /// message verification. + /// @dev The gas limit for this transaction is set to 250K in geth and raiko. /// @dev This function can be called freely as the golden touch private key is publicly known, /// but the Taiko node guarantees the first transaction of each block is always this anchor /// transaction, and any subsequent calls will revert with L2_PUBLIC_INPUT_HASH_MISMATCH. From fa9bbaa49253d12d9aa8fa6019ed7077990dbfdf Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 17:19:48 +0800 Subject: [PATCH 14/46] rename --- packages/protocol/contracts/L1/TaikoData.sol | 2 +- packages/protocol/contracts/L1/libs/LibProposing.sol | 4 ++-- packages/protocol/contracts/L2/TaikoL2.sol | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 642abb11eeb..476cd85269d 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -154,7 +154,7 @@ library TaikoData { } struct SlotC { - uint64 lastSnapshot; + uint64 lastSnapshotIndex; uint64 __reservedC1; uint64 __reservedC2; uint64 __reservedC3; diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 477d892618c..67cdd74866b 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -232,8 +232,8 @@ library LibProposing { // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. uint256 v = block.number / 50_400; - if (v > _state.slotC.lastSnapshot) { - _state.slotC.lastSnapshot = uint64(v); + if (v > _state.slotC.lastSnapshotIndex) { + _state.slotC.lastSnapshotIndex = uint64(v); ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); } } diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 5ff1f92eee1..8f4f68fcbc7 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -51,7 +51,7 @@ contract TaikoL2 is EssentialContract { uint64 public l1ChainId; /// @notice The last snapshot marker - uint64 public lastSnapshot; + uint64 public lastSnapshotIndex; uint256[46] private __gap; @@ -179,8 +179,8 @@ contract TaikoL2 is EssentialContract { address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); if (taikoToken != address(0)) { uint256 v = _l1BlockId / 50_400; - if (v > lastSnapshot) { - lastSnapshot = uint64(v); + if (v > lastSnapshotIndex) { + lastSnapshotIndex = uint64(v); ISnapshot(taikoToken).snapshot(); } } From 62f5a2612f8bc80a2e86efb004a13d4632a68b85 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 17:28:14 +0800 Subject: [PATCH 15/46] more --- packages/protocol/contracts/L1/TaikoData.sol | 2 ++ packages/protocol/contracts/L1/TaikoL1.sol | 3 ++- packages/protocol/contracts/L1/libs/LibProposing.sol | 10 ++++++---- packages/protocol/contracts/L2/TaikoL2.sol | 8 ++++++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 476cd85269d..6a03a8c00b2 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -35,6 +35,8 @@ library TaikoData { // The max number of L2 blocks that can stay unsynced on L1 (a value of zero disables // syncing) uint8 blockSyncThreshold; + // The number of L1 blocks after which a TKO snapshot should be taken. + uint32 tkoSnapshotPeriod; } /// @dev Struct representing prover fees per given tier diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index ac450b627c5..b7705e69f75 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -215,7 +215,8 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { // Taiko blocks proposed per Ethereum block is smaller than 1. blockMaxGasLimit: 240_000_000, livenessBond: 250e18, // 250 Taiko token - blockSyncThreshold: 16 + blockSyncThreshold: 16, + tkoSnapshotPeriod: 50_400 }); } diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 67cdd74866b..de812b7b91c 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -231,10 +231,12 @@ library LibProposing { }); // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. - uint256 v = block.number / 50_400; - if (v > _state.slotC.lastSnapshotIndex) { - _state.slotC.lastSnapshotIndex = uint64(v); - ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); + if (_config.tkoSnapshotPeriod != 0) { + uint256 v = block.number / _config.tkoSnapshotPeriod; + if (v != _state.slotC.lastSnapshotIndex) { + _state.slotC.lastSnapshotIndex = uint64(v); + ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); + } } } diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 8f4f68fcbc7..671b3c0a6cd 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -23,6 +23,10 @@ contract TaikoL2 is EssentialContract { using LibAddress for address; using SafeERC20 for IERC20; + /// @notice The number of L1 blocks after which a TKO snapshot should be taken. + /// This number must be the same as L1's tkoSnapshotPeriod value. + uint256 public constant TAIKO_TOKEN_SNAPSHOT_PERIOD = 50_400; + /// @notice Golden touch address is the only address that can do the anchor transaction. address public constant GOLDEN_TOUCH_ADDRESS = 0x0000777735367b36bC9B61C50022d9D0700dB4Ec; @@ -178,8 +182,8 @@ contract TaikoL2 is EssentialContract { // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); if (taikoToken != address(0)) { - uint256 v = _l1BlockId / 50_400; - if (v > lastSnapshotIndex) { + uint256 v = _l1BlockId / TAIKO_TOKEN_SNAPSHOT_PERIOD; + if (v != lastSnapshotIndex) { lastSnapshotIndex = uint64(v); ISnapshot(taikoToken).snapshot(); } From b1772e93ca9a1f9256fd2069947e000442536a6d Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 17:29:25 +0800 Subject: [PATCH 16/46] Update TaikoToken.sol --- packages/protocol/contracts/L1/TaikoToken.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoToken.sol b/packages/protocol/contracts/L1/TaikoToken.sol index a27aafaa835..81ffd741018 100644 --- a/packages/protocol/contracts/L1/TaikoToken.sol +++ b/packages/protocol/contracts/L1/TaikoToken.sol @@ -31,7 +31,7 @@ contract TaikoToken is EssentialContract, ERC20SnapshotUpgradeable, ERC20VotesUp address _recipient, address _addressManager ) - external + public initializer { __Essential_init(_owner, _addressManager); @@ -48,12 +48,12 @@ contract TaikoToken is EssentialContract, ERC20SnapshotUpgradeable, ERC20VotesUp /// @notice Burns tokens from the specified address. /// @param _from The address to burn tokens from. /// @param _amount The amount of tokens to burn. - function burn(address _from, uint256 _amount) external onlyOwner { + function burn(address _from, uint256 _amount) public onlyOwner { return _burn(_from, _amount); } /// @notice Creates a new token snapshot. - function snapshot() external onlyFromOwnerOrNamed(LibStrings.B_TAIKO) returns (uint256) { + function snapshot() public onlyFromOwnerOrNamed(LibStrings.B_TAIKO) returns (uint256) { return _snapshot(); } From 6d899ba9ca7bbcaa228a5b6c1456113254e094c9 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 17:30:02 +0800 Subject: [PATCH 17/46] Update LibStrings.sol --- packages/protocol/contracts/common/LibStrings.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/protocol/contracts/common/LibStrings.sol b/packages/protocol/contracts/common/LibStrings.sol index 2467e8f2177..16a05bf8826 100644 --- a/packages/protocol/contracts/common/LibStrings.sol +++ b/packages/protocol/contracts/common/LibStrings.sol @@ -7,9 +7,6 @@ library LibStrings { /// @notice bytes32 representation of the string "chain_pauser". bytes32 internal constant B_CHAIN_PAUSER = bytes32("chain_pauser"); - /// @notice bytes32 representation of the string "snapshooter". - bytes32 internal constant B_SNAPSHOOTER = bytes32("snapshooter"); - /// @notice bytes32 representation of the string "withdrawer". bytes32 internal constant B_WITHDRAWER = bytes32("withdrawer"); From d97267d1019ca3a62587abb945af12b6d8729443 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 17:31:03 +0800 Subject: [PATCH 18/46] Update TaikoL2.sol --- packages/protocol/contracts/L2/TaikoL2.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 671b3c0a6cd..163ce8c13eb 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -52,6 +52,7 @@ contract TaikoL2 is EssentialContract { uint64 private __currentBlockTimestamp; /// @notice The L1's chain ID. + /// @dev Slot 4. uint64 public l1ChainId; /// @notice The last snapshot marker From 8a0d80b37af475d8d03a87bb292143ae8b5c0b29 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 17:32:15 +0800 Subject: [PATCH 19/46] rename --- packages/protocol/contracts/L1/TaikoData.sol | 2 +- packages/protocol/contracts/L1/TaikoL1.sol | 2 +- packages/protocol/contracts/L1/libs/LibProposing.sol | 4 ++-- packages/protocol/contracts/L2/TaikoL2.sol | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 6a03a8c00b2..402ff7c92c7 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -36,7 +36,7 @@ library TaikoData { // syncing) uint8 blockSyncThreshold; // The number of L1 blocks after which a TKO snapshot should be taken. - uint32 tkoSnapshotPeriod; + uint32 tkoSnapshotInterval; } /// @dev Struct representing prover fees per given tier diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index b7705e69f75..7e81508ef97 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -216,7 +216,7 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { blockMaxGasLimit: 240_000_000, livenessBond: 250e18, // 250 Taiko token blockSyncThreshold: 16, - tkoSnapshotPeriod: 50_400 + tkoSnapshotInterval: 50_400 }); } diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index de812b7b91c..2494286c631 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -231,8 +231,8 @@ library LibProposing { }); // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. - if (_config.tkoSnapshotPeriod != 0) { - uint256 v = block.number / _config.tkoSnapshotPeriod; + if (_config.tkoSnapshotInterval != 0) { + uint256 v = block.number / _config.tkoSnapshotInterval; if (v != _state.slotC.lastSnapshotIndex) { _state.slotC.lastSnapshotIndex = uint64(v); ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 163ce8c13eb..e5498829455 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -24,8 +24,8 @@ contract TaikoL2 is EssentialContract { using SafeERC20 for IERC20; /// @notice The number of L1 blocks after which a TKO snapshot should be taken. - /// This number must be the same as L1's tkoSnapshotPeriod value. - uint256 public constant TAIKO_TOKEN_SNAPSHOT_PERIOD = 50_400; + /// This number must be the same as L1's tkoSnapshotInterval value. + uint256 public constant TAIKO_TOKEN_SNAPSHOT_INTERVAL = 50_400; /// @notice Golden touch address is the only address that can do the anchor transaction. address public constant GOLDEN_TOUCH_ADDRESS = 0x0000777735367b36bC9B61C50022d9D0700dB4Ec; @@ -183,7 +183,7 @@ contract TaikoL2 is EssentialContract { // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); if (taikoToken != address(0)) { - uint256 v = _l1BlockId / TAIKO_TOKEN_SNAPSHOT_PERIOD; + uint256 v = _l1BlockId / TAIKO_TOKEN_SNAPSHOT_INTERVAL; if (v != lastSnapshotIndex) { lastSnapshotIndex = uint64(v); ISnapshot(taikoToken).snapshot(); From cfa6dfe71135d05575a7dc375dc3f45edd2a73b5 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 12 Apr 2024 17:33:41 +0800 Subject: [PATCH 20/46] Update BridgedERC20.sol --- packages/protocol/contracts/tokenvault/BridgedERC20.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20.sol b/packages/protocol/contracts/tokenvault/BridgedERC20.sol index bd6a203094d..3a136098802 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20.sol @@ -33,7 +33,7 @@ contract BridgedERC20 is error BTOKEN_CANNOT_RECEIVE(); error BTOKEN_UNAUTHORIZED(); - modifier onlyOwnerOrTaikoOrSnapshooter() { + modifier onlyAuthorizedForSnapshot() { if ( msg.sender != owner() && msg.sender != snapshooter && msg.sender != resolve(LibStrings.B_TAIKO, true) @@ -84,7 +84,7 @@ contract BridgedERC20 is } /// @notice Creates a new token snapshot. - function snapshot() external onlyOwnerOrTaikoOrSnapshooter returns (uint256) { + function snapshot() external onlyAuthorizedForSnapshot returns (uint256) { return _snapshot(); } From 340e46a647c8d7a0f5586f5bb6c1f26b28fa668b Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 04:34:51 +0800 Subject: [PATCH 21/46] Revert "rename" This reverts commit 8a0d80b37af475d8d03a87bb292143ae8b5c0b29. --- packages/protocol/contracts/L1/TaikoData.sol | 2 +- packages/protocol/contracts/L1/TaikoL1.sol | 2 +- packages/protocol/contracts/L1/libs/LibProposing.sol | 4 ++-- packages/protocol/contracts/L2/TaikoL2.sol | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 402ff7c92c7..6a03a8c00b2 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -36,7 +36,7 @@ library TaikoData { // syncing) uint8 blockSyncThreshold; // The number of L1 blocks after which a TKO snapshot should be taken. - uint32 tkoSnapshotInterval; + uint32 tkoSnapshotPeriod; } /// @dev Struct representing prover fees per given tier diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index 7e81508ef97..b7705e69f75 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -216,7 +216,7 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { blockMaxGasLimit: 240_000_000, livenessBond: 250e18, // 250 Taiko token blockSyncThreshold: 16, - tkoSnapshotInterval: 50_400 + tkoSnapshotPeriod: 50_400 }); } diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 2494286c631..de812b7b91c 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -231,8 +231,8 @@ library LibProposing { }); // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. - if (_config.tkoSnapshotInterval != 0) { - uint256 v = block.number / _config.tkoSnapshotInterval; + if (_config.tkoSnapshotPeriod != 0) { + uint256 v = block.number / _config.tkoSnapshotPeriod; if (v != _state.slotC.lastSnapshotIndex) { _state.slotC.lastSnapshotIndex = uint64(v); ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index e5498829455..163ce8c13eb 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -24,8 +24,8 @@ contract TaikoL2 is EssentialContract { using SafeERC20 for IERC20; /// @notice The number of L1 blocks after which a TKO snapshot should be taken. - /// This number must be the same as L1's tkoSnapshotInterval value. - uint256 public constant TAIKO_TOKEN_SNAPSHOT_INTERVAL = 50_400; + /// This number must be the same as L1's tkoSnapshotPeriod value. + uint256 public constant TAIKO_TOKEN_SNAPSHOT_PERIOD = 50_400; /// @notice Golden touch address is the only address that can do the anchor transaction. address public constant GOLDEN_TOUCH_ADDRESS = 0x0000777735367b36bC9B61C50022d9D0700dB4Ec; @@ -183,7 +183,7 @@ contract TaikoL2 is EssentialContract { // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); if (taikoToken != address(0)) { - uint256 v = _l1BlockId / TAIKO_TOKEN_SNAPSHOT_INTERVAL; + uint256 v = _l1BlockId / TAIKO_TOKEN_SNAPSHOT_PERIOD; if (v != lastSnapshotIndex) { lastSnapshotIndex = uint64(v); ISnapshot(taikoToken).snapshot(); From a5aa52df8b9dc99950ef4102e0bd2d26eaae5dd5 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 04:35:33 +0800 Subject: [PATCH 22/46] Revert "more" This reverts commit 62f5a2612f8bc80a2e86efb004a13d4632a68b85. --- packages/protocol/contracts/L1/TaikoData.sol | 2 -- packages/protocol/contracts/L1/TaikoL1.sol | 3 +-- packages/protocol/contracts/L1/libs/LibProposing.sol | 10 ++++------ packages/protocol/contracts/L2/TaikoL2.sol | 8 ++------ 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 6a03a8c00b2..476cd85269d 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -35,8 +35,6 @@ library TaikoData { // The max number of L2 blocks that can stay unsynced on L1 (a value of zero disables // syncing) uint8 blockSyncThreshold; - // The number of L1 blocks after which a TKO snapshot should be taken. - uint32 tkoSnapshotPeriod; } /// @dev Struct representing prover fees per given tier diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index b7705e69f75..ac450b627c5 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -215,8 +215,7 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { // Taiko blocks proposed per Ethereum block is smaller than 1. blockMaxGasLimit: 240_000_000, livenessBond: 250e18, // 250 Taiko token - blockSyncThreshold: 16, - tkoSnapshotPeriod: 50_400 + blockSyncThreshold: 16 }); } diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index de812b7b91c..67cdd74866b 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -231,12 +231,10 @@ library LibProposing { }); // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. - if (_config.tkoSnapshotPeriod != 0) { - uint256 v = block.number / _config.tkoSnapshotPeriod; - if (v != _state.slotC.lastSnapshotIndex) { - _state.slotC.lastSnapshotIndex = uint64(v); - ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); - } + uint256 v = block.number / 50_400; + if (v > _state.slotC.lastSnapshotIndex) { + _state.slotC.lastSnapshotIndex = uint64(v); + ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); } } diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 163ce8c13eb..25ff15fbce8 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -23,10 +23,6 @@ contract TaikoL2 is EssentialContract { using LibAddress for address; using SafeERC20 for IERC20; - /// @notice The number of L1 blocks after which a TKO snapshot should be taken. - /// This number must be the same as L1's tkoSnapshotPeriod value. - uint256 public constant TAIKO_TOKEN_SNAPSHOT_PERIOD = 50_400; - /// @notice Golden touch address is the only address that can do the anchor transaction. address public constant GOLDEN_TOUCH_ADDRESS = 0x0000777735367b36bC9B61C50022d9D0700dB4Ec; @@ -183,8 +179,8 @@ contract TaikoL2 is EssentialContract { // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); if (taikoToken != address(0)) { - uint256 v = _l1BlockId / TAIKO_TOKEN_SNAPSHOT_PERIOD; - if (v != lastSnapshotIndex) { + uint256 v = _l1BlockId / 50_400; + if (v > lastSnapshotIndex) { lastSnapshotIndex = uint64(v); ISnapshot(taikoToken).snapshot(); } From 766c9e97251426ddc0e0f1beef29f0c58122ce06 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 04:44:08 +0800 Subject: [PATCH 23/46] more --- packages/protocol/contracts/L1/TaikoData.sol | 10 +-------- .../protocol/contracts/L1/TaikoEvents.sol | 4 ++++ .../contracts/L1/libs/LibProposing.sol | 13 +++++++----- packages/protocol/contracts/L2/TaikoL2.sol | 21 ++++++++++--------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 476cd85269d..4079dae2387 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -153,13 +153,6 @@ library TaikoData { uint64 lastUnpausedAt; } - struct SlotC { - uint64 lastSnapshotIndex; - uint64 __reservedC1; - uint64 __reservedC2; - uint64 __reservedC3; - } - /// @dev Struct holding the state variables for the {TaikoL1} contract. struct State { // Ring buffer for proposed blocks and a some recent verified blocks. @@ -174,7 +167,6 @@ library TaikoData { bytes32 __reserve1; SlotA slotA; // slot 5 SlotB slotB; // slot 6 - SlotC slotC; // slot 7 - uint256[43] __gap; + uint256[44] __gap; } } diff --git a/packages/protocol/contracts/L1/TaikoEvents.sol b/packages/protocol/contracts/L1/TaikoEvents.sol index 60b877443e8..2dde4534a08 100644 --- a/packages/protocol/contracts/L1/TaikoEvents.sol +++ b/packages/protocol/contracts/L1/TaikoEvents.sol @@ -45,6 +45,10 @@ abstract contract TaikoEvents { /// @param slotB The SlotB data structure. event StateVariablesUpdated(TaikoData.SlotB slotB); + /// @notice Emitted when the Taiko token snapshot is taken. + /// @param id The snapshot id. + event TaikoTokenSnapshotTaken(uint256 id); + /// @dev Emitted when a block transition is proved or re-proved. /// @param blockId The ID of the proven block. /// @param tran The verified transition. diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 67cdd74866b..c4b2774119c 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -37,6 +37,10 @@ library LibProposing { TaikoData.EthDeposit[] depositsProcessed ); + /// @notice Emitted when the Taiko token snapshot is taken. + /// @param id The snapshot id. + event TaikoTokenSnapshotTaken(uint256 id); + // Warning: Any errors defined here must also be defined in TaikoErrors.sol. error L1_BLOB_NOT_AVAILABLE(); error L1_BLOB_NOT_FOUND(); @@ -230,11 +234,10 @@ library LibProposing { depositsProcessed: deposits_ }); - // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. - uint256 v = block.number / 50_400; - if (v > _state.slotC.lastSnapshotIndex) { - _state.slotC.lastSnapshotIndex = uint64(v); - ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); + // Take a snapshot every 100,000 L1 blocks which is roughly 13 days and 21 hours. + if (block.number % 100_000 == 0) { + uint256 id = ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); + emit TaikoTokenSnapshotTaken(id); } } diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 25ff15fbce8..8672e26a67d 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -51,9 +51,6 @@ contract TaikoL2 is EssentialContract { /// @dev Slot 4. uint64 public l1ChainId; - /// @notice The last snapshot marker - uint64 public lastSnapshotIndex; - uint256[46] private __gap; /// @notice Emitted when the latest L1 block details are anchored to L2. @@ -61,6 +58,11 @@ contract TaikoL2 is EssentialContract { /// @param gasExcess The gas excess value used to calculate the base fee. event Anchored(bytes32 parentHash, uint64 gasExcess); + /// @notice Emitted when the Taiko token snapshot is taken. + /// @param tkoAddress The Taiko token address. + /// @param id The snapshot id. + event TaikoTokenSnapshotTaken(address tkoAddress, uint256 id); + error L2_BASEFEE_MISMATCH(); error L2_INVALID_L1_CHAIN_ID(); error L2_INVALID_L2_CHAIN_ID(); @@ -176,13 +178,12 @@ contract TaikoL2 is EssentialContract { emit Anchored(_parentHash, _gasExcess); - // Take a snapshot every week - Ethereum will have ~50_400 blocks each week. - address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); - if (taikoToken != address(0)) { - uint256 v = _l1BlockId / 50_400; - if (v > lastSnapshotIndex) { - lastSnapshotIndex = uint64(v); - ISnapshot(taikoToken).snapshot(); + // Take a snapshot every 100,000 L1 blocks which is roughly 13 days and 21 hours. + if (_l1BlockId % 100_000 == 0) { + address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); + if (taikoToken != address(0)) { + uint256 id = ISnapshot(taikoToken).snapshot(); + emit TaikoTokenSnapshotTaken(taikoToken, id); } } } From 0985d86dbf4daa81560a712b4301cb7e7acef299 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 04:52:35 +0800 Subject: [PATCH 24/46] more --- .../protocol/contracts/L1/TaikoEvents.sol | 3 +- .../contracts/L1/libs/LibProposing.sol | 13 ++------- packages/protocol/contracts/L2/TaikoL2.sol | 12 ++------ .../protocol/contracts/common/ISnapshot.sol | 8 ----- .../contracts/common/LibAutoSnapshot.sol | 29 +++++++++++++++++++ 5 files changed, 35 insertions(+), 30 deletions(-) delete mode 100644 packages/protocol/contracts/common/ISnapshot.sol create mode 100644 packages/protocol/contracts/common/LibAutoSnapshot.sol diff --git a/packages/protocol/contracts/L1/TaikoEvents.sol b/packages/protocol/contracts/L1/TaikoEvents.sol index 2dde4534a08..022ea463f6a 100644 --- a/packages/protocol/contracts/L1/TaikoEvents.sol +++ b/packages/protocol/contracts/L1/TaikoEvents.sol @@ -46,8 +46,9 @@ abstract contract TaikoEvents { event StateVariablesUpdated(TaikoData.SlotB slotB); /// @notice Emitted when the Taiko token snapshot is taken. + /// @param tkoAddress The Taiko token address. /// @param id The snapshot id. - event TaikoTokenSnapshotTaken(uint256 id); + event TaikoTokenSnapshotTaken(address tkoAddress, uint256 id); /// @dev Emitted when a block transition is proved or re-proved. /// @param blockId The ID of the proven block. diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index c4b2774119c..fa49b5f6ed8 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -4,8 +4,7 @@ pragma solidity 0.8.24; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../../common/IAddressResolver.sol"; -import "../../common/ISnapshot.sol"; -import "../../common/LibStrings.sol"; +import "../../common/LibAutoSnapshot.sol"; import "../../libs/LibAddress.sol"; import "../../libs/LibNetwork.sol"; import "../hooks/IHook.sol"; @@ -37,10 +36,6 @@ library LibProposing { TaikoData.EthDeposit[] depositsProcessed ); - /// @notice Emitted when the Taiko token snapshot is taken. - /// @param id The snapshot id. - event TaikoTokenSnapshotTaken(uint256 id); - // Warning: Any errors defined here must also be defined in TaikoErrors.sol. error L1_BLOB_NOT_AVAILABLE(); error L1_BLOB_NOT_FOUND(); @@ -234,11 +229,7 @@ library LibProposing { depositsProcessed: deposits_ }); - // Take a snapshot every 100,000 L1 blocks which is roughly 13 days and 21 hours. - if (block.number % 100_000 == 0) { - uint256 id = ISnapshot(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)).snapshot(); - emit TaikoTokenSnapshotTaken(id); - } + LibAutoSnapshot.autoSnapshot(_resolver, block.number); } function _isProposerPermitted( diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 8672e26a67d..460a389e403 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -5,8 +5,7 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../common/EssentialContract.sol"; -import "../common/ISnapshot.sol"; -import "../common/LibStrings.sol"; +import "../common/LibAutoSnapshot.sol"; import "../libs/LibAddress.sol"; import "../signal/ISignalService.sol"; import "./Lib1559Math.sol"; @@ -178,14 +177,7 @@ contract TaikoL2 is EssentialContract { emit Anchored(_parentHash, _gasExcess); - // Take a snapshot every 100,000 L1 blocks which is roughly 13 days and 21 hours. - if (_l1BlockId % 100_000 == 0) { - address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); - if (taikoToken != address(0)) { - uint256 id = ISnapshot(taikoToken).snapshot(); - emit TaikoTokenSnapshotTaken(taikoToken, id); - } - } + LibAutoSnapshot.autoSnapshot(this, _l1BlockId); } /// @notice Withdraw token or Ether from this address diff --git a/packages/protocol/contracts/common/ISnapshot.sol b/packages/protocol/contracts/common/ISnapshot.sol deleted file mode 100644 index ac7656f8c36..00000000000 --- a/packages/protocol/contracts/common/ISnapshot.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -/// @title ISnapshot -/// @custom:security-contact security@taiko.xyz -interface ISnapshot { - function snapshot() external returns (uint256); -} diff --git a/packages/protocol/contracts/common/LibAutoSnapshot.sol b/packages/protocol/contracts/common/LibAutoSnapshot.sol new file mode 100644 index 00000000000..10150f2a9e9 --- /dev/null +++ b/packages/protocol/contracts/common/LibAutoSnapshot.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import "./IAddressResolver.sol"; +import "./LibStrings.sol"; + +/// @title ISnapshot +/// @custom:security-contact security@taiko.xyz +interface ISnapshot { + function snapshot() external returns (uint256); +} + +library LibAutoSnapshot { + /// @notice Emitted when the Taiko token snapshot is taken. + /// @param tkoAddress The Taiko token address. + /// @param id The snapshot id. + event TaikoTokenSnapshotTaken(address tkoAddress, uint256 id); + + // Take a snapshot every 100,000 L1 blocks which is roughly 13 days and 21 hours. + function autoSnapshot(IAddressResolver _resolver, uint256 _blockId) internal { + if (_blockId % 100_000 != 0) return; + + address taikoToken = _resolver.resolve(LibStrings.B_TAIKO_TOKEN, true); + if (taikoToken != address(0)) { + uint256 id = ISnapshot(taikoToken).snapshot(); + emit TaikoTokenSnapshotTaken(taikoToken, id); + } + } +} From 62bbe06ecd37ebcaf46cc15985c68c83775d0366 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 04:54:25 +0800 Subject: [PATCH 25/46] Update LibAutoSnapshot.sol --- packages/protocol/contracts/common/LibAutoSnapshot.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/common/LibAutoSnapshot.sol b/packages/protocol/contracts/common/LibAutoSnapshot.sol index 10150f2a9e9..a5ce72518e0 100644 --- a/packages/protocol/contracts/common/LibAutoSnapshot.sol +++ b/packages/protocol/contracts/common/LibAutoSnapshot.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.24; import "./IAddressResolver.sol"; import "./LibStrings.sol"; -/// @title ISnapshot +/// @title LibAutoSnapshot /// @custom:security-contact security@taiko.xyz interface ISnapshot { function snapshot() external returns (uint256); From 633f91307a5156b25097a65b468f7221c3bac76a Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 05:03:06 +0800 Subject: [PATCH 26/46] Update LibAutoSnapshot.sol --- packages/protocol/contracts/common/LibAutoSnapshot.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/common/LibAutoSnapshot.sol b/packages/protocol/contracts/common/LibAutoSnapshot.sol index a5ce72518e0..c07c8eb03b9 100644 --- a/packages/protocol/contracts/common/LibAutoSnapshot.sol +++ b/packages/protocol/contracts/common/LibAutoSnapshot.sol @@ -16,9 +16,9 @@ library LibAutoSnapshot { /// @param id The snapshot id. event TaikoTokenSnapshotTaken(address tkoAddress, uint256 id); - // Take a snapshot every 100,000 L1 blocks which is roughly 13 days and 21 hours. + // Take a snapshot every 200,000 L1 blocks which is roughly 27 days. function autoSnapshot(IAddressResolver _resolver, uint256 _blockId) internal { - if (_blockId % 100_000 != 0) return; + if (_blockId % 200_000 != 0) return; address taikoToken = _resolver.resolve(LibStrings.B_TAIKO_TOKEN, true); if (taikoToken != address(0)) { From cf6c4bb75bbbb95c45672c16bc90f6112b2f4c32 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 20:45:17 +0800 Subject: [PATCH 27/46] more --- packages/protocol/contracts/L1/TaikoData.sol | 2 +- .../contracts/L1/libs/LibProposing.sol | 10 ++++- .../contracts/L1/libs/LibVerifying.sol | 1 - packages/protocol/contracts/L2/TaikoL2.sol | 7 +++- .../contracts/common/LibAutoSnapshot.sol | 38 ++++++++++++++----- 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 4079dae2387..0f5baa6a64c 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -140,7 +140,7 @@ library TaikoData { uint64 genesisHeight; uint64 genesisTimestamp; uint64 lastSyncedBlockId; - uint64 lastSynecdAt; + uint64 lastSnapshotIdx; } struct SlotB { diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index fa49b5f6ed8..4877588e16b 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -229,7 +229,15 @@ library LibProposing { depositsProcessed: deposits_ }); - LibAutoSnapshot.autoSnapshot(_resolver, block.number); + { + // Take regular snapshots + uint64 _lastSnapshotIdx = _state.slotA.lastSnapshotIdx; + _lastSnapshotIdx = + LibAutoSnapshot.autoSnapshot(_resolver, block.number, _lastSnapshotIdx); + if (_lastSnapshotIdx != 0) { + _state.slotA.lastSnapshotIdx = _lastSnapshotIdx; + } + } } function _isProposerPermitted( diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol index 160b064abf6..6824c32a998 100644 --- a/packages/protocol/contracts/L1/libs/LibVerifying.sol +++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol @@ -229,7 +229,6 @@ library LibVerifying { if (_lastVerifiedBlockId > lastSyncedBlock + _config.blockSyncThreshold) { _state.slotA.lastSyncedBlockId = _lastVerifiedBlockId; - _state.slotA.lastSynecdAt = uint64(block.timestamp); signalService.syncChainData( _config.chainId, LibStrings.H_STATE_ROOT, _lastVerifiedBlockId, _stateRoot diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 460a389e403..9f990d4e98f 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -50,6 +50,8 @@ contract TaikoL2 is EssentialContract { /// @dev Slot 4. uint64 public l1ChainId; + uint64 public lastSnapshotIdx; + uint256[46] private __gap; /// @notice Emitted when the latest L1 block details are anchored to L2. @@ -177,7 +179,10 @@ contract TaikoL2 is EssentialContract { emit Anchored(_parentHash, _gasExcess); - LibAutoSnapshot.autoSnapshot(this, _l1BlockId); + uint64 _lastSnapshotIdx = LibAutoSnapshot.autoSnapshot(this, _l1BlockId, lastSnapshotIdx); + if (_lastSnapshotIdx != 0) { + lastSnapshotIdx = _lastSnapshotIdx; + } } /// @notice Withdraw token or Ether from this address diff --git a/packages/protocol/contracts/common/LibAutoSnapshot.sol b/packages/protocol/contracts/common/LibAutoSnapshot.sol index c07c8eb03b9..4229710abf5 100644 --- a/packages/protocol/contracts/common/LibAutoSnapshot.sol +++ b/packages/protocol/contracts/common/LibAutoSnapshot.sol @@ -11,19 +11,39 @@ interface ISnapshot { } library LibAutoSnapshot { + uint256 public constant SNAPSHOT_INTERVAL = 200_000; // uint = 1 L1 block /// @notice Emitted when the Taiko token snapshot is taken. /// @param tkoAddress The Taiko token address. - /// @param id The snapshot id. - event TaikoTokenSnapshotTaken(address tkoAddress, uint256 id); + /// @param snapshotIdx The snapshot index. + /// @param snapshotId The snapshot id. - // Take a snapshot every 200,000 L1 blocks which is roughly 27 days. - function autoSnapshot(IAddressResolver _resolver, uint256 _blockId) internal { - if (_blockId % 200_000 != 0) return; + event TaikoTokenSnapshotTaken(address tkoAddress, uint256 snapshotIdx, uint256 snapshotId); - address taikoToken = _resolver.resolve(LibStrings.B_TAIKO_TOKEN, true); - if (taikoToken != address(0)) { - uint256 id = ISnapshot(taikoToken).snapshot(); - emit TaikoTokenSnapshotTaken(taikoToken, id); + /// @dev Takes a snapshot every 200,000 L1 blocks which is roughly 27 days. + /// @param _resolver The IAddressResolve address. + /// @param _blockId The L1's block ID. + /// @param _lastSnapshotIdx The latest snapshot's index. + /// @return The new snapshot's index, 0 if no new snapshot is taken. + function autoSnapshot( + IAddressResolver _resolver, + uint256 _blockId, + uint64 _lastSnapshotIdx + ) + internal + returns (uint64) + { + if (_blockId % SNAPSHOT_INTERVAL != 0) return 0; + + uint256 snapshotIdx = _blockId / SNAPSHOT_INTERVAL; + if (snapshotIdx == 0 || snapshotIdx == _lastSnapshotIdx) { + return 0; } + + address taikoToken = _resolver.resolve(LibStrings.B_TAIKO_TOKEN, true); + if (taikoToken == address(0)) return 0; + + uint256 snapshotId = ISnapshot(taikoToken).snapshot(); + emit TaikoTokenSnapshotTaken(taikoToken, snapshotIdx, snapshotId); + return uint64(snapshotIdx); } } From 7f9ad39dec54a286612a27363cd2f9838b4f70bf Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 20:47:30 +0800 Subject: [PATCH 28/46] Update LibAutoSnapshot.sol From 9227586808c6341d85c27e09285530c2e928aee6 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 21:10:20 +0800 Subject: [PATCH 29/46] fix --- .../protocol/contracts/L1/TaikoEvents.sol | 5 +++-- .../contracts/L1/libs/LibProposing.sol | 16 ++++++++-------- packages/protocol/contracts/L2/TaikoL2.sol | 12 +++++++----- .../contracts/common/LibAutoSnapshot.sol | 19 +++++++------------ 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoEvents.sol b/packages/protocol/contracts/L1/TaikoEvents.sol index 022ea463f6a..5ab6cb2390e 100644 --- a/packages/protocol/contracts/L1/TaikoEvents.sol +++ b/packages/protocol/contracts/L1/TaikoEvents.sol @@ -47,8 +47,9 @@ abstract contract TaikoEvents { /// @notice Emitted when the Taiko token snapshot is taken. /// @param tkoAddress The Taiko token address. - /// @param id The snapshot id. - event TaikoTokenSnapshotTaken(address tkoAddress, uint256 id); + /// @param snapshotIdx The snapshot index. + /// @param snapshotId The snapshot id. + event TaikoTokenSnapshotTaken(address tkoAddress, uint256 snapshotIdx, uint256 snapshotId); /// @dev Emitted when a block transition is proved or re-proved. /// @param blockId The ID of the proven block. diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 4877588e16b..68ad3b8ac39 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -185,6 +185,8 @@ library LibProposing { { IERC20 tko = IERC20(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)); + _takeRegularSnapshot(_state, address(tko)); + uint256 tkoBalance = tko.balanceOf(address(this)); // Run all hooks. @@ -228,15 +230,13 @@ library LibProposing { meta: meta_, depositsProcessed: deposits_ }); + } - { - // Take regular snapshots - uint64 _lastSnapshotIdx = _state.slotA.lastSnapshotIdx; - _lastSnapshotIdx = - LibAutoSnapshot.autoSnapshot(_resolver, block.number, _lastSnapshotIdx); - if (_lastSnapshotIdx != 0) { - _state.slotA.lastSnapshotIdx = _lastSnapshotIdx; - } + function _takeRegularSnapshot(TaikoData.State storage _state, address tkoToken) private { + uint64 idx = + LibAutoSnapshot.autoSnapshot(tkoToken, block.number, _state.slotA.lastSnapshotIdx); + if (idx != 0) { + _state.slotA.lastSnapshotIdx = idx; } } diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 9f990d4e98f..19df001b309 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -61,8 +61,9 @@ contract TaikoL2 is EssentialContract { /// @notice Emitted when the Taiko token snapshot is taken. /// @param tkoAddress The Taiko token address. - /// @param id The snapshot id. - event TaikoTokenSnapshotTaken(address tkoAddress, uint256 id); + /// @param snapshotIdx The snapshot index. + /// @param snapshotId The snapshot id. + event TaikoTokenSnapshotTaken(address tkoAddress, uint256 snapshotIdx, uint256 snapshotId); error L2_BASEFEE_MISMATCH(); error L2_INVALID_L1_CHAIN_ID(); @@ -179,9 +180,10 @@ contract TaikoL2 is EssentialContract { emit Anchored(_parentHash, _gasExcess); - uint64 _lastSnapshotIdx = LibAutoSnapshot.autoSnapshot(this, _l1BlockId, lastSnapshotIdx); - if (_lastSnapshotIdx != 0) { - lastSnapshotIdx = _lastSnapshotIdx; + address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); + if (taikoToken != address(0)) { + uint64 idx = LibAutoSnapshot.autoSnapshot(taikoToken, _l1BlockId, lastSnapshotIdx); + if (idx != 0) lastSnapshotIdx = idx; } } diff --git a/packages/protocol/contracts/common/LibAutoSnapshot.sol b/packages/protocol/contracts/common/LibAutoSnapshot.sol index 4229710abf5..803e7214713 100644 --- a/packages/protocol/contracts/common/LibAutoSnapshot.sol +++ b/packages/protocol/contracts/common/LibAutoSnapshot.sol @@ -12,20 +12,20 @@ interface ISnapshot { library LibAutoSnapshot { uint256 public constant SNAPSHOT_INTERVAL = 200_000; // uint = 1 L1 block + /// @notice Emitted when the Taiko token snapshot is taken. /// @param tkoAddress The Taiko token address. /// @param snapshotIdx The snapshot index. /// @param snapshotId The snapshot id. - event TaikoTokenSnapshotTaken(address tkoAddress, uint256 snapshotIdx, uint256 snapshotId); /// @dev Takes a snapshot every 200,000 L1 blocks which is roughly 27 days. - /// @param _resolver The IAddressResolve address. + /// @param _taikoToken The Taiko token address. /// @param _blockId The L1's block ID. /// @param _lastSnapshotIdx The latest snapshot's index. /// @return The new snapshot's index, 0 if no new snapshot is taken. function autoSnapshot( - IAddressResolver _resolver, + address _taikoToken, uint256 _blockId, uint64 _lastSnapshotIdx ) @@ -34,16 +34,11 @@ library LibAutoSnapshot { { if (_blockId % SNAPSHOT_INTERVAL != 0) return 0; - uint256 snapshotIdx = _blockId / SNAPSHOT_INTERVAL; - if (snapshotIdx == 0 || snapshotIdx == _lastSnapshotIdx) { - return 0; - } - - address taikoToken = _resolver.resolve(LibStrings.B_TAIKO_TOKEN, true); - if (taikoToken == address(0)) return 0; + uint256 snapshotIdx = _blockId / SNAPSHOT_INTERVAL + 1; + if (snapshotIdx == _lastSnapshotIdx) return 0; - uint256 snapshotId = ISnapshot(taikoToken).snapshot(); - emit TaikoTokenSnapshotTaken(taikoToken, snapshotIdx, snapshotId); + uint256 snapshotId = ISnapshot(_taikoToken).snapshot(); + emit TaikoTokenSnapshotTaken(_taikoToken, snapshotIdx, snapshotId); return uint64(snapshotIdx); } } From f8addd858471c2bb8875ad640903f76f22ca1b27 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 21:11:44 +0800 Subject: [PATCH 30/46] Update LibProposing.sol --- packages/protocol/contracts/L1/libs/LibProposing.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 68ad3b8ac39..3a8cd7322ba 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -185,7 +185,7 @@ library LibProposing { { IERC20 tko = IERC20(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)); - _takeRegularSnapshot(_state, address(tko)); + _autoSnapshot(_state, address(tko)); uint256 tkoBalance = tko.balanceOf(address(this)); @@ -232,7 +232,7 @@ library LibProposing { }); } - function _takeRegularSnapshot(TaikoData.State storage _state, address tkoToken) private { + function _autoSnapshot(TaikoData.State storage _state, address tkoToken) private { uint64 idx = LibAutoSnapshot.autoSnapshot(tkoToken, block.number, _state.slotA.lastSnapshotIdx); if (idx != 0) { From 2a5e7489d2c64466c71fa1b4154fe61dd60a350d Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 21:13:01 +0800 Subject: [PATCH 31/46] Update TaikoL2.sol --- packages/protocol/contracts/L2/TaikoL2.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 19df001b309..a5c4d1b8676 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -180,9 +180,9 @@ contract TaikoL2 is EssentialContract { emit Anchored(_parentHash, _gasExcess); - address taikoToken = resolve(LibStrings.B_TAIKO_TOKEN, true); - if (taikoToken != address(0)) { - uint64 idx = LibAutoSnapshot.autoSnapshot(taikoToken, _l1BlockId, lastSnapshotIdx); + address tko = resolve(LibStrings.B_TAIKO_TOKEN, true); + if (tko != address(0)) { + uint64 idx = LibAutoSnapshot.autoSnapshot(tko, _l1BlockId, lastSnapshotIdx); if (idx != 0) lastSnapshotIdx = idx; } } From 5cf171fc1fb682d484213dd92cd010b7760e7bba Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 13 Apr 2024 21:13:46 +0800 Subject: [PATCH 32/46] Update TaikoL2.sol --- packages/protocol/contracts/L2/TaikoL2.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index a5c4d1b8676..edc71fd1d3a 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -178,13 +178,13 @@ contract TaikoL2 is EssentialContract { __currentBlockTimestamp = uint64(block.timestamp); gasExcess = _gasExcess; - emit Anchored(_parentHash, _gasExcess); - address tko = resolve(LibStrings.B_TAIKO_TOKEN, true); if (tko != address(0)) { uint64 idx = LibAutoSnapshot.autoSnapshot(tko, _l1BlockId, lastSnapshotIdx); if (idx != 0) lastSnapshotIdx = idx; } + + emit Anchored(_parentHash, _gasExcess); } /// @notice Withdraw token or Ether from this address From b1894a6aeed45769a9f9c4e2e5c4824300ce20eb Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 14 Apr 2024 14:02:44 +0800 Subject: [PATCH 33/46] more --- packages/protocol/contracts/L1/TaikoData.sol | 4 ++-- packages/protocol/contracts/L1/TaikoEvents.sol | 2 +- packages/protocol/contracts/L1/TaikoL1.sol | 1 - .../protocol/contracts/L1/libs/LibProposing.sol | 15 ++++++++++----- .../protocol/contracts/L1/libs/LibVerifying.sol | 1 + packages/protocol/contracts/L2/TaikoL2.sol | 2 +- .../protocol/contracts/common/LibAutoSnapshot.sol | 15 +++++++++------ 7 files changed, 24 insertions(+), 16 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 0f5baa6a64c..43fbbbfd0cf 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -140,7 +140,7 @@ library TaikoData { uint64 genesisHeight; uint64 genesisTimestamp; uint64 lastSyncedBlockId; - uint64 lastSnapshotIdx; + uint64 lastSyncedAt; } struct SlotB { @@ -149,7 +149,7 @@ library TaikoData { bool provingPaused; uint8 __reservedB1; uint16 __reservedB2; - uint32 __reservedB3; + uint32 lastSnapshotIdx; uint64 lastUnpausedAt; } diff --git a/packages/protocol/contracts/L1/TaikoEvents.sol b/packages/protocol/contracts/L1/TaikoEvents.sol index 5ab6cb2390e..f342fb058a8 100644 --- a/packages/protocol/contracts/L1/TaikoEvents.sol +++ b/packages/protocol/contracts/L1/TaikoEvents.sol @@ -49,7 +49,7 @@ abstract contract TaikoEvents { /// @param tkoAddress The Taiko token address. /// @param snapshotIdx The snapshot index. /// @param snapshotId The snapshot id. - event TaikoTokenSnapshotTaken(address tkoAddress, uint256 snapshotIdx, uint256 snapshotId); + event TaikoTokenSnapshot(address tkoAddress, uint256 snapshotIdx, uint256 snapshotId); /// @dev Emitted when a block transition is proved or re-proved. /// @param blockId The ID of the proven block. diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index ac450b627c5..bb1b3579e56 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -59,7 +59,6 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { // reset some previously used slots for future reuse state.slotB.__reservedB1 = 0; state.slotB.__reservedB2 = 0; - state.slotB.__reservedB3 = 0; state.__reserve1 = 0; } diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 3a8cd7322ba..358cfe85489 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -185,7 +185,7 @@ library LibProposing { { IERC20 tko = IERC20(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)); - _autoSnapshot(_state, address(tko)); + _autoSnapshot(_state, address(tko), b); uint256 tkoBalance = tko.balanceOf(address(this)); @@ -232,11 +232,16 @@ library LibProposing { }); } - function _autoSnapshot(TaikoData.State storage _state, address tkoToken) private { - uint64 idx = - LibAutoSnapshot.autoSnapshot(tkoToken, block.number, _state.slotA.lastSnapshotIdx); + function _autoSnapshot( + TaikoData.State storage _state, + address _taikoToken, + TaikoData.SlotB memory _slotB + ) + private + { + uint32 idx = LibAutoSnapshot.autoSnapshot(_taikoToken, block.number, _slotB.lastSnapshotIdx); if (idx != 0) { - _state.slotA.lastSnapshotIdx = idx; + _state.slotB.lastSnapshotIdx = idx; } } diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol index 6824c32a998..43d6f0d1729 100644 --- a/packages/protocol/contracts/L1/libs/LibVerifying.sol +++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol @@ -229,6 +229,7 @@ library LibVerifying { if (_lastVerifiedBlockId > lastSyncedBlock + _config.blockSyncThreshold) { _state.slotA.lastSyncedBlockId = _lastVerifiedBlockId; + _state.slotA.lastSyncedAt = uint64(block.timestamp); signalService.syncChainData( _config.chainId, LibStrings.H_STATE_ROOT, _lastVerifiedBlockId, _stateRoot diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index edc71fd1d3a..14a22f5b2e2 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -63,7 +63,7 @@ contract TaikoL2 is EssentialContract { /// @param tkoAddress The Taiko token address. /// @param snapshotIdx The snapshot index. /// @param snapshotId The snapshot id. - event TaikoTokenSnapshotTaken(address tkoAddress, uint256 snapshotIdx, uint256 snapshotId); + event TaikoTokenSnapshot(address tkoAddress, uint256 snapshotIdx, uint256 snapshotId); error L2_BASEFEE_MISMATCH(); error L2_INVALID_L1_CHAIN_ID(); diff --git a/packages/protocol/contracts/common/LibAutoSnapshot.sol b/packages/protocol/contracts/common/LibAutoSnapshot.sol index 803e7214713..d97c30e1782 100644 --- a/packages/protocol/contracts/common/LibAutoSnapshot.sol +++ b/packages/protocol/contracts/common/LibAutoSnapshot.sol @@ -4,12 +4,14 @@ pragma solidity 0.8.24; import "./IAddressResolver.sol"; import "./LibStrings.sol"; -/// @title LibAutoSnapshot +/// @title ISnapshot /// @custom:security-contact security@taiko.xyz interface ISnapshot { function snapshot() external returns (uint256); } +/// @title LibAutoSnapshot +/// @custom:security-contact security@taiko.xyz library LibAutoSnapshot { uint256 public constant SNAPSHOT_INTERVAL = 200_000; // uint = 1 L1 block @@ -17,7 +19,7 @@ library LibAutoSnapshot { /// @param tkoAddress The Taiko token address. /// @param snapshotIdx The snapshot index. /// @param snapshotId The snapshot id. - event TaikoTokenSnapshotTaken(address tkoAddress, uint256 snapshotIdx, uint256 snapshotId); + event TaikoTokenSnapshot(address tkoAddress, uint256 snapshotIdx, uint256 snapshotId); /// @dev Takes a snapshot every 200,000 L1 blocks which is roughly 27 days. /// @param _taikoToken The Taiko token address. @@ -30,15 +32,16 @@ library LibAutoSnapshot { uint64 _lastSnapshotIdx ) internal - returns (uint64) + returns (uint32) { if (_blockId % SNAPSHOT_INTERVAL != 0) return 0; - uint256 snapshotIdx = _blockId / SNAPSHOT_INTERVAL + 1; + // if snapshotIdx = type(uint32).max, we can handle L1 block id up to 4e14. + uint32 snapshotIdx = uint32(_blockId / SNAPSHOT_INTERVAL + 1); if (snapshotIdx == _lastSnapshotIdx) return 0; uint256 snapshotId = ISnapshot(_taikoToken).snapshot(); - emit TaikoTokenSnapshotTaken(_taikoToken, snapshotIdx, snapshotId); - return uint64(snapshotIdx); + emit TaikoTokenSnapshot(_taikoToken, snapshotIdx, snapshotId); + return snapshotIdx; } } From f14202985a0f425c8efd89d97949c687672e6576 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 14 Apr 2024 14:05:21 +0800 Subject: [PATCH 34/46] rename --- packages/protocol/contracts/L1/libs/LibProposing.sol | 4 ++-- packages/protocol/contracts/L2/TaikoL2.sol | 4 ++-- .../contracts/common/{LibAutoSnapshot.sol => LibSnapshot.sol} | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename packages/protocol/contracts/common/{LibAutoSnapshot.sol => LibSnapshot.sol} (96%) diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 358cfe85489..40e61fbae24 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.24; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../../common/IAddressResolver.sol"; -import "../../common/LibAutoSnapshot.sol"; +import "../../common/LibSnapshot.sol"; import "../../libs/LibAddress.sol"; import "../../libs/LibNetwork.sol"; import "../hooks/IHook.sol"; @@ -239,7 +239,7 @@ library LibProposing { ) private { - uint32 idx = LibAutoSnapshot.autoSnapshot(_taikoToken, block.number, _slotB.lastSnapshotIdx); + uint32 idx = LibSnapshot.autoSnapshot(_taikoToken, block.number, _slotB.lastSnapshotIdx); if (idx != 0) { _state.slotB.lastSnapshotIdx = idx; } diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 14a22f5b2e2..c2ac9c4d78c 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -5,7 +5,7 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../common/EssentialContract.sol"; -import "../common/LibAutoSnapshot.sol"; +import "../common/LibSnapshot.sol"; import "../libs/LibAddress.sol"; import "../signal/ISignalService.sol"; import "./Lib1559Math.sol"; @@ -180,7 +180,7 @@ contract TaikoL2 is EssentialContract { address tko = resolve(LibStrings.B_TAIKO_TOKEN, true); if (tko != address(0)) { - uint64 idx = LibAutoSnapshot.autoSnapshot(tko, _l1BlockId, lastSnapshotIdx); + uint64 idx = LibSnapshot.autoSnapshot(tko, _l1BlockId, lastSnapshotIdx); if (idx != 0) lastSnapshotIdx = idx; } diff --git a/packages/protocol/contracts/common/LibAutoSnapshot.sol b/packages/protocol/contracts/common/LibSnapshot.sol similarity index 96% rename from packages/protocol/contracts/common/LibAutoSnapshot.sol rename to packages/protocol/contracts/common/LibSnapshot.sol index d97c30e1782..0f5b0e54734 100644 --- a/packages/protocol/contracts/common/LibAutoSnapshot.sol +++ b/packages/protocol/contracts/common/LibSnapshot.sol @@ -10,9 +10,9 @@ interface ISnapshot { function snapshot() external returns (uint256); } -/// @title LibAutoSnapshot +/// @title LibSnapshot /// @custom:security-contact security@taiko.xyz -library LibAutoSnapshot { +library LibSnapshot { uint256 public constant SNAPSHOT_INTERVAL = 200_000; // uint = 1 L1 block /// @notice Emitted when the Taiko token snapshot is taken. From dee1e8397cc93308b0b6673f81a7baf9bd817142 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 14 Apr 2024 14:06:30 +0800 Subject: [PATCH 35/46] Update LibProposing.sol --- packages/protocol/contracts/L1/libs/LibProposing.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 40e61fbae24..fee0a802ad8 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -185,7 +185,7 @@ library LibProposing { { IERC20 tko = IERC20(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)); - _autoSnapshot(_state, address(tko), b); + _takeTaikoTokenSnapshot(_state, address(tko), b); uint256 tkoBalance = tko.balanceOf(address(this)); @@ -232,7 +232,7 @@ library LibProposing { }); } - function _autoSnapshot( + function _takeTaikoTokenSnapshot( TaikoData.State storage _state, address _taikoToken, TaikoData.SlotB memory _slotB From 8b22b19b371f8bfba56a288938a9dc842a328bc6 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 14 Apr 2024 14:07:27 +0800 Subject: [PATCH 36/46] Update TaikoL2.sol --- packages/protocol/contracts/L2/TaikoL2.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index c2ac9c4d78c..19893cd8b9f 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -50,7 +50,7 @@ contract TaikoL2 is EssentialContract { /// @dev Slot 4. uint64 public l1ChainId; - uint64 public lastSnapshotIdx; + uint32 public lastSnapshotIdx; uint256[46] private __gap; @@ -180,7 +180,7 @@ contract TaikoL2 is EssentialContract { address tko = resolve(LibStrings.B_TAIKO_TOKEN, true); if (tko != address(0)) { - uint64 idx = LibSnapshot.autoSnapshot(tko, _l1BlockId, lastSnapshotIdx); + uint32 idx = LibSnapshot.autoSnapshot(tko, _l1BlockId, lastSnapshotIdx); if (idx != 0) lastSnapshotIdx = idx; } From 867d1565c9dfd4a617db205673e2a91f086f116f Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Tue, 16 Apr 2024 18:51:46 +0800 Subject: [PATCH 37/46] revert --- packages/protocol/contracts/L1/TaikoData.sol | 2 +- packages/protocol/contracts/L1/libs/LibVerifying.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 43fbbbfd0cf..1bf8e336309 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -140,7 +140,7 @@ library TaikoData { uint64 genesisHeight; uint64 genesisTimestamp; uint64 lastSyncedBlockId; - uint64 lastSyncedAt; + uint64 lastSynecdAt; // typo! } struct SlotB { diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol index 43d6f0d1729..160b064abf6 100644 --- a/packages/protocol/contracts/L1/libs/LibVerifying.sol +++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol @@ -229,7 +229,7 @@ library LibVerifying { if (_lastVerifiedBlockId > lastSyncedBlock + _config.blockSyncThreshold) { _state.slotA.lastSyncedBlockId = _lastVerifiedBlockId; - _state.slotA.lastSyncedAt = uint64(block.timestamp); + _state.slotA.lastSynecdAt = uint64(block.timestamp); signalService.syncChainData( _config.chainId, LibStrings.H_STATE_ROOT, _lastVerifiedBlockId, _stateRoot From 7db0b3ad644fc7f3e1f8eb69b739cf2610987c14 Mon Sep 17 00:00:00 2001 From: Daniel Wang <99078276+dantaik@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:26:20 +0800 Subject: [PATCH 38/46] Update LibSnapshot.sol --- packages/protocol/contracts/common/LibSnapshot.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/common/LibSnapshot.sol b/packages/protocol/contracts/common/LibSnapshot.sol index 0f5b0e54734..7bcca21261a 100644 --- a/packages/protocol/contracts/common/LibSnapshot.sol +++ b/packages/protocol/contracts/common/LibSnapshot.sol @@ -13,7 +13,7 @@ interface ISnapshot { /// @title LibSnapshot /// @custom:security-contact security@taiko.xyz library LibSnapshot { - uint256 public constant SNAPSHOT_INTERVAL = 200_000; // uint = 1 L1 block + uint256 public constant SNAPSHOT_INTERVAL = 100_000; // uint = 1 L1 block /// @notice Emitted when the Taiko token snapshot is taken. /// @param tkoAddress The Taiko token address. From 679a73ccfdc170ac5f8f636fc008aa3d992d160f Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Tue, 16 Apr 2024 22:33:41 +0800 Subject: [PATCH 39/46] more --- packages/protocol/contracts/L1/TaikoToken.sol | 4 ++++ packages/protocol/contracts/tokenvault/BridgedERC20.sol | 4 ++++ packages/protocol/package.json | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/protocol/contracts/L1/TaikoToken.sol b/packages/protocol/contracts/L1/TaikoToken.sol index 81ffd741018..4120568049a 100644 --- a/packages/protocol/contracts/L1/TaikoToken.sol +++ b/packages/protocol/contracts/L1/TaikoToken.sol @@ -84,6 +84,10 @@ contract TaikoToken is EssentialContract, ERC20SnapshotUpgradeable, ERC20VotesUp return super.transferFrom(_from, _to, _amount); } + function currentSnapshotId() public view returns (uint256) { + return _getCurrentSnapshotId(); + } + function _beforeTokenTransfer( address _from, address _to, diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20.sol b/packages/protocol/contracts/tokenvault/BridgedERC20.sol index 3a136098802..97f90c23ef4 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20.sol @@ -121,6 +121,10 @@ contract BridgedERC20 is return __srcDecimals; } + function currentSnapshotId() public view returns (uint256) { + return _getCurrentSnapshotId(); + } + /// @notice Gets the canonical token's address and chain ID. /// @return The canonical token's address. /// @return The canonical token's chain ID. diff --git a/packages/protocol/package.json b/packages/protocol/package.json index 943deaff1e3..c49cd226b4f 100644 --- a/packages/protocol/package.json +++ b/packages/protocol/package.json @@ -30,7 +30,7 @@ "eslint-plugin-promise": "^6.1.1", "ethers": "^5.7.2", "solc": "0.7.3", - "solhint": "^4.5.2", + "solhint": "^4.5.4", "ts-node": "^10.9.2", "typescript": "^5.2.2" }, From 6f10750a1e357a39535ab6d3c83e718ba8cf25a2 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Tue, 16 Apr 2024 22:33:53 +0800 Subject: [PATCH 40/46] Update pnpm-lock.yaml --- pnpm-lock.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4ccdc710fdf..973cd0f5fdc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -328,8 +328,8 @@ importers: specifier: 0.7.3 version: 0.7.3 solhint: - specifier: ^4.5.2 - version: 4.5.2(typescript@5.4.3) + specifier: ^4.5.4 + version: 4.5.4(typescript@5.4.3) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@20.11.20)(typescript@5.4.3) @@ -12242,8 +12242,8 @@ packages: - debug dev: true - /solhint@4.5.2(typescript@5.4.3): - resolution: {integrity: sha512-o7MNYS5QPgE6l+PTGOTAUtCzo0ZLnffQsv586hntSHBe2JbSDfkoxfhAOcjZjN4OesTgaX4UEEjCjH9y/4BP5w==} + /solhint@4.5.4(typescript@5.4.3): + resolution: {integrity: sha512-Cu1XiJXub2q1eCr9kkJ9VPv1sGcmj3V7Zb76B0CoezDOB9bu3DxKIFFH7ggCl9fWpEPD6xBmRLfZrYijkVmujQ==} hasBin: true dependencies: '@solidity-parser/parser': 0.18.0 From 79b73209c5a7791c5f7a5cf9489dc0ca1468bf6c Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Tue, 16 Apr 2024 22:45:22 +0800 Subject: [PATCH 41/46] x --- packages/protocol/contracts/L1/TaikoToken.sol | 2 +- packages/protocol/test/L1/TaikoL1.t.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoToken.sol b/packages/protocol/contracts/L1/TaikoToken.sol index 4120568049a..0a29fde763f 100644 --- a/packages/protocol/contracts/L1/TaikoToken.sol +++ b/packages/protocol/contracts/L1/TaikoToken.sol @@ -53,7 +53,7 @@ contract TaikoToken is EssentialContract, ERC20SnapshotUpgradeable, ERC20VotesUp } /// @notice Creates a new token snapshot. - function snapshot() public onlyFromOwnerOrNamed(LibStrings.B_TAIKO) returns (uint256) { + function snapshot() public onlyFromNamed(LibStrings.B_TAIKO) returns (uint256) { return _snapshot(); } diff --git a/packages/protocol/test/L1/TaikoL1.t.sol b/packages/protocol/test/L1/TaikoL1.t.sol index 1c4c2927da2..3516ea22ece 100644 --- a/packages/protocol/test/L1/TaikoL1.t.sol +++ b/packages/protocol/test/L1/TaikoL1.t.sol @@ -187,7 +187,7 @@ contract TaikoL1Test is TaikoL1TestBase { } function test_snapshot() external { - vm.prank(tko.owner(), tko.owner()); + vm.prank(address(L1)); tko.snapshot(); uint256 totalSupplyAtSnapshot = tko.totalSupplyAt(1); From 2f592002b357f966f8c358267bd604fc8fce86b5 Mon Sep 17 00:00:00 2001 From: Daniel Wang <99078276+dantaik@users.noreply.github.com> Date: Wed, 17 Apr 2024 14:10:00 +0800 Subject: [PATCH 42/46] Update LibSnapshot.sol --- packages/protocol/contracts/common/LibSnapshot.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/common/LibSnapshot.sol b/packages/protocol/contracts/common/LibSnapshot.sol index 7bcca21261a..afdce05c3cf 100644 --- a/packages/protocol/contracts/common/LibSnapshot.sol +++ b/packages/protocol/contracts/common/LibSnapshot.sol @@ -13,7 +13,7 @@ interface ISnapshot { /// @title LibSnapshot /// @custom:security-contact security@taiko.xyz library LibSnapshot { - uint256 public constant SNAPSHOT_INTERVAL = 100_000; // uint = 1 L1 block + uint256 public constant SNAPSHOT_INTERVAL = 7_200; // uint = 1 L1 block /// @notice Emitted when the Taiko token snapshot is taken. /// @param tkoAddress The Taiko token address. From a578292176c18a7ac38e225a127ba3dbc4c1151e Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Wed, 17 Apr 2024 14:14:24 +0800 Subject: [PATCH 43/46] Update LibSnapshot.sol --- packages/protocol/contracts/common/LibSnapshot.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/common/LibSnapshot.sol b/packages/protocol/contracts/common/LibSnapshot.sol index afdce05c3cf..77ea1a12abb 100644 --- a/packages/protocol/contracts/common/LibSnapshot.sol +++ b/packages/protocol/contracts/common/LibSnapshot.sol @@ -13,7 +13,7 @@ interface ISnapshot { /// @title LibSnapshot /// @custom:security-contact security@taiko.xyz library LibSnapshot { - uint256 public constant SNAPSHOT_INTERVAL = 7_200; // uint = 1 L1 block + uint256 public constant SNAPSHOT_INTERVAL = 7200; // uint = 1 L1 block /// @notice Emitted when the Taiko token snapshot is taken. /// @param tkoAddress The Taiko token address. From 7687c3b92a4cd477ca50bb050ff1c82bcb81b315 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Thu, 18 Apr 2024 13:00:07 +0800 Subject: [PATCH 44/46] Update BridgedERC20.sol --- .../contracts/tokenvault/BridgedERC20.sol | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20.sol b/packages/protocol/contracts/tokenvault/BridgedERC20.sol index 97f90c23ef4..08207d95414 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20.sol @@ -34,12 +34,7 @@ contract BridgedERC20 is error BTOKEN_UNAUTHORIZED(); modifier onlyAuthorizedForSnapshot() { - if ( - msg.sender != owner() && msg.sender != snapshooter - && msg.sender != resolve(LibStrings.B_TAIKO, true) - ) { - revert BTOKEN_UNAUTHORIZED(); - } + if (!isAuthorizedForSnapshot(msg.sender)) revert BTOKEN_UNAUTHORIZED(); _; } @@ -121,10 +116,25 @@ contract BridgedERC20 is return __srcDecimals; } + /// @notice Get the current snapshot ID. + /// @returns The current snapshot ID. function currentSnapshotId() public view returns (uint256) { return _getCurrentSnapshotId(); } + /// @notice Checks if an address can take a snapshot. + /// @param addr The address. + /// @return true if the address can perform a snapshot, false otherwise. + function isAuthorizedForSnapshot(address addr) public view returns (bool) { + if (addr == address(0)) return false; + if (addr == snapshooter) return true; + if ( + addr == resolve(LibStrings.B_TAIKO, true) + && address(this) == resolve(LibStrings.B_TAIKO_TOKEN, true) + ) return true; + return false; + } + /// @notice Gets the canonical token's address and chain ID. /// @return The canonical token's address. /// @return The canonical token's chain ID. From cb41cbc1777d92bcfdb21dd4f5ac7c5eb6ae22c8 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Thu, 18 Apr 2024 14:04:46 +0800 Subject: [PATCH 45/46] Update BridgedERC20.sol --- packages/protocol/contracts/tokenvault/BridgedERC20.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20.sol b/packages/protocol/contracts/tokenvault/BridgedERC20.sol index 08207d95414..34d27a69f8b 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20.sol @@ -116,8 +116,8 @@ contract BridgedERC20 is return __srcDecimals; } - /// @notice Get the current snapshot ID. - /// @returns The current snapshot ID. + /// @notice Gets the current snapshot ID. + /// @return The current snapshot ID. function currentSnapshotId() public view returns (uint256) { return _getCurrentSnapshotId(); } From 739d28d872f2b2dbdf45151905f9b6d2072e2aeb Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Thu, 18 Apr 2024 16:17:25 +0800 Subject: [PATCH 46/46] Update BridgedERC20.sol --- packages/protocol/contracts/tokenvault/BridgedERC20.sol | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20.sol b/packages/protocol/contracts/tokenvault/BridgedERC20.sol index 34d27a69f8b..10c15e1b960 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20.sol @@ -127,11 +127,14 @@ contract BridgedERC20 is /// @return true if the address can perform a snapshot, false otherwise. function isAuthorizedForSnapshot(address addr) public view returns (bool) { if (addr == address(0)) return false; - if (addr == snapshooter) return true; + if ( addr == resolve(LibStrings.B_TAIKO, true) && address(this) == resolve(LibStrings.B_TAIKO_TOKEN, true) ) return true; + + if (addr == snapshooter) return true; + return false; }