@keep-network/tbtc-v2 0.1.1-dev.41 → 0.1.1-dev.44

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.
Files changed (81) hide show
  1. package/artifacts/Bank.json +742 -0
  2. package/artifacts/Bridge.json +2914 -0
  3. package/artifacts/Deposit.json +117 -0
  4. package/artifacts/EcdsaDkgValidator.json +532 -0
  5. package/artifacts/EcdsaInactivity.json +156 -0
  6. package/artifacts/Fraud.json +153 -0
  7. package/artifacts/KeepRegistry.json +99 -0
  8. package/artifacts/KeepStake.json +286 -0
  9. package/artifacts/KeepToken.json +711 -0
  10. package/artifacts/KeepTokenStaking.json +483 -0
  11. package/artifacts/MovingFunds.json +137 -0
  12. package/artifacts/NuCypherStakingEscrow.json +256 -0
  13. package/artifacts/NuCypherToken.json +711 -0
  14. package/artifacts/RandomBeaconStub.json +141 -0
  15. package/artifacts/Redemption.json +161 -0
  16. package/artifacts/ReimbursementPool.json +509 -0
  17. package/artifacts/Relay.json +123 -0
  18. package/artifacts/SortitionPool.json +944 -0
  19. package/artifacts/Sweep.json +76 -0
  20. package/artifacts/T.json +1148 -0
  21. package/artifacts/TBTC.json +21 -21
  22. package/artifacts/TBTCToken.json +21 -21
  23. package/artifacts/TokenStaking.json +2288 -0
  24. package/artifacts/TokenholderGovernor.json +1795 -0
  25. package/artifacts/TokenholderTimelock.json +1058 -0
  26. package/artifacts/VendingMachine.json +24 -24
  27. package/artifacts/VendingMachineKeep.json +400 -0
  28. package/artifacts/VendingMachineNuCypher.json +400 -0
  29. package/artifacts/WalletRegistry.json +2709 -0
  30. package/artifacts/WalletRegistryGovernance.json +2364 -0
  31. package/artifacts/Wallets.json +186 -0
  32. package/artifacts/solcInputs/{e9b173393b9fd7287a0bfaa6d4eb4b71.json → bbe44823ec28554a9429cce5cafee035.json} +34 -34
  33. package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
  34. package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
  35. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +1 -1
  36. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.json +2 -2
  37. package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
  38. package/build/contracts/bridge/Bridge.sol/Bridge.json +535 -273
  39. package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
  40. package/build/contracts/bridge/BridgeState.sol/BridgeState.json +147 -3
  41. package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +1 -1
  42. package/build/contracts/bridge/Deposit.sol/Deposit.json +2 -2
  43. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +1 -1
  44. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.json +2 -2
  45. package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +1 -1
  46. package/build/contracts/bridge/Fraud.sol/Fraud.json +5 -57
  47. package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +1 -1
  48. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +1 -1
  49. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.json +41 -21
  50. package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +4 -0
  51. package/build/contracts/bridge/{Redeem.sol → Redemption.sol}/OutboundTx.json +3 -3
  52. package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +4 -0
  53. package/build/contracts/bridge/Redemption.sol/Redemption.json +92 -0
  54. package/build/contracts/bridge/Sweep.sol/Sweep.dbg.json +1 -1
  55. package/build/contracts/bridge/Sweep.sol/Sweep.json +2 -2
  56. package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
  57. package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +1 -1
  58. package/build/contracts/bridge/Wallets.sol/Wallets.json +12 -38
  59. package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
  60. package/build/contracts/vault/IVault.sol/IVault.dbg.json +1 -1
  61. package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
  62. package/contracts/bridge/BitcoinTx.sol +19 -26
  63. package/contracts/bridge/Bridge.sol +765 -524
  64. package/contracts/bridge/BridgeState.sol +312 -23
  65. package/contracts/bridge/Deposit.sol +25 -6
  66. package/contracts/bridge/EcdsaLib.sol +15 -0
  67. package/contracts/bridge/Fraud.sol +65 -33
  68. package/contracts/bridge/MovingFunds.sol +196 -10
  69. package/contracts/bridge/{Redeem.sol → Redemption.sol} +26 -29
  70. package/contracts/bridge/Sweep.sol +16 -12
  71. package/contracts/bridge/Wallets.sol +90 -153
  72. package/deploy/00_resolve_relay.ts +28 -0
  73. package/deploy/04_deploy_bank.ts +25 -0
  74. package/deploy/05_deploy_bridge.ts +60 -0
  75. package/deploy/06_bank_update_bridge.ts +19 -0
  76. package/deploy/07_transfer_ownership.ts +17 -0
  77. package/export.json +14797 -459
  78. package/package.json +2 -2
  79. package/build/contracts/bridge/Redeem.sol/OutboundTx.dbg.json +0 -4
  80. package/build/contracts/bridge/Redeem.sol/Redeem.dbg.json +0 -4
  81. package/build/contracts/bridge/Redeem.sol/Redeem.json +0 -110
@@ -17,16 +17,13 @@ pragma solidity ^0.8.9;
17
17
 
18
18
  import "@openzeppelin/contracts/access/Ownable.sol";
19
19
 
20
- import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
21
- import {BytesLib} from "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
22
-
23
20
  import {IWalletOwner as EcdsaWalletOwner} from "@keep-network/ecdsa/contracts/api/IWalletOwner.sol";
24
21
 
25
22
  import "./IRelay.sol";
26
23
  import "./BridgeState.sol";
27
24
  import "./Deposit.sol";
28
25
  import "./Sweep.sol";
29
- import "./Redeem.sol";
26
+ import "./Redemption.sol";
30
27
  import "./BitcoinTx.sol";
31
28
  import "./EcdsaLib.sol";
32
29
  import "./Wallets.sol";
@@ -53,77 +50,24 @@ import "../bank/Bank.sol";
53
50
  /// the sweep operation is confirmed on the Bitcoin network, the ECDSA
54
51
  /// wallet informs the Bridge about the sweep increasing appropriate
55
52
  /// balances in the Bank.
56
- /// @dev Bridge is an upgradeable component of the Bank.
53
+ /// @dev Bridge is an upgradeable component of the Bank. The order of
54
+ /// functionalities in this contract is: deposit, sweep, redemption,
55
+ /// moving funds, wallet lifecycle, frauds, parameters.
57
56
  ///
58
- // TODO: All wallets-related operations that are currently done directly
59
- // by the Bridge can be probably delegated to the Wallets library.
60
- // Examples of such operations are main UTXO or pending redemptions
61
- // value updates.
57
+ /// TODO: Revisit all events and look which parameters should be indexed.
58
+ /// TODO: Align the convention around `param` and `dev` endings. They should
59
+ /// not have a punctuation mark.
62
60
  contract Bridge is Ownable, EcdsaWalletOwner {
63
61
  using BridgeState for BridgeState.Storage;
64
62
  using Deposit for BridgeState.Storage;
65
63
  using Sweep for BridgeState.Storage;
66
- using Redeem for BridgeState.Storage;
64
+ using Redemption for BridgeState.Storage;
67
65
  using MovingFunds for BridgeState.Storage;
66
+ using Wallets for BridgeState.Storage;
68
67
  using Fraud for BridgeState.Storage;
69
- using Wallets for Wallets.Data;
70
-
71
- using BTCUtils for bytes;
72
- using BTCUtils for uint256;
73
- using BytesLib for bytes;
74
68
 
75
69
  BridgeState.Storage internal self;
76
70
 
77
- /// @notice State related with wallets.
78
- Wallets.Data internal wallets;
79
-
80
- event WalletCreationPeriodUpdated(uint32 newCreationPeriod);
81
-
82
- event WalletBtcBalanceRangeUpdated(
83
- uint64 newMinBtcBalance,
84
- uint64 newMaxBtcBalance
85
- );
86
-
87
- event WalletMaxAgeUpdated(uint32 newMaxAge);
88
-
89
- event NewWalletRequested();
90
-
91
- event NewWalletRegistered(
92
- bytes32 indexed ecdsaWalletID,
93
- bytes20 indexed walletPubKeyHash
94
- );
95
-
96
- event WalletMovingFunds(
97
- bytes32 indexed ecdsaWalletID,
98
- bytes20 indexed walletPubKeyHash
99
- );
100
-
101
- event WalletClosed(
102
- bytes32 indexed ecdsaWalletID,
103
- bytes20 indexed walletPubKeyHash
104
- );
105
-
106
- event WalletTerminated(
107
- bytes32 indexed ecdsaWalletID,
108
- bytes20 indexed walletPubKeyHash
109
- );
110
-
111
- event VaultStatusUpdated(address indexed vault, bool isTrusted);
112
-
113
- event FraudSlashingAmountUpdated(uint256 newFraudSlashingAmount);
114
-
115
- event FraudNotifierRewardMultiplierUpdated(
116
- uint256 newFraudNotifierRewardMultiplier
117
- );
118
-
119
- event FraudChallengeDefeatTimeoutUpdated(
120
- uint256 newFraudChallengeDefeatTimeout
121
- );
122
-
123
- event FraudChallengeDepositAmountUpdated(
124
- uint256 newFraudChallengeDepositAmount
125
- );
126
-
127
71
  event DepositRevealed(
128
72
  bytes32 fundingTxHash,
129
73
  uint32 fundingOutputIndex,
@@ -157,24 +101,94 @@ contract Bridge is Ownable, EcdsaWalletOwner {
157
101
  bytes redeemerOutputScript
158
102
  );
159
103
 
104
+ event WalletMovingFunds(
105
+ bytes32 indexed ecdsaWalletID,
106
+ bytes20 indexed walletPubKeyHash
107
+ );
108
+
109
+ event MovingFundsCommitmentSubmitted(
110
+ bytes20 walletPubKeyHash,
111
+ bytes20[] targetWallets,
112
+ address submitter
113
+ );
114
+
115
+ event MovingFundsCompleted(
116
+ bytes20 walletPubKeyHash,
117
+ bytes32 movingFundsTxHash
118
+ );
119
+
120
+ event MovingFundsTimedOut(bytes20 walletPubKeyHash);
121
+
122
+ event NewWalletRequested();
123
+
124
+ event NewWalletRegistered(
125
+ bytes32 indexed ecdsaWalletID,
126
+ bytes20 indexed walletPubKeyHash
127
+ );
128
+
129
+ event WalletClosing(
130
+ bytes32 indexed ecdsaWalletID,
131
+ bytes20 indexed walletPubKeyHash
132
+ );
133
+
134
+ event WalletClosed(
135
+ bytes32 indexed ecdsaWalletID,
136
+ bytes20 indexed walletPubKeyHash
137
+ );
138
+
139
+ event WalletTerminated(
140
+ bytes32 indexed ecdsaWalletID,
141
+ bytes20 indexed walletPubKeyHash
142
+ );
143
+
160
144
  event FraudChallengeSubmitted(
161
- bytes20 walletPublicKeyHash,
145
+ bytes20 walletPubKeyHash,
162
146
  bytes32 sighash,
163
147
  uint8 v,
164
148
  bytes32 r,
165
149
  bytes32 s
166
150
  );
167
151
 
168
- event FraudChallengeDefeated(bytes20 walletPublicKeyHash, bytes32 sighash);
152
+ event FraudChallengeDefeated(bytes20 walletPubKeyHash, bytes32 sighash);
169
153
 
170
154
  event FraudChallengeDefeatTimedOut(
171
- bytes20 walletPublicKeyHash,
155
+ bytes20 walletPubKeyHash,
172
156
  bytes32 sighash
173
157
  );
174
158
 
175
- event MovingFundsCompleted(
176
- bytes20 walletPubKeyHash,
177
- bytes32 movingFundsTxHash
159
+ event VaultStatusUpdated(address indexed vault, bool isTrusted);
160
+
161
+ event DepositParametersUpdated(
162
+ uint64 depositDustThreshold,
163
+ uint64 depositTreasuryFeeDivisor,
164
+ uint64 depositTxMaxFee
165
+ );
166
+
167
+ event RedemptionParametersUpdated(
168
+ uint64 redemptionDustThreshold,
169
+ uint64 redemptionTreasuryFeeDivisor,
170
+ uint64 redemptionTxMaxFee,
171
+ uint256 redemptionTimeout
172
+ );
173
+
174
+ event MovingFundsParametersUpdated(
175
+ uint64 movingFundsTxMaxTotalFee,
176
+ uint32 movingFundsTimeout
177
+ );
178
+
179
+ event WalletParametersUpdated(
180
+ uint32 walletCreationPeriod,
181
+ uint64 walletMinBtcBalance,
182
+ uint64 walletMaxBtcBalance,
183
+ uint32 walletMaxAge,
184
+ uint64 walletMaxBtcTransfer
185
+ );
186
+
187
+ event FraudParametersUpdated(
188
+ uint256 fraudSlashingAmount,
189
+ uint256 fraudNotifierRewardMultiplier,
190
+ uint256 fraudChallengeDefeatTimeout,
191
+ uint256 fraudChallengeDepositAmount
178
192
  );
179
193
 
180
194
  constructor(
@@ -190,6 +204,12 @@ contract Bridge is Ownable, EcdsaWalletOwner {
190
204
  require(_relay != address(0), "Relay address cannot be zero");
191
205
  self.relay = IRelay(_relay);
192
206
 
207
+ require(
208
+ _ecdsaWalletRegistry != address(0),
209
+ "ECDSA Wallet Registry address cannot be zero"
210
+ );
211
+ self.ecdsaWalletRegistry = EcdsaWalletRegistry(_ecdsaWalletRegistry);
212
+
193
213
  require(_treasury != address(0), "Treasury address cannot be zero");
194
214
  self.treasury = _treasury;
195
215
 
@@ -204,175 +224,16 @@ contract Bridge is Ownable, EcdsaWalletOwner {
204
224
  self.redemptionTxMaxFee = 10000; // 10000 satoshi
205
225
  self.redemptionTimeout = 172800; // 48 hours
206
226
  self.movingFundsTxMaxTotalFee = 10000; // 10000 satoshi
227
+ self.movingFundsTimeout = 7 days;
207
228
  self.fraudSlashingAmount = 10000 * 1e18; // 10000 T
208
229
  self.fraudNotifierRewardMultiplier = 100; // 100%
209
230
  self.fraudChallengeDefeatTimeout = 7 days;
210
231
  self.fraudChallengeDepositAmount = 2 ether;
211
-
212
- // TODO: Revisit initial values.
213
- wallets.init(_ecdsaWalletRegistry);
214
- wallets.setCreationPeriod(1 weeks);
215
- wallets.setBtcBalanceRange(1 * 1e8, 10 * 1e8); // [1 BTC, 10 BTC]
216
- wallets.setMaxAge(26 weeks); // ~6 months
217
- }
218
-
219
- /// @notice Updates parameters used by the `Wallets` library.
220
- /// @param creationPeriod New value of the wallet creation period
221
- /// @param minBtcBalance New value of the minimum BTC balance
222
- /// @param maxBtcBalance New value of the maximum BTC balance
223
- /// @param maxAge New value of the wallet maximum age
224
- /// @dev Requirements:
225
- /// - Caller must be the contract owner.
226
- /// - Minimum BTC balance must be greater than zero
227
- /// - Maximum BTC balance must be greater than minimum BTC balance
228
- function updateWalletsParameters(
229
- uint32 creationPeriod,
230
- uint64 minBtcBalance,
231
- uint64 maxBtcBalance,
232
- uint32 maxAge
233
- ) external onlyOwner {
234
- wallets.setCreationPeriod(creationPeriod);
235
- wallets.setBtcBalanceRange(minBtcBalance, maxBtcBalance);
236
- wallets.setMaxAge(maxAge);
237
- }
238
-
239
- /// @return creationPeriod Value of the wallet creation period
240
- /// @return minBtcBalance Value of the minimum BTC balance
241
- /// @return maxBtcBalance Value of the maximum BTC balance
242
- /// @return maxAge Value of the wallet max age
243
- function getWalletsParameters()
244
- external
245
- view
246
- returns (
247
- uint32 creationPeriod,
248
- uint64 minBtcBalance,
249
- uint64 maxBtcBalance,
250
- uint32 maxAge
251
- )
252
- {
253
- creationPeriod = wallets.creationPeriod;
254
- minBtcBalance = wallets.minBtcBalance;
255
- maxBtcBalance = wallets.maxBtcBalance;
256
- maxAge = wallets.maxAge;
257
-
258
- return (creationPeriod, minBtcBalance, maxBtcBalance, maxAge);
259
- }
260
-
261
- /// @notice Allows the Governance to mark the given vault address as trusted
262
- /// or no longer trusted. Vaults are not trusted by default.
263
- /// Trusted vault must meet the following criteria:
264
- /// - `IVault.receiveBalanceIncrease` must have a known, low gas
265
- /// cost.
266
- /// - `IVault.receiveBalanceIncrease` must never revert.
267
- /// @dev Without restricting reveal only to trusted vaults, malicious
268
- /// vaults not meeting the criteria would be able to nuke sweep proof
269
- /// transactions executed by ECDSA wallet with deposits routed to
270
- /// them.
271
- /// @param vault The address of the vault
272
- /// @param isTrusted flag indicating whether the vault is trusted or not
273
- /// @dev Can only be called by the Governance.
274
- function setVaultStatus(address vault, bool isTrusted) external onlyOwner {
275
- self.isVaultTrusted[vault] = isTrusted;
276
- emit VaultStatusUpdated(vault, isTrusted);
277
- }
278
-
279
- /// @notice Requests creation of a new wallet. This function just
280
- /// forms a request and the creation process is performed
281
- /// asynchronously. Once a wallet is created, the ECDSA Wallet
282
- /// Registry will notify this contract by calling the
283
- /// `__ecdsaWalletCreatedCallback` function.
284
- /// @param activeWalletMainUtxo Data of the active wallet's main UTXO, as
285
- /// currently known on the Ethereum chain.
286
- /// @dev Requirements:
287
- /// - `activeWalletMainUtxo` components must point to the recent main
288
- /// UTXO of the given active wallet, as currently known on the
289
- /// Ethereum chain. If there is no active wallet at the moment, or
290
- /// the active wallet has no main UTXO, this parameter can be
291
- /// empty as it is ignored.
292
- /// - Wallet creation must not be in progress
293
- /// - If the active wallet is set, one of the following
294
- /// conditions must be true:
295
- /// - The active wallet BTC balance is above the minimum threshold
296
- /// and the active wallet is old enough, i.e. the creation period
297
- /// was elapsed since its creation time
298
- /// - The active wallet BTC balance is above the maximum threshold
299
- function requestNewWallet(BitcoinTx.UTXO calldata activeWalletMainUtxo)
300
- external
301
- {
302
- wallets.requestNewWallet(activeWalletMainUtxo);
303
- }
304
-
305
- /// @notice A callback function that is called by the ECDSA Wallet Registry
306
- /// once a new ECDSA wallet is created.
307
- /// @param ecdsaWalletID Wallet's unique identifier.
308
- /// @param publicKeyX Wallet's public key's X coordinate.
309
- /// @param publicKeyY Wallet's public key's Y coordinate.
310
- /// @dev Requirements:
311
- /// - The only caller authorized to call this function is `registry`
312
- /// - Given wallet data must not belong to an already registered wallet
313
- function __ecdsaWalletCreatedCallback(
314
- bytes32 ecdsaWalletID,
315
- bytes32 publicKeyX,
316
- bytes32 publicKeyY
317
- ) external override {
318
- wallets.registerNewWallet(ecdsaWalletID, publicKeyX, publicKeyY);
319
- }
320
-
321
- /// @notice A callback function that is called by the ECDSA Wallet Registry
322
- /// once a wallet heartbeat failure is detected.
323
- /// @param publicKeyX Wallet's public key's X coordinate
324
- /// @param publicKeyY Wallet's public key's Y coordinate
325
- /// @dev Requirements:
326
- /// - The only caller authorized to call this function is `registry`
327
- /// - Wallet must be in Live state
328
- function __ecdsaWalletHeartbeatFailedCallback(
329
- bytes32,
330
- bytes32 publicKeyX,
331
- bytes32 publicKeyY
332
- ) external override {
333
- wallets.notifyWalletHeartbeatFailed(publicKeyX, publicKeyY);
334
- }
335
-
336
- /// @notice Notifies that the wallet is either old enough or has too few
337
- /// satoshis left and qualifies to be closed.
338
- /// @param walletPubKeyHash 20-byte public key hash of the wallet
339
- /// @param walletMainUtxo Data of the wallet's main UTXO, as currently
340
- /// known on the Ethereum chain.
341
- /// @dev Requirements:
342
- /// - Wallet must not be set as the current active wallet
343
- /// - Wallet must exceed the wallet maximum age OR the wallet BTC
344
- /// balance must be lesser than the minimum threshold. If the latter
345
- /// case is true, the `walletMainUtxo` components must point to the
346
- /// recent main UTXO of the given wallet, as currently known on the
347
- /// Ethereum chain. If the wallet has no main UTXO, this parameter
348
- /// can be empty as it is ignored since the wallet balance is
349
- /// assumed to be zero.
350
- /// - Wallet must be in Live state
351
- function notifyCloseableWallet(
352
- bytes20 walletPubKeyHash,
353
- BitcoinTx.UTXO calldata walletMainUtxo
354
- ) external {
355
- wallets.notifyCloseableWallet(walletPubKeyHash, walletMainUtxo);
356
- }
357
-
358
- /// @notice Gets details about a registered wallet.
359
- /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
360
- /// using Bitcoin HASH160 over the compressed ECDSA public key)
361
- /// @return Wallet details.
362
- function getWallet(bytes20 walletPubKeyHash)
363
- external
364
- view
365
- returns (Wallets.Wallet memory)
366
- {
367
- return wallets.registeredWallets[walletPubKeyHash];
368
- }
369
-
370
- /// @notice Gets the public key hash of the active wallet.
371
- /// @return The 20-byte public key hash (computed using Bitcoin HASH160
372
- /// over the compressed ECDSA public key) of the active wallet.
373
- /// Returns bytes20(0) if there is no active wallet at the moment.
374
- function getActiveWalletPubKeyHash() external view returns (bytes20) {
375
- return wallets.activeWalletPubKeyHash;
232
+ self.walletCreationPeriod = 1 weeks;
233
+ self.walletMinBtcBalance = 1e8; // 1 BTC
234
+ self.walletMaxBtcBalance = 10e8; // 10 BTC
235
+ self.walletMaxAge = 26 weeks; // ~6 months
236
+ self.walletMaxBtcTransfer = 10e8; // 10 BTC
376
237
  }
377
238
 
378
239
  /// @notice Used by the depositor to reveal information about their P2(W)SH
@@ -413,7 +274,7 @@ contract Bridge is Ownable, EcdsaWalletOwner {
413
274
  BitcoinTx.Info calldata fundingTx,
414
275
  Deposit.DepositRevealInfo calldata reveal
415
276
  ) external {
416
- self.revealDeposit(wallets, fundingTx, reveal);
277
+ self.revealDeposit(fundingTx, reveal);
417
278
  }
418
279
 
419
280
  /// @notice Used by the wallet to prove the BTC deposit sweep transaction
@@ -457,142 +318,26 @@ contract Bridge is Ownable, EcdsaWalletOwner {
457
318
  BitcoinTx.Proof calldata sweepProof,
458
319
  BitcoinTx.UTXO calldata mainUtxo
459
320
  ) external {
460
- self.submitSweepProof(wallets, sweepTx, sweepProof, mainUtxo);
321
+ self.submitSweepProof(sweepTx, sweepProof, mainUtxo);
461
322
  }
462
323
 
463
- /// @notice Submits a fraud challenge indicating that a UTXO being under
464
- /// wallet control was unlocked by the wallet but was not used
465
- /// according to the protocol rules. That means the wallet signed
466
- /// a transaction input pointing to that UTXO and there is a unique
467
- /// sighash and signature pair associated with that input. This
468
- /// function uses those parameters to create a fraud accusation that
469
- /// proves a given transaction input unlocking the given UTXO was
470
- /// actually signed by the wallet. This function cannot determine
471
- /// whether the transaction was actually broadcast and the input was
472
- /// consumed in a fraudulent way so it just opens a challenge period
473
- /// during which the wallet can defeat the challenge by submitting
474
- /// proof of a transaction that consumes the given input according
475
- /// to protocol rules. To prevent spurious allegations, the caller
476
- /// must deposit ETH that is returned back upon justified fraud
477
- /// challenge or confiscated otherwise.
478
- ///@param walletPublicKey The public key of the wallet in the uncompressed
479
- /// and unprefixed format (64 bytes)
480
- /// @param sighash The hash that was used to produce the ECDSA signature
481
- /// that is the subject of the fraud claim. This hash is constructed
482
- /// by applying double SHA-256 over a serialized subset of the
483
- /// transaction. The exact subset used as hash preimage depends on
484
- /// the transaction input the signature is produced for. See BIP-143
485
- /// for reference
486
- /// @param signature Bitcoin signature in the R/S/V format
487
- /// @dev Requirements:
488
- /// - Wallet behind `walletPubKey` must be in `Live` or `MovingFunds`
489
- /// state
490
- /// - The challenger must send appropriate amount of ETH used as
491
- /// fraud challenge deposit
492
- /// - The signature (represented by r, s and v) must be generated by
493
- /// the wallet behind `walletPubKey` during signing of `sighash`
494
- /// - Wallet can be challenged for the given signature only once
495
- function submitFraudChallenge(
496
- bytes calldata walletPublicKey,
497
- bytes32 sighash,
498
- BitcoinTx.RSVSignature calldata signature
499
- ) external payable {
500
- self.submitFraudChallenge(wallets, walletPublicKey, sighash, signature);
501
- }
502
-
503
- /// @notice Allows to defeat a pending fraud challenge against a wallet if
504
- /// the transaction that spends the UTXO follows the protocol rules.
505
- /// In order to defeat the challenge the same `walletPublicKey` and
506
- /// signature (represented by `r`, `s` and `v`) must be provided as
507
- /// were used to calculate the sighash during input signing.
508
- /// The fraud challenge defeat attempt will only succeed if the
509
- /// inputs in the preimage are considered honestly spent by the
510
- /// wallet. Therefore the transaction spending the UTXO must be
511
- /// proven in the Bridge before a challenge defeat is called.
512
- /// If successfully defeated, the fraud challenge is marked as
513
- /// resolved and the amount of ether deposited by the challenger is
514
- /// sent to the treasury.
515
- /// @param walletPublicKey The public key of the wallet in the uncompressed
516
- /// and unprefixed format (64 bytes)
517
- /// @param preimage The preimage which produces sighash used to generate the
518
- /// ECDSA signature that is the subject of the fraud claim. It is a
519
- /// serialized subset of the transaction. The exact subset used as
520
- /// the preimage depends on the transaction input the signature is
521
- /// produced for. See BIP-143 for reference
522
- /// @param witness Flag indicating whether the preimage was produced for a
523
- /// witness input. True for witness, false for non-witness input
524
- /// @dev Requirements:
525
- /// - `walletPublicKey` and `sighash` calculated as `hash256(preimage)`
526
- /// must identify an open fraud challenge
527
- /// - the preimage must be a valid preimage of a transaction generated
528
- /// according to the protocol rules and already proved in the Bridge
529
- /// - before a defeat attempt is made the transaction that spends the
530
- /// given UTXO must be proven in the Bridge
531
- function defeatFraudChallenge(
532
- bytes calldata walletPublicKey,
533
- bytes calldata preimage,
534
- bool witness
535
- ) external {
536
- self.defeatFraudChallenge(walletPublicKey, preimage, witness);
537
- }
538
-
539
- /// @notice Notifies about defeat timeout for the given fraud challenge.
540
- /// Can be called only if there was a fraud challenge identified by
541
- /// the provided `walletPublicKey` and `sighash` and it was not
542
- /// defeated on time. The amount of time that needs to pass after
543
- /// a fraud challenge is reported is indicated by the
544
- /// `challengeDefeatTimeout`. After a successful fraud challenge
545
- /// defeat timeout notification the fraud challenge is marked as
546
- /// resolved, the stake of each operator is slashed, the ether
547
- /// deposited is returned to the challenger and the challenger is
548
- /// rewarded.
549
- /// @param walletPublicKey The public key of the wallet in the uncompressed
550
- /// and unprefixed format (64 bytes)
551
- /// @param sighash The hash that was used to produce the ECDSA signature
552
- /// that is the subject of the fraud claim. This hash is constructed
553
- /// by applying double SHA-256 over a serialized subset of the
554
- /// transaction. The exact subset used as hash preimage depends on
555
- /// the transaction input the signature is produced for. See BIP-143
556
- /// for reference
557
- /// @dev Requirements:
558
- /// - `walletPublicKey`and `sighash` must identify an open fraud
559
- /// challenge
560
- /// - the amount of time indicated by `challengeDefeatTimeout` must
561
- /// pass after the challenge was reported
562
- function notifyFraudChallengeDefeatTimeout(
563
- bytes calldata walletPublicKey,
564
- bytes32 sighash
565
- ) external {
566
- self.notifyFraudChallengeDefeatTimeout(walletPublicKey, sighash);
567
- }
568
-
569
- /// @notice Returns the fraud challenge identified by the given key built
570
- /// as keccak256(walletPublicKey|sighash).
571
- function fraudChallenges(uint256 challengeKey)
572
- external
573
- view
574
- returns (Fraud.FraudChallenge memory)
575
- {
576
- return self.fraudChallenges[challengeKey];
577
- }
578
-
579
- /// @notice Requests redemption of the given amount from the specified
580
- /// wallet to the redeemer Bitcoin output script.
581
- /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
582
- /// using Bitcoin HASH160 over the compressed ECDSA public key)
583
- /// @param mainUtxo Data of the wallet's main UTXO, as currently known on
584
- /// the Ethereum chain
585
- /// @param redeemerOutputScript The redeemer's length-prefixed output
586
- /// script (P2PKH, P2WPKH, P2SH or P2WSH) that will be used to lock
587
- /// redeemed BTC
588
- /// @param amount Requested amount in satoshi. This is also the TBTC amount
589
- /// that is taken from redeemer's balance in the Bank upon request.
590
- /// Once the request is handled, the actual amount of BTC locked
591
- /// on the redeemer output script will be always lower than this value
592
- /// since the treasury and Bitcoin transaction fees must be incurred.
593
- /// The minimal amount satisfying the request can be computed as:
594
- /// `amount - (amount / redemptionTreasuryFeeDivisor) - redemptionTxMaxFee`.
595
- /// Fees values are taken at the moment of request creation.
324
+ /// @notice Requests redemption of the given amount from the specified
325
+ /// wallet to the redeemer Bitcoin output script.
326
+ /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
327
+ /// using Bitcoin HASH160 over the compressed ECDSA public key)
328
+ /// @param mainUtxo Data of the wallet's main UTXO, as currently known on
329
+ /// the Ethereum chain
330
+ /// @param redeemerOutputScript The redeemer's length-prefixed output
331
+ /// script (P2PKH, P2WPKH, P2SH or P2WSH) that will be used to lock
332
+ /// redeemed BTC
333
+ /// @param amount Requested amount in satoshi. This is also the TBTC amount
334
+ /// that is taken from redeemer's balance in the Bank upon request.
335
+ /// Once the request is handled, the actual amount of BTC locked
336
+ /// on the redeemer output script will be always lower than this value
337
+ /// since the treasury and Bitcoin transaction fees must be incurred.
338
+ /// The minimal amount satisfying the request can be computed as:
339
+ /// `amount - (amount / redemptionTreasuryFeeDivisor) - redemptionTxMaxFee`.
340
+ /// Fees values are taken at the moment of request creation.
596
341
  /// @dev Requirements:
597
342
  /// - Wallet behind `walletPubKeyHash` must be live
598
343
  /// - `mainUtxo` components must point to the recent main UTXO
@@ -612,7 +357,6 @@ contract Bridge is Ownable, EcdsaWalletOwner {
612
357
  uint64 amount
613
358
  ) external {
614
359
  self.requestRedemption(
615
- wallets,
616
360
  walletPubKeyHash,
617
361
  mainUtxo,
618
362
  redeemerOutputScript,
@@ -671,7 +415,6 @@ contract Bridge is Ownable, EcdsaWalletOwner {
671
415
  bytes20 walletPubKeyHash
672
416
  ) external {
673
417
  self.submitRedemptionProof(
674
- wallets,
675
418
  redemptionTx,
676
419
  redemptionProof,
677
420
  mainUtxo,
@@ -707,10 +450,61 @@ contract Bridge is Ownable, EcdsaWalletOwner {
707
450
  bytes20 walletPubKeyHash,
708
451
  bytes calldata redeemerOutputScript
709
452
  ) external {
710
- self.notifyRedemptionTimeout(
711
- wallets,
453
+ self.notifyRedemptionTimeout(walletPubKeyHash, redeemerOutputScript);
454
+ }
455
+
456
+ /// @notice Submits the moving funds target wallets commitment.
457
+ /// Once all requirements are met, that function registers the
458
+ /// target wallets commitment and opens the way for moving funds
459
+ /// proof submission.
460
+ /// @param walletPubKeyHash 20-byte public key hash of the source wallet
461
+ /// @param walletMainUtxo Data of the source wallet's main UTXO, as
462
+ /// currently known on the Ethereum chain
463
+ /// @param walletMembersIDs Identifiers of the source wallet signing group
464
+ /// members
465
+ /// @param walletMemberIndex Position of the caller in the source wallet
466
+ /// signing group members list
467
+ /// @param targetWallets List of 20-byte public key hashes of the target
468
+ /// wallets that the source wallet commits to move the funds to
469
+ /// @dev Requirements:
470
+ /// - The source wallet must be in the MovingFunds state
471
+ /// - The source wallet must not have pending redemption requests
472
+ /// - The source wallet must not have submitted its commitment already
473
+ /// - The expression `keccak256(abi.encode(walletMembersIDs))` must
474
+ /// be exactly the same as the hash stored under `membersIdsHash`
475
+ /// for the given source wallet in the ECDSA registry. Those IDs are
476
+ /// not directly stored in the contract for gas efficiency purposes
477
+ /// but they can be read from appropriate `DkgResultSubmitted`
478
+ /// and `DkgResultApproved` events.
479
+ /// - The `walletMemberIndex` must be in range [1, walletMembersIDs.length]
480
+ /// - The caller must be the member of the source wallet signing group
481
+ /// at the position indicated by `walletMemberIndex` parameter
482
+ /// - The `walletMainUtxo` components must point to the recent main
483
+ /// UTXO of the source wallet, as currently known on the Ethereum
484
+ /// chain.
485
+ /// - Source wallet BTC balance must be greater than zero
486
+ /// - At least one Live wallet must exist in the system
487
+ /// - Submitted target wallets count must match the expected count
488
+ /// `N = min(liveWalletsCount, ceil(walletBtcBalance / walletMaxBtcTransfer))`
489
+ /// where `N > 0`
490
+ /// - Each target wallet must be not equal to the source wallet
491
+ /// - Each target wallet must follow the expected order i.e. all
492
+ /// target wallets 20-byte public key hashes represented as numbers
493
+ /// must form a strictly increasing sequence without duplicates.
494
+ /// - Each target wallet must be in Live state
495
+ function submitMovingFundsCommitment(
496
+ bytes20 walletPubKeyHash,
497
+ BitcoinTx.UTXO calldata walletMainUtxo,
498
+ uint32[] calldata walletMembersIDs,
499
+ uint256 walletMemberIndex,
500
+ bytes20[] calldata targetWallets
501
+ ) external {
502
+ self.submitMovingFundsCommitment(
712
503
  walletPubKeyHash,
713
- redeemerOutputScript
504
+ walletMainUtxo,
505
+ walletMembersIDs,
506
+ walletMemberIndex,
507
+ targetWallets
714
508
  );
715
509
  }
716
510
 
@@ -766,7 +560,6 @@ contract Bridge is Ownable, EcdsaWalletOwner {
766
560
  bytes20 walletPubKeyHash
767
561
  ) external {
768
562
  self.submitMovingFundsProof(
769
- wallets,
770
563
  movingFundsTx,
771
564
  movingFundsProof,
772
565
  mainUtxo,
@@ -774,153 +567,385 @@ contract Bridge is Ownable, EcdsaWalletOwner {
774
567
  );
775
568
  }
776
569
 
777
- /// @notice Returns the addresses of contracts Bridge is interacting with.
778
- /// @return bank Address of the Bank the Bridge belongs to.
779
- /// @return relay Address of the Bitcoin relay providing the current Bitcoin
780
- /// network difficulty.
781
- function getContracts() external view returns (Bank bank, IRelay relay) {
782
- bank = self.bank;
783
- relay = self.relay;
784
- }
785
-
786
- /// @notice Address where the deposit treasury fees will be sent to.
787
- /// Treasury takes part in the operators rewarding process.
788
- function treasury() external view returns (address treasury) {
789
- treasury = self.treasury;
790
- }
791
-
792
- /// @notice The number of confirmations on the Bitcoin chain required to
793
- /// successfully evaluate an SPV proof.
794
- function txProofDifficultyFactor()
795
- external
796
- view
797
- returns (uint256 txProofDifficultyFactor)
798
- {
799
- txProofDifficultyFactor = self.txProofDifficultyFactor;
570
+ /// @notice Notifies about a timed out moving funds process. Terminates
571
+ /// the wallet and slashes signing group members as a result.
572
+ /// @param walletPubKeyHash 20-byte public key hash of the wallet
573
+ /// @dev Requirements:
574
+ /// - The wallet must be in the MovingFunds state
575
+ /// - The moving funds timeout must be actually exceeded
576
+ function notifyMovingFundsTimeout(bytes20 walletPubKeyHash) external {
577
+ self.notifyMovingFundsTimeout(walletPubKeyHash);
800
578
  }
801
579
 
802
- /// @notice Returns the current values of Bridge deposit parameters.
803
- /// @return depositDustThreshold The minimal amount that can be requested
804
- /// to deposit. Value of this parameter must take into account the
805
- /// value of `depositTreasuryFeeDivisor` and `depositTxMaxFee`
806
- /// parameters in order to make requests that can incur the
807
- /// treasury and transaction fee and still satisfy the depositor.
808
- /// @return depositTreasuryFeeDivisor Divisor used to compute the treasury
809
- /// fee taken from each deposit and transferred to the treasury upon
810
- /// sweep proof submission. That fee is computed as follows:
811
- /// `treasuryFee = depositedAmount / depositTreasuryFeeDivisor`
812
- /// For example, if the treasury fee needs to be 2% of each deposit,
813
- /// the `depositTreasuryFeeDivisor` should be set to `50`
814
- /// because `1/50 = 0.02 = 2%`.
815
- /// @return depositTxMaxFee Maximum amount of BTC transaction fee that can
816
- /// be incurred by each swept deposit being part of the given sweep
817
- /// transaction. If the maximum BTC transaction fee is exceeded,
818
- /// such transaction is considered a fraud.
819
- function depositParameters()
580
+ /// @notice Requests creation of a new wallet. This function just
581
+ /// forms a request and the creation process is performed
582
+ /// asynchronously. Once a wallet is created, the ECDSA Wallet
583
+ /// Registry will notify this contract by calling the
584
+ /// `__ecdsaWalletCreatedCallback` function.
585
+ /// @param activeWalletMainUtxo Data of the active wallet's main UTXO, as
586
+ /// currently known on the Ethereum chain.
587
+ /// @dev Requirements:
588
+ /// - `activeWalletMainUtxo` components must point to the recent main
589
+ /// UTXO of the given active wallet, as currently known on the
590
+ /// Ethereum chain. If there is no active wallet at the moment, or
591
+ /// the active wallet has no main UTXO, this parameter can be
592
+ /// empty as it is ignored.
593
+ /// - Wallet creation must not be in progress
594
+ /// - If the active wallet is set, one of the following
595
+ /// conditions must be true:
596
+ /// - The active wallet BTC balance is above the minimum threshold
597
+ /// and the active wallet is old enough, i.e. the creation period
598
+ /// was elapsed since its creation time
599
+ /// - The active wallet BTC balance is above the maximum threshold
600
+ function requestNewWallet(BitcoinTx.UTXO calldata activeWalletMainUtxo)
820
601
  external
821
- view
822
- returns (
823
- uint64 depositDustThreshold,
824
- uint64 depositTreasuryFeeDivisor,
825
- uint64 depositTxMaxFee
826
- )
827
602
  {
828
- depositDustThreshold = self.depositDustThreshold;
829
- depositTreasuryFeeDivisor = self.depositTreasuryFeeDivisor;
830
- depositTxMaxFee = self.depositTxMaxFee;
603
+ self.requestNewWallet(activeWalletMainUtxo);
831
604
  }
832
605
 
833
- /// @notice Returns the current values of Bridge redemption parameters.
834
- /// @return redemptionDustThreshold The minimal amount that can be requested
835
- /// for redemption. Value of this parameter must take into account
836
- /// the value of `redemptionTreasuryFeeDivisor` and `redemptionTxMaxFee`
837
- /// parameters in order to make requests that can incur the
838
- /// treasury and transaction fee and still satisfy the redeemer.
839
- /// @return redemptionTreasuryFeeDivisor Divisor used to compute the treasury
840
- /// fee taken from each redemption request and transferred to the
841
- /// treasury upon successful request finalization. That fee is
842
- /// computed as follows:
843
- /// `treasuryFee = requestedAmount / redemptionTreasuryFeeDivisor`
844
- /// For example, if the treasury fee needs to be 2% of each
845
- /// redemption request, the `redemptionTreasuryFeeDivisor` should
846
- /// be set to `50` because `1/50 = 0.02 = 2%`.
847
- /// @return redemptionTxMaxFee Maximum amount of BTC transaction fee that
848
- /// can be incurred by each redemption request being part of the
849
- /// given redemption transaction. If the maximum BTC transaction
850
- /// fee is exceeded, such transaction is considered a fraud.
851
- /// @return redemptionTimeout Time after which the redemption request can be
852
- /// reported as timed out. It is counted from the moment when the
853
- /// redemption request was created via `requestRedemption` call.
854
- /// Reported timed out requests are cancelled and locked TBTC is
855
- /// returned to the redeemer in full amount.
856
- function redemptionParameters()
857
- external
858
- view
859
- returns (
860
- uint64 redemptionDustThreshold,
861
- uint64 redemptionTreasuryFeeDivisor,
862
- uint64 redemptionTxMaxFee,
863
- uint256 redemptionTimeout,
864
- address treasury,
865
- uint256 txProofDifficultyFactor
866
- )
867
- {
868
- redemptionDustThreshold = self.redemptionDustThreshold;
869
- redemptionTreasuryFeeDivisor = self.redemptionTreasuryFeeDivisor;
870
- redemptionTxMaxFee = self.redemptionTxMaxFee;
871
- redemptionTimeout = self.redemptionTimeout;
606
+ /// @notice A callback function that is called by the ECDSA Wallet Registry
607
+ /// once a new ECDSA wallet is created.
608
+ /// @param ecdsaWalletID Wallet's unique identifier.
609
+ /// @param publicKeyX Wallet's public key's X coordinate.
610
+ /// @param publicKeyY Wallet's public key's Y coordinate.
611
+ /// @dev Requirements:
612
+ /// - The only caller authorized to call this function is `registry`
613
+ /// - Given wallet data must not belong to an already registered wallet
614
+ function __ecdsaWalletCreatedCallback(
615
+ bytes32 ecdsaWalletID,
616
+ bytes32 publicKeyX,
617
+ bytes32 publicKeyY
618
+ ) external override {
619
+ self.registerNewWallet(ecdsaWalletID, publicKeyX, publicKeyY);
872
620
  }
873
621
 
874
- /// @notice Returns the current values of Bridge moving funds between
875
- /// wallets parameters.
876
- /// @return movingFundsTxMaxTotalFee Maximum amount of the total BTC
877
- /// transaction fee that is acceptable in a single moving funds
878
- /// transaction. This is a _total_ max fee for the entire moving
879
- /// funds transaction.
880
- function movingFundsParameters()
881
- external
882
- view
883
- returns (uint64 movingFundsTxMaxTotalFee)
884
- {
885
- // TODO: we will have more parameters here, for example moving funds timeout
886
- movingFundsTxMaxTotalFee = self.movingFundsTxMaxTotalFee;
622
+ /// @notice A callback function that is called by the ECDSA Wallet Registry
623
+ /// once a wallet heartbeat failure is detected.
624
+ /// @param publicKeyX Wallet's public key's X coordinate
625
+ /// @param publicKeyY Wallet's public key's Y coordinate
626
+ /// @dev Requirements:
627
+ /// - The only caller authorized to call this function is `registry`
628
+ /// - Wallet must be in Live state
629
+ function __ecdsaWalletHeartbeatFailedCallback(
630
+ bytes32,
631
+ bytes32 publicKeyX,
632
+ bytes32 publicKeyY
633
+ ) external override {
634
+ self.notifyWalletHeartbeatFailed(publicKeyX, publicKeyY);
887
635
  }
888
636
 
889
- /// @notice Returns the current values of Bridge fraud parameters.
890
- /// @return fraudSlashingAmount The amount slashed from each wallet member
891
- /// for committing a fraud.
892
- /// @return fraudNotifierRewardMultiplier The percentage of the notifier
893
- /// reward from the staking contract the notifier of a fraud
894
- /// receives. The value is in the range [0, 100].
895
- /// @return fraudChallengeDefeatTimeout The amount of time the wallet has to
896
- /// defeat a fraud challenge.
897
- /// @return fraudChallengeDepositAmount The amount of ETH in wei the party
898
- /// challenging the wallet for fraud needs to deposit.
899
- function fraudParameters()
900
- external
901
- view
902
- returns (
903
- uint256 fraudSlashingAmount,
904
- uint256 fraudNotifierRewardMultiplier,
905
- uint256 fraudChallengeDefeatTimeout,
906
- uint256 fraudChallengeDepositAmount
907
- )
908
- {
909
- fraudSlashingAmount = self.fraudSlashingAmount;
910
- fraudNotifierRewardMultiplier = self.fraudNotifierRewardMultiplier;
911
- fraudChallengeDefeatTimeout = self.fraudChallengeDefeatTimeout;
912
- fraudChallengeDepositAmount = self.fraudChallengeDepositAmount;
637
+ /// @notice Notifies that the wallet is either old enough or has too few
638
+ /// satoshi left and qualifies to be closed.
639
+ /// @param walletPubKeyHash 20-byte public key hash of the wallet
640
+ /// @param walletMainUtxo Data of the wallet's main UTXO, as currently
641
+ /// known on the Ethereum chain.
642
+ /// @dev Requirements:
643
+ /// - Wallet must not be set as the current active wallet
644
+ /// - Wallet must exceed the wallet maximum age OR the wallet BTC
645
+ /// balance must be lesser than the minimum threshold. If the latter
646
+ /// case is true, the `walletMainUtxo` components must point to the
647
+ /// recent main UTXO of the given wallet, as currently known on the
648
+ /// Ethereum chain. If the wallet has no main UTXO, this parameter
649
+ /// can be empty as it is ignored since the wallet balance is
650
+ /// assumed to be zero.
651
+ /// - Wallet must be in Live state
652
+ function notifyCloseableWallet(
653
+ bytes20 walletPubKeyHash,
654
+ BitcoinTx.UTXO calldata walletMainUtxo
655
+ ) external {
656
+ self.notifyCloseableWallet(walletPubKeyHash, walletMainUtxo);
913
657
  }
914
658
 
915
- /// @notice Indicates if the vault with the given address is trusted or not.
916
- /// Depositors can route their revealed deposits only to trusted
917
- /// vaults and have trusted vaults notified about new deposits as
918
- /// soon as these deposits get swept. Vaults not trusted by the
919
- /// Bridge can still be used by Bank balance owners on their own
920
- /// responsibility - anyone can approve their Bank balance to any
921
- /// address.
922
- function isVaultTrusted(address vault) external view returns (bool) {
923
- return self.isVaultTrusted[vault];
659
+ /// @notice Submits a fraud challenge indicating that a UTXO being under
660
+ /// wallet control was unlocked by the wallet but was not used
661
+ /// according to the protocol rules. That means the wallet signed
662
+ /// a transaction input pointing to that UTXO and there is a unique
663
+ /// sighash and signature pair associated with that input. This
664
+ /// function uses those parameters to create a fraud accusation that
665
+ /// proves a given transaction input unlocking the given UTXO was
666
+ /// actually signed by the wallet. This function cannot determine
667
+ /// whether the transaction was actually broadcast and the input was
668
+ /// consumed in a fraudulent way so it just opens a challenge period
669
+ /// during which the wallet can defeat the challenge by submitting
670
+ /// proof of a transaction that consumes the given input according
671
+ /// to protocol rules. To prevent spurious allegations, the caller
672
+ /// must deposit ETH that is returned back upon justified fraud
673
+ /// challenge or confiscated otherwise.
674
+ ///@param walletPublicKey The public key of the wallet in the uncompressed
675
+ /// and unprefixed format (64 bytes)
676
+ /// @param sighash The hash that was used to produce the ECDSA signature
677
+ /// that is the subject of the fraud claim. This hash is constructed
678
+ /// by applying double SHA-256 over a serialized subset of the
679
+ /// transaction. The exact subset used as hash preimage depends on
680
+ /// the transaction input the signature is produced for. See BIP-143
681
+ /// for reference
682
+ /// @param signature Bitcoin signature in the R/S/V format
683
+ /// @dev Requirements:
684
+ /// - Wallet behind `walletPublicKey` must be in Live or MovingFunds
685
+ /// or Closing state
686
+ /// - The challenger must send appropriate amount of ETH used as
687
+ /// fraud challenge deposit
688
+ /// - The signature (represented by r, s and v) must be generated by
689
+ /// the wallet behind `walletPubKey` during signing of `sighash`
690
+ /// - Wallet can be challenged for the given signature only once
691
+ function submitFraudChallenge(
692
+ bytes calldata walletPublicKey,
693
+ bytes32 sighash,
694
+ BitcoinTx.RSVSignature calldata signature
695
+ ) external payable {
696
+ self.submitFraudChallenge(walletPublicKey, sighash, signature);
697
+ }
698
+
699
+ /// @notice Allows to defeat a pending fraud challenge against a wallet if
700
+ /// the transaction that spends the UTXO follows the protocol rules.
701
+ /// In order to defeat the challenge the same `walletPublicKey` and
702
+ /// signature (represented by `r`, `s` and `v`) must be provided as
703
+ /// were used to calculate the sighash during input signing.
704
+ /// The fraud challenge defeat attempt will only succeed if the
705
+ /// inputs in the preimage are considered honestly spent by the
706
+ /// wallet. Therefore the transaction spending the UTXO must be
707
+ /// proven in the Bridge before a challenge defeat is called.
708
+ /// If successfully defeated, the fraud challenge is marked as
709
+ /// resolved and the amount of ether deposited by the challenger is
710
+ /// sent to the treasury.
711
+ /// @param walletPublicKey The public key of the wallet in the uncompressed
712
+ /// and unprefixed format (64 bytes)
713
+ /// @param preimage The preimage which produces sighash used to generate the
714
+ /// ECDSA signature that is the subject of the fraud claim. It is a
715
+ /// serialized subset of the transaction. The exact subset used as
716
+ /// the preimage depends on the transaction input the signature is
717
+ /// produced for. See BIP-143 for reference
718
+ /// @param witness Flag indicating whether the preimage was produced for a
719
+ /// witness input. True for witness, false for non-witness input
720
+ /// @dev Requirements:
721
+ /// - `walletPublicKey` and `sighash` calculated as `hash256(preimage)`
722
+ /// must identify an open fraud challenge
723
+ /// - the preimage must be a valid preimage of a transaction generated
724
+ /// according to the protocol rules and already proved in the Bridge
725
+ /// - before a defeat attempt is made the transaction that spends the
726
+ /// given UTXO must be proven in the Bridge
727
+ function defeatFraudChallenge(
728
+ bytes calldata walletPublicKey,
729
+ bytes calldata preimage,
730
+ bool witness
731
+ ) external {
732
+ self.defeatFraudChallenge(walletPublicKey, preimage, witness);
733
+ }
734
+
735
+ /// @notice Notifies about defeat timeout for the given fraud challenge.
736
+ /// Can be called only if there was a fraud challenge identified by
737
+ /// the provided `walletPublicKey` and `sighash` and it was not
738
+ /// defeated on time. The amount of time that needs to pass after
739
+ /// a fraud challenge is reported is indicated by the
740
+ /// `challengeDefeatTimeout`. After a successful fraud challenge
741
+ /// defeat timeout notification the fraud challenge is marked as
742
+ /// resolved, the stake of each operator is slashed, the ether
743
+ /// deposited is returned to the challenger and the challenger is
744
+ /// rewarded.
745
+ /// @param walletPublicKey The public key of the wallet in the uncompressed
746
+ /// and unprefixed format (64 bytes)
747
+ /// @param sighash The hash that was used to produce the ECDSA signature
748
+ /// that is the subject of the fraud claim. This hash is constructed
749
+ /// by applying double SHA-256 over a serialized subset of the
750
+ /// transaction. The exact subset used as hash preimage depends on
751
+ /// the transaction input the signature is produced for. See BIP-143
752
+ /// for reference
753
+ /// @dev Requirements:
754
+ /// - `walletPublicKey`and `sighash` must identify an open fraud
755
+ /// challenge
756
+ /// - the amount of time indicated by `challengeDefeatTimeout` must
757
+ /// pass after the challenge was reported
758
+ function notifyFraudChallengeDefeatTimeout(
759
+ bytes calldata walletPublicKey,
760
+ bytes32 sighash
761
+ ) external {
762
+ self.notifyFraudChallengeDefeatTimeout(walletPublicKey, sighash);
763
+ }
764
+
765
+ /// @notice Allows the Governance to mark the given vault address as trusted
766
+ /// or no longer trusted. Vaults are not trusted by default.
767
+ /// Trusted vault must meet the following criteria:
768
+ /// - `IVault.receiveBalanceIncrease` must have a known, low gas
769
+ /// cost.
770
+ /// - `IVault.receiveBalanceIncrease` must never revert.
771
+ /// @dev Without restricting reveal only to trusted vaults, malicious
772
+ /// vaults not meeting the criteria would be able to nuke sweep proof
773
+ /// transactions executed by ECDSA wallet with deposits routed to
774
+ /// them.
775
+ /// @param vault The address of the vault
776
+ /// @param isTrusted flag indicating whether the vault is trusted or not
777
+ /// @dev Can only be called by the Governance.
778
+ function setVaultStatus(address vault, bool isTrusted) external onlyOwner {
779
+ self.isVaultTrusted[vault] = isTrusted;
780
+ emit VaultStatusUpdated(vault, isTrusted);
781
+ }
782
+
783
+ /// @notice Updates parameters of deposits.
784
+ /// @param depositDustThreshold New value of the deposit dust threshold in
785
+ /// satoshis. It is the minimal amount that can be requested to
786
+ //// deposit. Value of this parameter must take into account the value
787
+ /// of `depositTreasuryFeeDivisor` and `depositTxMaxFee` parameters
788
+ /// in order to make requests that can incur the treasury and
789
+ /// transaction fee and still satisfy the depositor
790
+ /// @param depositTreasuryFeeDivisor New value of the treasury fee divisor.
791
+ /// It is the divisor used to compute the treasury fee taken from
792
+ /// each deposit and transferred to the treasury upon sweep proof
793
+ /// submission. That fee is computed as follows:
794
+ /// `treasuryFee = depositedAmount / depositTreasuryFeeDivisor`
795
+ /// For example, if the treasury fee needs to be 2% of each deposit,
796
+ /// the `depositTreasuryFeeDivisor` should be set to `50`
797
+ /// because `1/50 = 0.02 = 2%`
798
+ /// @param depositTxMaxFee New value of the deposit tx max fee in satoshis.
799
+ /// It is the maximum amount of BTC transaction fee that can
800
+ /// be incurred by each swept deposit being part of the given sweep
801
+ /// transaction. If the maximum BTC transaction fee is exceeded,
802
+ /// such transaction is considered a fraud
803
+ /// @dev Requirements:
804
+ /// - Deposit treasury fee divisor must be greater than zero
805
+ function updateDepositParameters(
806
+ uint64 depositDustThreshold,
807
+ uint64 depositTreasuryFeeDivisor,
808
+ uint64 depositTxMaxFee
809
+ ) external onlyOwner {
810
+ self.updateDepositParameters(
811
+ depositDustThreshold,
812
+ depositTreasuryFeeDivisor,
813
+ depositTxMaxFee
814
+ );
815
+ }
816
+
817
+ /// @notice Updates parameters of redemptions.
818
+ /// @param redemptionDustThreshold New value of the redemption dust
819
+ /// threshold in satoshis. It is the minimal amount that can be
820
+ /// requested for redemption. Value of this parameter must take into
821
+ /// account the value of `redemptionTreasuryFeeDivisor` and
822
+ /// `redemptionTxMaxFee` parameters in order to make requests that
823
+ /// can incur the treasury and transaction fee and still satisfy the
824
+ /// redeemer.
825
+ /// @param redemptionTreasuryFeeDivisor New value of the redemption
826
+ /// treasury fee divisor. It is the divisor used to compute the
827
+ /// treasury fee taken from each redemption request and transferred
828
+ /// to the treasury upon successful request finalization. That fee is
829
+ /// computed as follows:
830
+ /// `treasuryFee = requestedAmount / redemptionTreasuryFeeDivisor`
831
+ /// For example, if the treasury fee needs to be 2% of each
832
+ /// redemption request, the `redemptionTreasuryFeeDivisor` should
833
+ /// be set to `50` because `1/50 = 0.02 = 2%`.
834
+ /// @param redemptionTxMaxFee New value of the redemption transaction max
835
+ /// fee in satoshis. It is the maximum amount of BTC transaction fee
836
+ /// that can be incurred by each redemption request being part of the
837
+ /// given redemption transaction. If the maximum BTC transaction fee
838
+ /// is exceeded, such transaction is considered a fraud.
839
+ /// @param redemptionTimeout New value of the redemption timeout in seconds.
840
+ /// It is the time after which the redemption request can be reported
841
+ /// as timed out. It is counted from the moment when the redemption
842
+ /// request was created via `requestRedemption` call. Reported timed
843
+ /// out requests are cancelled and locked TBTC is returned to the
844
+ /// redeemer in full amount.
845
+ /// @dev Requirements:
846
+ /// - Redemption treasury fee divisor must be greater than zero
847
+ /// - Redemption timeout must be greater than zero
848
+ function updateRedemptionParameters(
849
+ uint64 redemptionDustThreshold,
850
+ uint64 redemptionTreasuryFeeDivisor,
851
+ uint64 redemptionTxMaxFee,
852
+ uint256 redemptionTimeout
853
+ ) external onlyOwner {
854
+ self.updateRedemptionParameters(
855
+ redemptionDustThreshold,
856
+ redemptionTreasuryFeeDivisor,
857
+ redemptionTxMaxFee,
858
+ redemptionTimeout
859
+ );
860
+ }
861
+
862
+ /// @notice Updates parameters of moving funds.
863
+ /// @param movingFundsTxMaxTotalFee New value of the moving funds transaction
864
+ /// max total fee in satoshis. It is the maximum amount of the total
865
+ /// BTC transaction fee that is acceptable in a single moving funds
866
+ /// transaction. This is a _total_ max fee for the entire moving
867
+ /// funds transaction.
868
+ /// @param movingFundsTimeout New value of the moving funds timeout in
869
+ /// seconds. It is the time after which the moving funds process can
870
+ /// be reported as timed out. It is counted from the moment when the
871
+ /// wallet was requested to move their funds and switched to the
872
+ /// MovingFunds state.
873
+ /// @dev Requirements:
874
+ /// - Moving funds timeout must be greater than zero
875
+ function updateMovingFundsParameters(
876
+ uint64 movingFundsTxMaxTotalFee,
877
+ uint32 movingFundsTimeout
878
+ ) external onlyOwner {
879
+ self.updateMovingFundsParameters(
880
+ movingFundsTxMaxTotalFee,
881
+ movingFundsTimeout
882
+ );
883
+ }
884
+
885
+ /// @notice Updates parameters of wallets.
886
+ /// @param walletCreationPeriod New value of the wallet creation period in
887
+ /// seconds, determines how frequently a new wallet creation can be
888
+ /// requested
889
+ /// @param walletMinBtcBalance New value of the wallet minimum BTC balance
890
+ /// in satoshi, used to decide about wallet creation or closing
891
+ /// @param walletMaxBtcBalance New value of the wallet maximum BTC balance
892
+ /// in satoshi, used to decide about wallet creation
893
+ /// @param walletMaxAge New value of the wallet maximum age in seconds,
894
+ /// indicates the maximum age of a wallet in seconds, after which
895
+ /// the wallet moving funds process can be requested
896
+ /// @param walletMaxBtcTransfer New value of the wallet maximum BTC transfer
897
+ /// in satoshi, determines the maximum amount that can be transferred
898
+ // to a single target wallet during the moving funds process
899
+ /// @dev Requirements:
900
+ /// - Wallet minimum BTC balance must be greater than zero
901
+ /// - Wallet maximum BTC balance must be greater than the wallet
902
+ /// minimum BTC balance
903
+ /// - Wallet maximum BTC transfer must be greater than zero
904
+ function updateWalletParameters(
905
+ uint32 walletCreationPeriod,
906
+ uint64 walletMinBtcBalance,
907
+ uint64 walletMaxBtcBalance,
908
+ uint32 walletMaxAge,
909
+ uint64 walletMaxBtcTransfer
910
+ ) external onlyOwner {
911
+ self.updateWalletParameters(
912
+ walletCreationPeriod,
913
+ walletMinBtcBalance,
914
+ walletMaxBtcBalance,
915
+ walletMaxAge,
916
+ walletMaxBtcTransfer
917
+ );
918
+ }
919
+
920
+ /// @notice Updates parameters related to frauds.
921
+ /// @param fraudSlashingAmount New value of the fraud slashing amount in T,
922
+ /// it is the amount slashed from each wallet member for committing
923
+ /// a fraud
924
+ /// @param fraudNotifierRewardMultiplier New value of the fraud notifier
925
+ /// reward multiplier as percentage, it determines the percentage of
926
+ /// the notifier reward from the staking contact the notifier of
927
+ /// a fraud receives. The value must be in the range [0, 100]
928
+ /// @param fraudChallengeDefeatTimeout New value of the challenge defeat
929
+ /// timeout in seconds, it is the amount of time the wallet has to
930
+ /// defeat a fraud challenge. The value must be greater than zero
931
+ /// @param fraudChallengeDepositAmount New value of the fraud challenge
932
+ /// deposit amount in wei, it is the amount of ETH the party
933
+ /// challenging the wallet for fraud needs to deposit
934
+ /// @dev Requirements:
935
+ /// - Fraud notifier reward multiplier must be in the range [0, 100]
936
+ /// - Fraud challenge defeat timeout must be greater than 0
937
+ function updateFraudParameters(
938
+ uint256 fraudSlashingAmount,
939
+ uint256 fraudNotifierRewardMultiplier,
940
+ uint256 fraudChallengeDefeatTimeout,
941
+ uint256 fraudChallengeDepositAmount
942
+ ) external onlyOwner {
943
+ self.updateFraudParameters(
944
+ fraudSlashingAmount,
945
+ fraudNotifierRewardMultiplier,
946
+ fraudChallengeDefeatTimeout,
947
+ fraudChallengeDepositAmount
948
+ );
924
949
  }
925
950
 
926
951
  /// @notice Collection of all revealed deposits indexed by
@@ -937,16 +962,6 @@ contract Bridge is Ownable, EcdsaWalletOwner {
937
962
  return self.deposits[depositKey];
938
963
  }
939
964
 
940
- /// @notice Collection of main UTXOs that are honestly spent indexed by
941
- /// keccak256(fundingTxHash | fundingOutputIndex). The fundingTxHash
942
- /// is bytes32 (ordered as in Bitcoin internally) and
943
- /// fundingOutputIndex an uint32. A main UTXO is considered honestly
944
- /// spent if it was used as an input of a transaction that have been
945
- /// proven in the Bridge.
946
- function spentMainUTXOs(uint256 utxoKey) external view returns (bool) {
947
- return self.spentMainUTXOs[utxoKey];
948
- }
949
-
950
965
  /// @notice Collection of all pending redemption requests indexed by
951
966
  /// redemption key built as
952
967
  /// keccak256(walletPubKeyHash | redeemerOutputScript). The
@@ -964,7 +979,7 @@ contract Bridge is Ownable, EcdsaWalletOwner {
964
979
  function pendingRedemptions(uint256 redemptionKey)
965
980
  external
966
981
  view
967
- returns (Redeem.RedemptionRequest memory)
982
+ returns (Redemption.RedemptionRequest memory)
968
983
  {
969
984
  return self.pendingRedemptions[redemptionKey];
970
985
  }
@@ -985,8 +1000,234 @@ contract Bridge is Ownable, EcdsaWalletOwner {
985
1000
  function timedOutRedemptions(uint256 redemptionKey)
986
1001
  external
987
1002
  view
988
- returns (Redeem.RedemptionRequest memory)
1003
+ returns (Redemption.RedemptionRequest memory)
989
1004
  {
990
1005
  return self.timedOutRedemptions[redemptionKey];
991
1006
  }
1007
+
1008
+ /// @notice Collection of main UTXOs that are honestly spent indexed by
1009
+ /// keccak256(fundingTxHash | fundingOutputIndex). The fundingTxHash
1010
+ /// is bytes32 (ordered as in Bitcoin internally) and
1011
+ /// fundingOutputIndex an uint32. A main UTXO is considered honestly
1012
+ /// spent if it was used as an input of a transaction that have been
1013
+ /// proven in the Bridge.
1014
+ function spentMainUTXOs(uint256 utxoKey) external view returns (bool) {
1015
+ return self.spentMainUTXOs[utxoKey];
1016
+ }
1017
+
1018
+ /// @notice Gets details about a registered wallet.
1019
+ /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
1020
+ /// using Bitcoin HASH160 over the compressed ECDSA public key)
1021
+ /// @return Wallet details.
1022
+ function wallets(bytes20 walletPubKeyHash)
1023
+ external
1024
+ view
1025
+ returns (Wallets.Wallet memory)
1026
+ {
1027
+ return self.registeredWallets[walletPubKeyHash];
1028
+ }
1029
+
1030
+ /// @notice Gets the public key hash of the active wallet.
1031
+ /// @return The 20-byte public key hash (computed using Bitcoin HASH160
1032
+ /// over the compressed ECDSA public key) of the active wallet.
1033
+ /// Returns bytes20(0) if there is no active wallet at the moment.
1034
+ function activeWalletPubKeyHash() external view returns (bytes20) {
1035
+ return self.activeWalletPubKeyHash;
1036
+ }
1037
+
1038
+ /// @notice Gets the live wallets count.
1039
+ /// @return The current count of wallets being in the Live state.
1040
+ function liveWalletsCount() external view returns (uint32) {
1041
+ return self.liveWalletsCount;
1042
+ }
1043
+
1044
+ /// @notice Returns the fraud challenge identified by the given key built
1045
+ /// as keccak256(walletPublicKey|sighash).
1046
+ function fraudChallenges(uint256 challengeKey)
1047
+ external
1048
+ view
1049
+ returns (Fraud.FraudChallenge memory)
1050
+ {
1051
+ return self.fraudChallenges[challengeKey];
1052
+ }
1053
+
1054
+ /// @notice Indicates if the vault with the given address is trusted or not.
1055
+ /// Depositors can route their revealed deposits only to trusted
1056
+ /// vaults and have trusted vaults notified about new deposits as
1057
+ /// soon as these deposits get swept. Vaults not trusted by the
1058
+ /// Bridge can still be used by Bank balance owners on their own
1059
+ /// responsibility - anyone can approve their Bank balance to any
1060
+ /// address.
1061
+ function isVaultTrusted(address vault) external view returns (bool) {
1062
+ return self.isVaultTrusted[vault];
1063
+ }
1064
+
1065
+ /// @notice Returns the current values of Bridge deposit parameters.
1066
+ /// @return depositDustThreshold The minimal amount that can be requested
1067
+ /// to deposit. Value of this parameter must take into account the
1068
+ /// value of `depositTreasuryFeeDivisor` and `depositTxMaxFee`
1069
+ /// parameters in order to make requests that can incur the
1070
+ /// treasury and transaction fee and still satisfy the depositor.
1071
+ /// @return depositTreasuryFeeDivisor Divisor used to compute the treasury
1072
+ /// fee taken from each deposit and transferred to the treasury upon
1073
+ /// sweep proof submission. That fee is computed as follows:
1074
+ /// `treasuryFee = depositedAmount / depositTreasuryFeeDivisor`
1075
+ /// For example, if the treasury fee needs to be 2% of each deposit,
1076
+ /// the `depositTreasuryFeeDivisor` should be set to `50`
1077
+ /// because `1/50 = 0.02 = 2%`.
1078
+ /// @return depositTxMaxFee Maximum amount of BTC transaction fee that can
1079
+ /// be incurred by each swept deposit being part of the given sweep
1080
+ /// transaction. If the maximum BTC transaction fee is exceeded,
1081
+ /// such transaction is considered a fraud.
1082
+ function depositParameters()
1083
+ external
1084
+ view
1085
+ returns (
1086
+ uint64 depositDustThreshold,
1087
+ uint64 depositTreasuryFeeDivisor,
1088
+ uint64 depositTxMaxFee
1089
+ )
1090
+ {
1091
+ depositDustThreshold = self.depositDustThreshold;
1092
+ depositTreasuryFeeDivisor = self.depositTreasuryFeeDivisor;
1093
+ depositTxMaxFee = self.depositTxMaxFee;
1094
+ }
1095
+
1096
+ /// @notice Returns the current values of Bridge redemption parameters.
1097
+ /// @return redemptionDustThreshold The minimal amount that can be requested
1098
+ /// for redemption. Value of this parameter must take into account
1099
+ /// the value of `redemptionTreasuryFeeDivisor` and `redemptionTxMaxFee`
1100
+ /// parameters in order to make requests that can incur the
1101
+ /// treasury and transaction fee and still satisfy the redeemer.
1102
+ /// @return redemptionTreasuryFeeDivisor Divisor used to compute the treasury
1103
+ /// fee taken from each redemption request and transferred to the
1104
+ /// treasury upon successful request finalization. That fee is
1105
+ /// computed as follows:
1106
+ /// `treasuryFee = requestedAmount / redemptionTreasuryFeeDivisor`
1107
+ /// For example, if the treasury fee needs to be 2% of each
1108
+ /// redemption request, the `redemptionTreasuryFeeDivisor` should
1109
+ /// be set to `50` because `1/50 = 0.02 = 2%`.
1110
+ /// @return redemptionTxMaxFee Maximum amount of BTC transaction fee that
1111
+ /// can be incurred by each redemption request being part of the
1112
+ /// given redemption transaction. If the maximum BTC transaction
1113
+ /// fee is exceeded, such transaction is considered a fraud.
1114
+ /// @return redemptionTimeout Time after which the redemption request can be
1115
+ /// reported as timed out. It is counted from the moment when the
1116
+ /// redemption request was created via `requestRedemption` call.
1117
+ /// Reported timed out requests are cancelled and locked TBTC is
1118
+ /// returned to the redeemer in full amount.
1119
+ function redemptionParameters()
1120
+ external
1121
+ view
1122
+ returns (
1123
+ uint64 redemptionDustThreshold,
1124
+ uint64 redemptionTreasuryFeeDivisor,
1125
+ uint64 redemptionTxMaxFee,
1126
+ uint256 redemptionTimeout
1127
+ )
1128
+ {
1129
+ redemptionDustThreshold = self.redemptionDustThreshold;
1130
+ redemptionTreasuryFeeDivisor = self.redemptionTreasuryFeeDivisor;
1131
+ redemptionTxMaxFee = self.redemptionTxMaxFee;
1132
+ redemptionTimeout = self.redemptionTimeout;
1133
+ }
1134
+
1135
+ /// @notice Returns the current values of Bridge moving funds between
1136
+ /// wallets parameters.
1137
+ /// @return movingFundsTxMaxTotalFee Maximum amount of the total BTC
1138
+ /// transaction fee that is acceptable in a single moving funds
1139
+ /// transaction. This is a _total_ max fee for the entire moving
1140
+ /// funds transaction.
1141
+ /// @return movingFundsTimeout Time after which the moving funds process
1142
+ /// can be reported as timed out. It is counted from the moment
1143
+ /// when the wallet was requested to move their funds and switched
1144
+ /// to the MovingFunds state. Value in seconds.
1145
+ function movingFundsParameters()
1146
+ external
1147
+ view
1148
+ returns (uint64 movingFundsTxMaxTotalFee, uint32 movingFundsTimeout)
1149
+ {
1150
+ movingFundsTxMaxTotalFee = self.movingFundsTxMaxTotalFee;
1151
+ movingFundsTimeout = self.movingFundsTimeout;
1152
+ }
1153
+
1154
+ /// @return walletCreationPeriod Determines how frequently a new wallet
1155
+ /// creation can be requested. Value in seconds.
1156
+ /// @return walletMinBtcBalance The minimum BTC threshold in satoshi that is
1157
+ /// used to decide about wallet creation or closing.
1158
+ /// @return walletMaxBtcBalance The maximum BTC threshold in satoshi that is
1159
+ /// used to decide about wallet creation.
1160
+ /// @return walletMaxAge The maximum age of a wallet in seconds, after which
1161
+ /// the wallet moving funds process can be requested.
1162
+ /// @return walletMaxBtcTransfer The maximum BTC amount in satoshi than
1163
+ /// can be transferred to a single target wallet during the moving
1164
+ /// funds process.
1165
+ function walletParameters()
1166
+ external
1167
+ view
1168
+ returns (
1169
+ uint32 walletCreationPeriod,
1170
+ uint64 walletMinBtcBalance,
1171
+ uint64 walletMaxBtcBalance,
1172
+ uint32 walletMaxAge,
1173
+ uint64 walletMaxBtcTransfer
1174
+ )
1175
+ {
1176
+ walletCreationPeriod = self.walletCreationPeriod;
1177
+ walletMinBtcBalance = self.walletMinBtcBalance;
1178
+ walletMaxBtcBalance = self.walletMaxBtcBalance;
1179
+ walletMaxAge = self.walletMaxAge;
1180
+ walletMaxBtcTransfer = self.walletMaxBtcTransfer;
1181
+ }
1182
+
1183
+ /// @notice Returns the current values of Bridge fraud parameters.
1184
+ /// @return fraudSlashingAmount The amount slashed from each wallet member
1185
+ /// for committing a fraud.
1186
+ /// @return fraudNotifierRewardMultiplier The percentage of the notifier
1187
+ /// reward from the staking contract the notifier of a fraud
1188
+ /// receives. The value is in the range [0, 100].
1189
+ /// @return fraudChallengeDefeatTimeout The amount of time the wallet has to
1190
+ /// defeat a fraud challenge.
1191
+ /// @return fraudChallengeDepositAmount The amount of ETH in wei the party
1192
+ /// challenging the wallet for fraud needs to deposit.
1193
+ function fraudParameters()
1194
+ external
1195
+ view
1196
+ returns (
1197
+ uint256 fraudSlashingAmount,
1198
+ uint256 fraudNotifierRewardMultiplier,
1199
+ uint256 fraudChallengeDefeatTimeout,
1200
+ uint256 fraudChallengeDepositAmount
1201
+ )
1202
+ {
1203
+ fraudSlashingAmount = self.fraudSlashingAmount;
1204
+ fraudNotifierRewardMultiplier = self.fraudNotifierRewardMultiplier;
1205
+ fraudChallengeDefeatTimeout = self.fraudChallengeDefeatTimeout;
1206
+ fraudChallengeDepositAmount = self.fraudChallengeDepositAmount;
1207
+ }
1208
+
1209
+ /// @notice Returns the addresses of contracts Bridge is interacting with.
1210
+ /// @return bank Address of the Bank the Bridge belongs to.
1211
+ /// @return relay Address of the Bitcoin relay providing the current Bitcoin
1212
+ /// network difficulty.
1213
+ function contractReferences()
1214
+ external
1215
+ view
1216
+ returns (Bank bank, IRelay relay)
1217
+ {
1218
+ bank = self.bank;
1219
+ relay = self.relay;
1220
+ }
1221
+
1222
+ /// @notice Address where the deposit treasury fees will be sent to.
1223
+ /// Treasury takes part in the operators rewarding process.
1224
+ function treasury() external view returns (address) {
1225
+ return self.treasury;
1226
+ }
1227
+
1228
+ /// @notice The number of confirmations on the Bitcoin chain required to
1229
+ /// successfully evaluate an SPV proof.
1230
+ function txProofDifficultyFactor() external view returns (uint256) {
1231
+ return self.txProofDifficultyFactor;
1232
+ }
992
1233
  }