@keep-network/tbtc-v2 0.1.1-dev.40 → 0.1.1-dev.43

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 (49) hide show
  1. package/artifacts/TBTC.json +3 -3
  2. package/artifacts/TBTCToken.json +3 -3
  3. package/artifacts/VendingMachine.json +10 -10
  4. package/artifacts/solcInputs/{f1a50b67569d88ee54efa3e22c6b484e.json → f2c15d3cf1bd9566483f595c5ed30ccc.json} +25 -25
  5. package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
  6. package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
  7. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +1 -1
  8. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.json +2 -2
  9. package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
  10. package/build/contracts/bridge/Bridge.sol/Bridge.json +191 -331
  11. package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
  12. package/build/contracts/bridge/BridgeState.sol/BridgeState.json +35 -3
  13. package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +1 -1
  14. package/build/contracts/bridge/Deposit.sol/Deposit.json +2 -2
  15. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +1 -1
  16. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.json +2 -2
  17. package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +4 -0
  18. package/build/contracts/bridge/Fraud.sol/Fraud.json +86 -0
  19. package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +1 -1
  20. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +1 -1
  21. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.json +4 -22
  22. package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +4 -0
  23. package/build/contracts/bridge/{Redeem.sol → Redemption.sol}/OutboundTx.json +3 -3
  24. package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +4 -0
  25. package/build/contracts/bridge/Redemption.sol/Redemption.json +92 -0
  26. package/build/contracts/bridge/Sweep.sol/Sweep.dbg.json +1 -1
  27. package/build/contracts/bridge/Sweep.sol/Sweep.json +2 -2
  28. package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
  29. package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +1 -1
  30. package/build/contracts/bridge/Wallets.sol/Wallets.json +2 -47
  31. package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
  32. package/build/contracts/vault/IVault.sol/IVault.dbg.json +1 -1
  33. package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
  34. package/contracts/bridge/BitcoinTx.sol +19 -26
  35. package/contracts/bridge/Bridge.sol +476 -534
  36. package/contracts/bridge/BridgeState.sol +190 -129
  37. package/contracts/bridge/Deposit.sol +23 -4
  38. package/contracts/bridge/EcdsaLib.sol +15 -0
  39. package/contracts/bridge/{Frauds.sol → Fraud.sol} +75 -146
  40. package/contracts/bridge/MovingFunds.sol +15 -9
  41. package/contracts/bridge/{Redeem.sol → Redemption.sol} +19 -17
  42. package/contracts/bridge/Sweep.sol +16 -9
  43. package/contracts/bridge/Wallets.sol +40 -121
  44. package/package.json +1 -1
  45. package/build/contracts/bridge/Frauds.sol/Frauds.dbg.json +0 -4
  46. package/build/contracts/bridge/Frauds.sol/Frauds.json +0 -138
  47. package/build/contracts/bridge/Redeem.sol/OutboundTx.dbg.json +0 -4
  48. package/build/contracts/bridge/Redeem.sol/Redeem.dbg.json +0 -4
  49. package/build/contracts/bridge/Redeem.sol/Redeem.json +0 -110
@@ -17,20 +17,17 @@ 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";
33
- import "./Frauds.sol";
30
+ import "./Fraud.sol";
34
31
  import "./MovingFunds.sol";
35
32
 
36
33
  import "../bank/Bank.sol";
@@ -53,81 +50,20 @@ 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.
57
- ///
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.
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.
62
56
  contract Bridge is Ownable, EcdsaWalletOwner {
63
57
  using BridgeState for BridgeState.Storage;
64
58
  using Deposit for BridgeState.Storage;
65
59
  using Sweep for BridgeState.Storage;
66
- using Redeem for BridgeState.Storage;
60
+ using Redemption for BridgeState.Storage;
67
61
  using MovingFunds for BridgeState.Storage;
68
- using Frauds for Frauds.Data;
69
- using Wallets for Wallets.Data;
70
-
71
- using BTCUtils for bytes;
72
- using BTCUtils for uint256;
73
- using BytesLib for bytes;
62
+ using Wallets for BridgeState.Storage;
63
+ using Fraud for BridgeState.Storage;
74
64
 
75
65
  BridgeState.Storage internal self;
76
66
 
77
- /// @notice Contains parameters related to frauds and the collection of all
78
- /// submitted fraud challenges.
79
- Frauds.Data internal frauds;
80
-
81
- /// @notice State related with wallets.
82
- Wallets.Data internal wallets;
83
-
84
- event WalletCreationPeriodUpdated(uint32 newCreationPeriod);
85
-
86
- event WalletBtcBalanceRangeUpdated(
87
- uint64 newMinBtcBalance,
88
- uint64 newMaxBtcBalance
89
- );
90
-
91
- event WalletMaxAgeUpdated(uint32 newMaxAge);
92
-
93
- event NewWalletRequested();
94
-
95
- event NewWalletRegistered(
96
- bytes32 indexed ecdsaWalletID,
97
- bytes20 indexed walletPubKeyHash
98
- );
99
-
100
- event WalletMovingFunds(
101
- bytes32 indexed ecdsaWalletID,
102
- bytes20 indexed walletPubKeyHash
103
- );
104
-
105
- event WalletClosed(
106
- bytes32 indexed ecdsaWalletID,
107
- bytes20 indexed walletPubKeyHash
108
- );
109
-
110
- event WalletTerminated(
111
- bytes32 indexed ecdsaWalletID,
112
- bytes20 indexed walletPubKeyHash
113
- );
114
-
115
- event VaultStatusUpdated(address indexed vault, bool isTrusted);
116
-
117
- event FraudSlashingAmountUpdated(uint256 newFraudSlashingAmount);
118
-
119
- event FraudNotifierRewardMultiplierUpdated(
120
- uint256 newFraudNotifierRewardMultiplier
121
- );
122
-
123
- event FraudChallengeDefeatTimeoutUpdated(
124
- uint256 newFraudChallengeDefeatTimeout
125
- );
126
-
127
- event FraudChallengeDepositAmountUpdated(
128
- uint256 newFraudChallengeDepositAmount
129
- );
130
-
131
67
  event DepositRevealed(
132
68
  bytes32 fundingTxHash,
133
69
  uint32 fundingOutputIndex,
@@ -161,6 +97,33 @@ contract Bridge is Ownable, EcdsaWalletOwner {
161
97
  bytes redeemerOutputScript
162
98
  );
163
99
 
100
+ event WalletMovingFunds(
101
+ bytes32 indexed ecdsaWalletID,
102
+ bytes20 indexed walletPubKeyHash
103
+ );
104
+
105
+ event MovingFundsCompleted(
106
+ bytes20 walletPubKeyHash,
107
+ bytes32 movingFundsTxHash
108
+ );
109
+
110
+ event NewWalletRequested();
111
+
112
+ event NewWalletRegistered(
113
+ bytes32 indexed ecdsaWalletID,
114
+ bytes20 indexed walletPubKeyHash
115
+ );
116
+
117
+ event WalletClosed(
118
+ bytes32 indexed ecdsaWalletID,
119
+ bytes20 indexed walletPubKeyHash
120
+ );
121
+
122
+ event WalletTerminated(
123
+ bytes32 indexed ecdsaWalletID,
124
+ bytes20 indexed walletPubKeyHash
125
+ );
126
+
164
127
  event FraudChallengeSubmitted(
165
128
  bytes20 walletPublicKeyHash,
166
129
  bytes32 sighash,
@@ -176,9 +139,13 @@ contract Bridge is Ownable, EcdsaWalletOwner {
176
139
  bytes32 sighash
177
140
  );
178
141
 
179
- event MovingFundsCompleted(
180
- bytes20 walletPubKeyHash,
181
- bytes32 movingFundsTxHash
142
+ event VaultStatusUpdated(address indexed vault, bool isTrusted);
143
+
144
+ event WalletParametersUpdated(
145
+ uint32 walletCreationPeriod,
146
+ uint64 walletMinBtcBalance,
147
+ uint64 walletMaxBtcBalance,
148
+ uint32 walletMaxAge
182
149
  );
183
150
 
184
151
  constructor(
@@ -194,6 +161,12 @@ contract Bridge is Ownable, EcdsaWalletOwner {
194
161
  require(_relay != address(0), "Relay address cannot be zero");
195
162
  self.relay = IRelay(_relay);
196
163
 
164
+ require(
165
+ _ecdsaWalletRegistry != address(0),
166
+ "ECDSA Wallet Registry address cannot be zero"
167
+ );
168
+ self.ecdsaWalletRegistry = EcdsaWalletRegistry(_ecdsaWalletRegistry);
169
+
197
170
  require(_treasury != address(0), "Treasury address cannot be zero");
198
171
  self.treasury = _treasury;
199
172
 
@@ -208,177 +181,14 @@ contract Bridge is Ownable, EcdsaWalletOwner {
208
181
  self.redemptionTxMaxFee = 10000; // 10000 satoshi
209
182
  self.redemptionTimeout = 172800; // 48 hours
210
183
  self.movingFundsTxMaxTotalFee = 10000; // 10000 satoshi
211
-
212
- // TODO: Revisit initial values.
213
- frauds.setSlashingAmount(10000 * 1e18); // 10000 T
214
- frauds.setNotifierRewardMultiplier(100); // 100%
215
- frauds.setChallengeDefeatTimeout(7 days);
216
- frauds.setChallengeDepositAmount(2 ether);
217
-
218
- // TODO: Revisit initial values.
219
- wallets.init(_ecdsaWalletRegistry);
220
- wallets.setCreationPeriod(1 weeks);
221
- wallets.setBtcBalanceRange(1 * 1e8, 10 * 1e8); // [1 BTC, 10 BTC]
222
- wallets.setMaxAge(26 weeks); // ~6 months
223
- }
224
-
225
- /// @notice Updates parameters used by the `Wallets` library.
226
- /// @param creationPeriod New value of the wallet creation period
227
- /// @param minBtcBalance New value of the minimum BTC balance
228
- /// @param maxBtcBalance New value of the maximum BTC balance
229
- /// @param maxAge New value of the wallet maximum age
230
- /// @dev Requirements:
231
- /// - Caller must be the contract owner.
232
- /// - Minimum BTC balance must be greater than zero
233
- /// - Maximum BTC balance must be greater than minimum BTC balance
234
- function updateWalletsParameters(
235
- uint32 creationPeriod,
236
- uint64 minBtcBalance,
237
- uint64 maxBtcBalance,
238
- uint32 maxAge
239
- ) external onlyOwner {
240
- wallets.setCreationPeriod(creationPeriod);
241
- wallets.setBtcBalanceRange(minBtcBalance, maxBtcBalance);
242
- wallets.setMaxAge(maxAge);
243
- }
244
-
245
- /// @return creationPeriod Value of the wallet creation period
246
- /// @return minBtcBalance Value of the minimum BTC balance
247
- /// @return maxBtcBalance Value of the maximum BTC balance
248
- /// @return maxAge Value of the wallet max age
249
- function getWalletsParameters()
250
- external
251
- view
252
- returns (
253
- uint32 creationPeriod,
254
- uint64 minBtcBalance,
255
- uint64 maxBtcBalance,
256
- uint32 maxAge
257
- )
258
- {
259
- creationPeriod = wallets.creationPeriod;
260
- minBtcBalance = wallets.minBtcBalance;
261
- maxBtcBalance = wallets.maxBtcBalance;
262
- maxAge = wallets.maxAge;
263
-
264
- return (creationPeriod, minBtcBalance, maxBtcBalance, maxAge);
265
- }
266
-
267
- /// @notice Allows the Governance to mark the given vault address as trusted
268
- /// or no longer trusted. Vaults are not trusted by default.
269
- /// Trusted vault must meet the following criteria:
270
- /// - `IVault.receiveBalanceIncrease` must have a known, low gas
271
- /// cost.
272
- /// - `IVault.receiveBalanceIncrease` must never revert.
273
- /// @dev Without restricting reveal only to trusted vaults, malicious
274
- /// vaults not meeting the criteria would be able to nuke sweep proof
275
- /// transactions executed by ECDSA wallet with deposits routed to
276
- /// them.
277
- /// @param vault The address of the vault
278
- /// @param isTrusted flag indicating whether the vault is trusted or not
279
- /// @dev Can only be called by the Governance.
280
- function setVaultStatus(address vault, bool isTrusted) external onlyOwner {
281
- self.isVaultTrusted[vault] = isTrusted;
282
- emit VaultStatusUpdated(vault, isTrusted);
283
- }
284
-
285
- /// @notice Requests creation of a new wallet. This function just
286
- /// forms a request and the creation process is performed
287
- /// asynchronously. Once a wallet is created, the ECDSA Wallet
288
- /// Registry will notify this contract by calling the
289
- /// `__ecdsaWalletCreatedCallback` function.
290
- /// @param activeWalletMainUtxo Data of the active wallet's main UTXO, as
291
- /// currently known on the Ethereum chain.
292
- /// @dev Requirements:
293
- /// - `activeWalletMainUtxo` components must point to the recent main
294
- /// UTXO of the given active wallet, as currently known on the
295
- /// Ethereum chain. If there is no active wallet at the moment, or
296
- /// the active wallet has no main UTXO, this parameter can be
297
- /// empty as it is ignored.
298
- /// - Wallet creation must not be in progress
299
- /// - If the active wallet is set, one of the following
300
- /// conditions must be true:
301
- /// - The active wallet BTC balance is above the minimum threshold
302
- /// and the active wallet is old enough, i.e. the creation period
303
- /// was elapsed since its creation time
304
- /// - The active wallet BTC balance is above the maximum threshold
305
- function requestNewWallet(BitcoinTx.UTXO calldata activeWalletMainUtxo)
306
- external
307
- {
308
- wallets.requestNewWallet(activeWalletMainUtxo);
309
- }
310
-
311
- /// @notice A callback function that is called by the ECDSA Wallet Registry
312
- /// once a new ECDSA wallet is created.
313
- /// @param ecdsaWalletID Wallet's unique identifier.
314
- /// @param publicKeyX Wallet's public key's X coordinate.
315
- /// @param publicKeyY Wallet's public key's Y coordinate.
316
- /// @dev Requirements:
317
- /// - The only caller authorized to call this function is `registry`
318
- /// - Given wallet data must not belong to an already registered wallet
319
- function __ecdsaWalletCreatedCallback(
320
- bytes32 ecdsaWalletID,
321
- bytes32 publicKeyX,
322
- bytes32 publicKeyY
323
- ) external override {
324
- wallets.registerNewWallet(ecdsaWalletID, publicKeyX, publicKeyY);
325
- }
326
-
327
- /// @notice A callback function that is called by the ECDSA Wallet Registry
328
- /// once a wallet heartbeat failure is detected.
329
- /// @param publicKeyX Wallet's public key's X coordinate
330
- /// @param publicKeyY Wallet's public key's Y coordinate
331
- /// @dev Requirements:
332
- /// - The only caller authorized to call this function is `registry`
333
- /// - Wallet must be in Live state
334
- function __ecdsaWalletHeartbeatFailedCallback(
335
- bytes32,
336
- bytes32 publicKeyX,
337
- bytes32 publicKeyY
338
- ) external override {
339
- wallets.notifyWalletHeartbeatFailed(publicKeyX, publicKeyY);
340
- }
341
-
342
- /// @notice Notifies that the wallet is either old enough or has too few
343
- /// satoshis left and qualifies to be closed.
344
- /// @param walletPubKeyHash 20-byte public key hash of the wallet
345
- /// @param walletMainUtxo Data of the wallet's main UTXO, as currently
346
- /// known on the Ethereum chain.
347
- /// @dev Requirements:
348
- /// - Wallet must not be set as the current active wallet
349
- /// - Wallet must exceed the wallet maximum age OR the wallet BTC
350
- /// balance must be lesser than the minimum threshold. If the latter
351
- /// case is true, the `walletMainUtxo` components must point to the
352
- /// recent main UTXO of the given wallet, as currently known on the
353
- /// Ethereum chain. If the wallet has no main UTXO, this parameter
354
- /// can be empty as it is ignored since the wallet balance is
355
- /// assumed to be zero.
356
- /// - Wallet must be in Live state
357
- function notifyCloseableWallet(
358
- bytes20 walletPubKeyHash,
359
- BitcoinTx.UTXO calldata walletMainUtxo
360
- ) external {
361
- wallets.notifyCloseableWallet(walletPubKeyHash, walletMainUtxo);
362
- }
363
-
364
- /// @notice Gets details about a registered wallet.
365
- /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
366
- /// using Bitcoin HASH160 over the compressed ECDSA public key)
367
- /// @return Wallet details.
368
- function getWallet(bytes20 walletPubKeyHash)
369
- external
370
- view
371
- returns (Wallets.Wallet memory)
372
- {
373
- return wallets.registeredWallets[walletPubKeyHash];
374
- }
375
-
376
- /// @notice Gets the public key hash of the active wallet.
377
- /// @return The 20-byte public key hash (computed using Bitcoin HASH160
378
- /// over the compressed ECDSA public key) of the active wallet.
379
- /// Returns bytes20(0) if there is no active wallet at the moment.
380
- function getActiveWalletPubKeyHash() external view returns (bytes20) {
381
- return wallets.activeWalletPubKeyHash;
184
+ self.fraudSlashingAmount = 10000 * 1e18; // 10000 T
185
+ self.fraudNotifierRewardMultiplier = 100; // 100%
186
+ self.fraudChallengeDefeatTimeout = 7 days;
187
+ self.fraudChallengeDepositAmount = 2 ether;
188
+ self.walletCreationPeriod = 1 weeks;
189
+ self.walletMinBtcBalance = 1e8; // 1 BTC
190
+ self.walletMaxBtcBalance = 10e8; // 10 BTC
191
+ self.walletMaxAge = 26 weeks; // ~6 months
382
192
  }
383
193
 
384
194
  /// @notice Used by the depositor to reveal information about their P2(W)SH
@@ -419,7 +229,7 @@ contract Bridge is Ownable, EcdsaWalletOwner {
419
229
  BitcoinTx.Info calldata fundingTx,
420
230
  Deposit.DepositRevealInfo calldata reveal
421
231
  ) external {
422
- self.revealDeposit(wallets, fundingTx, reveal);
232
+ self.revealDeposit(fundingTx, reveal);
423
233
  }
424
234
 
425
235
  /// @notice Used by the wallet to prove the BTC deposit sweep transaction
@@ -463,203 +273,26 @@ contract Bridge is Ownable, EcdsaWalletOwner {
463
273
  BitcoinTx.Proof calldata sweepProof,
464
274
  BitcoinTx.UTXO calldata mainUtxo
465
275
  ) external {
466
- self.submitSweepProof(wallets, sweepTx, sweepProof, mainUtxo);
276
+ self.submitSweepProof(sweepTx, sweepProof, mainUtxo);
467
277
  }
468
278
 
469
- /// @notice Submits a fraud challenge indicating that a UTXO being under
470
- /// wallet control was unlocked by the wallet but was not used
471
- /// according to the protocol rules. That means the wallet signed
472
- /// a transaction input pointing to that UTXO and there is a unique
473
- /// sighash and signature pair associated with that input. This
474
- /// function uses those parameters to create a fraud accusation that
475
- /// proves a given transaction input unlocking the given UTXO was
476
- /// actually signed by the wallet. This function cannot determine
477
- /// whether the transaction was actually broadcast and the input was
478
- /// consumed in a fraudulent way so it just opens a challenge period
479
- /// during which the wallet can defeat the challenge by submitting
480
- /// proof of a transaction that consumes the given input according
481
- /// to protocol rules. To prevent spurious allegations, the caller
482
- /// must deposit ETH that is returned back upon justified fraud
483
- /// challenge or confiscated otherwise.
484
- ///@param walletPublicKey The public key of the wallet in the uncompressed
485
- /// and unprefixed format (64 bytes)
486
- /// @param sighash The hash that was used to produce the ECDSA signature
487
- /// that is the subject of the fraud claim. This hash is constructed
488
- /// by applying double SHA-256 over a serialized subset of the
489
- /// transaction. The exact subset used as hash preimage depends on
490
- /// the transaction input the signature is produced for. See BIP-143
491
- /// for reference
492
- /// @param signature Bitcoin signature in the R/S/V format
493
- /// @dev Requirements:
494
- /// - Wallet behind `walletPubKey` must be in `Live` or `MovingFunds`
495
- /// state
496
- /// - The challenger must send appropriate amount of ETH used as
497
- /// fraud challenge deposit
498
- /// - The signature (represented by r, s and v) must be generated by
499
- /// the wallet behind `walletPubKey` during signing of `sighash`
500
- /// - Wallet can be challenged for the given signature only once
501
- function submitFraudChallenge(
502
- bytes calldata walletPublicKey,
503
- bytes32 sighash,
504
- BitcoinTx.RSVSignature calldata signature
505
- ) external payable {
506
- bytes memory compressedWalletPublicKey = EcdsaLib.compressPublicKey(
507
- walletPublicKey.slice32(0),
508
- walletPublicKey.slice32(32)
509
- );
510
- bytes20 walletPubKeyHash = compressedWalletPublicKey.hash160View();
511
-
512
- Wallets.Wallet storage wallet = wallets.registeredWallets[
513
- walletPubKeyHash
514
- ];
515
-
516
- require(
517
- wallet.state == Wallets.WalletState.Live ||
518
- wallet.state == Wallets.WalletState.MovingFunds,
519
- "Wallet is neither in Live nor MovingFunds state"
520
- );
521
-
522
- frauds.submitChallenge(
523
- walletPublicKey,
524
- walletPubKeyHash,
525
- sighash,
526
- signature
527
- );
528
- }
529
-
530
- /// @notice Allows to defeat a pending fraud challenge against a wallet if
531
- /// the transaction that spends the UTXO follows the protocol rules.
532
- /// In order to defeat the challenge the same `walletPublicKey` and
533
- /// signature (represented by `r`, `s` and `v`) must be provided as
534
- /// were used to calculate the sighash during input signing.
535
- /// The fraud challenge defeat attempt will only succeed if the
536
- /// inputs in the preimage are considered honestly spent by the
537
- /// wallet. Therefore the transaction spending the UTXO must be
538
- /// proven in the Bridge before a challenge defeat is called.
539
- /// If successfully defeated, the fraud challenge is marked as
540
- /// resolved and the amount of ether deposited by the challenger is
541
- /// sent to the treasury.
542
- /// @param walletPublicKey The public key of the wallet in the uncompressed
543
- /// and unprefixed format (64 bytes)
544
- /// @param preimage The preimage which produces sighash used to generate the
545
- /// ECDSA signature that is the subject of the fraud claim. It is a
546
- /// serialized subset of the transaction. The exact subset used as
547
- /// the preimage depends on the transaction input the signature is
548
- /// produced for. See BIP-143 for reference
549
- /// @param witness Flag indicating whether the preimage was produced for a
550
- /// witness input. True for witness, false for non-witness input
551
- /// @dev Requirements:
552
- /// - `walletPublicKey` and `sighash` calculated as `hash256(preimage)`
553
- /// must identify an open fraud challenge
554
- /// - the preimage must be a valid preimage of a transaction generated
555
- /// according to the protocol rules and already proved in the Bridge
556
- /// - before a defeat attempt is made the transaction that spends the
557
- /// given UTXO must be proven in the Bridge
558
- function defeatFraudChallenge(
559
- bytes calldata walletPublicKey,
560
- bytes calldata preimage,
561
- bool witness
562
- ) external {
563
- uint256 utxoKey = frauds.unwrapChallenge(
564
- walletPublicKey,
565
- preimage,
566
- witness
567
- );
568
-
569
- // Check that the UTXO key identifies a correctly spent UTXO.
570
- require(
571
- self.deposits[utxoKey].sweptAt > 0 || self.spentMainUTXOs[utxoKey],
572
- "Spent UTXO not found among correctly spent UTXOs"
573
- );
574
-
575
- frauds.defeatChallenge(walletPublicKey, preimage, self.treasury);
576
- }
577
-
578
- /// @notice Notifies about defeat timeout for the given fraud challenge.
579
- /// Can be called only if there was a fraud challenge identified by
580
- /// the provided `walletPublicKey` and `sighash` and it was not
581
- /// defeated on time. The amount of time that needs to pass after
582
- /// a fraud challenge is reported is indicated by the
583
- /// `challengeDefeatTimeout`. After a successful fraud challenge
584
- /// defeat timeout notification the fraud challenge is marked as
585
- /// resolved, the stake of each operator is slashed, the ether
586
- /// deposited is returned to the challenger and the challenger is
587
- /// rewarded.
588
- /// @param walletPublicKey The public key of the wallet in the uncompressed
589
- /// and unprefixed format (64 bytes)
590
- /// @param sighash The hash that was used to produce the ECDSA signature
591
- /// that is the subject of the fraud claim. This hash is constructed
592
- /// by applying double SHA-256 over a serialized subset of the
593
- /// transaction. The exact subset used as hash preimage depends on
594
- /// the transaction input the signature is produced for. See BIP-143
595
- /// for reference
596
- /// @dev Requirements:
597
- /// - `walletPublicKey`and `sighash` must identify an open fraud
598
- /// challenge
599
- /// - the amount of time indicated by `challengeDefeatTimeout` must
600
- /// pass after the challenge was reported
601
- function notifyFraudChallengeDefeatTimeout(
602
- bytes calldata walletPublicKey,
603
- bytes32 sighash
604
- ) external {
605
- frauds.notifyChallengeDefeatTimeout(walletPublicKey, sighash);
606
- }
607
-
608
- /// @notice Returns parameters used by the `Frauds` library.
609
- /// @return slashingAmount Value of the slashing amount
610
- /// @return notifierRewardMultiplier Value of the notifier reward multiplier
611
- /// @return challengeDefeatTimeout Value of the challenge defeat timeout
612
- /// @return challengeDepositAmount Value of the challenge deposit amount
613
- function getFraudParameters()
614
- external
615
- view
616
- returns (
617
- uint256 slashingAmount,
618
- uint256 notifierRewardMultiplier,
619
- uint256 challengeDefeatTimeout,
620
- uint256 challengeDepositAmount
621
- )
622
- {
623
- slashingAmount = frauds.slashingAmount;
624
- notifierRewardMultiplier = frauds.notifierRewardMultiplier;
625
- challengeDefeatTimeout = frauds.challengeDefeatTimeout;
626
- challengeDepositAmount = frauds.challengeDepositAmount;
627
-
628
- return (
629
- slashingAmount,
630
- notifierRewardMultiplier,
631
- challengeDefeatTimeout,
632
- challengeDepositAmount
633
- );
634
- }
635
-
636
- /// @notice Returns the fraud challenge identified by the given key built
637
- /// as keccak256(walletPublicKey|sighash).
638
- function fraudChallenges(uint256 challengeKey)
639
- external
640
- view
641
- returns (Frauds.FraudChallenge memory)
642
- {
643
- return frauds.challenges[challengeKey];
644
- }
645
-
646
- /// @notice Requests redemption of the given amount from the specified
647
- /// wallet to the redeemer Bitcoin output script.
648
- /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
649
- /// using Bitcoin HASH160 over the compressed ECDSA public key)
650
- /// @param mainUtxo Data of the wallet's main UTXO, as currently known on
651
- /// the Ethereum chain
652
- /// @param redeemerOutputScript The redeemer's length-prefixed output
653
- /// script (P2PKH, P2WPKH, P2SH or P2WSH) that will be used to lock
654
- /// redeemed BTC
655
- /// @param amount Requested amount in satoshi. This is also the TBTC amount
656
- /// that is taken from redeemer's balance in the Bank upon request.
657
- /// Once the request is handled, the actual amount of BTC locked
658
- /// on the redeemer output script will be always lower than this value
659
- /// since the treasury and Bitcoin transaction fees must be incurred.
660
- /// The minimal amount satisfying the request can be computed as:
661
- /// `amount - (amount / redemptionTreasuryFeeDivisor) - redemptionTxMaxFee`.
662
- /// Fees values are taken at the moment of request creation.
279
+ /// @notice Requests redemption of the given amount from the specified
280
+ /// wallet to the redeemer Bitcoin output script.
281
+ /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
282
+ /// using Bitcoin HASH160 over the compressed ECDSA public key)
283
+ /// @param mainUtxo Data of the wallet's main UTXO, as currently known on
284
+ /// the Ethereum chain
285
+ /// @param redeemerOutputScript The redeemer's length-prefixed output
286
+ /// script (P2PKH, P2WPKH, P2SH or P2WSH) that will be used to lock
287
+ /// redeemed BTC
288
+ /// @param amount Requested amount in satoshi. This is also the TBTC amount
289
+ /// that is taken from redeemer's balance in the Bank upon request.
290
+ /// Once the request is handled, the actual amount of BTC locked
291
+ /// on the redeemer output script will be always lower than this value
292
+ /// since the treasury and Bitcoin transaction fees must be incurred.
293
+ /// The minimal amount satisfying the request can be computed as:
294
+ /// `amount - (amount / redemptionTreasuryFeeDivisor) - redemptionTxMaxFee`.
295
+ /// Fees values are taken at the moment of request creation.
663
296
  /// @dev Requirements:
664
297
  /// - Wallet behind `walletPubKeyHash` must be live
665
298
  /// - `mainUtxo` components must point to the recent main UTXO
@@ -679,7 +312,6 @@ contract Bridge is Ownable, EcdsaWalletOwner {
679
312
  uint64 amount
680
313
  ) external {
681
314
  self.requestRedemption(
682
- wallets,
683
315
  walletPubKeyHash,
684
316
  mainUtxo,
685
317
  redeemerOutputScript,
@@ -738,7 +370,6 @@ contract Bridge is Ownable, EcdsaWalletOwner {
738
370
  bytes20 walletPubKeyHash
739
371
  ) external {
740
372
  self.submitRedemptionProof(
741
- wallets,
742
373
  redemptionTx,
743
374
  redemptionProof,
744
375
  mainUtxo,
@@ -774,11 +405,7 @@ contract Bridge is Ownable, EcdsaWalletOwner {
774
405
  bytes20 walletPubKeyHash,
775
406
  bytes calldata redeemerOutputScript
776
407
  ) external {
777
- self.notifyRedemptionTimeout(
778
- wallets,
779
- walletPubKeyHash,
780
- redeemerOutputScript
781
- );
408
+ self.notifyRedemptionTimeout(walletPubKeyHash, redeemerOutputScript);
782
409
  }
783
410
 
784
411
  /// @notice Used by the wallet to prove the BTC moving funds transaction
@@ -833,7 +460,6 @@ contract Bridge is Ownable, EcdsaWalletOwner {
833
460
  bytes20 walletPubKeyHash
834
461
  ) external {
835
462
  self.submitMovingFundsProof(
836
- wallets,
837
463
  movingFundsTx,
838
464
  movingFundsProof,
839
465
  mainUtxo,
@@ -841,29 +467,350 @@ contract Bridge is Ownable, EcdsaWalletOwner {
841
467
  );
842
468
  }
843
469
 
844
- /// @notice Returns the addresses of contracts Bridge is interacting with.
845
- /// @return bank Address of the Bank the Bridge belongs to.
846
- /// @return relay Address of the Bitcoin relay providing the current Bitcoin
847
- /// network difficulty.
848
- function getContracts() external view returns (Bank bank, IRelay relay) {
849
- bank = self.bank;
850
- relay = self.relay;
470
+ /// @notice Requests creation of a new wallet. This function just
471
+ /// forms a request and the creation process is performed
472
+ /// asynchronously. Once a wallet is created, the ECDSA Wallet
473
+ /// Registry will notify this contract by calling the
474
+ /// `__ecdsaWalletCreatedCallback` function.
475
+ /// @param activeWalletMainUtxo Data of the active wallet's main UTXO, as
476
+ /// currently known on the Ethereum chain.
477
+ /// @dev Requirements:
478
+ /// - `activeWalletMainUtxo` components must point to the recent main
479
+ /// UTXO of the given active wallet, as currently known on the
480
+ /// Ethereum chain. If there is no active wallet at the moment, or
481
+ /// the active wallet has no main UTXO, this parameter can be
482
+ /// empty as it is ignored.
483
+ /// - Wallet creation must not be in progress
484
+ /// - If the active wallet is set, one of the following
485
+ /// conditions must be true:
486
+ /// - The active wallet BTC balance is above the minimum threshold
487
+ /// and the active wallet is old enough, i.e. the creation period
488
+ /// was elapsed since its creation time
489
+ /// - The active wallet BTC balance is above the maximum threshold
490
+ function requestNewWallet(BitcoinTx.UTXO calldata activeWalletMainUtxo)
491
+ external
492
+ {
493
+ self.requestNewWallet(activeWalletMainUtxo);
851
494
  }
852
495
 
853
- /// @notice Address where the deposit treasury fees will be sent to.
854
- /// Treasury takes part in the operators rewarding process.
855
- function treasury() external view returns (address treasury) {
856
- treasury = self.treasury;
496
+ /// @notice A callback function that is called by the ECDSA Wallet Registry
497
+ /// once a new ECDSA wallet is created.
498
+ /// @param ecdsaWalletID Wallet's unique identifier.
499
+ /// @param publicKeyX Wallet's public key's X coordinate.
500
+ /// @param publicKeyY Wallet's public key's Y coordinate.
501
+ /// @dev Requirements:
502
+ /// - The only caller authorized to call this function is `registry`
503
+ /// - Given wallet data must not belong to an already registered wallet
504
+ function __ecdsaWalletCreatedCallback(
505
+ bytes32 ecdsaWalletID,
506
+ bytes32 publicKeyX,
507
+ bytes32 publicKeyY
508
+ ) external override {
509
+ self.registerNewWallet(ecdsaWalletID, publicKeyX, publicKeyY);
857
510
  }
858
511
 
859
- /// @notice The number of confirmations on the Bitcoin chain required to
860
- /// successfully evaluate an SPV proof.
861
- function txProofDifficultyFactor()
512
+ /// @notice A callback function that is called by the ECDSA Wallet Registry
513
+ /// once a wallet heartbeat failure is detected.
514
+ /// @param publicKeyX Wallet's public key's X coordinate
515
+ /// @param publicKeyY Wallet's public key's Y coordinate
516
+ /// @dev Requirements:
517
+ /// - The only caller authorized to call this function is `registry`
518
+ /// - Wallet must be in Live state
519
+ function __ecdsaWalletHeartbeatFailedCallback(
520
+ bytes32,
521
+ bytes32 publicKeyX,
522
+ bytes32 publicKeyY
523
+ ) external override {
524
+ self.notifyWalletHeartbeatFailed(publicKeyX, publicKeyY);
525
+ }
526
+
527
+ /// @notice Notifies that the wallet is either old enough or has too few
528
+ /// satoshis left and qualifies to be closed.
529
+ /// @param walletPubKeyHash 20-byte public key hash of the wallet
530
+ /// @param walletMainUtxo Data of the wallet's main UTXO, as currently
531
+ /// known on the Ethereum chain.
532
+ /// @dev Requirements:
533
+ /// - Wallet must not be set as the current active wallet
534
+ /// - Wallet must exceed the wallet maximum age OR the wallet BTC
535
+ /// balance must be lesser than the minimum threshold. If the latter
536
+ /// case is true, the `walletMainUtxo` components must point to the
537
+ /// recent main UTXO of the given wallet, as currently known on the
538
+ /// Ethereum chain. If the wallet has no main UTXO, this parameter
539
+ /// can be empty as it is ignored since the wallet balance is
540
+ /// assumed to be zero.
541
+ /// - Wallet must be in Live state
542
+ function notifyCloseableWallet(
543
+ bytes20 walletPubKeyHash,
544
+ BitcoinTx.UTXO calldata walletMainUtxo
545
+ ) external {
546
+ self.notifyCloseableWallet(walletPubKeyHash, walletMainUtxo);
547
+ }
548
+
549
+ /// @notice Submits a fraud challenge indicating that a UTXO being under
550
+ /// wallet control was unlocked by the wallet but was not used
551
+ /// according to the protocol rules. That means the wallet signed
552
+ /// a transaction input pointing to that UTXO and there is a unique
553
+ /// sighash and signature pair associated with that input. This
554
+ /// function uses those parameters to create a fraud accusation that
555
+ /// proves a given transaction input unlocking the given UTXO was
556
+ /// actually signed by the wallet. This function cannot determine
557
+ /// whether the transaction was actually broadcast and the input was
558
+ /// consumed in a fraudulent way so it just opens a challenge period
559
+ /// during which the wallet can defeat the challenge by submitting
560
+ /// proof of a transaction that consumes the given input according
561
+ /// to protocol rules. To prevent spurious allegations, the caller
562
+ /// must deposit ETH that is returned back upon justified fraud
563
+ /// challenge or confiscated otherwise.
564
+ ///@param walletPublicKey The public key of the wallet in the uncompressed
565
+ /// and unprefixed format (64 bytes)
566
+ /// @param sighash The hash that was used to produce the ECDSA signature
567
+ /// that is the subject of the fraud claim. This hash is constructed
568
+ /// by applying double SHA-256 over a serialized subset of the
569
+ /// transaction. The exact subset used as hash preimage depends on
570
+ /// the transaction input the signature is produced for. See BIP-143
571
+ /// for reference
572
+ /// @param signature Bitcoin signature in the R/S/V format
573
+ /// @dev Requirements:
574
+ /// - Wallet behind `walletPubKey` must be in `Live` or `MovingFunds`
575
+ /// state
576
+ /// - The challenger must send appropriate amount of ETH used as
577
+ /// fraud challenge deposit
578
+ /// - The signature (represented by r, s and v) must be generated by
579
+ /// the wallet behind `walletPubKey` during signing of `sighash`
580
+ /// - Wallet can be challenged for the given signature only once
581
+ function submitFraudChallenge(
582
+ bytes calldata walletPublicKey,
583
+ bytes32 sighash,
584
+ BitcoinTx.RSVSignature calldata signature
585
+ ) external payable {
586
+ self.submitFraudChallenge(walletPublicKey, sighash, signature);
587
+ }
588
+
589
+ /// @notice Allows to defeat a pending fraud challenge against a wallet if
590
+ /// the transaction that spends the UTXO follows the protocol rules.
591
+ /// In order to defeat the challenge the same `walletPublicKey` and
592
+ /// signature (represented by `r`, `s` and `v`) must be provided as
593
+ /// were used to calculate the sighash during input signing.
594
+ /// The fraud challenge defeat attempt will only succeed if the
595
+ /// inputs in the preimage are considered honestly spent by the
596
+ /// wallet. Therefore the transaction spending the UTXO must be
597
+ /// proven in the Bridge before a challenge defeat is called.
598
+ /// If successfully defeated, the fraud challenge is marked as
599
+ /// resolved and the amount of ether deposited by the challenger is
600
+ /// sent to the treasury.
601
+ /// @param walletPublicKey The public key of the wallet in the uncompressed
602
+ /// and unprefixed format (64 bytes)
603
+ /// @param preimage The preimage which produces sighash used to generate the
604
+ /// ECDSA signature that is the subject of the fraud claim. It is a
605
+ /// serialized subset of the transaction. The exact subset used as
606
+ /// the preimage depends on the transaction input the signature is
607
+ /// produced for. See BIP-143 for reference
608
+ /// @param witness Flag indicating whether the preimage was produced for a
609
+ /// witness input. True for witness, false for non-witness input
610
+ /// @dev Requirements:
611
+ /// - `walletPublicKey` and `sighash` calculated as `hash256(preimage)`
612
+ /// must identify an open fraud challenge
613
+ /// - the preimage must be a valid preimage of a transaction generated
614
+ /// according to the protocol rules and already proved in the Bridge
615
+ /// - before a defeat attempt is made the transaction that spends the
616
+ /// given UTXO must be proven in the Bridge
617
+ function defeatFraudChallenge(
618
+ bytes calldata walletPublicKey,
619
+ bytes calldata preimage,
620
+ bool witness
621
+ ) external {
622
+ self.defeatFraudChallenge(walletPublicKey, preimage, witness);
623
+ }
624
+
625
+ /// @notice Notifies about defeat timeout for the given fraud challenge.
626
+ /// Can be called only if there was a fraud challenge identified by
627
+ /// the provided `walletPublicKey` and `sighash` and it was not
628
+ /// defeated on time. The amount of time that needs to pass after
629
+ /// a fraud challenge is reported is indicated by the
630
+ /// `challengeDefeatTimeout`. After a successful fraud challenge
631
+ /// defeat timeout notification the fraud challenge is marked as
632
+ /// resolved, the stake of each operator is slashed, the ether
633
+ /// deposited is returned to the challenger and the challenger is
634
+ /// rewarded.
635
+ /// @param walletPublicKey The public key of the wallet in the uncompressed
636
+ /// and unprefixed format (64 bytes)
637
+ /// @param sighash The hash that was used to produce the ECDSA signature
638
+ /// that is the subject of the fraud claim. This hash is constructed
639
+ /// by applying double SHA-256 over a serialized subset of the
640
+ /// transaction. The exact subset used as hash preimage depends on
641
+ /// the transaction input the signature is produced for. See BIP-143
642
+ /// for reference
643
+ /// @dev Requirements:
644
+ /// - `walletPublicKey`and `sighash` must identify an open fraud
645
+ /// challenge
646
+ /// - the amount of time indicated by `challengeDefeatTimeout` must
647
+ /// pass after the challenge was reported
648
+ function notifyFraudChallengeDefeatTimeout(
649
+ bytes calldata walletPublicKey,
650
+ bytes32 sighash
651
+ ) external {
652
+ self.notifyFraudChallengeDefeatTimeout(walletPublicKey, sighash);
653
+ }
654
+
655
+ /// @notice Allows the Governance to mark the given vault address as trusted
656
+ /// or no longer trusted. Vaults are not trusted by default.
657
+ /// Trusted vault must meet the following criteria:
658
+ /// - `IVault.receiveBalanceIncrease` must have a known, low gas
659
+ /// cost.
660
+ /// - `IVault.receiveBalanceIncrease` must never revert.
661
+ /// @dev Without restricting reveal only to trusted vaults, malicious
662
+ /// vaults not meeting the criteria would be able to nuke sweep proof
663
+ /// transactions executed by ECDSA wallet with deposits routed to
664
+ /// them.
665
+ /// @param vault The address of the vault
666
+ /// @param isTrusted flag indicating whether the vault is trusted or not
667
+ /// @dev Can only be called by the Governance.
668
+ function setVaultStatus(address vault, bool isTrusted) external onlyOwner {
669
+ self.isVaultTrusted[vault] = isTrusted;
670
+ emit VaultStatusUpdated(vault, isTrusted);
671
+ }
672
+
673
+ // TODO: updateDepositParameters
674
+ // TODO: updateRedemptionParameters
675
+ // TODO: updateMovingFundsParameters
676
+
677
+ /// @notice Updates parameters of wallets.
678
+ /// @param walletCreationPeriod New value of the wallet creation period in
679
+ /// seconds, determines how frequently a new wallet creation can be
680
+ /// requested
681
+ /// @param walletMinBtcBalance New value of the wallet minimum BTC balance
682
+ /// in satoshis, used to decide about wallet creation or closing
683
+ /// @param walletMaxBtcBalance New value of the wallet maximum BTC balance
684
+ /// in satoshis, used to decide about wallet creation
685
+ /// @param walletMaxAge New value of the wallet maximum age in seconds,
686
+ /// indicates the maximum age of a wallet in seconds, after which
687
+ /// the wallet moving funds process can be requested
688
+ /// @dev Requirements:
689
+ /// - Wallet minimum BTC balance must be greater than zero
690
+ /// - Wallet maximum BTC balance must be greater than the wallet
691
+ /// minimum BTC balance
692
+ function updateWalletParameters(
693
+ uint32 walletCreationPeriod,
694
+ uint64 walletMinBtcBalance,
695
+ uint64 walletMaxBtcBalance,
696
+ uint32 walletMaxAge
697
+ ) external onlyOwner {
698
+ self.updateWalletParameters(
699
+ walletCreationPeriod,
700
+ walletMinBtcBalance,
701
+ walletMaxBtcBalance,
702
+ walletMaxAge
703
+ );
704
+ }
705
+
706
+ // TODO: updateFraudParameters
707
+
708
+ /// @notice Collection of all revealed deposits indexed by
709
+ /// keccak256(fundingTxHash | fundingOutputIndex).
710
+ /// The fundingTxHash is bytes32 (ordered as in Bitcoin internally)
711
+ /// and fundingOutputIndex an uint32. This mapping may contain valid
712
+ /// and invalid deposits and the wallet is responsible for
713
+ /// validating them before attempting to execute a sweep.
714
+ function deposits(uint256 depositKey)
715
+ external
716
+ view
717
+ returns (Deposit.DepositRequest memory)
718
+ {
719
+ return self.deposits[depositKey];
720
+ }
721
+
722
+ /// @notice Collection of all pending redemption requests indexed by
723
+ /// redemption key built as
724
+ /// keccak256(walletPubKeyHash | redeemerOutputScript). The
725
+ /// walletPubKeyHash is the 20-byte wallet's public key hash
726
+ /// (computed using Bitcoin HASH160 over the compressed ECDSA
727
+ /// public key) and redeemerOutputScript is a Bitcoin script
728
+ /// (P2PKH, P2WPKH, P2SH or P2WSH) that will be used to lock
729
+ /// redeemed BTC as requested by the redeemer. Requests are added
730
+ /// to this mapping by the `requestRedemption` method (duplicates
731
+ /// not allowed) and are removed by one of the following methods:
732
+ /// - `submitRedemptionProof` in case the request was handled
733
+ /// successfully
734
+ /// - `notifyRedemptionTimeout` in case the request was reported
735
+ /// to be timed out
736
+ function pendingRedemptions(uint256 redemptionKey)
862
737
  external
863
738
  view
864
- returns (uint256 txProofDifficultyFactor)
739
+ returns (Redemption.RedemptionRequest memory)
865
740
  {
866
- txProofDifficultyFactor = self.txProofDifficultyFactor;
741
+ return self.pendingRedemptions[redemptionKey];
742
+ }
743
+
744
+ /// @notice Collection of all timed out redemptions requests indexed by
745
+ /// redemption key built as
746
+ /// keccak256(walletPubKeyHash | redeemerOutputScript). The
747
+ /// walletPubKeyHash is the 20-byte wallet's public key hash
748
+ /// (computed using Bitcoin HASH160 over the compressed ECDSA
749
+ /// public key) and redeemerOutputScript is the Bitcoin script
750
+ /// (P2PKH, P2WPKH, P2SH or P2WSH) that is involved in the timed
751
+ /// out request. Timed out requests are stored in this mapping to
752
+ /// avoid slashing the wallets multiple times for the same timeout.
753
+ /// Only one method can add to this mapping:
754
+ /// - `notifyRedemptionTimeout` which puts the redemption key
755
+ /// to this mapping basing on a timed out request stored
756
+ /// previously in `pendingRedemptions` mapping.
757
+ function timedOutRedemptions(uint256 redemptionKey)
758
+ external
759
+ view
760
+ returns (Redemption.RedemptionRequest memory)
761
+ {
762
+ return self.timedOutRedemptions[redemptionKey];
763
+ }
764
+
765
+ /// @notice Collection of main UTXOs that are honestly spent indexed by
766
+ /// keccak256(fundingTxHash | fundingOutputIndex). The fundingTxHash
767
+ /// is bytes32 (ordered as in Bitcoin internally) and
768
+ /// fundingOutputIndex an uint32. A main UTXO is considered honestly
769
+ /// spent if it was used as an input of a transaction that have been
770
+ /// proven in the Bridge.
771
+ function spentMainUTXOs(uint256 utxoKey) external view returns (bool) {
772
+ return self.spentMainUTXOs[utxoKey];
773
+ }
774
+
775
+ /// @notice Gets details about a registered wallet.
776
+ /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
777
+ /// using Bitcoin HASH160 over the compressed ECDSA public key)
778
+ /// @return Wallet details.
779
+ function wallets(bytes20 walletPubKeyHash)
780
+ external
781
+ view
782
+ returns (Wallets.Wallet memory)
783
+ {
784
+ return self.registeredWallets[walletPubKeyHash];
785
+ }
786
+
787
+ /// @notice Gets the public key hash of the active wallet.
788
+ /// @return The 20-byte public key hash (computed using Bitcoin HASH160
789
+ /// over the compressed ECDSA public key) of the active wallet.
790
+ /// Returns bytes20(0) if there is no active wallet at the moment.
791
+ function activeWalletPubKeyHash() external view returns (bytes20) {
792
+ return self.activeWalletPubKeyHash;
793
+ }
794
+
795
+ /// @notice Returns the fraud challenge identified by the given key built
796
+ /// as keccak256(walletPublicKey|sighash).
797
+ function fraudChallenges(uint256 challengeKey)
798
+ external
799
+ view
800
+ returns (Fraud.FraudChallenge memory)
801
+ {
802
+ return self.fraudChallenges[challengeKey];
803
+ }
804
+
805
+ /// @notice Indicates if the vault with the given address is trusted or not.
806
+ /// Depositors can route their revealed deposits only to trusted
807
+ /// vaults and have trusted vaults notified about new deposits as
808
+ /// soon as these deposits get swept. Vaults not trusted by the
809
+ /// Bridge can still be used by Bank balance owners on their own
810
+ /// responsibility - anyone can approve their Bank balance to any
811
+ /// address.
812
+ function isVaultTrusted(address vault) external view returns (bool) {
813
+ return self.isVaultTrusted[vault];
867
814
  }
868
815
 
869
816
  /// @notice Returns the current values of Bridge deposit parameters.
@@ -927,9 +874,7 @@ contract Bridge is Ownable, EcdsaWalletOwner {
927
874
  uint64 redemptionDustThreshold,
928
875
  uint64 redemptionTreasuryFeeDivisor,
929
876
  uint64 redemptionTxMaxFee,
930
- uint256 redemptionTimeout,
931
- address treasury,
932
- uint256 txProofDifficultyFactor
877
+ uint256 redemptionTimeout
933
878
  )
934
879
  {
935
880
  redemptionDustThreshold = self.redemptionDustThreshold;
@@ -953,81 +898,78 @@ contract Bridge is Ownable, EcdsaWalletOwner {
953
898
  movingFundsTxMaxTotalFee = self.movingFundsTxMaxTotalFee;
954
899
  }
955
900
 
956
- /// @notice Indicates if the vault with the given address is trusted or not.
957
- /// Depositors can route their revealed deposits only to trusted
958
- /// vaults and have trusted vaults notified about new deposits as
959
- /// soon as these deposits get swept. Vaults not trusted by the
960
- /// Bridge can still be used by Bank balance owners on their own
961
- /// responsibility - anyone can approve their Bank balance to any
962
- /// address.
963
- function isVaultTrusted(address vault) external view returns (bool) {
964
- return self.isVaultTrusted[vault];
965
- }
966
-
967
- /// @notice Collection of all revealed deposits indexed by
968
- /// keccak256(fundingTxHash | fundingOutputIndex).
969
- /// The fundingTxHash is bytes32 (ordered as in Bitcoin internally)
970
- /// and fundingOutputIndex an uint32. This mapping may contain valid
971
- /// and invalid deposits and the wallet is responsible for
972
- /// validating them before attempting to execute a sweep.
973
- function deposits(uint256 depositKey)
901
+ /// @return walletCreationPeriod Determines how frequently a new wallet
902
+ /// creation can be requested. Value in seconds.
903
+ /// @return walletMinBtcBalance The minimum BTC threshold in satoshi that is
904
+ /// used to decide about wallet creation or closing.
905
+ /// @return walletMaxBtcBalance The maximum BTC threshold in satoshi that is
906
+ /// used to decide about wallet creation.
907
+ /// @return walletMaxAge The maximum age of a wallet in seconds, after which
908
+ /// the wallet moving funds process can be requested.
909
+ function walletParameters()
974
910
  external
975
911
  view
976
- returns (Deposit.DepositRequest memory)
912
+ returns (
913
+ uint32 walletCreationPeriod,
914
+ uint64 walletMinBtcBalance,
915
+ uint64 walletMaxBtcBalance,
916
+ uint32 walletMaxAge
917
+ )
977
918
  {
978
- return self.deposits[depositKey];
979
- }
980
-
981
- /// @notice Collection of main UTXOs that are honestly spent indexed by
982
- /// keccak256(fundingTxHash | fundingOutputIndex). The fundingTxHash
983
- /// is bytes32 (ordered as in Bitcoin internally) and
984
- /// fundingOutputIndex an uint32. A main UTXO is considered honestly
985
- /// spent if it was used as an input of a transaction that have been
986
- /// proven in the Bridge.
987
- function spentMainUTXOs(uint256 utxoKey) external view returns (bool) {
988
- return self.spentMainUTXOs[utxoKey];
989
- }
990
-
991
- /// @notice Collection of all pending redemption requests indexed by
992
- /// redemption key built as
993
- /// keccak256(walletPubKeyHash | redeemerOutputScript). The
994
- /// walletPubKeyHash is the 20-byte wallet's public key hash
995
- /// (computed using Bitcoin HASH160 over the compressed ECDSA
996
- /// public key) and redeemerOutputScript is a Bitcoin script
997
- /// (P2PKH, P2WPKH, P2SH or P2WSH) that will be used to lock
998
- /// redeemed BTC as requested by the redeemer. Requests are added
999
- /// to this mapping by the `requestRedemption` method (duplicates
1000
- /// not allowed) and are removed by one of the following methods:
1001
- /// - `submitRedemptionProof` in case the request was handled
1002
- /// successfully
1003
- /// - `notifyRedemptionTimeout` in case the request was reported
1004
- /// to be timed out
1005
- function pendingRedemptions(uint256 redemptionKey)
919
+ walletCreationPeriod = self.walletCreationPeriod;
920
+ walletMinBtcBalance = self.walletMinBtcBalance;
921
+ walletMaxBtcBalance = self.walletMaxBtcBalance;
922
+ walletMaxAge = self.walletMaxAge;
923
+ }
924
+
925
+ /// @notice Returns the current values of Bridge fraud parameters.
926
+ /// @return fraudSlashingAmount The amount slashed from each wallet member
927
+ /// for committing a fraud.
928
+ /// @return fraudNotifierRewardMultiplier The percentage of the notifier
929
+ /// reward from the staking contract the notifier of a fraud
930
+ /// receives. The value is in the range [0, 100].
931
+ /// @return fraudChallengeDefeatTimeout The amount of time the wallet has to
932
+ /// defeat a fraud challenge.
933
+ /// @return fraudChallengeDepositAmount The amount of ETH in wei the party
934
+ /// challenging the wallet for fraud needs to deposit.
935
+ function fraudParameters()
1006
936
  external
1007
937
  view
1008
- returns (Redeem.RedemptionRequest memory)
938
+ returns (
939
+ uint256 fraudSlashingAmount,
940
+ uint256 fraudNotifierRewardMultiplier,
941
+ uint256 fraudChallengeDefeatTimeout,
942
+ uint256 fraudChallengeDepositAmount
943
+ )
1009
944
  {
1010
- return self.pendingRedemptions[redemptionKey];
945
+ fraudSlashingAmount = self.fraudSlashingAmount;
946
+ fraudNotifierRewardMultiplier = self.fraudNotifierRewardMultiplier;
947
+ fraudChallengeDefeatTimeout = self.fraudChallengeDefeatTimeout;
948
+ fraudChallengeDepositAmount = self.fraudChallengeDepositAmount;
1011
949
  }
1012
950
 
1013
- /// @notice Collection of all timed out redemptions requests indexed by
1014
- /// redemption key built as
1015
- /// keccak256(walletPubKeyHash | redeemerOutputScript). The
1016
- /// walletPubKeyHash is the 20-byte wallet's public key hash
1017
- /// (computed using Bitcoin HASH160 over the compressed ECDSA
1018
- /// public key) and redeemerOutputScript is the Bitcoin script
1019
- /// (P2PKH, P2WPKH, P2SH or P2WSH) that is involved in the timed
1020
- /// out request. Timed out requests are stored in this mapping to
1021
- /// avoid slashing the wallets multiple times for the same timeout.
1022
- /// Only one method can add to this mapping:
1023
- /// - `notifyRedemptionTimeout` which puts the redemption key
1024
- /// to this mapping basing on a timed out request stored
1025
- /// previously in `pendingRedemptions` mapping.
1026
- function timedOutRedemptions(uint256 redemptionKey)
951
+ /// @notice Returns the addresses of contracts Bridge is interacting with.
952
+ /// @return bank Address of the Bank the Bridge belongs to.
953
+ /// @return relay Address of the Bitcoin relay providing the current Bitcoin
954
+ /// network difficulty.
955
+ function contractReferences()
1027
956
  external
1028
957
  view
1029
- returns (Redeem.RedemptionRequest memory)
958
+ returns (Bank bank, IRelay relay)
1030
959
  {
1031
- return self.timedOutRedemptions[redemptionKey];
960
+ bank = self.bank;
961
+ relay = self.relay;
962
+ }
963
+
964
+ /// @notice Address where the deposit treasury fees will be sent to.
965
+ /// Treasury takes part in the operators rewarding process.
966
+ function treasury() external view returns (address) {
967
+ return self.treasury;
968
+ }
969
+
970
+ /// @notice The number of confirmations on the Bitcoin chain required to
971
+ /// successfully evaluate an SPV proof.
972
+ function txProofDifficultyFactor() external view returns (uint256) {
973
+ return self.txProofDifficultyFactor;
1032
974
  }
1033
975
  }