-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathProtocolGuardian.sol
More file actions
155 lines (127 loc) · 5.61 KB
/
ProtocolGuardian.sol
File metadata and controls
155 lines (127 loc) · 5.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {IRoot} from "./interfaces/IRoot.sol";
import {ISafe} from "./interfaces/ISafe.sol";
import {IProtocolGuardian} from "./interfaces/IProtocolGuardian.sol";
import {CastLib} from "../misc/libraries/CastLib.sol";
import {PoolId} from "../core/types/PoolId.sol";
import {IGateway} from "../core/messaging/interfaces/IGateway.sol";
import {IScheduleAuthMessageSender} from "../core/messaging/interfaces/IGatewaySenders.sol";
import {ITokenBridge} from "../bridge/interfaces/ITokenBridge.sol";
/// @title ProtocolGuardian
/// @notice This contract provides emergency controls and protocol-level management including pausing,
/// permission scheduling, cross-chain upgrade coordination, and adapter configuration.
contract ProtocolGuardian is IProtocolGuardian {
using CastLib for address;
PoolId public constant GLOBAL_POOL = PoolId.wrap(0);
IRoot public immutable root;
ISafe public safe;
IGateway public gateway;
IScheduleAuthMessageSender public sender;
ITokenBridge public tokenBridge;
constructor(
ISafe safe_,
IRoot root_,
IGateway gateway_,
IScheduleAuthMessageSender sender_,
ITokenBridge tokenBridge_
) {
safe = safe_;
root = root_;
gateway = gateway_;
sender = sender_;
tokenBridge = tokenBridge_;
}
modifier onlySafe() {
require(msg.sender == address(safe), NotTheAuthorizedSafe());
_;
}
modifier onlySafeOrOwner() {
require(msg.sender == address(safe) || _isSafeOwner(msg.sender), NotTheAuthorizedSafeOrItsOwner());
_;
}
//----------------------------------------------------------------------------------------------
// Administration
//----------------------------------------------------------------------------------------------
/// @inheritdoc IProtocolGuardian
function file(bytes32 what, address data) external onlySafe {
if (what == "safe") safe = ISafe(data);
else if (what == "gateway") gateway = IGateway(data);
else if (what == "sender") sender = IScheduleAuthMessageSender(data);
else if (what == "tokenBridge") tokenBridge = ITokenBridge(data);
else revert FileUnrecognizedParam();
emit File(what, data);
}
//----------------------------------------------------------------------------------------------
// Emergency Functions
//----------------------------------------------------------------------------------------------
/// @inheritdoc IProtocolGuardian
function pause() external onlySafeOrOwner {
root.pause();
}
/// @inheritdoc IProtocolGuardian
function unpause() external onlySafe {
root.unpause();
}
//----------------------------------------------------------------------------------------------
// Permission Management
//----------------------------------------------------------------------------------------------
/// @inheritdoc IProtocolGuardian
function scheduleRely(address target) external onlySafe {
root.scheduleRely(target);
}
/// @inheritdoc IProtocolGuardian
function cancelRely(address target) external onlySafe {
root.cancelRely(target);
}
//----------------------------------------------------------------------------------------------
// Cross-Chain Operations
//----------------------------------------------------------------------------------------------
/// @inheritdoc IProtocolGuardian
function scheduleUpgrade(uint16 centrifugeId, address target, address refund) external payable onlySafe {
sender.sendScheduleUpgrade{value: msg.value}(centrifugeId, target.toBytes32(), refund);
}
/// @inheritdoc IProtocolGuardian
function cancelUpgrade(uint16 centrifugeId, address target, address refund) external payable onlySafe {
sender.sendCancelUpgrade{value: msg.value}(centrifugeId, target.toBytes32(), refund);
}
/// @inheritdoc IProtocolGuardian
function recoverTokens(
uint16 centrifugeId,
address target,
address token,
uint256 tokenId,
address to,
uint256 amount,
address refund
) external payable onlySafe {
sender.sendRecoverTokens{value: msg.value}(
centrifugeId, target.toBytes32(), token.toBytes32(), tokenId, to.toBytes32(), amount, refund
);
}
/// @inheritdoc IProtocolGuardian
function blockOutgoing(uint16 centrifugeId, bool isBlocked) external onlySafe {
gateway.blockOutgoing(centrifugeId, GLOBAL_POOL, isBlocked);
}
//----------------------------------------------------------------------------------------------
// TokenBridge Management
//----------------------------------------------------------------------------------------------
/// @inheritdoc IProtocolGuardian
function fileTokenBridgeRelayer(address relayer) external onlySafe {
tokenBridge.file("relayer", relayer);
}
/// @inheritdoc IProtocolGuardian
function fileTokenBridgeCentrifugeId(uint256 evmChainId, uint16 centrifugeId) external onlySafe {
tokenBridge.file("centrifugeId", evmChainId, centrifugeId);
}
//----------------------------------------------------------------------------------------------
// Helpers
//----------------------------------------------------------------------------------------------
function _isSafeOwner(address addr) internal view returns (bool) {
try safe.isOwner(addr) returns (bool isOwner) {
return isOwner;
} catch {
return false;
}
}
}