@keep-network/tbtc-v2 0.1.1-dev.101 → 0.1.1-dev.102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/artifacts/Bank.json +6 -6
- package/artifacts/Bridge.json +11 -11
- package/artifacts/BridgeGovernance.json +6 -6
- package/artifacts/BridgeGovernanceParameters.json +4 -4
- package/artifacts/Deposit.json +4 -4
- package/artifacts/DepositSweep.json +4 -4
- package/artifacts/EcdsaDkgValidator.json +3 -3
- package/artifacts/EcdsaInactivity.json +3 -3
- package/artifacts/EcdsaSortitionPool.json +5 -5
- package/artifacts/Fraud.json +4 -4
- package/artifacts/KeepRegistry.json +3 -3
- package/artifacts/KeepStake.json +5 -5
- package/artifacts/KeepToken.json +5 -5
- package/artifacts/KeepTokenStaking.json +3 -3
- package/artifacts/MaintainerProxy.json +1522 -0
- package/artifacts/MovingFunds.json +4 -4
- package/artifacts/NuCypherStakingEscrow.json +3 -3
- package/artifacts/NuCypherToken.json +5 -5
- package/artifacts/RandomBeaconStub.json +3 -3
- package/artifacts/Redemption.json +4 -4
- package/artifacts/ReimbursementPool.json +5 -5
- package/artifacts/Relay.json +6 -6
- package/artifacts/T.json +5 -5
- package/artifacts/TBTC.json +6 -6
- package/artifacts/TBTCToken.json +6 -6
- package/artifacts/TBTCVault.json +12 -12
- package/artifacts/TokenStaking.json +3 -3
- package/artifacts/TokenholderGovernor.json +19 -19
- package/artifacts/TokenholderTimelock.json +17 -17
- package/artifacts/VendingMachine.json +6 -6
- package/artifacts/VendingMachineKeep.json +3 -3
- package/artifacts/VendingMachineNuCypher.json +3 -3
- package/artifacts/WalletRegistry.json +11 -11
- package/artifacts/WalletRegistryGovernance.json +5 -5
- package/artifacts/Wallets.json +4 -4
- package/artifacts/solcInputs/{af641e0b3597cdfa29d6ad42d1cd8742.json → f53bc10568b6d3c32d2989742aa1c456.json} +25 -22
- package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
- package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
- package/build/contracts/bank/IReceiveBalanceApproval.sol/IReceiveBalanceApproval.dbg.json +1 -1
- package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +1 -1
- package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
- package/build/contracts/bridge/BridgeGovernance.sol/BridgeGovernance.dbg.json +1 -1
- package/build/contracts/bridge/BridgeGovernanceParameters.sol/BridgeGovernanceParameters.dbg.json +1 -1
- package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
- package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +1 -1
- package/build/contracts/bridge/DepositSweep.sol/DepositSweep.dbg.json +1 -1
- package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +1 -1
- package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +1 -1
- package/build/contracts/bridge/Heartbeat.sol/Heartbeat.dbg.json +1 -1
- package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +1 -1
- package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +1 -1
- package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +1 -1
- package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +1 -1
- package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
- package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +1 -1
- package/build/contracts/maintainer/MaintainerProxy.sol/MaintainerProxy.dbg.json +4 -0
- package/build/contracts/maintainer/MaintainerProxy.sol/MaintainerProxy.json +1111 -0
- package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
- package/build/contracts/vault/DonationVault.sol/DonationVault.dbg.json +1 -1
- package/build/contracts/vault/IVault.sol/IVault.dbg.json +1 -1
- package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
- package/contracts/maintainer/MaintainerProxy.sol +512 -0
- package/deploy/08_deploy_maintainer_proxy.ts +30 -0
- package/deploy/{08_bank_update_bridge.ts → 09_bank_update_bridge.ts} +0 -0
- package/deploy/{09_transfer_bank_ownership.ts → 10_transfer_bank_ownership.ts} +0 -0
- package/deploy/{12_transfer_bridge_governance.ts → 11_transfer_bridge_governance.ts} +0 -0
- package/deploy/{11_transfer_bridge_governance_ownership.ts → 12_transfer_bridge_governance_ownership.ts} +0 -0
- package/deploy/{10_transfer_tbtc_vault_ownership.ts → 13_transfer_tbtc_vault_ownership.ts} +0 -0
- package/deploy/14_transfer_maintainer_proxy_ownership.ts +19 -0
- package/deploy/{13_initialize_wallet_owner.ts → 15_initialize_wallet_owner.ts} +0 -0
- package/deploy/{15_transfer_proxy_admin_ownership.ts → 16_transfer_proxy_admin_ownership.ts} +0 -0
- package/deploy/17_authorize_maintainer_proxy.ts +22 -0
- package/deploy/18_transfer_reimbursement_pool_ownership.ts +19 -0
- package/deploy/{14_deploy_proxy_admin_with_deputy.ts → 19_deploy_proxy_admin_with_deputy.ts} +0 -0
- package/export.json +1105 -0
- package/package.json +1 -1
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
// ██████████████ ▐████▌ ██████████████
|
|
4
|
+
// ██████████████ ▐████▌ ██████████████
|
|
5
|
+
// ▐████▌ ▐████▌
|
|
6
|
+
// ▐████▌ ▐████▌
|
|
7
|
+
// ██████████████ ▐████▌ ██████████████
|
|
8
|
+
// ██████████████ ▐████▌ ██████████████
|
|
9
|
+
// ▐████▌ ▐████▌
|
|
10
|
+
// ▐████▌ ▐████▌
|
|
11
|
+
// ▐████▌ ▐████▌
|
|
12
|
+
// ▐████▌ ▐████▌
|
|
13
|
+
// ▐████▌ ▐████▌
|
|
14
|
+
// ▐████▌ ▐████▌
|
|
15
|
+
|
|
16
|
+
pragma solidity ^0.8.9;
|
|
17
|
+
|
|
18
|
+
import "@openzeppelin/contracts/access/Ownable.sol";
|
|
19
|
+
import "@keep-network/random-beacon/contracts/Reimbursable.sol";
|
|
20
|
+
import "@keep-network/random-beacon/contracts/ReimbursementPool.sol";
|
|
21
|
+
|
|
22
|
+
import "../bridge/BitcoinTx.sol";
|
|
23
|
+
import "../bridge/Bridge.sol";
|
|
24
|
+
|
|
25
|
+
/// @title Maintainer Proxy
|
|
26
|
+
/// @notice Maintainers are the willing off-chain clients approved by the governance.
|
|
27
|
+
/// Maintainers proxy calls to the Bridge contract via 'MaintainerProxy'
|
|
28
|
+
/// and are refunded for the spent gas from the Reimbursement Pool.
|
|
29
|
+
/// Only the authorized maintainers can call 'MaintainerProxy' functions.
|
|
30
|
+
contract MaintainerProxy is Ownable, Reimbursable {
|
|
31
|
+
Bridge public bridge;
|
|
32
|
+
|
|
33
|
+
/// @notice Authorized maintainers that can interact with the set of functions
|
|
34
|
+
/// for maintainers only. Authorization can be granted and removed by
|
|
35
|
+
/// the governance.
|
|
36
|
+
/// @dev 'Key' is the address of the maintainer. 'Value' represents an index+1
|
|
37
|
+
/// in the 'maintainers' array. 1 was added so the maintainer index can
|
|
38
|
+
/// never be 0 which is a reserved index for a non-existent maintainer
|
|
39
|
+
/// in this map.
|
|
40
|
+
mapping(address => uint256) public isAuthorized;
|
|
41
|
+
|
|
42
|
+
/// @notice This list of maintainers keeps the order of which maintainer should
|
|
43
|
+
/// be submitting a next transaction. It does not enforce the order
|
|
44
|
+
/// but only tracks who should be next in line.
|
|
45
|
+
address[] public maintainers;
|
|
46
|
+
|
|
47
|
+
/// @notice Gas that is meant to balance the submission of deposit sweep proof
|
|
48
|
+
/// overall cost. Can be updated by the governance based on the current
|
|
49
|
+
/// market conditions.
|
|
50
|
+
uint256 public submitDepositSweepProofGasOffset;
|
|
51
|
+
|
|
52
|
+
/// @notice Gas that is meant to balance the submission of redemption proof
|
|
53
|
+
/// overall cost. Can be updated by the governance based on the current
|
|
54
|
+
/// market conditions.
|
|
55
|
+
uint256 public submitRedemptionProofGasOffset;
|
|
56
|
+
|
|
57
|
+
/// @notice Gas that is meant to balance the submission of moving funds commitment
|
|
58
|
+
/// overall cost. Can be updated by the governance based on the current
|
|
59
|
+
/// market conditions.
|
|
60
|
+
uint256 public submitMovingFundsCommitmentGasOffset;
|
|
61
|
+
|
|
62
|
+
/// @notice Gas that is meant to balance the reset of moving funds timeout
|
|
63
|
+
/// overall cost. Can be updated by the governance based on the current
|
|
64
|
+
/// market conditions.
|
|
65
|
+
uint256 public resetMovingFundsTimeoutGasOffset;
|
|
66
|
+
|
|
67
|
+
/// @notice Gas that is meant to balance the submission of moving funds proof
|
|
68
|
+
/// overall cost. Can be updated by the governance based on the current
|
|
69
|
+
/// market conditions.
|
|
70
|
+
uint256 public submitMovingFundsProofGasOffset;
|
|
71
|
+
|
|
72
|
+
/// @notice Gas that is meant to balance the notification of moving funds below
|
|
73
|
+
/// dust overall cost. Can be updated by the governance based on the
|
|
74
|
+
/// current market conditions.
|
|
75
|
+
uint256 public notifyMovingFundsBelowDustGasOffset;
|
|
76
|
+
|
|
77
|
+
/// @notice Gas that is meant to balance the submission of moved funds sweep
|
|
78
|
+
/// proof overall cost. Can be updated by the governance based on the
|
|
79
|
+
/// current market conditions.
|
|
80
|
+
uint256 public submitMovedFundsSweepProofGasOffset;
|
|
81
|
+
|
|
82
|
+
/// @notice Gas that is meant to balance the request of a new wallet overall
|
|
83
|
+
/// cost. Can be updated by the governance based on the current
|
|
84
|
+
/// market conditions.
|
|
85
|
+
uint256 public requestNewWalletGasOffset;
|
|
86
|
+
|
|
87
|
+
/// @notice Gas that is meant to balance the notification of closeable wallet
|
|
88
|
+
/// overall cost. Can be updated by the governance based on the current
|
|
89
|
+
/// market conditions.
|
|
90
|
+
uint256 public notifyWalletCloseableGasOffset;
|
|
91
|
+
|
|
92
|
+
/// @notice Gas that is meant to balance the notification of wallet closing
|
|
93
|
+
/// period elapsed overall cost. Can be updated by the governance
|
|
94
|
+
/// based on the current market conditions.
|
|
95
|
+
uint256 public notifyWalletClosingPeriodElapsedGasOffset;
|
|
96
|
+
|
|
97
|
+
/// @notice Gas that is meant to balance the defeat fraud challenge
|
|
98
|
+
/// overall cost. Can be updated by the governance based on the current
|
|
99
|
+
/// market conditions.
|
|
100
|
+
uint256 public defeatFraudChallengeGasOffset;
|
|
101
|
+
|
|
102
|
+
/// @notice Gas that is meant to balance the defeat fraud challenge with heartbeat
|
|
103
|
+
/// overall cost. Can be updated by the governance based on the current
|
|
104
|
+
/// market conditions.
|
|
105
|
+
uint256 public defeatFraudChallengeWithHeartbeatGasOffset;
|
|
106
|
+
|
|
107
|
+
event MaintainerAuthorized(address indexed maintainer);
|
|
108
|
+
|
|
109
|
+
event MaintainerUnauthorized(address indexed maintainer);
|
|
110
|
+
|
|
111
|
+
event BridgeUpdated(address newBridge);
|
|
112
|
+
|
|
113
|
+
event GasOffsetParametersUpdated(
|
|
114
|
+
uint256 submitDepositSweepProofGasOffset,
|
|
115
|
+
uint256 submitRedemptionProofGasOffset,
|
|
116
|
+
uint256 submitMovingFundsCommitmentGasOffset,
|
|
117
|
+
uint256 resetMovingFundsTimeoutGasOffset,
|
|
118
|
+
uint256 submitMovingFundsProofGasOffset,
|
|
119
|
+
uint256 notifyMovingFundsBelowDustGasOffset,
|
|
120
|
+
uint256 submitMovedFundsSweepProofGasOffset,
|
|
121
|
+
uint256 requestNewWalletGasOffset,
|
|
122
|
+
uint256 notifyWalletCloseableGasOffset,
|
|
123
|
+
uint256 notifyWalletClosingPeriodElapsedGasOffset,
|
|
124
|
+
uint256 defeatFraudChallengeGasOffset,
|
|
125
|
+
uint256 defeatFraudChallengeWithHeartbeatGasOffset
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
modifier onlyMaintainer() {
|
|
129
|
+
require(isAuthorized[msg.sender] != 0, "Caller is not authorized");
|
|
130
|
+
_;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
modifier onlyReimbursableAdmin() override {
|
|
134
|
+
require(owner() == msg.sender, "Caller is not the owner");
|
|
135
|
+
_;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
constructor(Bridge _bridge, ReimbursementPool _reimbursementPool) {
|
|
139
|
+
bridge = _bridge;
|
|
140
|
+
reimbursementPool = _reimbursementPool;
|
|
141
|
+
submitDepositSweepProofGasOffset = 27000;
|
|
142
|
+
submitRedemptionProofGasOffset = 9750;
|
|
143
|
+
submitMovingFundsCommitmentGasOffset = 8000;
|
|
144
|
+
resetMovingFundsTimeoutGasOffset = 1000;
|
|
145
|
+
submitMovingFundsProofGasOffset = 15000;
|
|
146
|
+
notifyMovingFundsBelowDustGasOffset = 3500;
|
|
147
|
+
submitMovedFundsSweepProofGasOffset = 22000;
|
|
148
|
+
requestNewWalletGasOffset = 3500;
|
|
149
|
+
notifyWalletCloseableGasOffset = 4000;
|
|
150
|
+
notifyWalletClosingPeriodElapsedGasOffset = 3000;
|
|
151
|
+
defeatFraudChallengeGasOffset = 10000;
|
|
152
|
+
defeatFraudChallengeWithHeartbeatGasOffset = 5000;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/// @notice Wraps `Bridge.submitDepositSweepProof` call and reimburses the
|
|
156
|
+
/// caller's transaction cost.
|
|
157
|
+
/// @dev See `Bridge.submitDepositSweepProof` function documentation.
|
|
158
|
+
function submitDepositSweepProof(
|
|
159
|
+
BitcoinTx.Info calldata sweepTx,
|
|
160
|
+
BitcoinTx.Proof calldata sweepProof,
|
|
161
|
+
BitcoinTx.UTXO calldata mainUtxo,
|
|
162
|
+
address vault
|
|
163
|
+
) external onlyMaintainer {
|
|
164
|
+
uint256 gasStart = gasleft();
|
|
165
|
+
|
|
166
|
+
bridge.submitDepositSweepProof(sweepTx, sweepProof, mainUtxo, vault);
|
|
167
|
+
|
|
168
|
+
reimbursementPool.refund(
|
|
169
|
+
(gasStart - gasleft()) + submitDepositSweepProofGasOffset,
|
|
170
|
+
msg.sender
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/// @notice Wraps `Bridge.submitRedemptionProof` call and reimburses the
|
|
175
|
+
/// caller's transaction cost.
|
|
176
|
+
/// @dev See `Bridge.submitRedemptionProof` function documentation.
|
|
177
|
+
function submitRedemptionProof(
|
|
178
|
+
BitcoinTx.Info calldata redemptionTx,
|
|
179
|
+
BitcoinTx.Proof calldata redemptionProof,
|
|
180
|
+
BitcoinTx.UTXO calldata mainUtxo,
|
|
181
|
+
bytes20 walletPubKeyHash
|
|
182
|
+
) external onlyMaintainer {
|
|
183
|
+
uint256 gasStart = gasleft();
|
|
184
|
+
|
|
185
|
+
bridge.submitRedemptionProof(
|
|
186
|
+
redemptionTx,
|
|
187
|
+
redemptionProof,
|
|
188
|
+
mainUtxo,
|
|
189
|
+
walletPubKeyHash
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
reimbursementPool.refund(
|
|
193
|
+
(gasStart - gasleft()) + submitRedemptionProofGasOffset,
|
|
194
|
+
msg.sender
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/// @notice Wraps `Bridge.submitMovingFundsCommitment` call and reimburses the
|
|
199
|
+
/// caller's transaction cost.
|
|
200
|
+
/// @dev See `Bridge.submitMovingFundsCommitment` function documentation.
|
|
201
|
+
function submitMovingFundsCommitment(
|
|
202
|
+
bytes20 walletPubKeyHash,
|
|
203
|
+
BitcoinTx.UTXO calldata walletMainUtxo,
|
|
204
|
+
uint32[] calldata walletMembersIDs,
|
|
205
|
+
uint256 walletMemberIndex,
|
|
206
|
+
bytes20[] calldata targetWallets
|
|
207
|
+
) external {
|
|
208
|
+
uint256 gasStart = gasleft();
|
|
209
|
+
|
|
210
|
+
bridge.submitMovingFundsCommitment(
|
|
211
|
+
walletPubKeyHash,
|
|
212
|
+
walletMainUtxo,
|
|
213
|
+
walletMembersIDs,
|
|
214
|
+
walletMemberIndex,
|
|
215
|
+
targetWallets
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
reimbursementPool.refund(
|
|
219
|
+
(gasStart - gasleft()) + submitMovingFundsCommitmentGasOffset,
|
|
220
|
+
msg.sender
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/// @notice Wraps `Bridge.resetMovingFundsTimeout` call and reimburses the
|
|
225
|
+
/// caller's transaction cost.
|
|
226
|
+
/// @dev See `Bridge.resetMovingFundsTimeout` function documentation.
|
|
227
|
+
function resetMovingFundsTimeout(bytes20 walletPubKeyHash) external {
|
|
228
|
+
uint256 gasStart = gasleft();
|
|
229
|
+
|
|
230
|
+
bridge.resetMovingFundsTimeout(walletPubKeyHash);
|
|
231
|
+
|
|
232
|
+
reimbursementPool.refund(
|
|
233
|
+
(gasStart - gasleft()) + resetMovingFundsTimeoutGasOffset,
|
|
234
|
+
msg.sender
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/// @notice Wraps `Bridge.submitMovingFundsProof` call and reimburses the
|
|
239
|
+
/// caller's transaction cost.
|
|
240
|
+
/// @dev See `Bridge.submitMovingFundsProof` function documentation.
|
|
241
|
+
function submitMovingFundsProof(
|
|
242
|
+
BitcoinTx.Info calldata movingFundsTx,
|
|
243
|
+
BitcoinTx.Proof calldata movingFundsProof,
|
|
244
|
+
BitcoinTx.UTXO calldata mainUtxo,
|
|
245
|
+
bytes20 walletPubKeyHash
|
|
246
|
+
) external onlyMaintainer {
|
|
247
|
+
uint256 gasStart = gasleft();
|
|
248
|
+
|
|
249
|
+
bridge.submitMovingFundsProof(
|
|
250
|
+
movingFundsTx,
|
|
251
|
+
movingFundsProof,
|
|
252
|
+
mainUtxo,
|
|
253
|
+
walletPubKeyHash
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
reimbursementPool.refund(
|
|
257
|
+
(gasStart - gasleft()) + submitMovingFundsProofGasOffset,
|
|
258
|
+
msg.sender
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/// @notice Wraps `Bridge.notifyMovingFundsBelowDust` call and reimburses the
|
|
263
|
+
/// caller's transaction cost.
|
|
264
|
+
/// @dev See `Bridge.notifyMovingFundsBelowDust` function documentation.
|
|
265
|
+
function notifyMovingFundsBelowDust(
|
|
266
|
+
bytes20 walletPubKeyHash,
|
|
267
|
+
BitcoinTx.UTXO calldata mainUtxo
|
|
268
|
+
) external onlyMaintainer {
|
|
269
|
+
uint256 gasStart = gasleft();
|
|
270
|
+
|
|
271
|
+
bridge.notifyMovingFundsBelowDust(walletPubKeyHash, mainUtxo);
|
|
272
|
+
|
|
273
|
+
reimbursementPool.refund(
|
|
274
|
+
(gasStart - gasleft()) + notifyMovingFundsBelowDustGasOffset,
|
|
275
|
+
msg.sender
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/// @notice Wraps `Bridge.submitMovedFundsSweepProof` call and reimburses the
|
|
280
|
+
/// caller's transaction cost.
|
|
281
|
+
/// @dev See `Bridge.submitMovedFundsSweepProof` function documentation.
|
|
282
|
+
function submitMovedFundsSweepProof(
|
|
283
|
+
BitcoinTx.Info calldata sweepTx,
|
|
284
|
+
BitcoinTx.Proof calldata sweepProof,
|
|
285
|
+
BitcoinTx.UTXO calldata mainUtxo
|
|
286
|
+
) external onlyMaintainer {
|
|
287
|
+
uint256 gasStart = gasleft();
|
|
288
|
+
|
|
289
|
+
bridge.submitMovedFundsSweepProof(sweepTx, sweepProof, mainUtxo);
|
|
290
|
+
|
|
291
|
+
reimbursementPool.refund(
|
|
292
|
+
(gasStart - gasleft()) + submitMovedFundsSweepProofGasOffset,
|
|
293
|
+
msg.sender
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/// @notice Wraps `Bridge.requestNewWallet` call and reimburses the
|
|
298
|
+
/// caller's transaction cost.
|
|
299
|
+
/// @dev See `Bridge.requestNewWallet` function documentation.
|
|
300
|
+
function requestNewWallet(BitcoinTx.UTXO calldata activeWalletMainUtxo)
|
|
301
|
+
external
|
|
302
|
+
onlyMaintainer
|
|
303
|
+
{
|
|
304
|
+
uint256 gasStart = gasleft();
|
|
305
|
+
|
|
306
|
+
bridge.requestNewWallet(activeWalletMainUtxo);
|
|
307
|
+
|
|
308
|
+
reimbursementPool.refund(
|
|
309
|
+
(gasStart - gasleft()) + requestNewWalletGasOffset,
|
|
310
|
+
msg.sender
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/// @notice Wraps `Bridge.notifyWalletCloseable` call and reimburses the
|
|
315
|
+
/// caller's transaction cost.
|
|
316
|
+
/// @dev See `Bridge.notifyWalletCloseable` function documentation.
|
|
317
|
+
function notifyWalletCloseable(
|
|
318
|
+
bytes20 walletPubKeyHash,
|
|
319
|
+
BitcoinTx.UTXO calldata walletMainUtxo
|
|
320
|
+
) external onlyMaintainer {
|
|
321
|
+
uint256 gasStart = gasleft();
|
|
322
|
+
|
|
323
|
+
bridge.notifyWalletCloseable(walletPubKeyHash, walletMainUtxo);
|
|
324
|
+
|
|
325
|
+
reimbursementPool.refund(
|
|
326
|
+
(gasStart - gasleft()) + notifyWalletCloseableGasOffset,
|
|
327
|
+
msg.sender
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/// @notice Wraps `Bridge.notifyWalletClosingPeriodElapsed` call and reimburses
|
|
332
|
+
/// the caller's transaction cost.
|
|
333
|
+
/// @dev See `Bridge.notifyWalletClosingPeriodElapsed` function documentation.
|
|
334
|
+
function notifyWalletClosingPeriodElapsed(bytes20 walletPubKeyHash)
|
|
335
|
+
external
|
|
336
|
+
onlyMaintainer
|
|
337
|
+
{
|
|
338
|
+
uint256 gasStart = gasleft();
|
|
339
|
+
|
|
340
|
+
bridge.notifyWalletClosingPeriodElapsed(walletPubKeyHash);
|
|
341
|
+
|
|
342
|
+
reimbursementPool.refund(
|
|
343
|
+
(gasStart - gasleft()) + notifyWalletClosingPeriodElapsedGasOffset,
|
|
344
|
+
msg.sender
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/// @notice Wraps `Bridge.defeatFraudChallenge` call and reimburses the
|
|
349
|
+
/// caller's transaction cost.
|
|
350
|
+
/// @dev See `Bridge.defeatFraudChallenge` function documentation.
|
|
351
|
+
function defeatFraudChallenge(
|
|
352
|
+
bytes calldata walletPublicKey,
|
|
353
|
+
bytes calldata preimage,
|
|
354
|
+
bool witness
|
|
355
|
+
) external {
|
|
356
|
+
uint256 gasStart = gasleft();
|
|
357
|
+
|
|
358
|
+
bridge.defeatFraudChallenge(walletPublicKey, preimage, witness);
|
|
359
|
+
|
|
360
|
+
reimbursementPool.refund(
|
|
361
|
+
(gasStart - gasleft()) + defeatFraudChallengeGasOffset,
|
|
362
|
+
msg.sender
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/// @notice Wraps `Bridge.defeatFraudChallengeWithHeartbeat` call and
|
|
367
|
+
/// reimburses the caller's transaction cost.
|
|
368
|
+
/// @dev See `Bridge.defeatFraudChallengeWithHeartbeat` function documentation.
|
|
369
|
+
function defeatFraudChallengeWithHeartbeat(
|
|
370
|
+
bytes calldata walletPublicKey,
|
|
371
|
+
bytes calldata heartbeatMessage
|
|
372
|
+
) external {
|
|
373
|
+
uint256 gasStart = gasleft();
|
|
374
|
+
|
|
375
|
+
bridge.defeatFraudChallengeWithHeartbeat(
|
|
376
|
+
walletPublicKey,
|
|
377
|
+
heartbeatMessage
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
reimbursementPool.refund(
|
|
381
|
+
(gasStart - gasleft()) + defeatFraudChallengeWithHeartbeatGasOffset,
|
|
382
|
+
msg.sender
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/// @notice Authorize a maintainer that can interact with this reimbursement pool.
|
|
387
|
+
/// Can be authorized by the owner only.
|
|
388
|
+
/// @param maintainer Maintainer to authorize.
|
|
389
|
+
function authorize(address maintainer) external onlyOwner {
|
|
390
|
+
maintainers.push(maintainer);
|
|
391
|
+
isAuthorized[maintainer] = maintainers.length;
|
|
392
|
+
|
|
393
|
+
emit MaintainerAuthorized(maintainer);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/// @notice Unauthorize a maintainer that was previously authorized to interact
|
|
397
|
+
/// with the Maintainer Proxy contract. Can be unauthorized by the
|
|
398
|
+
/// owner only.
|
|
399
|
+
/// @dev The last maintainer is swapped with the one to be unauthorized.
|
|
400
|
+
/// The unauthorized maintainer is then removed from the list. An index
|
|
401
|
+
/// of the last maintainer is changed with the removed maintainer.
|
|
402
|
+
/// Ex.
|
|
403
|
+
/// 'maintainers' list: [0x1, 0x2, 0x3, 0x4, 0x5]
|
|
404
|
+
/// 'isAuthorized' map: [0x1 -> 1, 0x2 -> 2, 0x3 -> 3, 0x4 -> 4, 0x5 -> 5]
|
|
405
|
+
/// unauthorize: 0x3
|
|
406
|
+
/// new 'maintainers' list: [0x1, 0x2, 0x5, 0x4]
|
|
407
|
+
/// new 'isAuthorized' map: [0x1 -> 1, 0x2 -> 2, 0x4 -> 4, 0x5 -> 3]
|
|
408
|
+
/// @param maintainerToUnauthorize Maintainer to unauthorize.
|
|
409
|
+
function unauthorize(address maintainerToUnauthorize) external onlyOwner {
|
|
410
|
+
uint256 maintainerIdToUnauthorize = isAuthorized[
|
|
411
|
+
maintainerToUnauthorize
|
|
412
|
+
];
|
|
413
|
+
|
|
414
|
+
require(maintainerIdToUnauthorize != 0, "No maintainer to unauthorize");
|
|
415
|
+
|
|
416
|
+
address lastMaintainerAddress = maintainers[maintainers.length - 1];
|
|
417
|
+
|
|
418
|
+
maintainers[maintainerIdToUnauthorize - 1] = lastMaintainerAddress;
|
|
419
|
+
maintainers.pop();
|
|
420
|
+
|
|
421
|
+
isAuthorized[lastMaintainerAddress] = maintainerIdToUnauthorize;
|
|
422
|
+
|
|
423
|
+
delete isAuthorized[maintainerToUnauthorize];
|
|
424
|
+
|
|
425
|
+
emit MaintainerUnauthorized(maintainerToUnauthorize);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/// @notice Allows the Governance to upgrade the Bridge address.
|
|
429
|
+
/// @dev The function does not implement any governance delay and does not
|
|
430
|
+
/// check the status of the Bridge. The Governance implementation needs
|
|
431
|
+
/// to ensure all requirements for the upgrade are satisfied before
|
|
432
|
+
/// executing this function.
|
|
433
|
+
function updateBridge(Bridge _bridge) external onlyOwner {
|
|
434
|
+
bridge = _bridge;
|
|
435
|
+
|
|
436
|
+
emit BridgeUpdated(address(_bridge));
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/// @notice Updates the values of gas offset parameters.
|
|
440
|
+
/// @dev Can be called only by the contract owner. The caller is responsible
|
|
441
|
+
/// for validating parameters.
|
|
442
|
+
/// @param newSubmitDepositSweepProofGasOffset New submit deposit sweep
|
|
443
|
+
/// proof gas offset.
|
|
444
|
+
/// @param newSubmitRedemptionProofGasOffset New submit redemption proof gas
|
|
445
|
+
/// offset.
|
|
446
|
+
/// @param newSubmitMovingFundsCommitmentGasOffset New submit moving funds
|
|
447
|
+
/// commitment gas offset.
|
|
448
|
+
/// @param newResetMovingFundsTimeoutGasOffset New reset moving funds
|
|
449
|
+
/// timeout gas offset.
|
|
450
|
+
/// @param newSubmitMovingFundsProofGasOffset New submit moving funds proof
|
|
451
|
+
/// gas offset.
|
|
452
|
+
/// @param newNotifyMovingFundsBelowDustGasOffset New notify moving funds
|
|
453
|
+
/// below dust gas offset.
|
|
454
|
+
/// @param newSubmitMovedFundsSweepProofGasOffset New submit moved funds
|
|
455
|
+
/// sweep proof gas offset.
|
|
456
|
+
/// @param newRequestNewWalletGasOffset New request new wallet gas offset.
|
|
457
|
+
/// @param newNotifyWalletCloseableGasOffset New notify closeable wallet gas
|
|
458
|
+
/// offset.
|
|
459
|
+
/// @param newNotifyWalletClosingPeriodElapsedGasOffset New notify wallet
|
|
460
|
+
/// closing period elapsed gas offset.
|
|
461
|
+
/// @param newDefeatFraudChallengeGasOffset New defeat fraud challenge gas
|
|
462
|
+
/// offset.
|
|
463
|
+
/// @param newDefeatFraudChallengeWithHeartbeatGasOffset New defeat fraud
|
|
464
|
+
/// challenge with heartbeat gas offset.
|
|
465
|
+
function updateGasOffsetParameters(
|
|
466
|
+
uint256 newSubmitDepositSweepProofGasOffset,
|
|
467
|
+
uint256 newSubmitRedemptionProofGasOffset,
|
|
468
|
+
uint256 newSubmitMovingFundsCommitmentGasOffset,
|
|
469
|
+
uint256 newResetMovingFundsTimeoutGasOffset,
|
|
470
|
+
uint256 newSubmitMovingFundsProofGasOffset,
|
|
471
|
+
uint256 newNotifyMovingFundsBelowDustGasOffset,
|
|
472
|
+
uint256 newSubmitMovedFundsSweepProofGasOffset,
|
|
473
|
+
uint256 newRequestNewWalletGasOffset,
|
|
474
|
+
uint256 newNotifyWalletCloseableGasOffset,
|
|
475
|
+
uint256 newNotifyWalletClosingPeriodElapsedGasOffset,
|
|
476
|
+
uint256 newDefeatFraudChallengeGasOffset,
|
|
477
|
+
uint256 newDefeatFraudChallengeWithHeartbeatGasOffset
|
|
478
|
+
) external onlyOwner {
|
|
479
|
+
submitDepositSweepProofGasOffset = newSubmitDepositSweepProofGasOffset;
|
|
480
|
+
submitRedemptionProofGasOffset = newSubmitRedemptionProofGasOffset;
|
|
481
|
+
submitMovingFundsCommitmentGasOffset = newSubmitMovingFundsCommitmentGasOffset;
|
|
482
|
+
resetMovingFundsTimeoutGasOffset = newResetMovingFundsTimeoutGasOffset;
|
|
483
|
+
submitMovingFundsProofGasOffset = newSubmitMovingFundsProofGasOffset;
|
|
484
|
+
notifyMovingFundsBelowDustGasOffset = newNotifyMovingFundsBelowDustGasOffset;
|
|
485
|
+
submitMovedFundsSweepProofGasOffset = newSubmitMovedFundsSweepProofGasOffset;
|
|
486
|
+
requestNewWalletGasOffset = newRequestNewWalletGasOffset;
|
|
487
|
+
notifyWalletCloseableGasOffset = newNotifyWalletCloseableGasOffset;
|
|
488
|
+
notifyWalletClosingPeriodElapsedGasOffset = newNotifyWalletClosingPeriodElapsedGasOffset;
|
|
489
|
+
defeatFraudChallengeGasOffset = newDefeatFraudChallengeGasOffset;
|
|
490
|
+
defeatFraudChallengeWithHeartbeatGasOffset = newDefeatFraudChallengeWithHeartbeatGasOffset;
|
|
491
|
+
|
|
492
|
+
emit GasOffsetParametersUpdated(
|
|
493
|
+
submitDepositSweepProofGasOffset,
|
|
494
|
+
submitRedemptionProofGasOffset,
|
|
495
|
+
submitMovingFundsCommitmentGasOffset,
|
|
496
|
+
resetMovingFundsTimeoutGasOffset,
|
|
497
|
+
submitMovingFundsProofGasOffset,
|
|
498
|
+
notifyMovingFundsBelowDustGasOffset,
|
|
499
|
+
submitMovedFundsSweepProofGasOffset,
|
|
500
|
+
requestNewWalletGasOffset,
|
|
501
|
+
notifyWalletCloseableGasOffset,
|
|
502
|
+
notifyWalletClosingPeriodElapsedGasOffset,
|
|
503
|
+
defeatFraudChallengeGasOffset,
|
|
504
|
+
defeatFraudChallengeWithHeartbeatGasOffset
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/// @notice Gets an entire array of maintainer addresses.
|
|
509
|
+
function allMaintainers() external view returns (address[] memory) {
|
|
510
|
+
return maintainers;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { deployments, getNamedAccounts } = hre
|
|
6
|
+
const { deploy } = deployments
|
|
7
|
+
const { deployer } = await getNamedAccounts()
|
|
8
|
+
|
|
9
|
+
const Bridge = await deployments.get("Bridge")
|
|
10
|
+
const ReimbursementPool = await deployments.get("ReimbursementPool")
|
|
11
|
+
|
|
12
|
+
const MaintainerProxy = await deploy("MaintainerProxy", {
|
|
13
|
+
contract: "MaintainerProxy",
|
|
14
|
+
from: deployer,
|
|
15
|
+
args: [Bridge.address, ReimbursementPool.address],
|
|
16
|
+
log: true,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
if (hre.network.tags.tenderly) {
|
|
20
|
+
await hre.tenderly.verify({
|
|
21
|
+
name: "MaintainerProxy",
|
|
22
|
+
address: MaintainerProxy.address,
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default func
|
|
28
|
+
|
|
29
|
+
func.tags = ["MaintainerProxy"]
|
|
30
|
+
func.dependencies = ["Bridge", "ReimbursementPool"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { getNamedAccounts, helpers } = hre
|
|
6
|
+
const { deployer, governance } = await getNamedAccounts()
|
|
7
|
+
|
|
8
|
+
await helpers.ownable.transferOwnership(
|
|
9
|
+
"MaintainerProxy",
|
|
10
|
+
governance,
|
|
11
|
+
deployer
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default func
|
|
16
|
+
|
|
17
|
+
func.tags = ["TransferMaintainerProxyOwnership"]
|
|
18
|
+
func.dependencies = ["MaintainerProxy"]
|
|
19
|
+
func.runAtTheEnd = true
|
|
File without changes
|
package/deploy/{15_transfer_proxy_admin_ownership.ts → 16_transfer_proxy_admin_ownership.ts}
RENAMED
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { getNamedAccounts, deployments } = hre
|
|
6
|
+
const { execute } = deployments
|
|
7
|
+
const { deployer } = await getNamedAccounts()
|
|
8
|
+
|
|
9
|
+
const MaintainerProxy = await deployments.get("MaintainerProxy")
|
|
10
|
+
|
|
11
|
+
await execute(
|
|
12
|
+
"ReimbursementPool",
|
|
13
|
+
{ from: deployer },
|
|
14
|
+
"authorize",
|
|
15
|
+
MaintainerProxy.address
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default func
|
|
20
|
+
|
|
21
|
+
func.tags = ["AuthorizeMaintainerProxy"]
|
|
22
|
+
func.dependencies = ["ReimbursementPool", "MaintainerProxy"]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { getNamedAccounts, helpers } = hre
|
|
6
|
+
const { deployer, governance } = await getNamedAccounts()
|
|
7
|
+
|
|
8
|
+
await helpers.ownable.transferOwnership(
|
|
9
|
+
"ReimbursementPool",
|
|
10
|
+
governance,
|
|
11
|
+
deployer
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default func
|
|
16
|
+
|
|
17
|
+
func.tags = ["TransferReimbursementPoolOwnership"]
|
|
18
|
+
func.dependencies = ["ReimbursementPool"]
|
|
19
|
+
func.runAtTheEnd = true
|
package/deploy/{14_deploy_proxy_admin_with_deputy.ts → 19_deploy_proxy_admin_with_deputy.ts}
RENAMED
|
File without changes
|