@keep-network/tbtc-v2 0.1.1-dev.101 → 0.1.1-dev.104
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 +13 -13
- package/artifacts/BridgeGovernanceParameters.json +4 -4
- package/artifacts/Deposit.json +7 -7
- package/artifacts/DepositSweep.json +9 -9
- package/artifacts/EcdsaDkgValidator.json +3 -3
- package/artifacts/EcdsaInactivity.json +3 -3
- package/artifacts/EcdsaSortitionPool.json +5 -5
- package/artifacts/Fraud.json +7 -7
- 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 +7 -7
- package/artifacts/NuCypherStakingEscrow.json +3 -3
- package/artifacts/NuCypherToken.json +5 -5
- package/artifacts/RandomBeaconStub.json +3 -3
- package/artifacts/Redemption.json +9 -9
- package/artifacts/ReimbursementPool.json +5 -5
- package/artifacts/Relay.json +9 -9
- 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 +7 -7
- package/artifacts/solcInputs/{af641e0b3597cdfa29d6ad42d1cd8742.json → 4d9b6f53ac50e0b0457be71c45eba893.json} +28 -25
- 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/BitcoinTx.sol/BitcoinTx.json +2 -2
- package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
- package/build/contracts/bridge/Bridge.sol/Bridge.json +2 -2
- package/build/contracts/bridge/BridgeGovernance.sol/BridgeGovernance.dbg.json +1 -1
- package/build/contracts/bridge/BridgeGovernance.sol/BridgeGovernance.json +2 -2
- 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/BridgeState.sol/BridgeState.json +2 -2
- package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +1 -1
- package/build/contracts/bridge/Deposit.sol/Deposit.json +2 -2
- package/build/contracts/bridge/DepositSweep.sol/DepositSweep.dbg.json +1 -1
- package/build/contracts/bridge/DepositSweep.sol/DepositSweep.json +2 -2
- 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/Fraud.sol/Fraud.json +2 -2
- 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/MovingFunds.sol/MovingFunds.json +2 -2
- package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +1 -1
- package/build/contracts/bridge/Redemption.sol/OutboundTx.json +2 -2
- package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +1 -1
- package/build/contracts/bridge/Redemption.sol/Redemption.json +2 -2
- 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/bridge/Wallets.sol/Wallets.json +2 -2
- 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/bridge/Bridge.sol +2 -2
- package/contracts/bridge/BridgeGovernance.sol +2 -2
- package/contracts/bridge/Redemption.sol +3 -3
- 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
|
@@ -472,10 +472,10 @@ contract Bridge is
|
|
|
472
472
|
/// - redeemer: The Ethereum address of the redeemer who will be able
|
|
473
473
|
/// to claim Bank balance if anything goes wrong during the redemption.
|
|
474
474
|
/// In the most basic case, when someone redeems their balance
|
|
475
|
-
/// from the Bank, `balanceOwner` is the same as `
|
|
475
|
+
/// from the Bank, `balanceOwner` is the same as `redeemer`.
|
|
476
476
|
/// However, when a Vault is redeeming part of its balance for some
|
|
477
477
|
/// redeemer address (for example, someone who has earlier deposited
|
|
478
|
-
/// into that Vault), `balanceOwner` is the Vault, and `
|
|
478
|
+
/// into that Vault), `balanceOwner` is the Vault, and `redeemer` is
|
|
479
479
|
/// the address for which the vault is redeeming its balance to,
|
|
480
480
|
/// - walletPubKeyHash: The 20-byte wallet public key hash (computed
|
|
481
481
|
/// using Bitcoin HASH160 over the compressed ECDSA public key),
|
|
@@ -336,7 +336,7 @@ contract BridgeGovernance is Ownable {
|
|
|
336
336
|
|
|
337
337
|
/// @notice Finalizes the bridge governance transfer process.
|
|
338
338
|
/// @dev Can be called only by the contract owner, after the governance
|
|
339
|
-
/// delay elapses. Bridge governance
|
|
339
|
+
/// delay elapses. Bridge governance transferred event can be read
|
|
340
340
|
/// from the Governable bridge contract 'GovernanceTransferred(old, new)'.
|
|
341
341
|
/// Event that informs about the transfer in this function is skipped on
|
|
342
342
|
/// purpose to go down with the contract size.
|
|
@@ -1329,7 +1329,7 @@ contract BridgeGovernance is Ownable {
|
|
|
1329
1329
|
walletData.finalizeWalletMaxAgeUpdate(governanceDelay());
|
|
1330
1330
|
}
|
|
1331
1331
|
|
|
1332
|
-
/// @notice Begins the wallet max btc
|
|
1332
|
+
/// @notice Begins the wallet max btc transfer amount update process.
|
|
1333
1333
|
/// @dev Can be called only by the contract owner.
|
|
1334
1334
|
/// @param _newWalletMaxBtcTransfer New wallet max btc transfer.
|
|
1335
1335
|
function beginWalletMaxBtcTransferUpdate(uint64 _newWalletMaxBtcTransfer)
|
|
@@ -218,7 +218,7 @@ library Redemption {
|
|
|
218
218
|
/// the Ethereum chain.
|
|
219
219
|
/// @param balanceOwner The address of the Bank balance owner whose balance
|
|
220
220
|
/// is getting redeemed. Balance owner address is stored as
|
|
221
|
-
/// a
|
|
221
|
+
/// a redeemer address who will be able co claim back the Bank
|
|
222
222
|
/// balance if anything goes wrong during the redemption.
|
|
223
223
|
/// @param redeemerOutputScript The redeemer's length-prefixed output
|
|
224
224
|
/// script (P2PKH, P2WPKH, P2SH or P2WSH) that will be used to lock
|
|
@@ -289,10 +289,10 @@ library Redemption {
|
|
|
289
289
|
/// - redeemer: The Ethereum address of the redeemer who will be able
|
|
290
290
|
/// to claim Bank balance if anything goes wrong during the redemption.
|
|
291
291
|
/// In the most basic case, when someone redeems their Bitcoin
|
|
292
|
-
/// balance from the Bank, `balanceOwner` is the same as `
|
|
292
|
+
/// balance from the Bank, `balanceOwner` is the same as `redeemer`.
|
|
293
293
|
/// However, when a Vault is redeeming part of its balance for some
|
|
294
294
|
/// redeemer address (for example, someone who has earlier deposited
|
|
295
|
-
/// into that Vault), `balanceOwner` is the Vault, and `
|
|
295
|
+
/// into that Vault), `balanceOwner` is the Vault, and `redeemer` is
|
|
296
296
|
/// the address for which the vault is redeeming its balance to,
|
|
297
297
|
/// - walletPubKeyHash: The 20-byte wallet public key hash (computed
|
|
298
298
|
/// using Bitcoin HASH160 over the compressed ECDSA public key),
|
|
@@ -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
|