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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/artifacts/Bank.json +742 -0
  2. package/artifacts/Bridge.json +2914 -0
  3. package/artifacts/Deposit.json +117 -0
  4. package/artifacts/EcdsaDkgValidator.json +532 -0
  5. package/artifacts/EcdsaInactivity.json +156 -0
  6. package/artifacts/Fraud.json +153 -0
  7. package/artifacts/KeepRegistry.json +99 -0
  8. package/artifacts/KeepStake.json +286 -0
  9. package/artifacts/KeepToken.json +711 -0
  10. package/artifacts/KeepTokenStaking.json +483 -0
  11. package/artifacts/MovingFunds.json +137 -0
  12. package/artifacts/NuCypherStakingEscrow.json +256 -0
  13. package/artifacts/NuCypherToken.json +711 -0
  14. package/artifacts/RandomBeaconStub.json +141 -0
  15. package/artifacts/Redemption.json +161 -0
  16. package/artifacts/ReimbursementPool.json +509 -0
  17. package/artifacts/Relay.json +123 -0
  18. package/artifacts/SortitionPool.json +944 -0
  19. package/artifacts/Sweep.json +76 -0
  20. package/artifacts/T.json +1148 -0
  21. package/artifacts/TBTC.json +21 -21
  22. package/artifacts/TBTCToken.json +21 -21
  23. package/artifacts/TokenStaking.json +2288 -0
  24. package/artifacts/TokenholderGovernor.json +1795 -0
  25. package/artifacts/TokenholderTimelock.json +1058 -0
  26. package/artifacts/VendingMachine.json +24 -24
  27. package/artifacts/VendingMachineKeep.json +400 -0
  28. package/artifacts/VendingMachineNuCypher.json +400 -0
  29. package/artifacts/WalletRegistry.json +2709 -0
  30. package/artifacts/WalletRegistryGovernance.json +2364 -0
  31. package/artifacts/Wallets.json +186 -0
  32. package/artifacts/solcInputs/{e9b173393b9fd7287a0bfaa6d4eb4b71.json → bbe44823ec28554a9429cce5cafee035.json} +34 -34
  33. package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
  34. package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
  35. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +1 -1
  36. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.json +2 -2
  37. package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
  38. package/build/contracts/bridge/Bridge.sol/Bridge.json +535 -273
  39. package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
  40. package/build/contracts/bridge/BridgeState.sol/BridgeState.json +147 -3
  41. package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +1 -1
  42. package/build/contracts/bridge/Deposit.sol/Deposit.json +2 -2
  43. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +1 -1
  44. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.json +2 -2
  45. package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +1 -1
  46. package/build/contracts/bridge/Fraud.sol/Fraud.json +5 -57
  47. package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +1 -1
  48. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +1 -1
  49. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.json +41 -21
  50. package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +4 -0
  51. package/build/contracts/bridge/{Redeem.sol → Redemption.sol}/OutboundTx.json +3 -3
  52. package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +4 -0
  53. package/build/contracts/bridge/Redemption.sol/Redemption.json +92 -0
  54. package/build/contracts/bridge/Sweep.sol/Sweep.dbg.json +1 -1
  55. package/build/contracts/bridge/Sweep.sol/Sweep.json +2 -2
  56. package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
  57. package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +1 -1
  58. package/build/contracts/bridge/Wallets.sol/Wallets.json +12 -38
  59. package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
  60. package/build/contracts/vault/IVault.sol/IVault.dbg.json +1 -1
  61. package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
  62. package/contracts/bridge/BitcoinTx.sol +19 -26
  63. package/contracts/bridge/Bridge.sol +765 -524
  64. package/contracts/bridge/BridgeState.sol +312 -23
  65. package/contracts/bridge/Deposit.sol +25 -6
  66. package/contracts/bridge/EcdsaLib.sol +15 -0
  67. package/contracts/bridge/Fraud.sol +65 -33
  68. package/contracts/bridge/MovingFunds.sol +196 -10
  69. package/contracts/bridge/{Redeem.sol → Redemption.sol} +26 -29
  70. package/contracts/bridge/Sweep.sol +16 -12
  71. package/contracts/bridge/Wallets.sol +90 -153
  72. package/deploy/00_resolve_relay.ts +28 -0
  73. package/deploy/04_deploy_bank.ts +25 -0
  74. package/deploy/05_deploy_bridge.ts +60 -0
  75. package/deploy/06_bank_update_bridge.ts +19 -0
  76. package/deploy/07_transfer_ownership.ts +17 -0
  77. package/export.json +14797 -459
  78. package/package.json +2 -2
  79. package/build/contracts/bridge/Redeem.sol/OutboundTx.dbg.json +0 -4
  80. package/build/contracts/bridge/Redeem.sol/Redeem.dbg.json +0 -4
  81. package/build/contracts/bridge/Redeem.sol/Redeem.json +0 -110
@@ -20,20 +20,174 @@ import {BytesLib} from "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
20
20
 
21
21
  import "./BitcoinTx.sol";
22
22
  import "./BridgeState.sol";
23
- import "./Redeem.sol";
23
+ import "./Redemption.sol";
24
+ import "./Wallets.sol";
24
25
 
26
+ /// @title Moving Bridge wallet funds
27
+ /// @notice The library handles the logic for moving Bitcoin between Bridge
28
+ /// wallets.
29
+ /// @dev A wallet that failed a heartbeat, did not process requested redemption
30
+ /// on time, or qualifies to be closed, begins the procedure of moving
31
+ /// funds to other wallets in the Bridge. The wallet needs to commit to
32
+ /// which other Live wallets it is moving the funds to and then, provide an
33
+ /// SPV proof of moving funds to the previously committed wallets.
25
34
  library MovingFunds {
26
35
  using BridgeState for BridgeState.Storage;
27
- using Wallets for Wallets.Data;
36
+ using Wallets for BridgeState.Storage;
37
+ using BitcoinTx for BridgeState.Storage;
28
38
 
29
39
  using BTCUtils for bytes;
30
40
  using BytesLib for bytes;
31
41
 
42
+ event MovingFundsCommitmentSubmitted(
43
+ bytes20 walletPubKeyHash,
44
+ bytes20[] targetWallets,
45
+ address submitter
46
+ );
47
+
32
48
  event MovingFundsCompleted(
33
49
  bytes20 walletPubKeyHash,
34
50
  bytes32 movingFundsTxHash
35
51
  );
36
52
 
53
+ event MovingFundsTimedOut(bytes20 walletPubKeyHash);
54
+
55
+ /// @notice Submits the moving funds target wallets commitment.
56
+ /// Once all requirements are met, that function registers the
57
+ /// target wallets commitment and opens the way for moving funds
58
+ /// proof submission.
59
+ /// @param walletPubKeyHash 20-byte public key hash of the source wallet
60
+ /// @param walletMainUtxo Data of the source wallet's main UTXO, as
61
+ /// currently known on the Ethereum chain
62
+ /// @param walletMembersIDs Identifiers of the source wallet signing group
63
+ /// members
64
+ /// @param walletMemberIndex Position of the caller in the source wallet
65
+ /// signing group members list
66
+ /// @param targetWallets List of 20-byte public key hashes of the target
67
+ /// wallets that the source wallet commits to move the funds to
68
+ /// @dev Requirements:
69
+ /// - The source wallet must be in the MovingFunds state
70
+ /// - The source wallet must not have pending redemption requests
71
+ /// - The source wallet must not have submitted its commitment already
72
+ /// - The expression `keccak256(abi.encode(walletMembersIDs))` must
73
+ /// be exactly the same as the hash stored under `membersIdsHash`
74
+ /// for the given source wallet in the ECDSA registry. Those IDs are
75
+ /// not directly stored in the contract for gas efficiency purposes
76
+ /// but they can be read from appropriate `DkgResultSubmitted`
77
+ /// and `DkgResultApproved` events.
78
+ /// - The `walletMemberIndex` must be in range [1, walletMembersIDs.length]
79
+ /// - The caller must be the member of the source wallet signing group
80
+ /// at the position indicated by `walletMemberIndex` parameter
81
+ /// - The `walletMainUtxo` components must point to the recent main
82
+ /// UTXO of the source wallet, as currently known on the Ethereum
83
+ /// chain.
84
+ /// - Source wallet BTC balance must be greater than zero
85
+ /// - At least one Live wallet must exist in the system
86
+ /// - Submitted target wallets count must match the expected count
87
+ /// `N = min(liveWalletsCount, ceil(walletBtcBalance / walletMaxBtcTransfer))`
88
+ /// where `N > 0`
89
+ /// - Each target wallet must be not equal to the source wallet
90
+ /// - Each target wallet must follow the expected order i.e. all
91
+ /// target wallets 20-byte public key hashes represented as numbers
92
+ /// must form a strictly increasing sequence without duplicates.
93
+ /// - Each target wallet must be in Live state
94
+ function submitMovingFundsCommitment(
95
+ BridgeState.Storage storage self,
96
+ bytes20 walletPubKeyHash,
97
+ BitcoinTx.UTXO calldata walletMainUtxo,
98
+ uint32[] calldata walletMembersIDs,
99
+ uint256 walletMemberIndex,
100
+ bytes20[] calldata targetWallets
101
+ ) external {
102
+ Wallets.Wallet storage wallet = self.registeredWallets[
103
+ walletPubKeyHash
104
+ ];
105
+
106
+ require(
107
+ wallet.state == Wallets.WalletState.MovingFunds,
108
+ "Source wallet must be in MovingFunds state"
109
+ );
110
+
111
+ require(
112
+ wallet.pendingRedemptionsValue == 0,
113
+ "Source wallet must handle all pending redemptions first"
114
+ );
115
+
116
+ require(
117
+ wallet.movingFundsTargetWalletsCommitmentHash == bytes32(0),
118
+ "Target wallets commitment already submitted"
119
+ );
120
+
121
+ require(
122
+ self.ecdsaWalletRegistry.isWalletMember(
123
+ wallet.ecdsaWalletID,
124
+ walletMembersIDs,
125
+ msg.sender,
126
+ walletMemberIndex
127
+ ),
128
+ "Caller is not a member of the source wallet"
129
+ );
130
+
131
+ uint64 walletBtcBalance = self.getWalletBtcBalance(
132
+ walletPubKeyHash,
133
+ walletMainUtxo
134
+ );
135
+
136
+ require(walletBtcBalance > 0, "Wallet BTC balance is zero");
137
+
138
+ uint256 expectedTargetWalletsCount = Math.min(
139
+ self.liveWalletsCount,
140
+ Math.ceilDiv(walletBtcBalance, self.walletMaxBtcTransfer)
141
+ );
142
+
143
+ // This requirement fails only when `liveWalletsCount` is zero. In
144
+ // that case, the system cannot accept the commitment and must provide
145
+ // new wallets first.
146
+ //
147
+ // TODO: Expose separate function to reset the moving funds timeout
148
+ // if no Live wallets exist in the system.
149
+ require(expectedTargetWalletsCount > 0, "No target wallets available");
150
+
151
+ require(
152
+ targetWallets.length == expectedTargetWalletsCount,
153
+ "Submitted target wallets count is other than expected"
154
+ );
155
+
156
+ uint160 lastProcessedTargetWallet = 0;
157
+
158
+ for (uint256 i = 0; i < targetWallets.length; i++) {
159
+ bytes20 targetWallet = targetWallets[i];
160
+
161
+ require(
162
+ targetWallet != walletPubKeyHash,
163
+ "Submitted target wallet cannot be equal to the source wallet"
164
+ );
165
+
166
+ require(
167
+ uint160(targetWallet) > lastProcessedTargetWallet,
168
+ "Submitted target wallet breaks the expected order"
169
+ );
170
+
171
+ require(
172
+ self.registeredWallets[targetWallet].state ==
173
+ Wallets.WalletState.Live,
174
+ "Submitted target wallet must be in Live state"
175
+ );
176
+
177
+ lastProcessedTargetWallet = uint160(targetWallet);
178
+ }
179
+
180
+ wallet.movingFundsTargetWalletsCommitmentHash = keccak256(
181
+ abi.encodePacked(targetWallets)
182
+ );
183
+
184
+ emit MovingFundsCommitmentSubmitted(
185
+ walletPubKeyHash,
186
+ targetWallets,
187
+ msg.sender
188
+ );
189
+ }
190
+
37
191
  /// @notice Used by the wallet to prove the BTC moving funds transaction
38
192
  /// and to make the necessary state changes. Moving funds is only
39
193
  /// accepted if it satisfies SPV proof.
@@ -81,7 +235,6 @@ library MovingFunds {
81
235
  /// to `movingFundsTxMaxTotalFee` governable parameter.
82
236
  function submitMovingFundsProof(
83
237
  BridgeState.Storage storage self,
84
- Wallets.Data storage wallets,
85
238
  BitcoinTx.Info calldata movingFundsTx,
86
239
  BitcoinTx.Proof calldata movingFundsProof,
87
240
  BitcoinTx.UTXO calldata mainUtxo,
@@ -91,17 +244,15 @@ library MovingFunds {
91
244
  // can assume the transaction happened on Bitcoin chain and has
92
245
  // a sufficient number of confirmations as determined by
93
246
  // `txProofDifficultyFactor` constant.
94
- bytes32 movingFundsTxHash = BitcoinTx.validateProof(
247
+ bytes32 movingFundsTxHash = self.validateProof(
95
248
  movingFundsTx,
96
- movingFundsProof,
97
- self.proofDifficultyContext()
249
+ movingFundsProof
98
250
  );
99
251
 
100
252
  // Process the moving funds transaction input. Specifically, check if
101
253
  // it refers to the expected wallet's main UTXO.
102
254
  OutboundTx.processWalletOutboundTxInput(
103
255
  self,
104
- wallets,
105
256
  movingFundsTx.inputVector,
106
257
  mainUtxo,
107
258
  walletPubKeyHash
@@ -118,8 +269,8 @@ library MovingFunds {
118
269
  "Transaction fee is too high"
119
270
  );
120
271
 
121
- wallets.notifyFundsMoved(walletPubKeyHash, targetWalletsHash);
122
-
272
+ self.notifyWalletFundsMoved(walletPubKeyHash, targetWalletsHash);
273
+ // slither-disable-next-line reentrancy-events
123
274
  emit MovingFundsCompleted(walletPubKeyHash, movingFundsTxHash);
124
275
  }
125
276
 
@@ -139,7 +290,7 @@ library MovingFunds {
139
290
  /// - The total outputs value must be evenly divided over all outputs.
140
291
  function processMovingFundsTxOutputs(bytes memory movingFundsTxOutputVector)
141
292
  internal
142
- view
293
+ pure
143
294
  returns (bytes32 targetWalletsHash, uint256 outputsTotalValue)
144
295
  {
145
296
  // Determining the total number of Bitcoin transaction outputs in
@@ -277,4 +428,39 @@ library MovingFunds {
277
428
 
278
429
  return (targetWalletsHash, outputsTotalValue);
279
430
  }
431
+
432
+ /// @notice Notifies about a timed out moving funds process. Terminates
433
+ /// the wallet and slashes signing group members as a result.
434
+ /// @param walletPubKeyHash 20-byte public key hash of the wallet
435
+ /// @dev Requirements:
436
+ /// - The wallet must be in the MovingFunds state
437
+ /// - The moving funds timeout must be actually exceeded
438
+ function notifyMovingFundsTimeout(
439
+ BridgeState.Storage storage self,
440
+ bytes20 walletPubKeyHash
441
+ ) external {
442
+ Wallets.Wallet storage wallet = self.registeredWallets[
443
+ walletPubKeyHash
444
+ ];
445
+
446
+ require(
447
+ wallet.state == Wallets.WalletState.MovingFunds,
448
+ "ECDSA wallet must be in MovingFunds state"
449
+ );
450
+
451
+ require(
452
+ /* solhint-disable-next-line not-rely-on-time */
453
+ block.timestamp >
454
+ wallet.movingFundsRequestedAt + self.movingFundsTimeout,
455
+ "Moving funds has not timed out yet"
456
+ );
457
+
458
+ self.terminateWallet(walletPubKeyHash);
459
+
460
+ // TODO: Perform slashing of wallet operators, reward the notifier
461
+ // using seized amount, and add unit tests for that.
462
+
463
+ // slither-disable-next-line reentrancy-events
464
+ emit MovingFundsTimedOut(walletPubKeyHash);
465
+ }
280
466
  }
@@ -47,13 +47,12 @@ library OutboundTx {
47
47
  /// performed the outbound transaction.
48
48
  function processWalletOutboundTxInput(
49
49
  BridgeState.Storage storage self,
50
- Wallets.Data storage wallets,
51
50
  bytes memory walletOutboundTxInputVector,
52
51
  BitcoinTx.UTXO calldata mainUtxo,
53
52
  bytes20 walletPubKeyHash
54
53
  ) internal {
55
54
  // Assert that main UTXO for passed wallet exists in storage.
56
- bytes32 mainUtxoHash = wallets
55
+ bytes32 mainUtxoHash = self
57
56
  .registeredWallets[walletPubKeyHash]
58
57
  .mainUtxoHash;
59
58
  require(mainUtxoHash != bytes32(0), "No main UTXO for given wallet");
@@ -141,10 +140,18 @@ library OutboundTx {
141
140
  }
142
141
  }
143
142
 
144
- // TODO: Rename to Redemption. All library names are nouns.
145
- library Redeem {
143
+ /// @title Bridge redemption
144
+ /// @notice The library handles the logic for redeeming Bitcoin balances from
145
+ /// the Bridge.
146
+ /// @dev To initiate a redemption, a user with a Bank balance supplies
147
+ /// a Bitcoin address. Then, the system calculates the redemption fee, and
148
+ /// releases balance to the provided Bitcoin address. Just like in case of
149
+ /// sweeps of revealed deposits, redemption requests are processed in
150
+ /// batches and require SPV proof to be submitted to the Bridge.
151
+ library Redemption {
146
152
  using BridgeState for BridgeState.Storage;
147
- using Wallets for Wallets.Data;
153
+ using Wallets for BridgeState.Storage;
154
+ using BitcoinTx for BridgeState.Storage;
148
155
 
149
156
  using BTCUtils for bytes;
150
157
  using BytesLib for bytes;
@@ -248,13 +255,12 @@ library Redeem {
248
255
  /// contract can spend the given `amount`.
249
256
  function requestRedemption(
250
257
  BridgeState.Storage storage self,
251
- Wallets.Data storage wallets,
252
258
  bytes20 walletPubKeyHash,
253
259
  BitcoinTx.UTXO calldata mainUtxo,
254
260
  bytes calldata redeemerOutputScript,
255
261
  uint64 amount
256
262
  ) external {
257
- Wallets.Wallet storage wallet = wallets.registeredWallets[
263
+ Wallets.Wallet storage wallet = self.registeredWallets[
258
264
  walletPubKeyHash
259
265
  ];
260
266
 
@@ -419,37 +425,30 @@ library Redeem {
419
425
  /// is identified, that check is omitted in further iterations.
420
426
  function submitRedemptionProof(
421
427
  BridgeState.Storage storage self,
422
- Wallets.Data storage wallets,
423
428
  BitcoinTx.Info calldata redemptionTx,
424
429
  BitcoinTx.Proof calldata redemptionProof,
425
430
  BitcoinTx.UTXO calldata mainUtxo,
426
431
  bytes20 walletPubKeyHash
427
432
  ) external {
428
- // TODO: Just as for `submitSweepProof`, fail early if the function
429
- // call gets frontrunned. See discussion:
430
- // https://github.com/keep-network/tbtc-v2/pull/106#discussion_r801745204
431
-
432
433
  // The actual transaction proof is performed here. After that point, we
433
434
  // can assume the transaction happened on Bitcoin chain and has
434
435
  // a sufficient number of confirmations as determined by
435
436
  // `txProofDifficultyFactor` constant.
436
- bytes32 redemptionTxHash = BitcoinTx.validateProof(
437
+ bytes32 redemptionTxHash = self.validateProof(
437
438
  redemptionTx,
438
- redemptionProof,
439
- self.proofDifficultyContext()
439
+ redemptionProof
440
440
  );
441
441
 
442
442
  // Process the redemption transaction input. Specifically, check if it
443
443
  // refers to the expected wallet's main UTXO.
444
444
  OutboundTx.processWalletOutboundTxInput(
445
445
  self,
446
- wallets,
447
446
  redemptionTx.inputVector,
448
447
  mainUtxo,
449
448
  walletPubKeyHash
450
449
  );
451
450
 
452
- Wallets.Wallet storage wallet = wallets.registeredWallets[
451
+ Wallets.Wallet storage wallet = self.registeredWallets[
453
452
  walletPubKeyHash
454
453
  ];
455
454
 
@@ -600,11 +599,10 @@ library Redeem {
600
599
  bytes20 walletPubKeyHash,
601
600
  RedemptionTxOutputsProcessingInfo memory processInfo
602
601
  ) internal returns (RedemptionTxOutputsInfo memory resultInfo) {
603
- // Helper variable that counts the number of processed redemption
604
- // outputs. Redemptions can be either pending or reported as timed out.
605
- // TODO: Revisit the approach with redemptions count according to
606
- // https://github.com/keep-network/tbtc-v2/pull/128#discussion_r808237765
607
- uint256 processedRedemptionsCount = 0;
602
+ // Helper flag indicating whether there was at least one redemption
603
+ // output present (redemption must be either pending or reported as
604
+ // timed out).
605
+ bool redemptionPresent = false;
608
606
 
609
607
  // Outputs processing loop.
610
608
  for (uint256 i = 0; i < processInfo.outputsCount; i++) {
@@ -651,7 +649,7 @@ library Redeem {
651
649
  );
652
650
  resultInfo.totalBurnableValue += burnableValue;
653
651
  resultInfo.totalTreasuryFee += treasuryFee;
654
- processedRedemptionsCount++;
652
+ redemptionPresent = true;
655
653
  }
656
654
 
657
655
  // Make the `outputStartingIndex` pointing to the next output by
@@ -663,7 +661,7 @@ library Redeem {
663
661
  // referring back to the wallet PKH and just burning main UTXO value
664
662
  // for transaction fees.
665
663
  require(
666
- processedRedemptionsCount > 0,
664
+ redemptionPresent,
667
665
  "Redemption transaction must process at least one redemption"
668
666
  );
669
667
  }
@@ -789,14 +787,13 @@ library Redeem {
789
787
  /// timed-out).
790
788
  function notifyRedemptionTimeout(
791
789
  BridgeState.Storage storage self,
792
- Wallets.Data storage wallets,
793
790
  bytes20 walletPubKeyHash,
794
791
  bytes calldata redeemerOutputScript
795
792
  ) external {
796
793
  uint256 redemptionKey = uint256(
797
794
  keccak256(abi.encodePacked(walletPubKeyHash, redeemerOutputScript))
798
795
  );
799
- Redeem.RedemptionRequest memory request = self.pendingRedemptions[
796
+ Redemption.RedemptionRequest memory request = self.pendingRedemptions[
800
797
  redemptionKey
801
798
  ];
802
799
 
@@ -808,7 +805,7 @@ library Redeem {
808
805
  );
809
806
 
810
807
  // Update the wallet's pending redemptions value
811
- Wallets.Wallet storage wallet = wallets.registeredWallets[
808
+ Wallets.Wallet storage wallet = self.registeredWallets[
812
809
  walletPubKeyHash
813
810
  ];
814
811
  wallet.pendingRedemptionsValue -=
@@ -838,9 +835,9 @@ library Redeem {
838
835
  wallet.state == Wallets.WalletState.MovingFunds
839
836
  ) {
840
837
  // Propagate timeout consequences to the wallet
841
- wallets.notifyRedemptionTimedOut(walletPubKeyHash);
838
+ self.notifyWalletTimedOutRedemption(walletPubKeyHash);
842
839
  }
843
-
840
+ // slither-disable-next-line reentrancy-events
844
841
  emit RedemptionTimedOut(walletPubKeyHash, redeemerOutputScript);
845
842
 
846
843
  // Return the requested amount of tokens to the redeemer
@@ -23,8 +23,19 @@ import "./Wallets.sol";
23
23
 
24
24
  import "../bank/Bank.sol";
25
25
 
26
+ /// @title Bridge deposit sweep
27
+ /// @notice The library handles the logic for sweeping transactions revealed to
28
+ /// the Bridge
29
+ /// @dev Bridge active wallet periodically signs a transaction that unlocks all
30
+ /// of the valid, revealed deposits above the dust threshold, combines them
31
+ /// into a single UTXO with the existing main wallet UTXO, and relocks
32
+ /// those transactions without a 30-day refund clause to the same wallet.
33
+ /// This has two main effects: it consolidates the UTXO set and it disables
34
+ /// the refund. Balances of depositors in the Bank are increased when the
35
+ /// SPV sweep proof is submitted to the Bridge.
26
36
  library Sweep {
27
37
  using BridgeState for BridgeState.Storage;
38
+ using BitcoinTx for BridgeState.Storage;
28
39
 
29
40
  using BTCUtils for bytes;
30
41
 
@@ -94,23 +105,15 @@ library Sweep {
94
105
  /// If there is no main UTXO, this parameter is ignored.
95
106
  function submitSweepProof(
96
107
  BridgeState.Storage storage self,
97
- Wallets.Data storage wallets,
98
108
  BitcoinTx.Info calldata sweepTx,
99
109
  BitcoinTx.Proof calldata sweepProof,
100
110
  BitcoinTx.UTXO calldata mainUtxo
101
111
  ) external {
102
- // TODO: Fail early if the function call gets frontrunned. See discussion:
103
- // https://github.com/keep-network/tbtc-v2/pull/106#discussion_r801745204
104
-
105
112
  // The actual transaction proof is performed here. After that point, we
106
113
  // can assume the transaction happened on Bitcoin chain and has
107
114
  // a sufficient number of confirmations as determined by
108
115
  // `txProofDifficultyFactor` constant.
109
- bytes32 sweepTxHash = BitcoinTx.validateProof(
110
- sweepTx,
111
- sweepProof,
112
- self.proofDifficultyContext()
113
- );
116
+ bytes32 sweepTxHash = self.validateProof(sweepTx, sweepProof);
114
117
 
115
118
  // Process sweep transaction output and extract its target wallet
116
119
  // public key hash and value.
@@ -122,7 +125,7 @@ library Sweep {
122
125
  (
123
126
  Wallets.Wallet storage wallet,
124
127
  BitcoinTx.UTXO memory resolvedMainUtxo
125
- ) = resolveSweepingWallet(wallets, walletPubKeyHash, mainUtxo);
128
+ ) = resolveSweepingWallet(self, walletPubKeyHash, mainUtxo);
126
129
 
127
130
  // Process sweep transaction inputs and extract all information needed
128
131
  // to perform deposit bookkeeping.
@@ -208,17 +211,18 @@ library Sweep {
208
211
  /// - If the main UTXO of the sweeping wallet exists in the storage,
209
212
  /// the passed `mainUTXO` parameter must be equal to the stored one.
210
213
  function resolveSweepingWallet(
211
- Wallets.Data storage wallets,
214
+ BridgeState.Storage storage self,
212
215
  bytes20 walletPubKeyHash,
213
216
  BitcoinTx.UTXO calldata mainUtxo
214
217
  )
215
218
  internal
219
+ view
216
220
  returns (
217
221
  Wallets.Wallet storage wallet,
218
222
  BitcoinTx.UTXO memory resolvedMainUtxo
219
223
  )
220
224
  {
221
- wallet = wallets.registeredWallets[walletPubKeyHash];
225
+ wallet = self.registeredWallets[walletPubKeyHash];
222
226
 
223
227
  Wallets.WalletState walletState = wallet.state;
224
228
  require(