@keep-network/tbtc-v2 0.1.1-dev.94 → 0.1.1-dev.97

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 (72) hide show
  1. package/artifacts/Bank.json +3 -3
  2. package/artifacts/Bridge.json +43 -43
  3. package/artifacts/Deposit.json +9 -9
  4. package/artifacts/DepositSweep.json +7 -7
  5. package/artifacts/EcdsaDkgValidator.json +1 -1
  6. package/artifacts/EcdsaInactivity.json +1 -1
  7. package/artifacts/EcdsaSortitionPool.json +2 -2
  8. package/artifacts/Fraud.json +9 -9
  9. package/artifacts/KeepRegistry.json +1 -1
  10. package/artifacts/KeepStake.json +2 -2
  11. package/artifacts/KeepToken.json +2 -2
  12. package/artifacts/KeepTokenStaking.json +1 -1
  13. package/artifacts/MovingFunds.json +9 -9
  14. package/artifacts/NuCypherStakingEscrow.json +1 -1
  15. package/artifacts/NuCypherToken.json +2 -2
  16. package/artifacts/RandomBeaconStub.json +1 -1
  17. package/artifacts/Redemption.json +9 -9
  18. package/artifacts/ReimbursementPool.json +2 -2
  19. package/artifacts/Relay.json +9 -9
  20. package/artifacts/T.json +2 -2
  21. package/artifacts/TBTC.json +3 -3
  22. package/artifacts/TBTCToken.json +3 -3
  23. package/artifacts/TBTCVault.json +12 -12
  24. package/artifacts/TokenStaking.json +1 -1
  25. package/artifacts/TokenholderGovernor.json +9 -9
  26. package/artifacts/TokenholderTimelock.json +8 -8
  27. package/artifacts/VendingMachine.json +10 -10
  28. package/artifacts/VendingMachineKeep.json +1 -1
  29. package/artifacts/VendingMachineNuCypher.json +1 -1
  30. package/artifacts/WalletRegistry.json +5 -5
  31. package/artifacts/WalletRegistryGovernance.json +2 -2
  32. package/artifacts/Wallets.json +9 -9
  33. package/artifacts/solcInputs/{b1eed895af5ae97fee0102eb17dac6e6.json → 5e62cff1ead0900b07facca4b559e818.json} +6 -6
  34. package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
  35. package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
  36. package/build/contracts/bank/IReceiveBalanceApproval.sol/IReceiveBalanceApproval.dbg.json +1 -1
  37. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +1 -1
  38. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.json +2 -2
  39. package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
  40. package/build/contracts/bridge/Bridge.sol/Bridge.json +61 -61
  41. package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
  42. package/build/contracts/bridge/BridgeState.sol/BridgeState.json +2 -2
  43. package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +1 -1
  44. package/build/contracts/bridge/Deposit.sol/Deposit.json +2 -2
  45. package/build/contracts/bridge/DepositSweep.sol/DepositSweep.dbg.json +1 -1
  46. package/build/contracts/bridge/DepositSweep.sol/DepositSweep.json +2 -2
  47. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +1 -1
  48. package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +1 -1
  49. package/build/contracts/bridge/Fraud.sol/Fraud.json +2 -2
  50. package/build/contracts/bridge/Heartbeat.sol/Heartbeat.dbg.json +1 -1
  51. package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +1 -1
  52. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +1 -1
  53. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.json +2 -2
  54. package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +1 -1
  55. package/build/contracts/bridge/Redemption.sol/OutboundTx.json +2 -2
  56. package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +1 -1
  57. package/build/contracts/bridge/Redemption.sol/Redemption.json +2 -2
  58. package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
  59. package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +1 -1
  60. package/build/contracts/bridge/Wallets.sol/Wallets.json +2 -2
  61. package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
  62. package/build/contracts/vault/DonationVault.sol/DonationVault.dbg.json +1 -1
  63. package/build/contracts/vault/IVault.sol/IVault.dbg.json +1 -1
  64. package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
  65. package/contracts/bridge/Bridge.sol +2 -2
  66. package/contracts/bridge/DepositSweep.sol +3 -0
  67. package/contracts/bridge/Fraud.sol +7 -32
  68. package/contracts/bridge/MovingFunds.sol +41 -53
  69. package/contracts/bridge/Redemption.sol +60 -61
  70. package/contracts/bridge/Wallets.sol +309 -143
  71. package/export.json +32 -32
  72. package/package.json +2 -2
@@ -359,6 +359,8 @@ library MovingFunds {
359
359
  BitcoinTx.UTXO calldata mainUtxo,
360
360
  bytes20 walletPubKeyHash
361
361
  ) external {
362
+ // Wallet state is validated in `notifyWalletFundsMoved`.
363
+
362
364
  // The actual transaction proof is performed here. After that point, we
363
365
  // can assume the transaction happened on Bitcoin chain and has
364
366
  // a sufficient number of confirmations as determined by
@@ -368,13 +370,31 @@ library MovingFunds {
368
370
  movingFundsProof
369
371
  );
370
372
 
373
+ // Assert that main UTXO for passed wallet exists in storage.
374
+ bytes32 mainUtxoHash = self
375
+ .registeredWallets[walletPubKeyHash]
376
+ .mainUtxoHash;
377
+ require(mainUtxoHash != bytes32(0), "No main UTXO for given wallet");
378
+
379
+ // Assert that passed main UTXO parameter is the same as in storage and
380
+ // can be used for further processing.
381
+ require(
382
+ keccak256(
383
+ abi.encodePacked(
384
+ mainUtxo.txHash,
385
+ mainUtxo.txOutputIndex,
386
+ mainUtxo.txOutputValue
387
+ )
388
+ ) == mainUtxoHash,
389
+ "Invalid main UTXO data"
390
+ );
391
+
371
392
  // Process the moving funds transaction input. Specifically, check if
372
393
  // it refers to the expected wallet's main UTXO.
373
394
  OutboundTx.processWalletOutboundTxInput(
374
395
  self,
375
396
  movingFundsTx.inputVector,
376
- mainUtxo,
377
- walletPubKeyHash
397
+ mainUtxo
378
398
  );
379
399
 
380
400
  (
@@ -548,31 +568,19 @@ library MovingFunds {
548
568
  bytes20 walletPubKeyHash,
549
569
  uint32[] calldata walletMembersIDs
550
570
  ) external {
551
- Wallets.Wallet storage wallet = self.registeredWallets[
552
- walletPubKeyHash
553
- ];
571
+ // Wallet state is validated in `notifyWalletMovingFundsTimeout`.
554
572
 
555
- require(
556
- wallet.state == Wallets.WalletState.MovingFunds,
557
- "Wallet must be in MovingFunds state"
558
- );
573
+ uint32 movingFundsRequestedAt = self
574
+ .registeredWallets[walletPubKeyHash]
575
+ .movingFundsRequestedAt;
559
576
 
560
577
  require(
561
578
  /* solhint-disable-next-line not-rely-on-time */
562
- block.timestamp >
563
- wallet.movingFundsRequestedAt + self.movingFundsTimeout,
579
+ block.timestamp > movingFundsRequestedAt + self.movingFundsTimeout,
564
580
  "Moving funds has not timed out yet"
565
581
  );
566
582
 
567
- self.ecdsaWalletRegistry.seize(
568
- self.movingFundsTimeoutSlashingAmount,
569
- self.movingFundsTimeoutNotifierRewardMultiplier,
570
- msg.sender,
571
- wallet.ecdsaWalletID,
572
- walletMembersIDs
573
- );
574
-
575
- self.terminateWallet(walletPubKeyHash);
583
+ self.notifyWalletMovingFundsTimeout(walletPubKeyHash, walletMembersIDs);
576
584
 
577
585
  // slither-disable-next-line reentrancy-events
578
586
  emit MovingFundsTimedOut(walletPubKeyHash);
@@ -596,14 +604,7 @@ library MovingFunds {
596
604
  bytes20 walletPubKeyHash,
597
605
  BitcoinTx.UTXO calldata mainUtxo
598
606
  ) external {
599
- Wallets.Wallet storage wallet = self.registeredWallets[
600
- walletPubKeyHash
601
- ];
602
-
603
- require(
604
- wallet.state == Wallets.WalletState.MovingFunds,
605
- "Wallet must be in MovingFunds state"
606
- );
607
+ // Wallet state is validated in `notifyWalletMovingFundsBelowDust`.
607
608
 
608
609
  uint64 walletBtcBalance = self.getWalletBtcBalance(
609
610
  walletPubKeyHash,
@@ -615,7 +616,7 @@ library MovingFunds {
615
616
  "Wallet BTC balance must be below the moving funds dust threshold"
616
617
  );
617
618
 
618
- self.beginWalletClosing(walletPubKeyHash);
619
+ self.notifyWalletMovingFundsBelowDust(walletPubKeyHash);
619
620
 
620
621
  // slither-disable-next-line reentrancy-events
621
622
  emit MovingFundsBelowDustReported(walletPubKeyHash);
@@ -666,6 +667,9 @@ library MovingFunds {
666
667
  BitcoinTx.Proof calldata sweepProof,
667
668
  BitcoinTx.UTXO calldata mainUtxo
668
669
  ) external {
670
+ // Wallet state validation is performed in the
671
+ // `resolveMovedFundsSweepingWallet` function.
672
+
669
673
  // The actual transaction proof is performed here. After that point, we
670
674
  // can assume the transaction happened on Bitcoin chain and has
671
675
  // a sufficient number of confirmations as determined by
@@ -1024,6 +1028,8 @@ library MovingFunds {
1024
1028
  uint32 movingFundsTxOutputIndex,
1025
1029
  uint32[] calldata walletMembersIDs
1026
1030
  ) external {
1031
+ // Wallet state is validated in `notifyWalletMovedFundsSweepTimeout`.
1032
+
1027
1033
  MovedFundsSweepRequest storage sweepRequest = self
1028
1034
  .movedFundsSweepRequests[
1029
1035
  uint256(
@@ -1049,36 +1055,18 @@ library MovingFunds {
1049
1055
  );
1050
1056
 
1051
1057
  bytes20 walletPubKeyHash = sweepRequest.walletPubKeyHash;
1052
- Wallets.Wallet storage wallet = self.registeredWallets[
1053
- walletPubKeyHash
1054
- ];
1055
- Wallets.WalletState walletState = wallet.state;
1056
1058
 
1057
- require(
1058
- walletState == Wallets.WalletState.Live ||
1059
- walletState == Wallets.WalletState.MovingFunds ||
1060
- walletState == Wallets.WalletState.Terminated,
1061
- "Wallet must be in Live or MovingFunds or Terminated state"
1059
+ self.notifyWalletMovedFundsSweepTimeout(
1060
+ walletPubKeyHash,
1061
+ walletMembersIDs
1062
1062
  );
1063
1063
 
1064
+ Wallets.Wallet storage wallet = self.registeredWallets[
1065
+ walletPubKeyHash
1066
+ ];
1064
1067
  sweepRequest.state = MovedFundsSweepRequestState.TimedOut;
1065
1068
  wallet.pendingMovedFundsSweepRequestsCount--;
1066
1069
 
1067
- if (
1068
- walletState == Wallets.WalletState.Live ||
1069
- walletState == Wallets.WalletState.MovingFunds
1070
- ) {
1071
- self.ecdsaWalletRegistry.seize(
1072
- self.movedFundsSweepTimeoutSlashingAmount,
1073
- self.movedFundsSweepTimeoutNotifierRewardMultiplier,
1074
- msg.sender,
1075
- wallet.ecdsaWalletID,
1076
- walletMembersIDs
1077
- );
1078
-
1079
- self.terminateWallet(walletPubKeyHash);
1080
- }
1081
-
1082
1070
  // slither-disable-next-line reentrancy-events
1083
1071
  emit MovedFundsSweepTimedOut(
1084
1072
  walletPubKeyHash,
@@ -42,34 +42,11 @@ library OutboundTx {
42
42
  /// before it is passed here.
43
43
  /// @param mainUtxo Data of the wallet's main UTXO, as currently known on
44
44
  /// the Ethereum chain.
45
- /// @param walletPubKeyHash 20-byte public key hash (computed using Bitcoin
46
- // HASH160 over the compressed ECDSA public key) of the wallet which
47
- /// performed the outbound transaction.
48
45
  function processWalletOutboundTxInput(
49
46
  BridgeState.Storage storage self,
50
47
  bytes memory walletOutboundTxInputVector,
51
- BitcoinTx.UTXO calldata mainUtxo,
52
- bytes20 walletPubKeyHash
48
+ BitcoinTx.UTXO calldata mainUtxo
53
49
  ) internal {
54
- // Assert that main UTXO for passed wallet exists in storage.
55
- bytes32 mainUtxoHash = self
56
- .registeredWallets[walletPubKeyHash]
57
- .mainUtxoHash;
58
- require(mainUtxoHash != bytes32(0), "No main UTXO for given wallet");
59
-
60
- // Assert that passed main UTXO parameter is the same as in storage and
61
- // can be used for further processing.
62
- require(
63
- keccak256(
64
- abi.encodePacked(
65
- mainUtxo.txHash,
66
- mainUtxo.txOutputIndex,
67
- mainUtxo.txOutputValue
68
- )
69
- ) == mainUtxoHash,
70
- "Invalid main UTXO data"
71
- );
72
-
73
50
  // Assert that the single outbound transaction input actually
74
51
  // refers to the wallet's main UTXO.
75
52
  (
@@ -583,6 +560,9 @@ library Redemption {
583
560
  BitcoinTx.UTXO calldata mainUtxo,
584
561
  bytes20 walletPubKeyHash
585
562
  ) external {
563
+ // Wallet state validation is performed in the `resolveRedeemingWallet`
564
+ // function.
565
+
586
566
  // The actual transaction proof is performed here. After that point, we
587
567
  // can assume the transaction happened on Bitcoin chain and has
588
568
  // a sufficient number of confirmations as determined by
@@ -592,24 +572,18 @@ library Redemption {
592
572
  redemptionProof
593
573
  );
594
574
 
575
+ Wallets.Wallet storage wallet = resolveRedeemingWallet(
576
+ self,
577
+ walletPubKeyHash,
578
+ mainUtxo
579
+ );
580
+
595
581
  // Process the redemption transaction input. Specifically, check if it
596
582
  // refers to the expected wallet's main UTXO.
597
583
  OutboundTx.processWalletOutboundTxInput(
598
584
  self,
599
585
  redemptionTx.inputVector,
600
- mainUtxo,
601
- walletPubKeyHash
602
- );
603
-
604
- Wallets.Wallet storage wallet = self.registeredWallets[
605
- walletPubKeyHash
606
- ];
607
-
608
- Wallets.WalletState walletState = wallet.state;
609
- require(
610
- walletState == Wallets.WalletState.Live ||
611
- walletState == Wallets.WalletState.MovingFunds,
612
- "Wallet must be in Live or MovingFunds state"
586
+ mainUtxo
613
587
  );
614
588
 
615
589
  // Process redemption transaction outputs to extract some info required
@@ -645,6 +619,50 @@ library Redemption {
645
619
  self.bank.transferBalance(self.treasury, outputsInfo.totalTreasuryFee);
646
620
  }
647
621
 
622
+ /// @notice Resolves redeeming wallet based on the provided wallet public
623
+ /// key hash. Validates the wallet state and current main UTXO, as
624
+ /// currently known on the Ethereum chain.
625
+ /// @param walletPubKeyHash public key hash of the wallet proving the sweep
626
+ /// Bitcoin transaction.
627
+ /// @param mainUtxo Data of the wallet's main UTXO, as currently known on
628
+ /// the Ethereum chain.
629
+ /// @return wallet Data of the sweeping wallet.
630
+ /// @dev Requirements:
631
+ /// - Sweeping wallet must be either in Live or MovingFunds state,
632
+ /// - Main UTXO of the redeeming wallet must exists in the storage,
633
+ /// - The passed `mainUTXO` parameter must be equal to the stored one.
634
+ function resolveRedeemingWallet(
635
+ BridgeState.Storage storage self,
636
+ bytes20 walletPubKeyHash,
637
+ BitcoinTx.UTXO calldata mainUtxo
638
+ ) internal view returns (Wallets.Wallet storage wallet) {
639
+ wallet = self.registeredWallets[walletPubKeyHash];
640
+
641
+ // Assert that main UTXO for passed wallet exists in storage.
642
+ bytes32 mainUtxoHash = wallet.mainUtxoHash;
643
+ require(mainUtxoHash != bytes32(0), "No main UTXO for given wallet");
644
+
645
+ // Assert that passed main UTXO parameter is the same as in storage and
646
+ // can be used for further processing.
647
+ require(
648
+ keccak256(
649
+ abi.encodePacked(
650
+ mainUtxo.txHash,
651
+ mainUtxo.txOutputIndex,
652
+ mainUtxo.txOutputValue
653
+ )
654
+ ) == mainUtxoHash,
655
+ "Invalid main UTXO data"
656
+ );
657
+
658
+ Wallets.WalletState walletState = wallet.state;
659
+ require(
660
+ walletState == Wallets.WalletState.Live ||
661
+ walletState == Wallets.WalletState.MovingFunds,
662
+ "Wallet must be in Live or MovingFunds state"
663
+ );
664
+ }
665
+
648
666
  /// @notice Processes the Bitcoin redemption transaction output vector.
649
667
  /// It extracts each output and tries to identify it as a pending
650
668
  /// redemption request, reported timed out request, or change.
@@ -956,6 +974,8 @@ library Redemption {
956
974
  uint32[] calldata walletMembersIDs,
957
975
  bytes calldata redeemerOutputScript
958
976
  ) external {
977
+ // Wallet state is validated in `notifyWalletRedemptionTimeout`.
978
+
959
979
  uint256 redemptionKey = uint256(
960
980
  keccak256(abi.encodePacked(walletPubKeyHash, redeemerOutputScript))
961
981
  );
@@ -978,40 +998,19 @@ library Redemption {
978
998
  request.requestedAmount -
979
999
  request.treasuryFee;
980
1000
 
981
- require(
982
- wallet.state == Wallets.WalletState.Live ||
983
- wallet.state == Wallets.WalletState.MovingFunds ||
984
- wallet.state == Wallets.WalletState.Terminated,
985
- "Wallet must be in Live, MovingFunds or Terminated state"
986
- );
987
-
988
1001
  // It is worth noting that there is no need to check if
989
1002
  // `timedOutRedemption` mapping already contains the given redemption
990
1003
  // key. There is no possibility to re-use a key of a reported timed-out
991
1004
  // redemption because the wallet responsible for causing the timeout is
992
1005
  // moved to a state that prevents it to receive new redemption requests.
993
1006
 
1007
+ // Propagate timeout consequences to the wallet
1008
+ self.notifyWalletRedemptionTimeout(walletPubKeyHash, walletMembersIDs);
1009
+
994
1010
  // Move the redemption from pending redemptions to timed-out redemptions
995
1011
  self.timedOutRedemptions[redemptionKey] = request;
996
1012
  delete self.pendingRedemptions[redemptionKey];
997
1013
 
998
- if (
999
- wallet.state == Wallets.WalletState.Live ||
1000
- wallet.state == Wallets.WalletState.MovingFunds
1001
- ) {
1002
- // Slash the wallet operators and reward the notifier
1003
- self.ecdsaWalletRegistry.seize(
1004
- self.redemptionTimeoutSlashingAmount,
1005
- self.redemptionTimeoutNotifierRewardMultiplier,
1006
- msg.sender,
1007
- wallet.ecdsaWalletID,
1008
- walletMembersIDs
1009
- );
1010
-
1011
- // Propagate timeout consequences to the wallet
1012
- self.notifyWalletTimedOutRedemption(walletPubKeyHash);
1013
- }
1014
-
1015
1014
  // slither-disable-next-line reentrancy-events
1016
1015
  emit RedemptionTimedOut(walletPubKeyHash, redeemerOutputScript);
1017
1016