Skip to content

Commit 46842de

Browse files
committed
feat: add pauser
1 parent 87a55c7 commit 46842de

File tree

8 files changed

+502
-34
lines changed

8 files changed

+502
-34
lines changed

docs/multichain/destination/OperatorTableUpdater.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ Sets the stake proportion threshold required for confirming global table roots.
169169
/**
170170
* @notice Disables a global table root
171171
* @param globalTableRoot the global table root to disable
172-
* @dev Only callable by the owner of the contract
172+
* @dev Only callable by the pauser
173173
*/
174174
function disableRoot(
175175
bytes32 globalTableRoot
@@ -183,7 +183,7 @@ Disables a global table root, preventing further operator table updates against
183183
* Emits a `GlobalRootDisabled` event
184184

185185
*Requirements*:
186-
* Caller MUST be the `owner`
186+
* Caller MUST be the `pauser`
187187
* The `globalTableRoot` MUST exist and be currently valid
188188

189189
### `updateGlobalRootConfirmerSet`

pkg/bindings/BN254CertificateVerifier/binding.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/bindings/ECDSACertificateVerifier/binding.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/bindings/OperatorTableUpdater/binding.go

Lines changed: 462 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/contracts/interfaces/IOperatorTableUpdater.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ interface IOperatorTableUpdater is
135135
/**
136136
* @notice Disables a global table root
137137
* @param globalTableRoot the global table root to disable
138-
* @dev Only callable by the owner of the contract
138+
* @dev Only callable by the pauser
139139
*/
140140
function disableRoot(
141141
bytes32 globalTableRoot

src/contracts/multichain/OperatorTableUpdater.sol

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@ import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol";
55
import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol";
66

77
import "../libraries/Merkle.sol";
8+
import "../permissions/Pausable.sol";
89
import "../mixins/SemVerMixin.sol";
910
import "./OperatorTableUpdaterStorage.sol";
1011

11-
contract OperatorTableUpdater is Initializable, OwnableUpgradeable, OperatorTableUpdaterStorage, SemVerMixin {
12+
contract OperatorTableUpdater is
13+
Initializable,
14+
OwnableUpgradeable,
15+
Pausable,
16+
OperatorTableUpdaterStorage,
17+
SemVerMixin
18+
{
1219
/**
1320
*
1421
* INITIALIZING FUNCTIONS
@@ -17,14 +24,20 @@ contract OperatorTableUpdater is Initializable, OwnableUpgradeable, OperatorTabl
1724
constructor(
1825
IBN254CertificateVerifier _bn254CertificateVerifier,
1926
IECDSACertificateVerifier _ecdsaCertificateVerifier,
27+
IPauserRegistry _pauserRegistry,
2028
string memory _version
21-
) OperatorTableUpdaterStorage(_bn254CertificateVerifier, _ecdsaCertificateVerifier) SemVerMixin(_version) {
29+
)
30+
OperatorTableUpdaterStorage(_bn254CertificateVerifier, _ecdsaCertificateVerifier)
31+
Pausable(_pauserRegistry)
32+
SemVerMixin(_version)
33+
{
2234
_disableInitializers();
2335
}
2436

2537
/**
2638
* @notice Initializes the OperatorTableUpdater
2739
* @param owner The owner of the OperatorTableUpdater
40+
* @param initialPausedStatus The initial paused status of the OperatorTableUpdater
2841
* @param _globalRootConfirmerSet The operatorSet which certifies against global roots
2942
* @param _globalRootConfirmationThreshold The threshold, in bps, for a global root to be signed off on and updated
3043
* @param referenceTimestamp The reference timestamp for the global root confirmer set
@@ -35,13 +48,15 @@ contract OperatorTableUpdater is Initializable, OwnableUpgradeable, OperatorTabl
3548
*/
3649
function initialize(
3750
address owner,
51+
uint256 initialPausedStatus,
3852
OperatorSet calldata _globalRootConfirmerSet,
3953
uint16 _globalRootConfirmationThreshold,
4054
uint32 referenceTimestamp,
4155
BN254OperatorSetInfo calldata globalRootConfirmerSetInfo,
4256
OperatorSetConfig calldata globalRootConfirmerSetConfig
4357
) external initializer {
4458
_transferOwnership(owner);
59+
_setPausedStatus(initialPausedStatus);
4560
_setGlobalRootConfirmerSet(_globalRootConfirmerSet);
4661
_setGlobalRootConfirmationThreshold(_globalRootConfirmationThreshold);
4762
_updateGlobalRootConfirmerSet(referenceTimestamp, globalRootConfirmerSetInfo, globalRootConfirmerSetConfig);
@@ -173,7 +188,7 @@ contract OperatorTableUpdater is Initializable, OwnableUpgradeable, OperatorTabl
173188
/// @inheritdoc IOperatorTableUpdater
174189
function disableRoot(
175190
bytes32 globalTableRoot
176-
) external onlyOwner {
191+
) external onlyPauser {
177192
// Check that the root already exists and is not disabled
178193
require(_isRootValid[globalTableRoot], InvalidRoot());
179194

src/test/tree/OperatorTableUpdaterUnit.tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@
4444
│ └── given that the caller is owner and threshold is valid
4545
│ └── it should update the threshold & emit GlobalRootConfirmationThresholdUpdated event
4646
├── when disableRoot is called
47-
│ ├── given that the caller is not the owner
47+
│ ├── given that the caller is not the pauser
4848
│ │ └── it should revert
4949
│ ├── given that the root is invalid or doesn't exist
5050
│ │ └── it should revert with InvalidRoot
51-
│ └── given that the caller is the owner and root is valid
51+
│ └── given that the caller is the pauser and root is valid
5252
│ └── it should disable the root & emit GlobalRootDisabled event
5353
├── when updateGlobalRootConfirmerSet is called
5454
│ ├── given that the caller is not the owner

src/test/unit/OperatorTableUpdaterUnit.t.sol

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ contract OperatorTableUpdaterUnitTests is
4646
operatorTableUpdaterImplementation = new OperatorTableUpdater(
4747
IBN254CertificateVerifier(address(bn254CertificateVerifierMock)),
4848
IECDSACertificateVerifier(address(ecdsaCertificateVerifierMock)),
49+
pauserRegistry,
4950
"1.0.0"
5051
);
5152

@@ -55,6 +56,7 @@ contract OperatorTableUpdaterUnitTests is
5556
abi.encodeWithSelector(
5657
OperatorTableUpdater.initialize.selector,
5758
address(this), // owner
59+
0, // initialPausedStatus
5860
globalRootConfirmerSet, // globalRootConfirmerSet
5961
GLOBAL_ROOT_CONFIRMATION_THRESHOLD, // globalRootConfirmationThreshold
6062
block.timestamp - 1, // referenceTimestamp
@@ -194,6 +196,7 @@ contract OperatorTableUpdaterUnitTests_initialize is OperatorTableUpdaterUnitTes
194196
cheats.expectRevert("Initializable: contract is already initialized");
195197
operatorTableUpdater.initialize(
196198
address(this),
199+
uint(0),
197200
globalRootConfirmerSet,
198201
GLOBAL_ROOT_CONFIRMATION_THRESHOLD,
199202
uint32(block.timestamp - 1),
@@ -661,14 +664,14 @@ contract OperatorTableUpdaterUnitTests_setGlobalRootConfirmationThreshold is Ope
661664
}
662665

663666
contract OperatorTableUpdaterUnitTests_disableRoot is OperatorTableUpdaterUnitTests {
664-
function testFuzz_revert_onlyOwner(Randomness r) public rand(r) {
667+
function testFuzz_revert_onlyPauser(Randomness r) public rand(r) {
665668
address invalidCaller = r.Address();
666-
cheats.assume(invalidCaller != address(this));
669+
cheats.assume(invalidCaller != pauser && invalidCaller != address(this));
667670
bytes32 globalTableRoot = bytes32(r.Uint256());
668671

669-
// Should revert when called by non-owner
672+
// Should revert when called by non-pauser
670673
cheats.prank(invalidCaller);
671-
cheats.expectRevert("Ownable: caller is not the owner");
674+
cheats.expectRevert("Pausable: caller is not the pauser");
672675
operatorTableUpdater.disableRoot(globalTableRoot);
673676
}
674677

@@ -692,7 +695,8 @@ contract OperatorTableUpdaterUnitTests_disableRoot is OperatorTableUpdaterUnitTe
692695
// Verify the root is valid
693696
assertTrue(operatorTableUpdater.isRootValid(globalTableRoot));
694697

695-
// Disable the root
698+
// Disable the root as pauser
699+
cheats.prank(pauser);
696700
cheats.expectEmit(true, true, true, true);
697701
emit GlobalRootDisabled(globalTableRoot);
698702
operatorTableUpdater.disableRoot(globalTableRoot);
@@ -754,7 +758,8 @@ contract OperatorTableUpdaterUnitTests_isRootValid is OperatorTableUpdaterUnitTe
754758
// Should now be valid
755759
assertTrue(operatorTableUpdater.isRootValid(globalTableRoot));
756760

757-
// Disable the root
761+
// Disable the root as pauser
762+
cheats.prank(pauser);
758763
operatorTableUpdater.disableRoot(globalTableRoot);
759764

760765
// Should now be invalid
@@ -777,7 +782,8 @@ contract OperatorTableUpdaterUnitTests_isRootValid is OperatorTableUpdaterUnitTe
777782
// Should be valid
778783
assertTrue(operatorTableUpdater.isRootValidByTimestamp(referenceTimestamp));
779784

780-
// Disable the root
785+
// Disable the root as pauser
786+
cheats.prank(pauser);
781787
operatorTableUpdater.disableRoot(globalTableRoot);
782788

783789
// Should now be invalid when queried by timestamp
@@ -791,7 +797,8 @@ contract OperatorTableUpdaterUnitTests_IntegrationScenarios is OperatorTableUpda
791797
bytes32 oldGlobalTableRoot = bytes32(uint(1));
792798
_updateGlobalTableRoot(oldGlobalTableRoot);
793799

794-
// Step 2: Disable the old root
800+
// Step 2: Disable the old root as pauser
801+
cheats.prank(pauser);
795802
operatorTableUpdater.disableRoot(oldGlobalTableRoot);
796803

797804
// Step 3: Set a new global root confirmer set

0 commit comments

Comments
 (0)