@keep-network/tbtc-v2 0.1.1-dev.50 → 0.1.1-dev.53
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.
- package/artifacts/Bank.json +6 -6
- package/artifacts/Bridge.json +235 -141
- package/artifacts/Deposit.json +9 -9
- package/artifacts/EcdsaDkgValidator.json +1 -1
- package/artifacts/EcdsaInactivity.json +1 -1
- package/artifacts/Fraud.json +13 -12
- package/artifacts/KeepRegistry.json +1 -1
- package/artifacts/KeepStake.json +2 -2
- package/artifacts/KeepToken.json +2 -2
- package/artifacts/KeepTokenStaking.json +1 -1
- package/artifacts/MovingFunds.json +9 -9
- package/artifacts/NuCypherStakingEscrow.json +1 -1
- package/artifacts/NuCypherToken.json +2 -2
- package/artifacts/RandomBeaconStub.json +1 -1
- package/artifacts/Redemption.json +14 -13
- package/artifacts/ReimbursementPool.json +2 -2
- package/artifacts/Relay.json +11 -11
- package/artifacts/SortitionPool.json +2 -2
- package/artifacts/Sweep.json +7 -7
- package/artifacts/T.json +2 -2
- package/artifacts/TBTC.json +6 -6
- package/artifacts/TBTCToken.json +6 -6
- package/artifacts/TokenStaking.json +1 -1
- package/artifacts/TokenholderGovernor.json +9 -9
- package/artifacts/TokenholderTimelock.json +8 -8
- package/artifacts/VendingMachine.json +13 -13
- package/artifacts/VendingMachineKeep.json +1 -1
- package/artifacts/VendingMachineNuCypher.json +1 -1
- package/artifacts/WalletRegistry.json +2 -2
- package/artifacts/WalletRegistryGovernance.json +2 -2
- package/artifacts/Wallets.json +9 -9
- package/artifacts/solcInputs/{b0c3ed0992bd570aaaee717425c37538.json → fa22a04615b4037761340d27e55c86ee.json} +5 -5
- package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
- package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
- package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +1 -1
- package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.json +2 -2
- package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
- package/build/contracts/bridge/Bridge.sol/Bridge.json +104 -46
- package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
- package/build/contracts/bridge/BridgeState.sol/BridgeState.json +24 -6
- package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +1 -1
- package/build/contracts/bridge/Deposit.sol/Deposit.json +2 -2
- package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +1 -1
- package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +1 -1
- package/build/contracts/bridge/Fraud.sol/Fraud.json +2 -2
- package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +1 -1
- package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +1 -1
- package/build/contracts/bridge/MovingFunds.sol/MovingFunds.json +2 -2
- package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +1 -1
- package/build/contracts/bridge/Redemption.sol/OutboundTx.json +2 -2
- package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +1 -1
- package/build/contracts/bridge/Redemption.sol/Redemption.json +2 -2
- package/build/contracts/bridge/Sweep.sol/Sweep.dbg.json +1 -1
- package/build/contracts/bridge/Sweep.sol/Sweep.json +2 -2
- package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
- package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +1 -1
- package/build/contracts/bridge/Wallets.sol/Wallets.json +2 -2
- package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
- package/build/contracts/vault/IVault.sol/IVault.dbg.json +1 -1
- package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
- package/contracts/bridge/Bridge.sol +111 -43
- package/contracts/bridge/BridgeState.sol +72 -26
- package/contracts/bridge/Fraud.sol +21 -5
- package/contracts/bridge/Redemption.sol +33 -11
- package/contracts/bridge/Wallets.sol +9 -12
- package/export.json +70 -12
- package/package.json +1 -1
|
@@ -170,7 +170,9 @@ 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(
|
|
@@ -181,15 +183,16 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
181
183
|
|
|
182
184
|
event WalletParametersUpdated(
|
|
183
185
|
uint32 walletCreationPeriod,
|
|
184
|
-
uint64
|
|
185
|
-
uint64
|
|
186
|
+
uint64 walletCreationMinBtcBalance,
|
|
187
|
+
uint64 walletCreationMaxBtcBalance,
|
|
188
|
+
uint64 walletClosureMinBtcBalance,
|
|
186
189
|
uint32 walletMaxAge,
|
|
187
190
|
uint64 walletMaxBtcTransfer,
|
|
188
191
|
uint32 walletClosingPeriod
|
|
189
192
|
);
|
|
190
193
|
|
|
191
194
|
event FraudParametersUpdated(
|
|
192
|
-
|
|
195
|
+
uint96 fraudSlashingAmount,
|
|
193
196
|
uint256 fraudNotifierRewardMultiplier,
|
|
194
197
|
uint256 fraudChallengeDefeatTimeout,
|
|
195
198
|
uint256 fraudChallengeDepositAmount
|
|
@@ -227,6 +230,8 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
227
230
|
self.redemptionTreasuryFeeDivisor = 2000; // 1/2000 == 5bps == 0.05% == 0.0005
|
|
228
231
|
self.redemptionTxMaxFee = 10000; // 10000 satoshi
|
|
229
232
|
self.redemptionTimeout = 172800; // 48 hours
|
|
233
|
+
self.redemptionTimeoutSlashingAmount = 10000 * 1e18; // 10000 T
|
|
234
|
+
self.redemptionTimeoutNotifierRewardMultiplier = 100; // 100%
|
|
230
235
|
self.movingFundsTxMaxTotalFee = 10000; // 10000 satoshi
|
|
231
236
|
self.movingFundsTimeout = 7 days;
|
|
232
237
|
self.movingFundsDustThreshold = 20000; // 20000 satoshi
|
|
@@ -235,8 +240,9 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
235
240
|
self.fraudChallengeDefeatTimeout = 7 days;
|
|
236
241
|
self.fraudChallengeDepositAmount = 2 ether;
|
|
237
242
|
self.walletCreationPeriod = 1 weeks;
|
|
238
|
-
self.
|
|
239
|
-
self.
|
|
243
|
+
self.walletCreationMinBtcBalance = 1e8; // 1 BTC
|
|
244
|
+
self.walletCreationMaxBtcBalance = 100e8; // 100 BTC
|
|
245
|
+
self.walletClosureMinBtcBalance = 5 * 1e7; // 0.5 BTC
|
|
240
246
|
self.walletMaxAge = 26 weeks; // ~6 months
|
|
241
247
|
self.walletMaxBtcTransfer = 10e8; // 10 BTC
|
|
242
248
|
self.walletClosingPeriod = 40 days;
|
|
@@ -434,31 +440,47 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
434
440
|
/// with the given wallet, that has timed out. The redemption
|
|
435
441
|
/// request is identified by the key built as
|
|
436
442
|
/// `keccak256(walletPubKeyHash | redeemerOutputScript)`.
|
|
437
|
-
/// The results of calling this function:
|
|
438
|
-
/// value for the wallet will be decreased
|
|
439
|
-
///
|
|
440
|
-
///
|
|
441
|
-
///
|
|
442
|
-
///
|
|
443
|
-
///
|
|
444
|
-
///
|
|
445
|
-
///
|
|
446
|
-
///
|
|
447
|
-
///
|
|
443
|
+
/// The results of calling this function:
|
|
444
|
+
/// - the pending redemptions value for the wallet will be decreased
|
|
445
|
+
/// by the requested amount (minus treasury fee),
|
|
446
|
+
/// - the tokens taken from the redeemer on redemption request will
|
|
447
|
+
/// be returned to the redeemer,
|
|
448
|
+
/// - the request will be moved from pending redemptions to
|
|
449
|
+
/// timed-out redemptions.
|
|
450
|
+
/// - if the state of the wallet is `Live` or `MovingFunds`, the
|
|
451
|
+
/// wallet operators will be slashed and the notifier will be
|
|
452
|
+
/// rewarded
|
|
453
|
+
/// - if the state of wallet is `Live`, the wallet will be closed or
|
|
454
|
+
/// marked as `MovingFunds` (depending on the presence or absence
|
|
455
|
+
/// of the wallet's main UTXO) and the wallet will no longer be
|
|
456
|
+
/// marked as the active wallet (if it was marked as such).
|
|
448
457
|
/// @param walletPubKeyHash 20-byte public key hash of the wallet
|
|
458
|
+
/// @param walletMembersIDs Identifiers of the wallet signing group members
|
|
449
459
|
/// @param redeemerOutputScript The redeemer's length-prefixed output
|
|
450
460
|
/// script (P2PKH, P2WPKH, P2SH or P2WSH)
|
|
451
461
|
/// @dev Requirements:
|
|
462
|
+
/// - The wallet must be in the Live or MovingFunds or Terminated state
|
|
452
463
|
/// - The redemption request identified by `walletPubKeyHash` and
|
|
453
464
|
/// `redeemerOutputScript` must exist
|
|
465
|
+
/// - The expression `keccak256(abi.encode(walletMembersIDs))` must
|
|
466
|
+
/// be exactly the same as the hash stored under `membersIdsHash`
|
|
467
|
+
/// for the given `walletID`. Those IDs are not directly stored
|
|
468
|
+
/// in the contract for gas efficiency purposes but they can be
|
|
469
|
+
/// read from appropriate `DkgResultSubmitted` and `DkgResultApproved`
|
|
470
|
+
/// events.
|
|
454
471
|
/// - The amount of time defined by `redemptionTimeout` must have
|
|
455
472
|
/// passed since the redemption was requested (the request must be
|
|
456
473
|
/// timed-out).
|
|
457
474
|
function notifyRedemptionTimeout(
|
|
458
475
|
bytes20 walletPubKeyHash,
|
|
476
|
+
uint32[] calldata walletMembersIDs,
|
|
459
477
|
bytes calldata redeemerOutputScript
|
|
460
478
|
) external {
|
|
461
|
-
self.notifyRedemptionTimeout(
|
|
479
|
+
self.notifyRedemptionTimeout(
|
|
480
|
+
walletPubKeyHash,
|
|
481
|
+
walletMembersIDs,
|
|
482
|
+
redeemerOutputScript
|
|
483
|
+
);
|
|
462
484
|
}
|
|
463
485
|
|
|
464
486
|
/// @notice Submits the moving funds target wallets commitment.
|
|
@@ -785,6 +807,7 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
785
807
|
/// rewarded.
|
|
786
808
|
/// @param walletPublicKey The public key of the wallet in the uncompressed
|
|
787
809
|
/// and unprefixed format (64 bytes)
|
|
810
|
+
/// @param walletMembersIDs Identifiers of the wallet signing group members
|
|
788
811
|
/// @param sighash The hash that was used to produce the ECDSA signature
|
|
789
812
|
/// that is the subject of the fraud claim. This hash is constructed
|
|
790
813
|
/// by applying double SHA-256 over a serialized subset of the
|
|
@@ -792,15 +815,28 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
792
815
|
/// the transaction input the signature is produced for. See BIP-143
|
|
793
816
|
/// for reference
|
|
794
817
|
/// @dev Requirements:
|
|
795
|
-
/// -
|
|
818
|
+
/// - The wallet must be in the Live or MovingFunds or Closing or
|
|
819
|
+
/// Terminated state
|
|
820
|
+
/// - The `walletPublicKey` and `sighash` must identify an open fraud
|
|
796
821
|
/// challenge
|
|
797
|
-
/// -
|
|
798
|
-
///
|
|
822
|
+
/// - The expression `keccak256(abi.encode(walletMembersIDs))` must
|
|
823
|
+
/// be exactly the same as the hash stored under `membersIdsHash`
|
|
824
|
+
/// for the given `walletID`. Those IDs are not directly stored
|
|
825
|
+
/// in the contract for gas efficiency purposes but they can be
|
|
826
|
+
/// read from appropriate `DkgResultSubmitted` and `DkgResultApproved`
|
|
827
|
+
/// events.
|
|
828
|
+
/// - The amount of time indicated by `challengeDefeatTimeout` must pass
|
|
829
|
+
/// after the challenge was reported
|
|
799
830
|
function notifyFraudChallengeDefeatTimeout(
|
|
800
831
|
bytes calldata walletPublicKey,
|
|
832
|
+
uint32[] calldata walletMembersIDs,
|
|
801
833
|
bytes32 sighash
|
|
802
834
|
) external {
|
|
803
|
-
self.notifyFraudChallengeDefeatTimeout(
|
|
835
|
+
self.notifyFraudChallengeDefeatTimeout(
|
|
836
|
+
walletPublicKey,
|
|
837
|
+
walletMembersIDs,
|
|
838
|
+
sighash
|
|
839
|
+
);
|
|
804
840
|
}
|
|
805
841
|
|
|
806
842
|
/// @notice Allows the Governance to mark the given vault address as trusted
|
|
@@ -890,22 +926,36 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
890
926
|
/// request was created via `requestRedemption` call. Reported timed
|
|
891
927
|
/// out requests are cancelled and locked TBTC is returned to the
|
|
892
928
|
/// redeemer in full amount.
|
|
929
|
+
/// @param redemptionTimeoutSlashingAmount New value of the redemption
|
|
930
|
+
/// timeout slashing amount in T, it is the amount slashed from each
|
|
931
|
+
/// wallet member for redemption timeout
|
|
932
|
+
/// @param redemptionTimeoutNotifierRewardMultiplier New value of the
|
|
933
|
+
/// redemption timeout notifier reward multiplier as percentage,
|
|
934
|
+
/// it determines the percentage of the notifier reward from the
|
|
935
|
+
/// staking contact the notifier of a redemption timeout receives.
|
|
936
|
+
/// The value must be in the range [0, 100]
|
|
893
937
|
/// @dev Requirements:
|
|
894
938
|
/// - Redemption dust threshold must be greater than zero
|
|
895
939
|
/// - Redemption treasury fee divisor must be greater than zero
|
|
896
940
|
/// - Redemption transaction max fee must be greater than zero
|
|
897
941
|
/// - Redemption timeout must be greater than zero
|
|
942
|
+
/// - Redemption timeout notifier reward multiplier must be in the
|
|
943
|
+
/// range [0, 100]
|
|
898
944
|
function updateRedemptionParameters(
|
|
899
945
|
uint64 redemptionDustThreshold,
|
|
900
946
|
uint64 redemptionTreasuryFeeDivisor,
|
|
901
947
|
uint64 redemptionTxMaxFee,
|
|
902
|
-
uint256 redemptionTimeout
|
|
948
|
+
uint256 redemptionTimeout,
|
|
949
|
+
uint96 redemptionTimeoutSlashingAmount,
|
|
950
|
+
uint256 redemptionTimeoutNotifierRewardMultiplier
|
|
903
951
|
) external onlyGovernance {
|
|
904
952
|
self.updateRedemptionParameters(
|
|
905
953
|
redemptionDustThreshold,
|
|
906
954
|
redemptionTreasuryFeeDivisor,
|
|
907
955
|
redemptionTxMaxFee,
|
|
908
|
-
redemptionTimeout
|
|
956
|
+
redemptionTimeout,
|
|
957
|
+
redemptionTimeoutSlashingAmount,
|
|
958
|
+
redemptionTimeoutNotifierRewardMultiplier
|
|
909
959
|
);
|
|
910
960
|
}
|
|
911
961
|
|
|
@@ -946,10 +996,12 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
946
996
|
/// @param walletCreationPeriod New value of the wallet creation period in
|
|
947
997
|
/// seconds, determines how frequently a new wallet creation can be
|
|
948
998
|
/// requested
|
|
949
|
-
/// @param
|
|
950
|
-
/// in satoshi, used to decide about wallet creation
|
|
951
|
-
/// @param
|
|
952
|
-
/// in satoshi, used to decide about wallet creation
|
|
999
|
+
/// @param walletCreationMinBtcBalance New value of the wallet minimum BTC
|
|
1000
|
+
/// balance in satoshi, used to decide about wallet creation
|
|
1001
|
+
/// @param walletCreationMaxBtcBalance New value of the wallet maximum BTC
|
|
1002
|
+
/// balance in satoshi, used to decide about wallet creation
|
|
1003
|
+
/// @param walletClosureMinBtcBalance New value of the wallet minimum BTC
|
|
1004
|
+
/// balance in satoshi, used to decide about wallet closure
|
|
953
1005
|
/// @param walletMaxAge New value of the wallet maximum age in seconds,
|
|
954
1006
|
/// indicates the maximum age of a wallet in seconds, after which
|
|
955
1007
|
/// the wallet moving funds process can be requested
|
|
@@ -968,16 +1020,18 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
968
1020
|
/// - Wallet closing period must be greater than zero
|
|
969
1021
|
function updateWalletParameters(
|
|
970
1022
|
uint32 walletCreationPeriod,
|
|
971
|
-
uint64
|
|
972
|
-
uint64
|
|
1023
|
+
uint64 walletCreationMinBtcBalance,
|
|
1024
|
+
uint64 walletCreationMaxBtcBalance,
|
|
1025
|
+
uint64 walletClosureMinBtcBalance,
|
|
973
1026
|
uint32 walletMaxAge,
|
|
974
1027
|
uint64 walletMaxBtcTransfer,
|
|
975
1028
|
uint32 walletClosingPeriod
|
|
976
1029
|
) external onlyGovernance {
|
|
977
1030
|
self.updateWalletParameters(
|
|
978
1031
|
walletCreationPeriod,
|
|
979
|
-
|
|
980
|
-
|
|
1032
|
+
walletCreationMinBtcBalance,
|
|
1033
|
+
walletCreationMaxBtcBalance,
|
|
1034
|
+
walletClosureMinBtcBalance,
|
|
981
1035
|
walletMaxAge,
|
|
982
1036
|
walletMaxBtcTransfer,
|
|
983
1037
|
walletClosingPeriod
|
|
@@ -1002,7 +1056,7 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
1002
1056
|
/// - Fraud notifier reward multiplier must be in the range [0, 100]
|
|
1003
1057
|
/// - Fraud challenge defeat timeout must be greater than 0
|
|
1004
1058
|
function updateFraudParameters(
|
|
1005
|
-
|
|
1059
|
+
uint96 fraudSlashingAmount,
|
|
1006
1060
|
uint256 fraudNotifierRewardMultiplier,
|
|
1007
1061
|
uint256 fraudChallengeDefeatTimeout,
|
|
1008
1062
|
uint256 fraudChallengeDepositAmount
|
|
@@ -1185,6 +1239,11 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
1185
1239
|
/// redemption request was created via `requestRedemption` call.
|
|
1186
1240
|
/// Reported timed out requests are cancelled and locked TBTC is
|
|
1187
1241
|
/// returned to the redeemer in full amount.
|
|
1242
|
+
/// @return redemptionTimeoutSlashingAmount The amount of stake slashed
|
|
1243
|
+
/// from each member of a wallet for a redemption timeout.
|
|
1244
|
+
/// @return redemptionTimeoutNotifierRewardMultiplier The percentage of the
|
|
1245
|
+
/// notifier reward from the staking contract the notifier of a
|
|
1246
|
+
/// redemption timeout receives. The value is in the range [0, 100].
|
|
1188
1247
|
function redemptionParameters()
|
|
1189
1248
|
external
|
|
1190
1249
|
view
|
|
@@ -1192,13 +1251,18 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
1192
1251
|
uint64 redemptionDustThreshold,
|
|
1193
1252
|
uint64 redemptionTreasuryFeeDivisor,
|
|
1194
1253
|
uint64 redemptionTxMaxFee,
|
|
1195
|
-
uint256 redemptionTimeout
|
|
1254
|
+
uint256 redemptionTimeout,
|
|
1255
|
+
uint96 redemptionTimeoutSlashingAmount,
|
|
1256
|
+
uint256 redemptionTimeoutNotifierRewardMultiplier
|
|
1196
1257
|
)
|
|
1197
1258
|
{
|
|
1198
1259
|
redemptionDustThreshold = self.redemptionDustThreshold;
|
|
1199
1260
|
redemptionTreasuryFeeDivisor = self.redemptionTreasuryFeeDivisor;
|
|
1200
1261
|
redemptionTxMaxFee = self.redemptionTxMaxFee;
|
|
1201
1262
|
redemptionTimeout = self.redemptionTimeout;
|
|
1263
|
+
redemptionTimeoutSlashingAmount = self.redemptionTimeoutSlashingAmount;
|
|
1264
|
+
redemptionTimeoutNotifierRewardMultiplier = self
|
|
1265
|
+
.redemptionTimeoutNotifierRewardMultiplier;
|
|
1202
1266
|
}
|
|
1203
1267
|
|
|
1204
1268
|
/// @notice Returns the current values of Bridge moving funds between
|
|
@@ -1232,10 +1296,12 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
1232
1296
|
|
|
1233
1297
|
/// @return walletCreationPeriod Determines how frequently a new wallet
|
|
1234
1298
|
/// creation can be requested. Value in seconds.
|
|
1235
|
-
/// @return
|
|
1236
|
-
/// used to decide about wallet creation
|
|
1237
|
-
/// @return
|
|
1238
|
-
/// used to decide about wallet creation.
|
|
1299
|
+
/// @return walletCreationMinBtcBalance The minimum BTC threshold in satoshi
|
|
1300
|
+
/// that is used to decide about wallet creation.
|
|
1301
|
+
/// @return walletCreationMaxBtcBalance The maximum BTC threshold in satoshi
|
|
1302
|
+
/// that is used to decide about wallet creation.
|
|
1303
|
+
/// @return walletClosureMinBtcBalance The minimum BTC threshold in satoshi
|
|
1304
|
+
/// that is used to decide about wallet closure.
|
|
1239
1305
|
/// @return walletMaxAge The maximum age of a wallet in seconds, after which
|
|
1240
1306
|
/// the wallet moving funds process can be requested.
|
|
1241
1307
|
/// @return walletMaxBtcTransfer The maximum BTC amount in satoshi than
|
|
@@ -1250,16 +1316,18 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
1250
1316
|
view
|
|
1251
1317
|
returns (
|
|
1252
1318
|
uint32 walletCreationPeriod,
|
|
1253
|
-
uint64
|
|
1254
|
-
uint64
|
|
1319
|
+
uint64 walletCreationMinBtcBalance,
|
|
1320
|
+
uint64 walletCreationMaxBtcBalance,
|
|
1321
|
+
uint64 walletClosureMinBtcBalance,
|
|
1255
1322
|
uint32 walletMaxAge,
|
|
1256
1323
|
uint64 walletMaxBtcTransfer,
|
|
1257
1324
|
uint32 walletClosingPeriod
|
|
1258
1325
|
)
|
|
1259
1326
|
{
|
|
1260
1327
|
walletCreationPeriod = self.walletCreationPeriod;
|
|
1261
|
-
|
|
1262
|
-
|
|
1328
|
+
walletCreationMinBtcBalance = self.walletCreationMinBtcBalance;
|
|
1329
|
+
walletCreationMaxBtcBalance = self.walletCreationMaxBtcBalance;
|
|
1330
|
+
walletClosureMinBtcBalance = self.walletClosureMinBtcBalance;
|
|
1263
1331
|
walletMaxAge = self.walletMaxAge;
|
|
1264
1332
|
walletMaxBtcTransfer = self.walletMaxBtcTransfer;
|
|
1265
1333
|
walletClosingPeriod = self.walletClosingPeriod;
|
|
@@ -1279,7 +1347,7 @@ contract Bridge is Governable, EcdsaWalletOwner {
|
|
|
1279
1347
|
external
|
|
1280
1348
|
view
|
|
1281
1349
|
returns (
|
|
1282
|
-
|
|
1350
|
+
uint96 fraudSlashingAmount,
|
|
1283
1351
|
uint256 fraudNotifierRewardMultiplier,
|
|
1284
1352
|
uint256 fraudChallengeDefeatTimeout,
|
|
1285
1353
|
uint256 fraudChallengeDepositAmount
|
|
@@ -122,6 +122,13 @@ library BridgeState {
|
|
|
122
122
|
// timed out requests are cancelled and locked TBTC is returned
|
|
123
123
|
// to the redeemer in full amount.
|
|
124
124
|
uint256 redemptionTimeout;
|
|
125
|
+
// The amount of stake slashed from each member of a wallet for a
|
|
126
|
+
// redemption timeout.
|
|
127
|
+
uint96 redemptionTimeoutSlashingAmount;
|
|
128
|
+
// The percentage of the notifier reward from the staking contract
|
|
129
|
+
// the notifier of a redemption timeout receives. The value is in the
|
|
130
|
+
// range [0, 100].
|
|
131
|
+
uint256 redemptionTimeoutNotifierRewardMultiplier;
|
|
125
132
|
// Collection of all pending redemption requests indexed by
|
|
126
133
|
// redemption key built as
|
|
127
134
|
// `keccak256(walletPubKeyHash | redeemerOutputScript)`.
|
|
@@ -152,7 +159,7 @@ library BridgeState {
|
|
|
152
159
|
// `pendingRedemptions` mapping.
|
|
153
160
|
mapping(uint256 => Redemption.RedemptionRequest) timedOutRedemptions;
|
|
154
161
|
// The amount of stake slashed from each member of a wallet for a fraud.
|
|
155
|
-
|
|
162
|
+
uint96 fraudSlashingAmount;
|
|
156
163
|
// The percentage of the notifier reward from the staking contract
|
|
157
164
|
// the notifier of a fraud receives. The value is in the range [0, 100].
|
|
158
165
|
uint256 fraudNotifierRewardMultiplier;
|
|
@@ -175,11 +182,20 @@ library BridgeState {
|
|
|
175
182
|
// Value in seconds.
|
|
176
183
|
uint32 walletCreationPeriod;
|
|
177
184
|
// The minimum BTC threshold in satoshi that is used to decide about
|
|
178
|
-
// wallet creation
|
|
179
|
-
|
|
185
|
+
// wallet creation. Specifically, we allow for the creation of a new
|
|
186
|
+
// wallet if the active wallet is old enough and their amount of BTC
|
|
187
|
+
// is greater than or equal this threshold.
|
|
188
|
+
uint64 walletCreationMinBtcBalance;
|
|
180
189
|
// The maximum BTC threshold in satoshi that is used to decide about
|
|
181
|
-
// wallet creation.
|
|
182
|
-
|
|
190
|
+
// wallet creation. Specifically, we allow for the creation of a new
|
|
191
|
+
// wallet if the active wallet's amount of BTC is greater than or equal
|
|
192
|
+
// this threshold, regardless of the active wallet's age.
|
|
193
|
+
uint64 walletCreationMaxBtcBalance;
|
|
194
|
+
// The minimum BTC threshold in satoshi that is used to decide about
|
|
195
|
+
// wallet closing. Specifically, we allow for the closure of the given
|
|
196
|
+
// wallet if their amount of BTC is lesser than this threshold,
|
|
197
|
+
// regardless of the wallet's age.
|
|
198
|
+
uint64 walletClosureMinBtcBalance;
|
|
183
199
|
// The maximum age of a wallet in seconds, after which the wallet
|
|
184
200
|
// moving funds process can be requested.
|
|
185
201
|
uint32 walletMaxAge;
|
|
@@ -213,7 +229,9 @@ library BridgeState {
|
|
|
213
229
|
uint64 redemptionDustThreshold,
|
|
214
230
|
uint64 redemptionTreasuryFeeDivisor,
|
|
215
231
|
uint64 redemptionTxMaxFee,
|
|
216
|
-
uint256 redemptionTimeout
|
|
232
|
+
uint256 redemptionTimeout,
|
|
233
|
+
uint96 redemptionTimeoutSlashingAmount,
|
|
234
|
+
uint256 redemptionTimeoutNotifierRewardMultiplier
|
|
217
235
|
);
|
|
218
236
|
|
|
219
237
|
event MovingFundsParametersUpdated(
|
|
@@ -224,15 +242,16 @@ library BridgeState {
|
|
|
224
242
|
|
|
225
243
|
event WalletParametersUpdated(
|
|
226
244
|
uint32 walletCreationPeriod,
|
|
227
|
-
uint64
|
|
228
|
-
uint64
|
|
245
|
+
uint64 walletCreationMinBtcBalance,
|
|
246
|
+
uint64 walletCreationMaxBtcBalance,
|
|
247
|
+
uint64 walletClosureMinBtcBalance,
|
|
229
248
|
uint32 walletMaxAge,
|
|
230
249
|
uint64 walletMaxBtcTransfer,
|
|
231
250
|
uint32 walletClosingPeriod
|
|
232
251
|
);
|
|
233
252
|
|
|
234
253
|
event FraudParametersUpdated(
|
|
235
|
-
|
|
254
|
+
uint96 fraudSlashingAmount,
|
|
236
255
|
uint256 fraudNotifierRewardMultiplier,
|
|
237
256
|
uint256 fraudChallengeDefeatTimeout,
|
|
238
257
|
uint256 fraudChallengeDepositAmount
|
|
@@ -324,17 +343,29 @@ library BridgeState {
|
|
|
324
343
|
/// request was created via `requestRedemption` call. Reported timed
|
|
325
344
|
/// out requests are cancelled and locked TBTC is returned to the
|
|
326
345
|
/// redeemer in full amount.
|
|
346
|
+
/// @param _redemptionTimeoutSlashingAmount New value of the redemption
|
|
347
|
+
/// timeout slashing amount in T, it is the amount slashed from each
|
|
348
|
+
/// wallet member for redemption timeout
|
|
349
|
+
/// @param _redemptionTimeoutNotifierRewardMultiplier New value of the
|
|
350
|
+
/// redemption timeout notifier reward multiplier as percentage,
|
|
351
|
+
/// it determines the percentage of the notifier reward from the
|
|
352
|
+
/// staking contact the notifier of a redemption timeout receives.
|
|
353
|
+
/// The value must be in the range [0, 100]
|
|
327
354
|
/// @dev Requirements:
|
|
328
355
|
/// - Redemption dust threshold must be greater than zero
|
|
329
356
|
/// - Redemption treasury fee divisor must be greater than zero
|
|
330
357
|
/// - Redemption transaction max fee must be greater than zero
|
|
331
358
|
/// - Redemption timeout must be greater than zero
|
|
359
|
+
/// - Redemption timeout notifier reward multiplier must be in the
|
|
360
|
+
/// range [0, 100]
|
|
332
361
|
function updateRedemptionParameters(
|
|
333
362
|
Storage storage self,
|
|
334
363
|
uint64 _redemptionDustThreshold,
|
|
335
364
|
uint64 _redemptionTreasuryFeeDivisor,
|
|
336
365
|
uint64 _redemptionTxMaxFee,
|
|
337
|
-
uint256 _redemptionTimeout
|
|
366
|
+
uint256 _redemptionTimeout,
|
|
367
|
+
uint96 _redemptionTimeoutSlashingAmount,
|
|
368
|
+
uint256 _redemptionTimeoutNotifierRewardMultiplier
|
|
338
369
|
) internal {
|
|
339
370
|
require(
|
|
340
371
|
_redemptionDustThreshold > 0,
|
|
@@ -356,16 +387,26 @@ library BridgeState {
|
|
|
356
387
|
"Redemption timeout must be greater than zero"
|
|
357
388
|
);
|
|
358
389
|
|
|
390
|
+
require(
|
|
391
|
+
_redemptionTimeoutNotifierRewardMultiplier <= 100,
|
|
392
|
+
"Redemption timeout notifier reward multiplier must be in the range [0, 100]"
|
|
393
|
+
);
|
|
394
|
+
|
|
359
395
|
self.redemptionDustThreshold = _redemptionDustThreshold;
|
|
360
396
|
self.redemptionTreasuryFeeDivisor = _redemptionTreasuryFeeDivisor;
|
|
361
397
|
self.redemptionTxMaxFee = _redemptionTxMaxFee;
|
|
362
398
|
self.redemptionTimeout = _redemptionTimeout;
|
|
399
|
+
self.redemptionTimeoutSlashingAmount = _redemptionTimeoutSlashingAmount;
|
|
400
|
+
self
|
|
401
|
+
.redemptionTimeoutNotifierRewardMultiplier = _redemptionTimeoutNotifierRewardMultiplier;
|
|
363
402
|
|
|
364
403
|
emit RedemptionParametersUpdated(
|
|
365
404
|
_redemptionDustThreshold,
|
|
366
405
|
_redemptionTreasuryFeeDivisor,
|
|
367
406
|
_redemptionTxMaxFee,
|
|
368
|
-
_redemptionTimeout
|
|
407
|
+
_redemptionTimeout,
|
|
408
|
+
_redemptionTimeoutSlashingAmount,
|
|
409
|
+
_redemptionTimeoutNotifierRewardMultiplier
|
|
369
410
|
);
|
|
370
411
|
}
|
|
371
412
|
|
|
@@ -426,10 +467,12 @@ library BridgeState {
|
|
|
426
467
|
/// @param _walletCreationPeriod New value of the wallet creation period in
|
|
427
468
|
/// seconds, determines how frequently a new wallet creation can be
|
|
428
469
|
/// requested
|
|
429
|
-
/// @param
|
|
430
|
-
/// in satoshi, used to decide about wallet creation
|
|
431
|
-
/// @param
|
|
432
|
-
/// in satoshi, used to decide about wallet creation
|
|
470
|
+
/// @param _walletCreationMinBtcBalance New value of the wallet minimum BTC
|
|
471
|
+
/// balance in satoshi, used to decide about wallet creation
|
|
472
|
+
/// @param _walletCreationMaxBtcBalance New value of the wallet maximum BTC
|
|
473
|
+
/// balance in satoshi, used to decide about wallet creation
|
|
474
|
+
/// @param _walletClosureMinBtcBalance New value of the wallet minimum BTC
|
|
475
|
+
/// balance in satoshi, used to decide about wallet closure
|
|
433
476
|
/// @param _walletMaxAge New value of the wallet maximum age in seconds,
|
|
434
477
|
/// indicates the maximum age of a wallet in seconds, after which
|
|
435
478
|
/// the wallet moving funds process can be requested
|
|
@@ -449,19 +492,20 @@ library BridgeState {
|
|
|
449
492
|
function updateWalletParameters(
|
|
450
493
|
Storage storage self,
|
|
451
494
|
uint32 _walletCreationPeriod,
|
|
452
|
-
uint64
|
|
453
|
-
uint64
|
|
495
|
+
uint64 _walletCreationMinBtcBalance,
|
|
496
|
+
uint64 _walletCreationMaxBtcBalance,
|
|
497
|
+
uint64 _walletClosureMinBtcBalance,
|
|
454
498
|
uint32 _walletMaxAge,
|
|
455
499
|
uint64 _walletMaxBtcTransfer,
|
|
456
500
|
uint32 _walletClosingPeriod
|
|
457
501
|
) internal {
|
|
458
502
|
require(
|
|
459
|
-
|
|
460
|
-
"Wallet
|
|
503
|
+
_walletCreationMaxBtcBalance > _walletCreationMinBtcBalance,
|
|
504
|
+
"Wallet creation maximum BTC balance must be greater than the creation minimum BTC balance"
|
|
461
505
|
);
|
|
462
506
|
require(
|
|
463
|
-
|
|
464
|
-
"Wallet
|
|
507
|
+
_walletClosureMinBtcBalance > 0,
|
|
508
|
+
"Wallet closure minimum BTC balance must be greater than zero"
|
|
465
509
|
);
|
|
466
510
|
require(
|
|
467
511
|
_walletMaxBtcTransfer > 0,
|
|
@@ -473,16 +517,18 @@ library BridgeState {
|
|
|
473
517
|
);
|
|
474
518
|
|
|
475
519
|
self.walletCreationPeriod = _walletCreationPeriod;
|
|
476
|
-
self.
|
|
477
|
-
self.
|
|
520
|
+
self.walletCreationMinBtcBalance = _walletCreationMinBtcBalance;
|
|
521
|
+
self.walletCreationMaxBtcBalance = _walletCreationMaxBtcBalance;
|
|
522
|
+
self.walletClosureMinBtcBalance = _walletClosureMinBtcBalance;
|
|
478
523
|
self.walletMaxAge = _walletMaxAge;
|
|
479
524
|
self.walletMaxBtcTransfer = _walletMaxBtcTransfer;
|
|
480
525
|
self.walletClosingPeriod = _walletClosingPeriod;
|
|
481
526
|
|
|
482
527
|
emit WalletParametersUpdated(
|
|
483
528
|
_walletCreationPeriod,
|
|
484
|
-
|
|
485
|
-
|
|
529
|
+
_walletCreationMinBtcBalance,
|
|
530
|
+
_walletCreationMaxBtcBalance,
|
|
531
|
+
_walletClosureMinBtcBalance,
|
|
486
532
|
_walletMaxAge,
|
|
487
533
|
_walletMaxBtcTransfer,
|
|
488
534
|
_walletClosingPeriod
|
|
@@ -508,7 +554,7 @@ library BridgeState {
|
|
|
508
554
|
/// - Fraud challenge defeat timeout must be greater than 0
|
|
509
555
|
function updateFraudParameters(
|
|
510
556
|
Storage storage self,
|
|
511
|
-
|
|
557
|
+
uint96 _fraudSlashingAmount,
|
|
512
558
|
uint256 _fraudNotifierRewardMultiplier,
|
|
513
559
|
uint256 _fraudChallengeDefeatTimeout,
|
|
514
560
|
uint256 _fraudChallengeDepositAmount
|
|
@@ -260,6 +260,7 @@ library Fraud {
|
|
|
260
260
|
/// rewarded.
|
|
261
261
|
/// @param walletPublicKey The public key of the wallet in the uncompressed
|
|
262
262
|
/// and unprefixed format (64 bytes)
|
|
263
|
+
/// @param walletMembersIDs Identifiers of the wallet signing group members
|
|
263
264
|
/// @param sighash The hash that was used to produce the ECDSA signature
|
|
264
265
|
/// that is the subject of the fraud claim. This hash is constructed
|
|
265
266
|
/// by applying double SHA-256 over a serialized subset of the
|
|
@@ -271,11 +272,18 @@ library Fraud {
|
|
|
271
272
|
/// Terminated state
|
|
272
273
|
/// - The `walletPublicKey` and `sighash` must identify an open fraud
|
|
273
274
|
/// challenge
|
|
275
|
+
/// - The expression `keccak256(abi.encode(walletMembersIDs))` must
|
|
276
|
+
/// be exactly the same as the hash stored under `membersIdsHash`
|
|
277
|
+
/// for the given `walletID`. Those IDs are not directly stored
|
|
278
|
+
/// in the contract for gas efficiency purposes but they can be
|
|
279
|
+
/// read from appropriate `DkgResultSubmitted` and `DkgResultApproved`
|
|
280
|
+
/// events.
|
|
274
281
|
/// - The amount of time indicated by `challengeDefeatTimeout` must pass
|
|
275
282
|
/// after the challenge was reported
|
|
276
283
|
function notifyFraudChallengeDefeatTimeout(
|
|
277
284
|
BridgeState.Storage storage self,
|
|
278
285
|
bytes calldata walletPublicKey,
|
|
286
|
+
uint32[] calldata walletMembersIDs,
|
|
279
287
|
bytes32 sighash
|
|
280
288
|
) external {
|
|
281
289
|
uint256 challengeKey = uint256(
|
|
@@ -312,9 +320,12 @@ library Fraud {
|
|
|
312
320
|
walletPublicKey.slice32(32)
|
|
313
321
|
);
|
|
314
322
|
bytes20 walletPubKeyHash = compressedWalletPublicKey.hash160View();
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
323
|
+
|
|
324
|
+
Wallets.Wallet storage wallet = self.registeredWallets[
|
|
325
|
+
walletPubKeyHash
|
|
326
|
+
];
|
|
327
|
+
|
|
328
|
+
Wallets.WalletState walletState = wallet.state;
|
|
318
329
|
|
|
319
330
|
if (
|
|
320
331
|
walletState == Wallets.WalletState.Live ||
|
|
@@ -323,8 +334,13 @@ library Fraud {
|
|
|
323
334
|
) {
|
|
324
335
|
self.terminateWallet(walletPubKeyHash);
|
|
325
336
|
|
|
326
|
-
|
|
327
|
-
|
|
337
|
+
self.ecdsaWalletRegistry.seize(
|
|
338
|
+
self.fraudSlashingAmount,
|
|
339
|
+
self.fraudNotifierRewardMultiplier,
|
|
340
|
+
challenge.challenger,
|
|
341
|
+
wallet.ecdsaWalletID,
|
|
342
|
+
walletMembersIDs
|
|
343
|
+
);
|
|
328
344
|
} else if (walletState == Wallets.WalletState.Terminated) {
|
|
329
345
|
// This is a special case when the wallet was already terminated
|
|
330
346
|
// due to a previous deliberate protocol violation. In that
|