@keep-network/tbtc-v2 0.1.1-dev.51 → 0.1.1-dev.54

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 (68) hide show
  1. package/artifacts/Bank.json +6 -6
  2. package/artifacts/Bridge.json +282 -156
  3. package/artifacts/Deposit.json +7 -7
  4. package/artifacts/EcdsaDkgValidator.json +1 -1
  5. package/artifacts/EcdsaInactivity.json +1 -1
  6. package/artifacts/Fraud.json +10 -10
  7. package/artifacts/KeepRegistry.json +1 -1
  8. package/artifacts/KeepStake.json +2 -2
  9. package/artifacts/KeepToken.json +2 -2
  10. package/artifacts/KeepTokenStaking.json +1 -1
  11. package/artifacts/MovingFunds.json +13 -12
  12. package/artifacts/NuCypherStakingEscrow.json +1 -1
  13. package/artifacts/NuCypherToken.json +2 -2
  14. package/artifacts/RandomBeaconStub.json +1 -1
  15. package/artifacts/Redemption.json +14 -13
  16. package/artifacts/ReimbursementPool.json +2 -2
  17. package/artifacts/Relay.json +11 -11
  18. package/artifacts/SortitionPool.json +2 -2
  19. package/artifacts/Sweep.json +9 -9
  20. package/artifacts/T.json +2 -2
  21. package/artifacts/TBTC.json +6 -6
  22. package/artifacts/TBTCToken.json +6 -6
  23. package/artifacts/TokenStaking.json +1 -1
  24. package/artifacts/TokenholderGovernor.json +9 -9
  25. package/artifacts/TokenholderTimelock.json +8 -8
  26. package/artifacts/VendingMachine.json +13 -13
  27. package/artifacts/VendingMachineKeep.json +1 -1
  28. package/artifacts/VendingMachineNuCypher.json +1 -1
  29. package/artifacts/WalletRegistry.json +2 -2
  30. package/artifacts/WalletRegistryGovernance.json +2 -2
  31. package/artifacts/Wallets.json +9 -9
  32. package/artifacts/solcInputs/{c0a2aa3c07bd118332a0dc765c7f6da0.json → 799c7b289d9b6d9cfc600d2fc23c7b64.json} +7 -7
  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 +130 -40
  39. package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
  40. package/build/contracts/bridge/BridgeState.sol/BridgeState.json +34 -4
  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/Fraud.sol/Fraud.dbg.json +1 -1
  45. package/build/contracts/bridge/Fraud.sol/Fraud.json +2 -2
  46. package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +1 -1
  47. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +1 -1
  48. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.json +2 -2
  49. package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +1 -1
  50. package/build/contracts/bridge/Redemption.sol/OutboundTx.json +2 -2
  51. package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +1 -1
  52. package/build/contracts/bridge/Redemption.sol/Redemption.json +2 -2
  53. package/build/contracts/bridge/Sweep.sol/Sweep.dbg.json +1 -1
  54. package/build/contracts/bridge/Sweep.sol/Sweep.json +2 -2
  55. package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
  56. package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +1 -1
  57. package/build/contracts/bridge/Wallets.sol/Wallets.json +2 -2
  58. package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
  59. package/build/contracts/vault/IVault.sol/IVault.dbg.json +1 -1
  60. package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
  61. package/contracts/bridge/Bridge.sol +133 -40
  62. package/contracts/bridge/BridgeState.sol +101 -23
  63. package/contracts/bridge/Fraud.sol +1 -1
  64. package/contracts/bridge/MovingFunds.sol +16 -3
  65. package/contracts/bridge/Redemption.sol +34 -12
  66. package/contracts/bridge/Wallets.sol +9 -12
  67. package/export.json +96 -19
  68. package/package.json +1 -1
@@ -170,19 +170,24 @@ contract Bridge is Governable, EcdsaWalletOwner {
170
170
  uint64 redemptionDustThreshold,
171
171
  uint64 redemptionTreasuryFeeDivisor,
172
172
  uint64 redemptionTxMaxFee,
173
- uint256 redemptionTimeout
173
+ uint256 redemptionTimeout,
174
+ uint96 redemptionTimeoutSlashingAmount,
175
+ uint256 redemptionTimeoutNotifierRewardMultiplier
174
176
  );
175
177
 
176
178
  event MovingFundsParametersUpdated(
177
179
  uint64 movingFundsTxMaxTotalFee,
178
180
  uint32 movingFundsTimeout,
181
+ uint96 movingFundsTimeoutSlashingAmount,
182
+ uint256 movingFundsTimeoutNotifierRewardMultiplier,
179
183
  uint64 movingFundsDustThreshold
180
184
  );
181
185
 
182
186
  event WalletParametersUpdated(
183
187
  uint32 walletCreationPeriod,
184
- uint64 walletMinBtcBalance,
185
- uint64 walletMaxBtcBalance,
188
+ uint64 walletCreationMinBtcBalance,
189
+ uint64 walletCreationMaxBtcBalance,
190
+ uint64 walletClosureMinBtcBalance,
186
191
  uint32 walletMaxAge,
187
192
  uint64 walletMaxBtcTransfer,
188
193
  uint32 walletClosingPeriod
@@ -227,16 +232,21 @@ contract Bridge is Governable, EcdsaWalletOwner {
227
232
  self.redemptionTreasuryFeeDivisor = 2000; // 1/2000 == 5bps == 0.05% == 0.0005
228
233
  self.redemptionTxMaxFee = 10000; // 10000 satoshi
229
234
  self.redemptionTimeout = 172800; // 48 hours
235
+ self.redemptionTimeoutSlashingAmount = 10000 * 1e18; // 10000 T
236
+ self.redemptionTimeoutNotifierRewardMultiplier = 100; // 100%
230
237
  self.movingFundsTxMaxTotalFee = 10000; // 10000 satoshi
231
238
  self.movingFundsTimeout = 7 days;
239
+ self.movingFundsTimeoutSlashingAmount = 10000 * 1e18; // 10000 T
240
+ self.movingFundsTimeoutNotifierRewardMultiplier = 100; //100%
232
241
  self.movingFundsDustThreshold = 20000; // 20000 satoshi
233
242
  self.fraudSlashingAmount = 10000 * 1e18; // 10000 T
234
243
  self.fraudNotifierRewardMultiplier = 100; // 100%
235
244
  self.fraudChallengeDefeatTimeout = 7 days;
236
245
  self.fraudChallengeDepositAmount = 2 ether;
237
246
  self.walletCreationPeriod = 1 weeks;
238
- self.walletMinBtcBalance = 1e8; // 1 BTC
239
- self.walletMaxBtcBalance = 10e8; // 10 BTC
247
+ self.walletCreationMinBtcBalance = 1e8; // 1 BTC
248
+ self.walletCreationMaxBtcBalance = 100e8; // 100 BTC
249
+ self.walletClosureMinBtcBalance = 5 * 1e7; // 0.5 BTC
240
250
  self.walletMaxAge = 26 weeks; // ~6 months
241
251
  self.walletMaxBtcTransfer = 10e8; // 10 BTC
242
252
  self.walletClosingPeriod = 40 days;
@@ -434,31 +444,47 @@ contract Bridge is Governable, EcdsaWalletOwner {
434
444
  /// with the given wallet, that has timed out. The redemption
435
445
  /// request is identified by the key built as
436
446
  /// `keccak256(walletPubKeyHash | redeemerOutputScript)`.
437
- /// The results of calling this function: the pending redemptions
438
- /// value for the wallet will be decreased by the requested amount
439
- /// (minus treasury fee), the tokens taken from the redeemer on
440
- /// redemption request will be returned to the redeemer, the request
441
- /// will be moved from pending redemptions to timed-out redemptions.
442
- /// If the state of the wallet is `Live` or `MovingFunds`, the
443
- /// wallet operators will be slashed.
444
- /// Additionally, if the state of wallet is `Live`, the wallet will
445
- /// be closed or marked as `MovingFunds` (depending on the presence
446
- /// or absence of the wallet's main UTXO) and the wallet will no
447
- /// longer be marked as the active wallet (if it was marked as such).
447
+ /// The results of calling this function:
448
+ /// - the pending redemptions value for the wallet will be decreased
449
+ /// by the requested amount (minus treasury fee),
450
+ /// - the tokens taken from the redeemer on redemption request will
451
+ /// be returned to the redeemer,
452
+ /// - the request will be moved from pending redemptions to
453
+ /// timed-out redemptions,
454
+ /// - if the state of the wallet is `Live` or `MovingFunds`, the
455
+ /// wallet operators will be slashed and the notifier will be
456
+ /// rewarded,
457
+ /// - if the state of wallet is `Live`, the wallet will be closed or
458
+ /// marked as `MovingFunds` (depending on the presence or absence
459
+ /// of the wallet's main UTXO) and the wallet will no longer be
460
+ /// marked as the active wallet (if it was marked as such).
448
461
  /// @param walletPubKeyHash 20-byte public key hash of the wallet
462
+ /// @param walletMembersIDs Identifiers of the wallet signing group members
449
463
  /// @param redeemerOutputScript The redeemer's length-prefixed output
450
464
  /// script (P2PKH, P2WPKH, P2SH or P2WSH)
451
465
  /// @dev Requirements:
466
+ /// - The wallet must be in the Live or MovingFunds or Terminated state
452
467
  /// - The redemption request identified by `walletPubKeyHash` and
453
468
  /// `redeemerOutputScript` must exist
469
+ /// - The expression `keccak256(abi.encode(walletMembersIDs))` must
470
+ /// be exactly the same as the hash stored under `membersIdsHash`
471
+ /// for the given `walletID`. Those IDs are not directly stored
472
+ /// in the contract for gas efficiency purposes but they can be
473
+ /// read from appropriate `DkgResultSubmitted` and `DkgResultApproved`
474
+ /// events of the `WalletRegistry` contract
454
475
  /// - The amount of time defined by `redemptionTimeout` must have
455
476
  /// passed since the redemption was requested (the request must be
456
- /// timed-out).
477
+ /// timed-out)
457
478
  function notifyRedemptionTimeout(
458
479
  bytes20 walletPubKeyHash,
480
+ uint32[] calldata walletMembersIDs,
459
481
  bytes calldata redeemerOutputScript
460
482
  ) external {
461
- self.notifyRedemptionTimeout(walletPubKeyHash, redeemerOutputScript);
483
+ self.notifyRedemptionTimeout(
484
+ walletPubKeyHash,
485
+ walletMembersIDs,
486
+ redeemerOutputScript
487
+ );
462
488
  }
463
489
 
464
490
  /// @notice Submits the moving funds target wallets commitment.
@@ -578,11 +604,21 @@ contract Bridge is Governable, EcdsaWalletOwner {
578
604
  /// @notice Notifies about a timed out moving funds process. Terminates
579
605
  /// the wallet and slashes signing group members as a result.
580
606
  /// @param walletPubKeyHash 20-byte public key hash of the wallet
607
+ /// @param walletMembersIDs Identifiers of the wallet signing group members
581
608
  /// @dev Requirements:
582
609
  /// - The wallet must be in the MovingFunds state
583
610
  /// - The moving funds timeout must be actually exceeded
584
- function notifyMovingFundsTimeout(bytes20 walletPubKeyHash) external {
585
- self.notifyMovingFundsTimeout(walletPubKeyHash);
611
+ /// - The expression `keccak256(abi.encode(walletMembersIDs))` must
612
+ /// be exactly the same as the hash stored under `membersIdsHash`
613
+ /// for the given `walletID`. Those IDs are not directly stored
614
+ /// in the contract for gas efficiency purposes but they can be
615
+ /// read from appropriate `DkgResultSubmitted` and `DkgResultApproved`
616
+ /// events of the `WalletRegistry` contract
617
+ function notifyMovingFundsTimeout(
618
+ bytes20 walletPubKeyHash,
619
+ uint32[] calldata walletMembersIDs
620
+ ) external {
621
+ self.notifyMovingFundsTimeout(walletPubKeyHash, walletMembersIDs);
586
622
  }
587
623
 
588
624
  /// @notice Notifies about a moving funds wallet whose BTC balance is
@@ -802,7 +838,7 @@ contract Bridge is Governable, EcdsaWalletOwner {
802
838
  /// for the given `walletID`. Those IDs are not directly stored
803
839
  /// in the contract for gas efficiency purposes but they can be
804
840
  /// read from appropriate `DkgResultSubmitted` and `DkgResultApproved`
805
- /// events.
841
+ /// events of the `WalletRegistry` contract
806
842
  /// - The amount of time indicated by `challengeDefeatTimeout` must pass
807
843
  /// after the challenge was reported
808
844
  function notifyFraudChallengeDefeatTimeout(
@@ -904,22 +940,36 @@ contract Bridge is Governable, EcdsaWalletOwner {
904
940
  /// request was created via `requestRedemption` call. Reported timed
905
941
  /// out requests are cancelled and locked TBTC is returned to the
906
942
  /// redeemer in full amount.
943
+ /// @param redemptionTimeoutSlashingAmount New value of the redemption
944
+ /// timeout slashing amount in T, it is the amount slashed from each
945
+ /// wallet member for redemption timeout
946
+ /// @param redemptionTimeoutNotifierRewardMultiplier New value of the
947
+ /// redemption timeout notifier reward multiplier as percentage,
948
+ /// it determines the percentage of the notifier reward from the
949
+ /// staking contact the notifier of a redemption timeout receives.
950
+ /// The value must be in the range [0, 100]
907
951
  /// @dev Requirements:
908
952
  /// - Redemption dust threshold must be greater than zero
909
953
  /// - Redemption treasury fee divisor must be greater than zero
910
954
  /// - Redemption transaction max fee must be greater than zero
911
955
  /// - Redemption timeout must be greater than zero
956
+ /// - Redemption timeout notifier reward multiplier must be in the
957
+ /// range [0, 100]
912
958
  function updateRedemptionParameters(
913
959
  uint64 redemptionDustThreshold,
914
960
  uint64 redemptionTreasuryFeeDivisor,
915
961
  uint64 redemptionTxMaxFee,
916
- uint256 redemptionTimeout
962
+ uint256 redemptionTimeout,
963
+ uint96 redemptionTimeoutSlashingAmount,
964
+ uint256 redemptionTimeoutNotifierRewardMultiplier
917
965
  ) external onlyGovernance {
918
966
  self.updateRedemptionParameters(
919
967
  redemptionDustThreshold,
920
968
  redemptionTreasuryFeeDivisor,
921
969
  redemptionTxMaxFee,
922
- redemptionTimeout
970
+ redemptionTimeout,
971
+ redemptionTimeoutSlashingAmount,
972
+ redemptionTimeoutNotifierRewardMultiplier
923
973
  );
924
974
  }
925
975
 
@@ -934,6 +984,14 @@ contract Bridge is Governable, EcdsaWalletOwner {
934
984
  /// be reported as timed out. It is counted from the moment when the
935
985
  /// wallet was requested to move their funds and switched to the
936
986
  /// MovingFunds state.
987
+ /// @param movingFundsTimeoutSlashingAmount New value of the moving funds
988
+ /// timeout slashing amount in T, it is the amount slashed from each
989
+ /// wallet member for moving funds timeout
990
+ /// @param movingFundsTimeoutNotifierRewardMultiplier New value of the
991
+ /// moving funds timeout notifier reward multiplier as percentage,
992
+ /// it determines the percentage of the notifier reward from the
993
+ /// staking contact the notifier of a moving funds timeout receives.
994
+ /// The value must be in the range [0, 100]
937
995
  /// @param movingFundsDustThreshold New value of the moving funds dust
938
996
  /// threshold. It is the minimal satoshi amount that makes sense to
939
997
  // be transferred during the moving funds process. Moving funds
@@ -943,15 +1001,21 @@ contract Bridge is Governable, EcdsaWalletOwner {
943
1001
  /// @dev Requirements:
944
1002
  /// - Moving funds transaction max total fee must be greater than zero
945
1003
  /// - Moving funds timeout must be greater than zero
1004
+ /// - Moving funds timeout notifier reward multiplier must be in the
1005
+ /// range [0, 100]
946
1006
  /// - Moving funds dust threshold must be greater than zero
947
1007
  function updateMovingFundsParameters(
948
1008
  uint64 movingFundsTxMaxTotalFee,
949
1009
  uint32 movingFundsTimeout,
1010
+ uint96 movingFundsTimeoutSlashingAmount,
1011
+ uint256 movingFundsTimeoutNotifierRewardMultiplier,
950
1012
  uint64 movingFundsDustThreshold
951
1013
  ) external onlyGovernance {
952
1014
  self.updateMovingFundsParameters(
953
1015
  movingFundsTxMaxTotalFee,
954
1016
  movingFundsTimeout,
1017
+ movingFundsTimeoutSlashingAmount,
1018
+ movingFundsTimeoutNotifierRewardMultiplier,
955
1019
  movingFundsDustThreshold
956
1020
  );
957
1021
  }
@@ -960,10 +1024,12 @@ contract Bridge is Governable, EcdsaWalletOwner {
960
1024
  /// @param walletCreationPeriod New value of the wallet creation period in
961
1025
  /// seconds, determines how frequently a new wallet creation can be
962
1026
  /// requested
963
- /// @param walletMinBtcBalance New value of the wallet minimum BTC balance
964
- /// in satoshi, used to decide about wallet creation or closing
965
- /// @param walletMaxBtcBalance New value of the wallet maximum BTC balance
966
- /// in satoshi, used to decide about wallet creation
1027
+ /// @param walletCreationMinBtcBalance New value of the wallet minimum BTC
1028
+ /// balance in satoshi, used to decide about wallet creation
1029
+ /// @param walletCreationMaxBtcBalance New value of the wallet maximum BTC
1030
+ /// balance in satoshi, used to decide about wallet creation
1031
+ /// @param walletClosureMinBtcBalance New value of the wallet minimum BTC
1032
+ /// balance in satoshi, used to decide about wallet closure
967
1033
  /// @param walletMaxAge New value of the wallet maximum age in seconds,
968
1034
  /// indicates the maximum age of a wallet in seconds, after which
969
1035
  /// the wallet moving funds process can be requested
@@ -982,16 +1048,18 @@ contract Bridge is Governable, EcdsaWalletOwner {
982
1048
  /// - Wallet closing period must be greater than zero
983
1049
  function updateWalletParameters(
984
1050
  uint32 walletCreationPeriod,
985
- uint64 walletMinBtcBalance,
986
- uint64 walletMaxBtcBalance,
1051
+ uint64 walletCreationMinBtcBalance,
1052
+ uint64 walletCreationMaxBtcBalance,
1053
+ uint64 walletClosureMinBtcBalance,
987
1054
  uint32 walletMaxAge,
988
1055
  uint64 walletMaxBtcTransfer,
989
1056
  uint32 walletClosingPeriod
990
1057
  ) external onlyGovernance {
991
1058
  self.updateWalletParameters(
992
1059
  walletCreationPeriod,
993
- walletMinBtcBalance,
994
- walletMaxBtcBalance,
1060
+ walletCreationMinBtcBalance,
1061
+ walletCreationMaxBtcBalance,
1062
+ walletClosureMinBtcBalance,
995
1063
  walletMaxAge,
996
1064
  walletMaxBtcTransfer,
997
1065
  walletClosingPeriod
@@ -1199,6 +1267,11 @@ contract Bridge is Governable, EcdsaWalletOwner {
1199
1267
  /// redemption request was created via `requestRedemption` call.
1200
1268
  /// Reported timed out requests are cancelled and locked TBTC is
1201
1269
  /// returned to the redeemer in full amount.
1270
+ /// @return redemptionTimeoutSlashingAmount The amount of stake slashed
1271
+ /// from each member of a wallet for a redemption timeout.
1272
+ /// @return redemptionTimeoutNotifierRewardMultiplier The percentage of the
1273
+ /// notifier reward from the staking contract the notifier of a
1274
+ /// redemption timeout receives. The value is in the range [0, 100].
1202
1275
  function redemptionParameters()
1203
1276
  external
1204
1277
  view
@@ -1206,13 +1279,18 @@ contract Bridge is Governable, EcdsaWalletOwner {
1206
1279
  uint64 redemptionDustThreshold,
1207
1280
  uint64 redemptionTreasuryFeeDivisor,
1208
1281
  uint64 redemptionTxMaxFee,
1209
- uint256 redemptionTimeout
1282
+ uint256 redemptionTimeout,
1283
+ uint96 redemptionTimeoutSlashingAmount,
1284
+ uint256 redemptionTimeoutNotifierRewardMultiplier
1210
1285
  )
1211
1286
  {
1212
1287
  redemptionDustThreshold = self.redemptionDustThreshold;
1213
1288
  redemptionTreasuryFeeDivisor = self.redemptionTreasuryFeeDivisor;
1214
1289
  redemptionTxMaxFee = self.redemptionTxMaxFee;
1215
1290
  redemptionTimeout = self.redemptionTimeout;
1291
+ redemptionTimeoutSlashingAmount = self.redemptionTimeoutSlashingAmount;
1292
+ redemptionTimeoutNotifierRewardMultiplier = self
1293
+ .redemptionTimeoutNotifierRewardMultiplier;
1216
1294
  }
1217
1295
 
1218
1296
  /// @notice Returns the current values of Bridge moving funds between
@@ -1225,6 +1303,11 @@ contract Bridge is Governable, EcdsaWalletOwner {
1225
1303
  /// can be reported as timed out. It is counted from the moment
1226
1304
  /// when the wallet was requested to move their funds and switched
1227
1305
  /// to the MovingFunds state. Value in seconds.
1306
+ /// @return movingFundsTimeoutSlashingAmount The amount of stake slashed
1307
+ /// from each member of a wallet for a moving funds timeout.
1308
+ /// @return movingFundsTimeoutNotifierRewardMultiplier The percentage of the
1309
+ /// notifier reward from the staking contract the notifier of a
1310
+ /// moving funds timeout receives. The value is in the range [0, 100].
1228
1311
  /// @return movingFundsDustThreshold The minimal satoshi amount that makes
1229
1312
  // sense to be transferred during the moving funds process. Moving
1230
1313
  // funds wallets having their BTC balance below that value can
@@ -1236,20 +1319,28 @@ contract Bridge is Governable, EcdsaWalletOwner {
1236
1319
  returns (
1237
1320
  uint64 movingFundsTxMaxTotalFee,
1238
1321
  uint32 movingFundsTimeout,
1322
+ uint96 movingFundsTimeoutSlashingAmount,
1323
+ uint256 movingFundsTimeoutNotifierRewardMultiplier,
1239
1324
  uint64 movingFundsDustThreshold
1240
1325
  )
1241
1326
  {
1242
1327
  movingFundsTxMaxTotalFee = self.movingFundsTxMaxTotalFee;
1243
1328
  movingFundsTimeout = self.movingFundsTimeout;
1329
+ movingFundsTimeoutSlashingAmount = self
1330
+ .movingFundsTimeoutSlashingAmount;
1331
+ movingFundsTimeoutNotifierRewardMultiplier = self
1332
+ .movingFundsTimeoutNotifierRewardMultiplier;
1244
1333
  movingFundsDustThreshold = self.movingFundsDustThreshold;
1245
1334
  }
1246
1335
 
1247
1336
  /// @return walletCreationPeriod Determines how frequently a new wallet
1248
1337
  /// creation can be requested. Value in seconds.
1249
- /// @return walletMinBtcBalance The minimum BTC threshold in satoshi that is
1250
- /// used to decide about wallet creation or closing.
1251
- /// @return walletMaxBtcBalance The maximum BTC threshold in satoshi that is
1252
- /// used to decide about wallet creation.
1338
+ /// @return walletCreationMinBtcBalance The minimum BTC threshold in satoshi
1339
+ /// that is used to decide about wallet creation.
1340
+ /// @return walletCreationMaxBtcBalance The maximum BTC threshold in satoshi
1341
+ /// that is used to decide about wallet creation.
1342
+ /// @return walletClosureMinBtcBalance The minimum BTC threshold in satoshi
1343
+ /// that is used to decide about wallet closure.
1253
1344
  /// @return walletMaxAge The maximum age of a wallet in seconds, after which
1254
1345
  /// the wallet moving funds process can be requested.
1255
1346
  /// @return walletMaxBtcTransfer The maximum BTC amount in satoshi than
@@ -1264,16 +1355,18 @@ contract Bridge is Governable, EcdsaWalletOwner {
1264
1355
  view
1265
1356
  returns (
1266
1357
  uint32 walletCreationPeriod,
1267
- uint64 walletMinBtcBalance,
1268
- uint64 walletMaxBtcBalance,
1358
+ uint64 walletCreationMinBtcBalance,
1359
+ uint64 walletCreationMaxBtcBalance,
1360
+ uint64 walletClosureMinBtcBalance,
1269
1361
  uint32 walletMaxAge,
1270
1362
  uint64 walletMaxBtcTransfer,
1271
1363
  uint32 walletClosingPeriod
1272
1364
  )
1273
1365
  {
1274
1366
  walletCreationPeriod = self.walletCreationPeriod;
1275
- walletMinBtcBalance = self.walletMinBtcBalance;
1276
- walletMaxBtcBalance = self.walletMaxBtcBalance;
1367
+ walletCreationMinBtcBalance = self.walletCreationMinBtcBalance;
1368
+ walletCreationMaxBtcBalance = self.walletCreationMaxBtcBalance;
1369
+ walletClosureMinBtcBalance = self.walletClosureMinBtcBalance;
1277
1370
  walletMaxAge = self.walletMaxAge;
1278
1371
  walletMaxBtcTransfer = self.walletMaxBtcTransfer;
1279
1372
  walletClosingPeriod = self.walletClosingPeriod;
@@ -88,6 +88,13 @@ library BridgeState {
88
88
  // was requested to move their funds and switched to the MovingFunds
89
89
  // state. Value in seconds.
90
90
  uint32 movingFundsTimeout;
91
+ // The amount of stake slashed from each member of a wallet for a moving
92
+ // funds timeout.
93
+ uint96 movingFundsTimeoutSlashingAmount;
94
+ // The percentage of the notifier reward from the staking contract
95
+ // the notifier of a moving funds timeout receives. The value is in the
96
+ // range [0, 100].
97
+ uint256 movingFundsTimeoutNotifierRewardMultiplier;
91
98
  // The minimal satoshi amount that makes sense to be transferred during
92
99
  // the moving funds process. Moving funds wallets having their BTC
93
100
  // balance below that value can begin closing immediately as
@@ -122,6 +129,13 @@ library BridgeState {
122
129
  // timed out requests are cancelled and locked TBTC is returned
123
130
  // to the redeemer in full amount.
124
131
  uint256 redemptionTimeout;
132
+ // The amount of stake slashed from each member of a wallet for a
133
+ // redemption timeout.
134
+ uint96 redemptionTimeoutSlashingAmount;
135
+ // The percentage of the notifier reward from the staking contract
136
+ // the notifier of a redemption timeout receives. The value is in the
137
+ // range [0, 100].
138
+ uint256 redemptionTimeoutNotifierRewardMultiplier;
125
139
  // Collection of all pending redemption requests indexed by
126
140
  // redemption key built as
127
141
  // `keccak256(walletPubKeyHash | redeemerOutputScript)`.
@@ -175,11 +189,20 @@ library BridgeState {
175
189
  // Value in seconds.
176
190
  uint32 walletCreationPeriod;
177
191
  // The minimum BTC threshold in satoshi that is used to decide about
178
- // wallet creation or closing.
179
- uint64 walletMinBtcBalance;
192
+ // wallet creation. Specifically, we allow for the creation of a new
193
+ // wallet if the active wallet is old enough and their amount of BTC
194
+ // is greater than or equal this threshold.
195
+ uint64 walletCreationMinBtcBalance;
180
196
  // The maximum BTC threshold in satoshi that is used to decide about
181
- // wallet creation.
182
- uint64 walletMaxBtcBalance;
197
+ // wallet creation. Specifically, we allow for the creation of a new
198
+ // wallet if the active wallet's amount of BTC is greater than or equal
199
+ // this threshold, regardless of the active wallet's age.
200
+ uint64 walletCreationMaxBtcBalance;
201
+ // The minimum BTC threshold in satoshi that is used to decide about
202
+ // wallet closing. Specifically, we allow for the closure of the given
203
+ // wallet if their amount of BTC is lesser than this threshold,
204
+ // regardless of the wallet's age.
205
+ uint64 walletClosureMinBtcBalance;
183
206
  // The maximum age of a wallet in seconds, after which the wallet
184
207
  // moving funds process can be requested.
185
208
  uint32 walletMaxAge;
@@ -213,19 +236,24 @@ library BridgeState {
213
236
  uint64 redemptionDustThreshold,
214
237
  uint64 redemptionTreasuryFeeDivisor,
215
238
  uint64 redemptionTxMaxFee,
216
- uint256 redemptionTimeout
239
+ uint256 redemptionTimeout,
240
+ uint96 redemptionTimeoutSlashingAmount,
241
+ uint256 redemptionTimeoutNotifierRewardMultiplier
217
242
  );
218
243
 
219
244
  event MovingFundsParametersUpdated(
220
245
  uint64 movingFundsTxMaxTotalFee,
221
246
  uint32 movingFundsTimeout,
247
+ uint96 movingFundsTimeoutSlashingAmount,
248
+ uint256 movingFundsTimeoutNotifierRewardMultiplier,
222
249
  uint64 movingFundsDustThreshold
223
250
  );
224
251
 
225
252
  event WalletParametersUpdated(
226
253
  uint32 walletCreationPeriod,
227
- uint64 walletMinBtcBalance,
228
- uint64 walletMaxBtcBalance,
254
+ uint64 walletCreationMinBtcBalance,
255
+ uint64 walletCreationMaxBtcBalance,
256
+ uint64 walletClosureMinBtcBalance,
229
257
  uint32 walletMaxAge,
230
258
  uint64 walletMaxBtcTransfer,
231
259
  uint32 walletClosingPeriod
@@ -324,17 +352,29 @@ library BridgeState {
324
352
  /// request was created via `requestRedemption` call. Reported timed
325
353
  /// out requests are cancelled and locked TBTC is returned to the
326
354
  /// redeemer in full amount.
355
+ /// @param _redemptionTimeoutSlashingAmount New value of the redemption
356
+ /// timeout slashing amount in T, it is the amount slashed from each
357
+ /// wallet member for redemption timeout
358
+ /// @param _redemptionTimeoutNotifierRewardMultiplier New value of the
359
+ /// redemption timeout notifier reward multiplier as percentage,
360
+ /// it determines the percentage of the notifier reward from the
361
+ /// staking contact the notifier of a redemption timeout receives.
362
+ /// The value must be in the range [0, 100]
327
363
  /// @dev Requirements:
328
364
  /// - Redemption dust threshold must be greater than zero
329
365
  /// - Redemption treasury fee divisor must be greater than zero
330
366
  /// - Redemption transaction max fee must be greater than zero
331
367
  /// - Redemption timeout must be greater than zero
368
+ /// - Redemption timeout notifier reward multiplier must be in the
369
+ /// range [0, 100]
332
370
  function updateRedemptionParameters(
333
371
  Storage storage self,
334
372
  uint64 _redemptionDustThreshold,
335
373
  uint64 _redemptionTreasuryFeeDivisor,
336
374
  uint64 _redemptionTxMaxFee,
337
- uint256 _redemptionTimeout
375
+ uint256 _redemptionTimeout,
376
+ uint96 _redemptionTimeoutSlashingAmount,
377
+ uint256 _redemptionTimeoutNotifierRewardMultiplier
338
378
  ) internal {
339
379
  require(
340
380
  _redemptionDustThreshold > 0,
@@ -356,16 +396,26 @@ library BridgeState {
356
396
  "Redemption timeout must be greater than zero"
357
397
  );
358
398
 
399
+ require(
400
+ _redemptionTimeoutNotifierRewardMultiplier <= 100,
401
+ "Redemption timeout notifier reward multiplier must be in the range [0, 100]"
402
+ );
403
+
359
404
  self.redemptionDustThreshold = _redemptionDustThreshold;
360
405
  self.redemptionTreasuryFeeDivisor = _redemptionTreasuryFeeDivisor;
361
406
  self.redemptionTxMaxFee = _redemptionTxMaxFee;
362
407
  self.redemptionTimeout = _redemptionTimeout;
408
+ self.redemptionTimeoutSlashingAmount = _redemptionTimeoutSlashingAmount;
409
+ self
410
+ .redemptionTimeoutNotifierRewardMultiplier = _redemptionTimeoutNotifierRewardMultiplier;
363
411
 
364
412
  emit RedemptionParametersUpdated(
365
413
  _redemptionDustThreshold,
366
414
  _redemptionTreasuryFeeDivisor,
367
415
  _redemptionTxMaxFee,
368
- _redemptionTimeout
416
+ _redemptionTimeout,
417
+ _redemptionTimeoutSlashingAmount,
418
+ _redemptionTimeoutNotifierRewardMultiplier
369
419
  );
370
420
  }
371
421
 
@@ -380,6 +430,14 @@ library BridgeState {
380
430
  /// be reported as timed out. It is counted from the moment when the
381
431
  /// wallet was requested to move their funds and switched to the
382
432
  /// MovingFunds state.
433
+ /// @param _movingFundsTimeoutSlashingAmount New value of the moving funds
434
+ /// timeout slashing amount in T, it is the amount slashed from each
435
+ /// wallet member for moving funds timeout
436
+ /// @param _movingFundsTimeoutNotifierRewardMultiplier New value of the
437
+ /// moving funds timeout notifier reward multiplier as percentage,
438
+ /// it determines the percentage of the notifier reward from the
439
+ /// staking contact the notifier of a moving funds timeout receives.
440
+ /// The value must be in the range [0, 100]
383
441
  /// @param _movingFundsDustThreshold New value of the moving funds dust
384
442
  /// threshold. It is the minimal satoshi amount that makes sense to
385
443
  // be transferred during the moving funds process. Moving funds
@@ -389,11 +447,15 @@ library BridgeState {
389
447
  /// @dev Requirements:
390
448
  /// - Moving funds transaction max total fee must be greater than zero
391
449
  /// - Moving funds timeout must be greater than zero
450
+ /// - Moving funds timeout notifier reward multiplier must be in the
451
+ /// range [0, 100]
392
452
  /// - Moving funds dust threshold must be greater than zero
393
453
  function updateMovingFundsParameters(
394
454
  Storage storage self,
395
455
  uint64 _movingFundsTxMaxTotalFee,
396
456
  uint32 _movingFundsTimeout,
457
+ uint96 _movingFundsTimeoutSlashingAmount,
458
+ uint256 _movingFundsTimeoutNotifierRewardMultiplier,
397
459
  uint64 _movingFundsDustThreshold
398
460
  ) internal {
399
461
  require(
@@ -406,6 +468,11 @@ library BridgeState {
406
468
  "Moving funds timeout must be greater than zero"
407
469
  );
408
470
 
471
+ require(
472
+ _movingFundsTimeoutNotifierRewardMultiplier <= 100,
473
+ "Moving funds timeout notifier reward multiplier must be in the range [0, 100]"
474
+ );
475
+
409
476
  require(
410
477
  _movingFundsDustThreshold > 0,
411
478
  "Moving funds dust threshold must be greater than zero"
@@ -413,11 +480,17 @@ library BridgeState {
413
480
 
414
481
  self.movingFundsTxMaxTotalFee = _movingFundsTxMaxTotalFee;
415
482
  self.movingFundsTimeout = _movingFundsTimeout;
483
+ self
484
+ .movingFundsTimeoutSlashingAmount = _movingFundsTimeoutSlashingAmount;
485
+ self
486
+ .movingFundsTimeoutNotifierRewardMultiplier = _movingFundsTimeoutNotifierRewardMultiplier;
416
487
  self.movingFundsDustThreshold = _movingFundsDustThreshold;
417
488
 
418
489
  emit MovingFundsParametersUpdated(
419
490
  _movingFundsTxMaxTotalFee,
420
491
  _movingFundsTimeout,
492
+ _movingFundsTimeoutSlashingAmount,
493
+ _movingFundsTimeoutNotifierRewardMultiplier,
421
494
  _movingFundsDustThreshold
422
495
  );
423
496
  }
@@ -426,10 +499,12 @@ library BridgeState {
426
499
  /// @param _walletCreationPeriod New value of the wallet creation period in
427
500
  /// seconds, determines how frequently a new wallet creation can be
428
501
  /// requested
429
- /// @param _walletMinBtcBalance New value of the wallet minimum BTC balance
430
- /// in satoshi, used to decide about wallet creation or closing
431
- /// @param _walletMaxBtcBalance New value of the wallet maximum BTC balance
432
- /// in satoshi, used to decide about wallet creation
502
+ /// @param _walletCreationMinBtcBalance New value of the wallet minimum BTC
503
+ /// balance in satoshi, used to decide about wallet creation
504
+ /// @param _walletCreationMaxBtcBalance New value of the wallet maximum BTC
505
+ /// balance in satoshi, used to decide about wallet creation
506
+ /// @param _walletClosureMinBtcBalance New value of the wallet minimum BTC
507
+ /// balance in satoshi, used to decide about wallet closure
433
508
  /// @param _walletMaxAge New value of the wallet maximum age in seconds,
434
509
  /// indicates the maximum age of a wallet in seconds, after which
435
510
  /// the wallet moving funds process can be requested
@@ -449,19 +524,20 @@ library BridgeState {
449
524
  function updateWalletParameters(
450
525
  Storage storage self,
451
526
  uint32 _walletCreationPeriod,
452
- uint64 _walletMinBtcBalance,
453
- uint64 _walletMaxBtcBalance,
527
+ uint64 _walletCreationMinBtcBalance,
528
+ uint64 _walletCreationMaxBtcBalance,
529
+ uint64 _walletClosureMinBtcBalance,
454
530
  uint32 _walletMaxAge,
455
531
  uint64 _walletMaxBtcTransfer,
456
532
  uint32 _walletClosingPeriod
457
533
  ) internal {
458
534
  require(
459
- _walletMinBtcBalance > 0,
460
- "Wallet minimum BTC balance must be greater than zero"
535
+ _walletCreationMaxBtcBalance > _walletCreationMinBtcBalance,
536
+ "Wallet creation maximum BTC balance must be greater than the creation minimum BTC balance"
461
537
  );
462
538
  require(
463
- _walletMaxBtcBalance > _walletMinBtcBalance,
464
- "Wallet maximum BTC balance must be greater than the minimum"
539
+ _walletClosureMinBtcBalance > 0,
540
+ "Wallet closure minimum BTC balance must be greater than zero"
465
541
  );
466
542
  require(
467
543
  _walletMaxBtcTransfer > 0,
@@ -473,16 +549,18 @@ library BridgeState {
473
549
  );
474
550
 
475
551
  self.walletCreationPeriod = _walletCreationPeriod;
476
- self.walletMinBtcBalance = _walletMinBtcBalance;
477
- self.walletMaxBtcBalance = _walletMaxBtcBalance;
552
+ self.walletCreationMinBtcBalance = _walletCreationMinBtcBalance;
553
+ self.walletCreationMaxBtcBalance = _walletCreationMaxBtcBalance;
554
+ self.walletClosureMinBtcBalance = _walletClosureMinBtcBalance;
478
555
  self.walletMaxAge = _walletMaxAge;
479
556
  self.walletMaxBtcTransfer = _walletMaxBtcTransfer;
480
557
  self.walletClosingPeriod = _walletClosingPeriod;
481
558
 
482
559
  emit WalletParametersUpdated(
483
560
  _walletCreationPeriod,
484
- _walletMinBtcBalance,
485
- _walletMaxBtcBalance,
561
+ _walletCreationMinBtcBalance,
562
+ _walletCreationMaxBtcBalance,
563
+ _walletClosureMinBtcBalance,
486
564
  _walletMaxAge,
487
565
  _walletMaxBtcTransfer,
488
566
  _walletClosingPeriod
@@ -277,7 +277,7 @@ library Fraud {
277
277
  /// for the given `walletID`. Those IDs are not directly stored
278
278
  /// in the contract for gas efficiency purposes but they can be
279
279
  /// read from appropriate `DkgResultSubmitted` and `DkgResultApproved`
280
- /// events.
280
+ /// events of the `WalletRegistry` contract
281
281
  /// - The amount of time indicated by `challengeDefeatTimeout` must pass
282
282
  /// after the challenge was reported
283
283
  function notifyFraudChallengeDefeatTimeout(