@keep-network/tbtc-v2 0.1.1-dev.42 → 0.1.1-dev.45

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/{002940e9cc8128f6629e90620c66cba5.json → 58ca6018672440f1c9c800806e096f9c.json} +22 -22
  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 +489 -173
  39. package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
  40. package/build/contracts/bridge/BridgeState.sol/BridgeState.json +114 -2
  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 +40 -2
  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 +21 -2
  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 +736 -489
  64. package/contracts/bridge/BridgeState.sol +271 -24
  65. package/contracts/bridge/Deposit.sol +24 -2
  66. package/contracts/bridge/EcdsaLib.sol +15 -0
  67. package/contracts/bridge/Fraud.sol +64 -31
  68. package/contracts/bridge/MovingFunds.sol +194 -6
  69. package/contracts/bridge/{Redeem.sol → Redemption.sol} +20 -18
  70. package/contracts/bridge/Sweep.sol +13 -8
  71. package/contracts/bridge/Wallets.sol +53 -35
  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 -92
@@ -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,72 +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;
68
- using Fraud for BridgeState.Storage;
69
66
  using Wallets for BridgeState.Storage;
70
-
71
- using BTCUtils for bytes;
72
- using BTCUtils for uint256;
73
- using BytesLib for bytes;
67
+ using Fraud for BridgeState.Storage;
74
68
 
75
69
  BridgeState.Storage internal self;
76
70
 
77
- event WalletParametersUpdated(
78
- uint32 walletCreationPeriod,
79
- uint64 walletMinBtcBalance,
80
- uint64 walletMaxBtcBalance,
81
- uint32 walletMaxAge
82
- );
83
-
84
- event NewWalletRequested();
85
-
86
- event NewWalletRegistered(
87
- bytes32 indexed ecdsaWalletID,
88
- bytes20 indexed walletPubKeyHash
89
- );
90
-
91
- event WalletMovingFunds(
92
- bytes32 indexed ecdsaWalletID,
93
- bytes20 indexed walletPubKeyHash
94
- );
95
-
96
- event WalletClosed(
97
- bytes32 indexed ecdsaWalletID,
98
- bytes20 indexed walletPubKeyHash
99
- );
100
-
101
- event WalletTerminated(
102
- bytes32 indexed ecdsaWalletID,
103
- bytes20 indexed walletPubKeyHash
104
- );
105
-
106
- event VaultStatusUpdated(address indexed vault, bool isTrusted);
107
-
108
- event FraudSlashingAmountUpdated(uint256 newFraudSlashingAmount);
109
-
110
- event FraudNotifierRewardMultiplierUpdated(
111
- uint256 newFraudNotifierRewardMultiplier
112
- );
113
-
114
- event FraudChallengeDefeatTimeoutUpdated(
115
- uint256 newFraudChallengeDefeatTimeout
116
- );
117
-
118
- event FraudChallengeDepositAmountUpdated(
119
- uint256 newFraudChallengeDepositAmount
120
- );
121
-
122
71
  event DepositRevealed(
123
72
  bytes32 fundingTxHash,
124
73
  uint32 fundingOutputIndex,
@@ -152,24 +101,94 @@ contract Bridge is Ownable, EcdsaWalletOwner {
152
101
  bytes redeemerOutputScript
153
102
  );
154
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
+
155
144
  event FraudChallengeSubmitted(
156
- bytes20 walletPublicKeyHash,
145
+ bytes20 walletPubKeyHash,
157
146
  bytes32 sighash,
158
147
  uint8 v,
159
148
  bytes32 r,
160
149
  bytes32 s
161
150
  );
162
151
 
163
- event FraudChallengeDefeated(bytes20 walletPublicKeyHash, bytes32 sighash);
152
+ event FraudChallengeDefeated(bytes20 walletPubKeyHash, bytes32 sighash);
164
153
 
165
154
  event FraudChallengeDefeatTimedOut(
166
- bytes20 walletPublicKeyHash,
155
+ bytes20 walletPubKeyHash,
167
156
  bytes32 sighash
168
157
  );
169
158
 
170
- event MovingFundsCompleted(
171
- bytes20 walletPubKeyHash,
172
- 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
173
192
  );
174
193
 
175
194
  constructor(
@@ -205,6 +224,7 @@ contract Bridge is Ownable, EcdsaWalletOwner {
205
224
  self.redemptionTxMaxFee = 10000; // 10000 satoshi
206
225
  self.redemptionTimeout = 172800; // 48 hours
207
226
  self.movingFundsTxMaxTotalFee = 10000; // 10000 satoshi
227
+ self.movingFundsTimeout = 7 days;
208
228
  self.fraudSlashingAmount = 10000 * 1e18; // 10000 T
209
229
  self.fraudNotifierRewardMultiplier = 100; // 100%
210
230
  self.fraudChallengeDefeatTimeout = 7 days;
@@ -213,123 +233,7 @@ contract Bridge is Ownable, EcdsaWalletOwner {
213
233
  self.walletMinBtcBalance = 1e8; // 1 BTC
214
234
  self.walletMaxBtcBalance = 10e8; // 10 BTC
215
235
  self.walletMaxAge = 26 weeks; // ~6 months
216
- }
217
-
218
- /// @notice Allows the Governance to mark the given vault address as trusted
219
- /// or no longer trusted. Vaults are not trusted by default.
220
- /// Trusted vault must meet the following criteria:
221
- /// - `IVault.receiveBalanceIncrease` must have a known, low gas
222
- /// cost.
223
- /// - `IVault.receiveBalanceIncrease` must never revert.
224
- /// @dev Without restricting reveal only to trusted vaults, malicious
225
- /// vaults not meeting the criteria would be able to nuke sweep proof
226
- /// transactions executed by ECDSA wallet with deposits routed to
227
- /// them.
228
- /// @param vault The address of the vault
229
- /// @param isTrusted flag indicating whether the vault is trusted or not
230
- /// @dev Can only be called by the Governance.
231
- function setVaultStatus(address vault, bool isTrusted) external onlyOwner {
232
- self.isVaultTrusted[vault] = isTrusted;
233
- emit VaultStatusUpdated(vault, isTrusted);
234
- }
235
-
236
- /// @notice Requests creation of a new wallet. This function just
237
- /// forms a request and the creation process is performed
238
- /// asynchronously. Once a wallet is created, the ECDSA Wallet
239
- /// Registry will notify this contract by calling the
240
- /// `__ecdsaWalletCreatedCallback` function.
241
- /// @param activeWalletMainUtxo Data of the active wallet's main UTXO, as
242
- /// currently known on the Ethereum chain.
243
- /// @dev Requirements:
244
- /// - `activeWalletMainUtxo` components must point to the recent main
245
- /// UTXO of the given active wallet, as currently known on the
246
- /// Ethereum chain. If there is no active wallet at the moment, or
247
- /// the active wallet has no main UTXO, this parameter can be
248
- /// empty as it is ignored.
249
- /// - Wallet creation must not be in progress
250
- /// - If the active wallet is set, one of the following
251
- /// conditions must be true:
252
- /// - The active wallet BTC balance is above the minimum threshold
253
- /// and the active wallet is old enough, i.e. the creation period
254
- /// was elapsed since its creation time
255
- /// - The active wallet BTC balance is above the maximum threshold
256
- function requestNewWallet(BitcoinTx.UTXO calldata activeWalletMainUtxo)
257
- external
258
- {
259
- self.requestNewWallet(activeWalletMainUtxo);
260
- }
261
-
262
- /// @notice A callback function that is called by the ECDSA Wallet Registry
263
- /// once a new ECDSA wallet is created.
264
- /// @param ecdsaWalletID Wallet's unique identifier.
265
- /// @param publicKeyX Wallet's public key's X coordinate.
266
- /// @param publicKeyY Wallet's public key's Y coordinate.
267
- /// @dev Requirements:
268
- /// - The only caller authorized to call this function is `registry`
269
- /// - Given wallet data must not belong to an already registered wallet
270
- function __ecdsaWalletCreatedCallback(
271
- bytes32 ecdsaWalletID,
272
- bytes32 publicKeyX,
273
- bytes32 publicKeyY
274
- ) external override {
275
- self.registerNewWallet(ecdsaWalletID, publicKeyX, publicKeyY);
276
- }
277
-
278
- /// @notice A callback function that is called by the ECDSA Wallet Registry
279
- /// once a wallet heartbeat failure is detected.
280
- /// @param publicKeyX Wallet's public key's X coordinate
281
- /// @param publicKeyY Wallet's public key's Y coordinate
282
- /// @dev Requirements:
283
- /// - The only caller authorized to call this function is `registry`
284
- /// - Wallet must be in Live state
285
- function __ecdsaWalletHeartbeatFailedCallback(
286
- bytes32,
287
- bytes32 publicKeyX,
288
- bytes32 publicKeyY
289
- ) external override {
290
- self.notifyWalletHeartbeatFailed(publicKeyX, publicKeyY);
291
- }
292
-
293
- /// @notice Notifies that the wallet is either old enough or has too few
294
- /// satoshis left and qualifies to be closed.
295
- /// @param walletPubKeyHash 20-byte public key hash of the wallet
296
- /// @param walletMainUtxo Data of the wallet's main UTXO, as currently
297
- /// known on the Ethereum chain.
298
- /// @dev Requirements:
299
- /// - Wallet must not be set as the current active wallet
300
- /// - Wallet must exceed the wallet maximum age OR the wallet BTC
301
- /// balance must be lesser than the minimum threshold. If the latter
302
- /// case is true, the `walletMainUtxo` components must point to the
303
- /// recent main UTXO of the given wallet, as currently known on the
304
- /// Ethereum chain. If the wallet has no main UTXO, this parameter
305
- /// can be empty as it is ignored since the wallet balance is
306
- /// assumed to be zero.
307
- /// - Wallet must be in Live state
308
- function notifyCloseableWallet(
309
- bytes20 walletPubKeyHash,
310
- BitcoinTx.UTXO calldata walletMainUtxo
311
- ) external {
312
- self.notifyCloseableWallet(walletPubKeyHash, walletMainUtxo);
313
- }
314
-
315
- /// @notice Gets details about a registered wallet.
316
- /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
317
- /// using Bitcoin HASH160 over the compressed ECDSA public key)
318
- /// @return Wallet details.
319
- function getWallet(bytes20 walletPubKeyHash)
320
- external
321
- view
322
- returns (Wallets.Wallet memory)
323
- {
324
- return self.registeredWallets[walletPubKeyHash];
325
- }
326
-
327
- /// @notice Gets the public key hash of the active wallet.
328
- /// @return The 20-byte public key hash (computed using Bitcoin HASH160
329
- /// over the compressed ECDSA public key) of the active wallet.
330
- /// Returns bytes20(0) if there is no active wallet at the moment.
331
- function getActiveWalletPubKeyHash() external view returns (bytes20) {
332
- return self.activeWalletPubKeyHash;
236
+ self.walletMaxBtcTransfer = 10e8; // 10 BTC
333
237
  }
334
238
 
335
239
  /// @notice Used by the depositor to reveal information about their P2(W)SH
@@ -417,139 +321,23 @@ contract Bridge is Ownable, EcdsaWalletOwner {
417
321
  self.submitSweepProof(sweepTx, sweepProof, mainUtxo);
418
322
  }
419
323
 
420
- /// @notice Submits a fraud challenge indicating that a UTXO being under
421
- /// wallet control was unlocked by the wallet but was not used
422
- /// according to the protocol rules. That means the wallet signed
423
- /// a transaction input pointing to that UTXO and there is a unique
424
- /// sighash and signature pair associated with that input. This
425
- /// function uses those parameters to create a fraud accusation that
426
- /// proves a given transaction input unlocking the given UTXO was
427
- /// actually signed by the wallet. This function cannot determine
428
- /// whether the transaction was actually broadcast and the input was
429
- /// consumed in a fraudulent way so it just opens a challenge period
430
- /// during which the wallet can defeat the challenge by submitting
431
- /// proof of a transaction that consumes the given input according
432
- /// to protocol rules. To prevent spurious allegations, the caller
433
- /// must deposit ETH that is returned back upon justified fraud
434
- /// challenge or confiscated otherwise.
435
- ///@param walletPublicKey The public key of the wallet in the uncompressed
436
- /// and unprefixed format (64 bytes)
437
- /// @param sighash The hash that was used to produce the ECDSA signature
438
- /// that is the subject of the fraud claim. This hash is constructed
439
- /// by applying double SHA-256 over a serialized subset of the
440
- /// transaction. The exact subset used as hash preimage depends on
441
- /// the transaction input the signature is produced for. See BIP-143
442
- /// for reference
443
- /// @param signature Bitcoin signature in the R/S/V format
444
- /// @dev Requirements:
445
- /// - Wallet behind `walletPubKey` must be in `Live` or `MovingFunds`
446
- /// state
447
- /// - The challenger must send appropriate amount of ETH used as
448
- /// fraud challenge deposit
449
- /// - The signature (represented by r, s and v) must be generated by
450
- /// the wallet behind `walletPubKey` during signing of `sighash`
451
- /// - Wallet can be challenged for the given signature only once
452
- function submitFraudChallenge(
453
- bytes calldata walletPublicKey,
454
- bytes32 sighash,
455
- BitcoinTx.RSVSignature calldata signature
456
- ) external payable {
457
- self.submitFraudChallenge(walletPublicKey, sighash, signature);
458
- }
459
-
460
- /// @notice Allows to defeat a pending fraud challenge against a wallet if
461
- /// the transaction that spends the UTXO follows the protocol rules.
462
- /// In order to defeat the challenge the same `walletPublicKey` and
463
- /// signature (represented by `r`, `s` and `v`) must be provided as
464
- /// were used to calculate the sighash during input signing.
465
- /// The fraud challenge defeat attempt will only succeed if the
466
- /// inputs in the preimage are considered honestly spent by the
467
- /// wallet. Therefore the transaction spending the UTXO must be
468
- /// proven in the Bridge before a challenge defeat is called.
469
- /// If successfully defeated, the fraud challenge is marked as
470
- /// resolved and the amount of ether deposited by the challenger is
471
- /// sent to the treasury.
472
- /// @param walletPublicKey The public key of the wallet in the uncompressed
473
- /// and unprefixed format (64 bytes)
474
- /// @param preimage The preimage which produces sighash used to generate the
475
- /// ECDSA signature that is the subject of the fraud claim. It is a
476
- /// serialized subset of the transaction. The exact subset used as
477
- /// the preimage depends on the transaction input the signature is
478
- /// produced for. See BIP-143 for reference
479
- /// @param witness Flag indicating whether the preimage was produced for a
480
- /// witness input. True for witness, false for non-witness input
481
- /// @dev Requirements:
482
- /// - `walletPublicKey` and `sighash` calculated as `hash256(preimage)`
483
- /// must identify an open fraud challenge
484
- /// - the preimage must be a valid preimage of a transaction generated
485
- /// according to the protocol rules and already proved in the Bridge
486
- /// - before a defeat attempt is made the transaction that spends the
487
- /// given UTXO must be proven in the Bridge
488
- function defeatFraudChallenge(
489
- bytes calldata walletPublicKey,
490
- bytes calldata preimage,
491
- bool witness
492
- ) external {
493
- self.defeatFraudChallenge(walletPublicKey, preimage, witness);
494
- }
495
-
496
- /// @notice Notifies about defeat timeout for the given fraud challenge.
497
- /// Can be called only if there was a fraud challenge identified by
498
- /// the provided `walletPublicKey` and `sighash` and it was not
499
- /// defeated on time. The amount of time that needs to pass after
500
- /// a fraud challenge is reported is indicated by the
501
- /// `challengeDefeatTimeout`. After a successful fraud challenge
502
- /// defeat timeout notification the fraud challenge is marked as
503
- /// resolved, the stake of each operator is slashed, the ether
504
- /// deposited is returned to the challenger and the challenger is
505
- /// rewarded.
506
- /// @param walletPublicKey The public key of the wallet in the uncompressed
507
- /// and unprefixed format (64 bytes)
508
- /// @param sighash The hash that was used to produce the ECDSA signature
509
- /// that is the subject of the fraud claim. This hash is constructed
510
- /// by applying double SHA-256 over a serialized subset of the
511
- /// transaction. The exact subset used as hash preimage depends on
512
- /// the transaction input the signature is produced for. See BIP-143
513
- /// for reference
514
- /// @dev Requirements:
515
- /// - `walletPublicKey`and `sighash` must identify an open fraud
516
- /// challenge
517
- /// - the amount of time indicated by `challengeDefeatTimeout` must
518
- /// pass after the challenge was reported
519
- function notifyFraudChallengeDefeatTimeout(
520
- bytes calldata walletPublicKey,
521
- bytes32 sighash
522
- ) external {
523
- self.notifyFraudChallengeDefeatTimeout(walletPublicKey, sighash);
524
- }
525
-
526
- /// @notice Returns the fraud challenge identified by the given key built
527
- /// as keccak256(walletPublicKey|sighash).
528
- function fraudChallenges(uint256 challengeKey)
529
- external
530
- view
531
- returns (Fraud.FraudChallenge memory)
532
- {
533
- return self.fraudChallenges[challengeKey];
534
- }
535
-
536
- /// @notice Requests redemption of the given amount from the specified
537
- /// wallet to the redeemer Bitcoin output script.
538
- /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
539
- /// using Bitcoin HASH160 over the compressed ECDSA public key)
540
- /// @param mainUtxo Data of the wallet's main UTXO, as currently known on
541
- /// the Ethereum chain
542
- /// @param redeemerOutputScript The redeemer's length-prefixed output
543
- /// script (P2PKH, P2WPKH, P2SH or P2WSH) that will be used to lock
544
- /// redeemed BTC
545
- /// @param amount Requested amount in satoshi. This is also the TBTC amount
546
- /// that is taken from redeemer's balance in the Bank upon request.
547
- /// Once the request is handled, the actual amount of BTC locked
548
- /// on the redeemer output script will be always lower than this value
549
- /// since the treasury and Bitcoin transaction fees must be incurred.
550
- /// The minimal amount satisfying the request can be computed as:
551
- /// `amount - (amount / redemptionTreasuryFeeDivisor) - redemptionTxMaxFee`.
552
- /// 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.
553
341
  /// @dev Requirements:
554
342
  /// - Wallet behind `walletPubKeyHash` must be live
555
343
  /// - `mainUtxo` components must point to the recent main UTXO
@@ -665,6 +453,61 @@ contract Bridge is Ownable, EcdsaWalletOwner {
665
453
  self.notifyRedemptionTimeout(walletPubKeyHash, redeemerOutputScript);
666
454
  }
667
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(
503
+ walletPubKeyHash,
504
+ walletMainUtxo,
505
+ walletMembersIDs,
506
+ walletMemberIndex,
507
+ targetWallets
508
+ );
509
+ }
510
+
668
511
  /// @notice Used by the wallet to prove the BTC moving funds transaction
669
512
  /// and to make the necessary state changes. Moving funds is only
670
513
  /// accepted if it satisfies SPV proof.
@@ -724,166 +567,326 @@ contract Bridge is Ownable, EcdsaWalletOwner {
724
567
  );
725
568
  }
726
569
 
727
- /// @notice Returns the addresses of contracts Bridge is interacting with.
728
- /// @return bank Address of the Bank the Bridge belongs to.
729
- /// @return relay Address of the Bitcoin relay providing the current Bitcoin
730
- /// network difficulty.
731
- function getContracts() external view returns (Bank bank, IRelay relay) {
732
- bank = self.bank;
733
- relay = self.relay;
734
- }
735
-
736
- /// @notice Address where the deposit treasury fees will be sent to.
737
- /// Treasury takes part in the operators rewarding process.
738
- function treasury() external view returns (address treasury) {
739
- treasury = self.treasury;
740
- }
741
-
742
- /// @notice The number of confirmations on the Bitcoin chain required to
743
- /// successfully evaluate an SPV proof.
744
- function txProofDifficultyFactor()
745
- external
746
- view
747
- returns (uint256 txProofDifficultyFactor)
748
- {
749
- 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);
750
578
  }
751
579
 
752
- /// @notice Returns the current values of Bridge deposit parameters.
753
- /// @return depositDustThreshold The minimal amount that can be requested
754
- /// to deposit. Value of this parameter must take into account the
755
- /// value of `depositTreasuryFeeDivisor` and `depositTxMaxFee`
756
- /// parameters in order to make requests that can incur the
757
- /// treasury and transaction fee and still satisfy the depositor.
758
- /// @return depositTreasuryFeeDivisor Divisor used to compute the treasury
759
- /// fee taken from each deposit and transferred to the treasury upon
760
- /// sweep proof submission. That fee is computed as follows:
761
- /// `treasuryFee = depositedAmount / depositTreasuryFeeDivisor`
762
- /// For example, if the treasury fee needs to be 2% of each deposit,
763
- /// the `depositTreasuryFeeDivisor` should be set to `50`
764
- /// because `1/50 = 0.02 = 2%`.
765
- /// @return depositTxMaxFee Maximum amount of BTC transaction fee that can
766
- /// be incurred by each swept deposit being part of the given sweep
767
- /// transaction. If the maximum BTC transaction fee is exceeded,
768
- /// such transaction is considered a fraud.
769
- 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)
770
601
  external
771
- view
772
- returns (
773
- uint64 depositDustThreshold,
774
- uint64 depositTreasuryFeeDivisor,
775
- uint64 depositTxMaxFee
776
- )
777
602
  {
778
- depositDustThreshold = self.depositDustThreshold;
779
- depositTreasuryFeeDivisor = self.depositTreasuryFeeDivisor;
780
- depositTxMaxFee = self.depositTxMaxFee;
603
+ self.requestNewWallet(activeWalletMainUtxo);
781
604
  }
782
605
 
783
- /// @notice Returns the current values of Bridge redemption parameters.
784
- /// @return redemptionDustThreshold The minimal amount that can be requested
785
- /// for redemption. Value of this parameter must take into account
786
- /// the value of `redemptionTreasuryFeeDivisor` and `redemptionTxMaxFee`
787
- /// parameters in order to make requests that can incur the
788
- /// treasury and transaction fee and still satisfy the redeemer.
789
- /// @return redemptionTreasuryFeeDivisor Divisor used to compute the treasury
790
- /// fee taken from each redemption request and transferred to the
791
- /// treasury upon successful request finalization. That fee is
792
- /// computed as follows:
793
- /// `treasuryFee = requestedAmount / redemptionTreasuryFeeDivisor`
794
- /// For example, if the treasury fee needs to be 2% of each
795
- /// redemption request, the `redemptionTreasuryFeeDivisor` should
796
- /// be set to `50` because `1/50 = 0.02 = 2%`.
797
- /// @return redemptionTxMaxFee Maximum amount of BTC transaction fee that
798
- /// can be incurred by each redemption request being part of the
799
- /// given redemption transaction. If the maximum BTC transaction
800
- /// fee is exceeded, such transaction is considered a fraud.
801
- /// @return redemptionTimeout Time after which the redemption request can be
802
- /// reported as timed out. It is counted from the moment when the
803
- /// redemption request was created via `requestRedemption` call.
804
- /// Reported timed out requests are cancelled and locked TBTC is
805
- /// returned to the redeemer in full amount.
806
- function redemptionParameters()
807
- external
808
- view
809
- returns (
810
- uint64 redemptionDustThreshold,
811
- uint64 redemptionTreasuryFeeDivisor,
812
- uint64 redemptionTxMaxFee,
813
- uint256 redemptionTimeout,
814
- address treasury,
815
- uint256 txProofDifficultyFactor
816
- )
817
- {
818
- redemptionDustThreshold = self.redemptionDustThreshold;
819
- redemptionTreasuryFeeDivisor = self.redemptionTreasuryFeeDivisor;
820
- redemptionTxMaxFee = self.redemptionTxMaxFee;
821
- 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);
822
620
  }
823
621
 
824
- /// @notice Returns the current values of Bridge moving funds between
825
- /// wallets parameters.
826
- /// @return movingFundsTxMaxTotalFee Maximum amount of the total BTC
827
- /// transaction fee that is acceptable in a single moving funds
828
- /// transaction. This is a _total_ max fee for the entire moving
829
- /// funds transaction.
830
- function movingFundsParameters()
831
- external
832
- view
833
- returns (uint64 movingFundsTxMaxTotalFee)
834
- {
835
- // TODO: we will have more parameters here, for example moving funds timeout
836
- 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);
837
635
  }
838
636
 
839
- /// @notice Returns the current values of Bridge fraud parameters.
840
- /// @return fraudSlashingAmount The amount slashed from each wallet member
841
- /// for committing a fraud.
842
- /// @return fraudNotifierRewardMultiplier The percentage of the notifier
843
- /// reward from the staking contract the notifier of a fraud
844
- /// receives. The value is in the range [0, 100].
845
- /// @return fraudChallengeDefeatTimeout The amount of time the wallet has to
846
- /// defeat a fraud challenge.
847
- /// @return fraudChallengeDepositAmount The amount of ETH in wei the party
848
- /// challenging the wallet for fraud needs to deposit.
849
- function fraudParameters()
850
- external
851
- view
852
- returns (
853
- uint256 fraudSlashingAmount,
854
- uint256 fraudNotifierRewardMultiplier,
855
- uint256 fraudChallengeDefeatTimeout,
856
- uint256 fraudChallengeDepositAmount
857
- )
858
- {
859
- fraudSlashingAmount = self.fraudSlashingAmount;
860
- fraudNotifierRewardMultiplier = self.fraudNotifierRewardMultiplier;
861
- fraudChallengeDefeatTimeout = self.fraudChallengeDefeatTimeout;
862
- 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);
863
657
  }
864
658
 
865
- /// @return walletCreationPeriod Determines how frequently a new wallet
866
- /// creation can be requested. Value in seconds.
867
- /// @return walletMinBtcBalance The minimum BTC threshold in satoshi that is
868
- /// used to decide about wallet creation or closing.
869
- /// @return walletMaxBtcBalance The maximum BTC threshold in satoshi that is
870
- /// used to decide about wallet creation.
871
- /// @return walletMaxAge The maximum age of a wallet in seconds, after which
872
- /// the wallet moving funds process can be requested.
873
- function walletParameters()
874
- external
875
- view
876
- returns (
877
- uint32 walletCreationPeriod,
878
- uint64 walletMinBtcBalance,
879
- uint64 walletMaxBtcBalance,
880
- uint32 walletMaxAge
881
- )
882
- {
883
- walletCreationPeriod = self.walletCreationPeriod;
884
- walletMinBtcBalance = self.walletMinBtcBalance;
885
- walletMaxBtcBalance = self.walletMaxBtcBalance;
886
- walletMaxAge = self.walletMaxAge;
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 dust threshold must be greater than zero
805
+ /// - Deposit treasury fee divisor must be greater than zero
806
+ /// - Deposit transaction max fee must be greater than zero
807
+ function updateDepositParameters(
808
+ uint64 depositDustThreshold,
809
+ uint64 depositTreasuryFeeDivisor,
810
+ uint64 depositTxMaxFee
811
+ ) external onlyOwner {
812
+ self.updateDepositParameters(
813
+ depositDustThreshold,
814
+ depositTreasuryFeeDivisor,
815
+ depositTxMaxFee
816
+ );
817
+ }
818
+
819
+ /// @notice Updates parameters of redemptions.
820
+ /// @param redemptionDustThreshold New value of the redemption dust
821
+ /// threshold in satoshis. It is the minimal amount that can be
822
+ /// requested for redemption. Value of this parameter must take into
823
+ /// account the value of `redemptionTreasuryFeeDivisor` and
824
+ /// `redemptionTxMaxFee` parameters in order to make requests that
825
+ /// can incur the treasury and transaction fee and still satisfy the
826
+ /// redeemer.
827
+ /// @param redemptionTreasuryFeeDivisor New value of the redemption
828
+ /// treasury fee divisor. It is the divisor used to compute the
829
+ /// treasury fee taken from each redemption request and transferred
830
+ /// to the treasury upon successful request finalization. That fee is
831
+ /// computed as follows:
832
+ /// `treasuryFee = requestedAmount / redemptionTreasuryFeeDivisor`
833
+ /// For example, if the treasury fee needs to be 2% of each
834
+ /// redemption request, the `redemptionTreasuryFeeDivisor` should
835
+ /// be set to `50` because `1/50 = 0.02 = 2%`.
836
+ /// @param redemptionTxMaxFee New value of the redemption transaction max
837
+ /// fee in satoshis. It is the maximum amount of BTC transaction fee
838
+ /// that can be incurred by each redemption request being part of the
839
+ /// given redemption transaction. If the maximum BTC transaction fee
840
+ /// is exceeded, such transaction is considered a fraud.
841
+ /// This is a per-redemption output max fee for the redemption
842
+ /// transaction.
843
+ /// @param redemptionTimeout New value of the redemption timeout in seconds.
844
+ /// It is the time after which the redemption request can be reported
845
+ /// as timed out. It is counted from the moment when the redemption
846
+ /// request was created via `requestRedemption` call. Reported timed
847
+ /// out requests are cancelled and locked TBTC is returned to the
848
+ /// redeemer in full amount.
849
+ /// @dev Requirements:
850
+ /// - Redemption dust threshold must be greater than zero
851
+ /// - Redemption treasury fee divisor must be greater than zero
852
+ /// - Redemption transaction max fee must be greater than zero
853
+ /// - Redemption timeout must be greater than zero
854
+ function updateRedemptionParameters(
855
+ uint64 redemptionDustThreshold,
856
+ uint64 redemptionTreasuryFeeDivisor,
857
+ uint64 redemptionTxMaxFee,
858
+ uint256 redemptionTimeout
859
+ ) external onlyOwner {
860
+ self.updateRedemptionParameters(
861
+ redemptionDustThreshold,
862
+ redemptionTreasuryFeeDivisor,
863
+ redemptionTxMaxFee,
864
+ redemptionTimeout
865
+ );
866
+ }
867
+
868
+ /// @notice Updates parameters of moving funds.
869
+ /// @param movingFundsTxMaxTotalFee New value of the moving funds transaction
870
+ /// max total fee in satoshis. It is the maximum amount of the total
871
+ /// BTC transaction fee that is acceptable in a single moving funds
872
+ /// transaction. This is a _total_ max fee for the entire moving
873
+ /// funds transaction.
874
+ /// @param movingFundsTimeout New value of the moving funds timeout in
875
+ /// seconds. It is the time after which the moving funds process can
876
+ /// be reported as timed out. It is counted from the moment when the
877
+ /// wallet was requested to move their funds and switched to the
878
+ /// MovingFunds state.
879
+ /// @dev Requirements:
880
+ /// - Moving funds transaction max total fee must be greater than zero
881
+ /// - Moving funds timeout must be greater than zero
882
+ function updateMovingFundsParameters(
883
+ uint64 movingFundsTxMaxTotalFee,
884
+ uint32 movingFundsTimeout
885
+ ) external onlyOwner {
886
+ self.updateMovingFundsParameters(
887
+ movingFundsTxMaxTotalFee,
888
+ movingFundsTimeout
889
+ );
887
890
  }
888
891
 
889
892
  /// @notice Updates parameters of wallets.
@@ -891,39 +894,65 @@ contract Bridge is Ownable, EcdsaWalletOwner {
891
894
  /// seconds, determines how frequently a new wallet creation can be
892
895
  /// requested
893
896
  /// @param walletMinBtcBalance New value of the wallet minimum BTC balance
894
- /// in sathoshis, used to decide about wallet creation or closing
897
+ /// in satoshi, used to decide about wallet creation or closing
895
898
  /// @param walletMaxBtcBalance New value of the wallet maximum BTC balance
896
- /// in sathoshis, used to decide about wallet creation
899
+ /// in satoshi, used to decide about wallet creation
897
900
  /// @param walletMaxAge New value of the wallet maximum age in seconds,
898
901
  /// indicates the maximum age of a wallet in seconds, after which
899
902
  /// the wallet moving funds process can be requested
903
+ /// @param walletMaxBtcTransfer New value of the wallet maximum BTC transfer
904
+ /// in satoshi, determines the maximum amount that can be transferred
905
+ // to a single target wallet during the moving funds process
900
906
  /// @dev Requirements:
901
907
  /// - Wallet minimum BTC balance must be greater than zero
902
908
  /// - Wallet maximum BTC balance must be greater than the wallet
903
909
  /// minimum BTC balance
910
+ /// - Wallet maximum BTC transfer must be greater than zero
904
911
  function updateWalletParameters(
905
912
  uint32 walletCreationPeriod,
906
913
  uint64 walletMinBtcBalance,
907
914
  uint64 walletMaxBtcBalance,
908
- uint32 walletMaxAge
915
+ uint32 walletMaxAge,
916
+ uint64 walletMaxBtcTransfer
909
917
  ) external onlyOwner {
910
918
  self.updateWalletParameters(
911
919
  walletCreationPeriod,
912
920
  walletMinBtcBalance,
913
921
  walletMaxBtcBalance,
914
- walletMaxAge
922
+ walletMaxAge,
923
+ walletMaxBtcTransfer
915
924
  );
916
925
  }
917
926
 
918
- /// @notice Indicates if the vault with the given address is trusted or not.
919
- /// Depositors can route their revealed deposits only to trusted
920
- /// vaults and have trusted vaults notified about new deposits as
921
- /// soon as these deposits get swept. Vaults not trusted by the
922
- /// Bridge can still be used by Bank balance owners on their own
923
- /// responsibility - anyone can approve their Bank balance to any
924
- /// address.
925
- function isVaultTrusted(address vault) external view returns (bool) {
926
- return self.isVaultTrusted[vault];
927
+ /// @notice Updates parameters related to frauds.
928
+ /// @param fraudSlashingAmount New value of the fraud slashing amount in T,
929
+ /// it is the amount slashed from each wallet member for committing
930
+ /// a fraud
931
+ /// @param fraudNotifierRewardMultiplier New value of the fraud notifier
932
+ /// reward multiplier as percentage, it determines the percentage of
933
+ /// the notifier reward from the staking contact the notifier of
934
+ /// a fraud receives. The value must be in the range [0, 100]
935
+ /// @param fraudChallengeDefeatTimeout New value of the challenge defeat
936
+ /// timeout in seconds, it is the amount of time the wallet has to
937
+ /// defeat a fraud challenge. The value must be greater than zero
938
+ /// @param fraudChallengeDepositAmount New value of the fraud challenge
939
+ /// deposit amount in wei, it is the amount of ETH the party
940
+ /// challenging the wallet for fraud needs to deposit
941
+ /// @dev Requirements:
942
+ /// - Fraud notifier reward multiplier must be in the range [0, 100]
943
+ /// - Fraud challenge defeat timeout must be greater than 0
944
+ function updateFraudParameters(
945
+ uint256 fraudSlashingAmount,
946
+ uint256 fraudNotifierRewardMultiplier,
947
+ uint256 fraudChallengeDefeatTimeout,
948
+ uint256 fraudChallengeDepositAmount
949
+ ) external onlyOwner {
950
+ self.updateFraudParameters(
951
+ fraudSlashingAmount,
952
+ fraudNotifierRewardMultiplier,
953
+ fraudChallengeDefeatTimeout,
954
+ fraudChallengeDepositAmount
955
+ );
927
956
  }
928
957
 
929
958
  /// @notice Collection of all revealed deposits indexed by
@@ -940,16 +969,6 @@ contract Bridge is Ownable, EcdsaWalletOwner {
940
969
  return self.deposits[depositKey];
941
970
  }
942
971
 
943
- /// @notice Collection of main UTXOs that are honestly spent indexed by
944
- /// keccak256(fundingTxHash | fundingOutputIndex). The fundingTxHash
945
- /// is bytes32 (ordered as in Bitcoin internally) and
946
- /// fundingOutputIndex an uint32. A main UTXO is considered honestly
947
- /// spent if it was used as an input of a transaction that have been
948
- /// proven in the Bridge.
949
- function spentMainUTXOs(uint256 utxoKey) external view returns (bool) {
950
- return self.spentMainUTXOs[utxoKey];
951
- }
952
-
953
972
  /// @notice Collection of all pending redemption requests indexed by
954
973
  /// redemption key built as
955
974
  /// keccak256(walletPubKeyHash | redeemerOutputScript). The
@@ -967,7 +986,7 @@ contract Bridge is Ownable, EcdsaWalletOwner {
967
986
  function pendingRedemptions(uint256 redemptionKey)
968
987
  external
969
988
  view
970
- returns (Redeem.RedemptionRequest memory)
989
+ returns (Redemption.RedemptionRequest memory)
971
990
  {
972
991
  return self.pendingRedemptions[redemptionKey];
973
992
  }
@@ -988,8 +1007,236 @@ contract Bridge is Ownable, EcdsaWalletOwner {
988
1007
  function timedOutRedemptions(uint256 redemptionKey)
989
1008
  external
990
1009
  view
991
- returns (Redeem.RedemptionRequest memory)
1010
+ returns (Redemption.RedemptionRequest memory)
992
1011
  {
993
1012
  return self.timedOutRedemptions[redemptionKey];
994
1013
  }
1014
+
1015
+ /// @notice Collection of main UTXOs that are honestly spent indexed by
1016
+ /// keccak256(fundingTxHash | fundingOutputIndex). The fundingTxHash
1017
+ /// is bytes32 (ordered as in Bitcoin internally) and
1018
+ /// fundingOutputIndex an uint32. A main UTXO is considered honestly
1019
+ /// spent if it was used as an input of a transaction that have been
1020
+ /// proven in the Bridge.
1021
+ function spentMainUTXOs(uint256 utxoKey) external view returns (bool) {
1022
+ return self.spentMainUTXOs[utxoKey];
1023
+ }
1024
+
1025
+ /// @notice Gets details about a registered wallet.
1026
+ /// @param walletPubKeyHash The 20-byte wallet public key hash (computed
1027
+ /// using Bitcoin HASH160 over the compressed ECDSA public key)
1028
+ /// @return Wallet details.
1029
+ function wallets(bytes20 walletPubKeyHash)
1030
+ external
1031
+ view
1032
+ returns (Wallets.Wallet memory)
1033
+ {
1034
+ return self.registeredWallets[walletPubKeyHash];
1035
+ }
1036
+
1037
+ /// @notice Gets the public key hash of the active wallet.
1038
+ /// @return The 20-byte public key hash (computed using Bitcoin HASH160
1039
+ /// over the compressed ECDSA public key) of the active wallet.
1040
+ /// Returns bytes20(0) if there is no active wallet at the moment.
1041
+ function activeWalletPubKeyHash() external view returns (bytes20) {
1042
+ return self.activeWalletPubKeyHash;
1043
+ }
1044
+
1045
+ /// @notice Gets the live wallets count.
1046
+ /// @return The current count of wallets being in the Live state.
1047
+ function liveWalletsCount() external view returns (uint32) {
1048
+ return self.liveWalletsCount;
1049
+ }
1050
+
1051
+ /// @notice Returns the fraud challenge identified by the given key built
1052
+ /// as keccak256(walletPublicKey|sighash).
1053
+ function fraudChallenges(uint256 challengeKey)
1054
+ external
1055
+ view
1056
+ returns (Fraud.FraudChallenge memory)
1057
+ {
1058
+ return self.fraudChallenges[challengeKey];
1059
+ }
1060
+
1061
+ /// @notice Indicates if the vault with the given address is trusted or not.
1062
+ /// Depositors can route their revealed deposits only to trusted
1063
+ /// vaults and have trusted vaults notified about new deposits as
1064
+ /// soon as these deposits get swept. Vaults not trusted by the
1065
+ /// Bridge can still be used by Bank balance owners on their own
1066
+ /// responsibility - anyone can approve their Bank balance to any
1067
+ /// address.
1068
+ function isVaultTrusted(address vault) external view returns (bool) {
1069
+ return self.isVaultTrusted[vault];
1070
+ }
1071
+
1072
+ /// @notice Returns the current values of Bridge deposit parameters.
1073
+ /// @return depositDustThreshold The minimal amount that can be requested
1074
+ /// to deposit. Value of this parameter must take into account the
1075
+ /// value of `depositTreasuryFeeDivisor` and `depositTxMaxFee`
1076
+ /// parameters in order to make requests that can incur the
1077
+ /// treasury and transaction fee and still satisfy the depositor.
1078
+ /// @return depositTreasuryFeeDivisor Divisor used to compute the treasury
1079
+ /// fee taken from each deposit and transferred to the treasury upon
1080
+ /// sweep proof submission. That fee is computed as follows:
1081
+ /// `treasuryFee = depositedAmount / depositTreasuryFeeDivisor`
1082
+ /// For example, if the treasury fee needs to be 2% of each deposit,
1083
+ /// the `depositTreasuryFeeDivisor` should be set to `50`
1084
+ /// because `1/50 = 0.02 = 2%`.
1085
+ /// @return depositTxMaxFee Maximum amount of BTC transaction fee that can
1086
+ /// be incurred by each swept deposit being part of the given sweep
1087
+ /// transaction. If the maximum BTC transaction fee is exceeded,
1088
+ /// such transaction is considered a fraud.
1089
+ function depositParameters()
1090
+ external
1091
+ view
1092
+ returns (
1093
+ uint64 depositDustThreshold,
1094
+ uint64 depositTreasuryFeeDivisor,
1095
+ uint64 depositTxMaxFee
1096
+ )
1097
+ {
1098
+ depositDustThreshold = self.depositDustThreshold;
1099
+ depositTreasuryFeeDivisor = self.depositTreasuryFeeDivisor;
1100
+ depositTxMaxFee = self.depositTxMaxFee;
1101
+ }
1102
+
1103
+ /// @notice Returns the current values of Bridge redemption parameters.
1104
+ /// @return redemptionDustThreshold The minimal amount that can be requested
1105
+ /// for redemption. Value of this parameter must take into account
1106
+ /// the value of `redemptionTreasuryFeeDivisor` and `redemptionTxMaxFee`
1107
+ /// parameters in order to make requests that can incur the
1108
+ /// treasury and transaction fee and still satisfy the redeemer.
1109
+ /// @return redemptionTreasuryFeeDivisor Divisor used to compute the treasury
1110
+ /// fee taken from each redemption request and transferred to the
1111
+ /// treasury upon successful request finalization. That fee is
1112
+ /// computed as follows:
1113
+ /// `treasuryFee = requestedAmount / redemptionTreasuryFeeDivisor`
1114
+ /// For example, if the treasury fee needs to be 2% of each
1115
+ /// redemption request, the `redemptionTreasuryFeeDivisor` should
1116
+ /// be set to `50` because `1/50 = 0.02 = 2%`.
1117
+ /// @return redemptionTxMaxFee Maximum amount of BTC transaction fee that
1118
+ /// can be incurred by each redemption request being part of the
1119
+ /// given redemption transaction. If the maximum BTC transaction
1120
+ /// fee is exceeded, such transaction is considered a fraud.
1121
+ /// This is a per-redemption output max fee for the redemption
1122
+ /// transaction.
1123
+ /// @return redemptionTimeout Time after which the redemption request can be
1124
+ /// reported as timed out. It is counted from the moment when the
1125
+ /// redemption request was created via `requestRedemption` call.
1126
+ /// Reported timed out requests are cancelled and locked TBTC is
1127
+ /// returned to the redeemer in full amount.
1128
+ function redemptionParameters()
1129
+ external
1130
+ view
1131
+ returns (
1132
+ uint64 redemptionDustThreshold,
1133
+ uint64 redemptionTreasuryFeeDivisor,
1134
+ uint64 redemptionTxMaxFee,
1135
+ uint256 redemptionTimeout
1136
+ )
1137
+ {
1138
+ redemptionDustThreshold = self.redemptionDustThreshold;
1139
+ redemptionTreasuryFeeDivisor = self.redemptionTreasuryFeeDivisor;
1140
+ redemptionTxMaxFee = self.redemptionTxMaxFee;
1141
+ redemptionTimeout = self.redemptionTimeout;
1142
+ }
1143
+
1144
+ /// @notice Returns the current values of Bridge moving funds between
1145
+ /// wallets parameters.
1146
+ /// @return movingFundsTxMaxTotalFee Maximum amount of the total BTC
1147
+ /// transaction fee that is acceptable in a single moving funds
1148
+ /// transaction. This is a _total_ max fee for the entire moving
1149
+ /// funds transaction.
1150
+ /// @return movingFundsTimeout Time after which the moving funds process
1151
+ /// can be reported as timed out. It is counted from the moment
1152
+ /// when the wallet was requested to move their funds and switched
1153
+ /// to the MovingFunds state. Value in seconds.
1154
+ function movingFundsParameters()
1155
+ external
1156
+ view
1157
+ returns (uint64 movingFundsTxMaxTotalFee, uint32 movingFundsTimeout)
1158
+ {
1159
+ movingFundsTxMaxTotalFee = self.movingFundsTxMaxTotalFee;
1160
+ movingFundsTimeout = self.movingFundsTimeout;
1161
+ }
1162
+
1163
+ /// @return walletCreationPeriod Determines how frequently a new wallet
1164
+ /// creation can be requested. Value in seconds.
1165
+ /// @return walletMinBtcBalance The minimum BTC threshold in satoshi that is
1166
+ /// used to decide about wallet creation or closing.
1167
+ /// @return walletMaxBtcBalance The maximum BTC threshold in satoshi that is
1168
+ /// used to decide about wallet creation.
1169
+ /// @return walletMaxAge The maximum age of a wallet in seconds, after which
1170
+ /// the wallet moving funds process can be requested.
1171
+ /// @return walletMaxBtcTransfer The maximum BTC amount in satoshi than
1172
+ /// can be transferred to a single target wallet during the moving
1173
+ /// funds process.
1174
+ function walletParameters()
1175
+ external
1176
+ view
1177
+ returns (
1178
+ uint32 walletCreationPeriod,
1179
+ uint64 walletMinBtcBalance,
1180
+ uint64 walletMaxBtcBalance,
1181
+ uint32 walletMaxAge,
1182
+ uint64 walletMaxBtcTransfer
1183
+ )
1184
+ {
1185
+ walletCreationPeriod = self.walletCreationPeriod;
1186
+ walletMinBtcBalance = self.walletMinBtcBalance;
1187
+ walletMaxBtcBalance = self.walletMaxBtcBalance;
1188
+ walletMaxAge = self.walletMaxAge;
1189
+ walletMaxBtcTransfer = self.walletMaxBtcTransfer;
1190
+ }
1191
+
1192
+ /// @notice Returns the current values of Bridge fraud parameters.
1193
+ /// @return fraudSlashingAmount The amount slashed from each wallet member
1194
+ /// for committing a fraud.
1195
+ /// @return fraudNotifierRewardMultiplier The percentage of the notifier
1196
+ /// reward from the staking contract the notifier of a fraud
1197
+ /// receives. The value is in the range [0, 100].
1198
+ /// @return fraudChallengeDefeatTimeout The amount of time the wallet has to
1199
+ /// defeat a fraud challenge.
1200
+ /// @return fraudChallengeDepositAmount The amount of ETH in wei the party
1201
+ /// challenging the wallet for fraud needs to deposit.
1202
+ function fraudParameters()
1203
+ external
1204
+ view
1205
+ returns (
1206
+ uint256 fraudSlashingAmount,
1207
+ uint256 fraudNotifierRewardMultiplier,
1208
+ uint256 fraudChallengeDefeatTimeout,
1209
+ uint256 fraudChallengeDepositAmount
1210
+ )
1211
+ {
1212
+ fraudSlashingAmount = self.fraudSlashingAmount;
1213
+ fraudNotifierRewardMultiplier = self.fraudNotifierRewardMultiplier;
1214
+ fraudChallengeDefeatTimeout = self.fraudChallengeDefeatTimeout;
1215
+ fraudChallengeDepositAmount = self.fraudChallengeDepositAmount;
1216
+ }
1217
+
1218
+ /// @notice Returns the addresses of contracts Bridge is interacting with.
1219
+ /// @return bank Address of the Bank the Bridge belongs to.
1220
+ /// @return relay Address of the Bitcoin relay providing the current Bitcoin
1221
+ /// network difficulty.
1222
+ function contractReferences()
1223
+ external
1224
+ view
1225
+ returns (Bank bank, IRelay relay)
1226
+ {
1227
+ bank = self.bank;
1228
+ relay = self.relay;
1229
+ }
1230
+
1231
+ /// @notice Address where the deposit treasury fees will be sent to.
1232
+ /// Treasury takes part in the operators rewarding process.
1233
+ function treasury() external view returns (address) {
1234
+ return self.treasury;
1235
+ }
1236
+
1237
+ /// @notice The number of confirmations on the Bitcoin chain required to
1238
+ /// successfully evaluate an SPV proof.
1239
+ function txProofDifficultyFactor() external view returns (uint256) {
1240
+ return self.txProofDifficultyFactor;
1241
+ }
995
1242
  }