@keep-network/tbtc-v2 0.1.1-dev.95 → 0.1.1-dev.98
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 +8 -8
- package/artifacts/Bridge.json +57 -57
- package/artifacts/Deposit.json +9 -9
- package/artifacts/DepositSweep.json +9 -9
- package/artifacts/EcdsaDkgValidator.json +1 -1
- package/artifacts/EcdsaInactivity.json +1 -1
- package/artifacts/EcdsaSortitionPool.json +2 -2
- package/artifacts/Fraud.json +9 -9
- 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 +9 -9
- package/artifacts/ReimbursementPool.json +2 -2
- package/artifacts/Relay.json +9 -9
- package/artifacts/T.json +2 -2
- package/artifacts/TBTC.json +10 -10
- package/artifacts/TBTCToken.json +10 -10
- package/artifacts/TBTCVault.json +15 -15
- package/artifacts/TokenStaking.json +1 -1
- package/artifacts/TokenholderGovernor.json +9 -9
- package/artifacts/TokenholderTimelock.json +8 -8
- package/artifacts/VendingMachine.json +11 -11
- package/artifacts/VendingMachineKeep.json +1 -1
- package/artifacts/VendingMachineNuCypher.json +1 -1
- package/artifacts/WalletRegistry.json +5 -5
- package/artifacts/WalletRegistryGovernance.json +2 -2
- package/artifacts/Wallets.json +9 -9
- package/artifacts/solcInputs/{b1eed895af5ae97fee0102eb17dac6e6.json → becdd5668a2170e95004d124119e4fcb.json} +10 -10
- package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
- package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
- package/build/contracts/bank/IReceiveBalanceApproval.sol/IReceiveBalanceApproval.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 +103 -103
- package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
- package/build/contracts/bridge/BridgeState.sol/BridgeState.json +2 -2
- 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/DepositSweep.sol/DepositSweep.dbg.json +1 -1
- package/build/contracts/bridge/DepositSweep.sol/DepositSweep.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/Heartbeat.sol/Heartbeat.dbg.json +1 -1
- 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/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/DonationVault.sol/DonationVault.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/BitcoinTx.sol +72 -39
- package/contracts/bridge/Bridge.sol +14 -14
- package/contracts/bridge/BridgeState.sol +83 -75
- package/contracts/bridge/DepositSweep.sol +3 -0
- package/contracts/bridge/Fraud.sol +7 -32
- package/contracts/bridge/MovingFunds.sol +41 -53
- package/contracts/bridge/Redemption.sol +143 -108
- package/contracts/bridge/Wallets.sol +309 -143
- package/export.json +44 -44
- package/package.json +2 -2
|
@@ -239,7 +239,7 @@ contract Bridge is
|
|
|
239
239
|
address _relay,
|
|
240
240
|
address _treasury,
|
|
241
241
|
address _ecdsaWalletRegistry,
|
|
242
|
-
|
|
242
|
+
uint96 _txProofDifficultyFactor
|
|
243
243
|
) external initializer {
|
|
244
244
|
require(_bank != address(0), "Bank address cannot be zero");
|
|
245
245
|
self.bank = Bank(_bank);
|
|
@@ -944,11 +944,11 @@ contract Bridge is
|
|
|
944
944
|
/// can be empty as it is ignored since the wallet balance is
|
|
945
945
|
/// assumed to be zero,
|
|
946
946
|
/// - Wallet must be in Live state.
|
|
947
|
-
function
|
|
947
|
+
function notifyWalletCloseable(
|
|
948
948
|
bytes20 walletPubKeyHash,
|
|
949
949
|
BitcoinTx.UTXO calldata walletMainUtxo
|
|
950
950
|
) external {
|
|
951
|
-
self.
|
|
951
|
+
self.notifyWalletCloseable(walletPubKeyHash, walletMainUtxo);
|
|
952
952
|
}
|
|
953
953
|
|
|
954
954
|
/// @notice Notifies about the end of the closing period for the given wallet.
|
|
@@ -1228,9 +1228,9 @@ contract Bridge is
|
|
|
1228
1228
|
uint64 redemptionDustThreshold,
|
|
1229
1229
|
uint64 redemptionTreasuryFeeDivisor,
|
|
1230
1230
|
uint64 redemptionTxMaxFee,
|
|
1231
|
-
|
|
1231
|
+
uint64 redemptionTimeout,
|
|
1232
1232
|
uint96 redemptionTimeoutSlashingAmount,
|
|
1233
|
-
|
|
1233
|
+
uint64 redemptionTimeoutNotifierRewardMultiplier
|
|
1234
1234
|
) external onlyGovernance {
|
|
1235
1235
|
self.updateRedemptionParameters(
|
|
1236
1236
|
redemptionDustThreshold,
|
|
@@ -1315,7 +1315,7 @@ contract Bridge is
|
|
|
1315
1315
|
uint64 movedFundsSweepTxMaxTotalFee,
|
|
1316
1316
|
uint32 movedFundsSweepTimeout,
|
|
1317
1317
|
uint96 movedFundsSweepTimeoutSlashingAmount,
|
|
1318
|
-
|
|
1318
|
+
uint64 movedFundsSweepTimeoutNotifierRewardMultiplier
|
|
1319
1319
|
) external onlyGovernance {
|
|
1320
1320
|
self.updateMovingFundsParameters(
|
|
1321
1321
|
movingFundsTxMaxTotalFee,
|
|
@@ -1395,10 +1395,10 @@ contract Bridge is
|
|
|
1395
1395
|
/// - Fraud challenge defeat timeout must be greater than 0,
|
|
1396
1396
|
/// - Fraud notifier reward multiplier must be in the range [0, 100].
|
|
1397
1397
|
function updateFraudParameters(
|
|
1398
|
-
|
|
1399
|
-
|
|
1398
|
+
uint96 fraudChallengeDepositAmount,
|
|
1399
|
+
uint32 fraudChallengeDefeatTimeout,
|
|
1400
1400
|
uint96 fraudSlashingAmount,
|
|
1401
|
-
|
|
1401
|
+
uint32 fraudNotifierRewardMultiplier
|
|
1402
1402
|
) external onlyGovernance {
|
|
1403
1403
|
self.updateFraudParameters(
|
|
1404
1404
|
fraudChallengeDepositAmount,
|
|
@@ -1607,9 +1607,9 @@ contract Bridge is
|
|
|
1607
1607
|
uint64 redemptionDustThreshold,
|
|
1608
1608
|
uint64 redemptionTreasuryFeeDivisor,
|
|
1609
1609
|
uint64 redemptionTxMaxFee,
|
|
1610
|
-
|
|
1610
|
+
uint64 redemptionTimeout,
|
|
1611
1611
|
uint96 redemptionTimeoutSlashingAmount,
|
|
1612
|
-
|
|
1612
|
+
uint64 redemptionTimeoutNotifierRewardMultiplier
|
|
1613
1613
|
)
|
|
1614
1614
|
{
|
|
1615
1615
|
redemptionDustThreshold = self.redemptionDustThreshold;
|
|
@@ -1748,10 +1748,10 @@ contract Bridge is
|
|
|
1748
1748
|
external
|
|
1749
1749
|
view
|
|
1750
1750
|
returns (
|
|
1751
|
-
|
|
1752
|
-
|
|
1751
|
+
uint96 fraudChallengeDepositAmount,
|
|
1752
|
+
uint32 fraudChallengeDefeatTimeout,
|
|
1753
1753
|
uint96 fraudSlashingAmount,
|
|
1754
|
-
|
|
1754
|
+
uint32 fraudNotifierRewardMultiplier
|
|
1755
1755
|
)
|
|
1756
1756
|
{
|
|
1757
1757
|
fraudChallengeDepositAmount = self.fraudChallengeDepositAmount;
|
|
@@ -32,11 +32,11 @@ library BridgeState {
|
|
|
32
32
|
Bank bank;
|
|
33
33
|
// Bitcoin relay providing the current Bitcoin network difficulty.
|
|
34
34
|
IRelay relay;
|
|
35
|
-
// ECDSA Wallet Registry contract handle.
|
|
36
|
-
EcdsaWalletRegistry ecdsaWalletRegistry;
|
|
37
35
|
// The number of confirmations on the Bitcoin chain required to
|
|
38
36
|
// successfully evaluate an SPV proof.
|
|
39
|
-
|
|
37
|
+
uint96 txProofDifficultyFactor;
|
|
38
|
+
// ECDSA Wallet Registry contract handle.
|
|
39
|
+
EcdsaWalletRegistry ecdsaWalletRegistry;
|
|
40
40
|
// Address where the deposit and redemption treasury fees will be sent
|
|
41
41
|
// to. Treasury takes part in the operators rewarding process.
|
|
42
42
|
address treasury;
|
|
@@ -61,20 +61,10 @@ library BridgeState {
|
|
|
61
61
|
//
|
|
62
62
|
// This is a per-deposit input max fee for the sweep transaction.
|
|
63
63
|
uint64 depositTxMaxFee;
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
// and invalid deposits and the wallet is responsible for validating
|
|
69
|
-
// them before attempting to execute a sweep.
|
|
70
|
-
mapping(uint256 => Deposit.DepositRequest) deposits;
|
|
71
|
-
// Indicates if the vault with the given address is trusted or not.
|
|
72
|
-
// Depositors can route their revealed deposits only to trusted vaults
|
|
73
|
-
// and have trusted vaults notified about new deposits as soon as these
|
|
74
|
-
// deposits get swept. Vaults not trusted by the Bridge can still be
|
|
75
|
-
// used by Bank balance owners on their own responsibility - anyone can
|
|
76
|
-
// approve their Bank balance to any address.
|
|
77
|
-
mapping(address => bool) isVaultTrusted;
|
|
64
|
+
// Move movingFundsTxMaxTotalFee to the next storage slot for a more
|
|
65
|
+
// efficient variable layout
|
|
66
|
+
// slither-disable-next-line unused-state
|
|
67
|
+
bytes8 __depositAlignmentGap;
|
|
78
68
|
// Maximum amount of the total BTC transaction fee that is acceptable in
|
|
79
69
|
// a single moving funds transaction.
|
|
80
70
|
//
|
|
@@ -129,14 +119,7 @@ library BridgeState {
|
|
|
129
119
|
// The percentage of the notifier reward from the staking contract
|
|
130
120
|
// the notifier of a moved funds sweep timeout receives. The value is
|
|
131
121
|
// in the range [0, 100].
|
|
132
|
-
|
|
133
|
-
// Collection of all moved funds sweep requests indexed by
|
|
134
|
-
// `keccak256(movingFundsTxHash | movingFundsOutputIndex)`.
|
|
135
|
-
// The `movingFundsTxHash` is `bytes32` (ordered as in Bitcoin
|
|
136
|
-
// internally) and `movingFundsOutputIndex` an `uint32`. Each entry
|
|
137
|
-
// is actually an UTXO representing the moved funds and is supposed
|
|
138
|
-
// to be swept with the current main UTXO of the recipient wallet.
|
|
139
|
-
mapping(uint256 => MovingFunds.MovedFundsSweepRequest) movedFundsSweepRequests;
|
|
122
|
+
uint64 movedFundsSweepTimeoutNotifierRewardMultiplier;
|
|
140
123
|
// The minimal amount that can be requested for redemption.
|
|
141
124
|
// Value of this parameter must take into account the value of
|
|
142
125
|
// `redemptionTreasuryFeeDivisor` and `redemptionTxMaxFee`
|
|
@@ -162,68 +145,33 @@ library BridgeState {
|
|
|
162
145
|
// This is a per-redemption output max fee for the redemption
|
|
163
146
|
// transaction.
|
|
164
147
|
uint64 redemptionTxMaxFee;
|
|
148
|
+
// Move redemptionTimeout to the next storage slot for a more efficient
|
|
149
|
+
// variable layout
|
|
150
|
+
// slither-disable-next-line unused-state
|
|
151
|
+
bytes8 __redemptionAlignmentGap;
|
|
165
152
|
// Time after which the redemption request can be reported as
|
|
166
153
|
// timed out. It is counted from the moment when the redemption
|
|
167
154
|
// request was created via `requestRedemption` call. Reported
|
|
168
155
|
// timed out requests are cancelled and locked TBTC is returned
|
|
169
156
|
// to the redeemer in full amount.
|
|
170
|
-
|
|
157
|
+
uint64 redemptionTimeout;
|
|
171
158
|
// The amount of stake slashed from each member of a wallet for a
|
|
172
159
|
// redemption timeout.
|
|
173
160
|
uint96 redemptionTimeoutSlashingAmount;
|
|
174
161
|
// The percentage of the notifier reward from the staking contract
|
|
175
162
|
// the notifier of a redemption timeout receives. The value is in the
|
|
176
163
|
// range [0, 100].
|
|
177
|
-
|
|
178
|
-
// Collection of all pending redemption requests indexed by
|
|
179
|
-
// redemption key built as
|
|
180
|
-
// `keccak256(walletPubKeyHash | redeemerOutputScript)`.
|
|
181
|
-
// The `walletPubKeyHash` is the 20-byte wallet's public key hash
|
|
182
|
-
// (computed using Bitcoin HASH160 over the compressed ECDSA
|
|
183
|
-
// public key) and `redeemerOutputScript` is a Bitcoin script
|
|
184
|
-
// (P2PKH, P2WPKH, P2SH or P2WSH) that will be used to lock
|
|
185
|
-
// redeemed BTC as requested by the redeemer. Requests are added
|
|
186
|
-
// to this mapping by the `requestRedemption` method (duplicates
|
|
187
|
-
// not allowed) and are removed by one of the following methods:
|
|
188
|
-
// - `submitRedemptionProof` in case the request was handled
|
|
189
|
-
// successfully,
|
|
190
|
-
// - `notifyRedemptionTimeout` in case the request was reported
|
|
191
|
-
// to be timed out.
|
|
192
|
-
mapping(uint256 => Redemption.RedemptionRequest) pendingRedemptions;
|
|
193
|
-
// Collection of all timed out redemptions requests indexed by
|
|
194
|
-
// redemption key built as
|
|
195
|
-
// `keccak256(walletPubKeyHash | redeemerOutputScript)`. The
|
|
196
|
-
// `walletPubKeyHash` is the 20-byte wallet's public key hash
|
|
197
|
-
// (computed using Bitcoin HASH160 over the compressed ECDSA
|
|
198
|
-
// public key) and `redeemerOutputScript` is the Bitcoin script
|
|
199
|
-
// (P2PKH, P2WPKH, P2SH or P2WSH) that is involved in the timed
|
|
200
|
-
// out request. Timed out requests are stored in this mapping to
|
|
201
|
-
// avoid slashing the wallets multiple times for the same timeout.
|
|
202
|
-
// Only one method can add to this mapping:
|
|
203
|
-
// - `notifyRedemptionTimeout` which puts the redemption key to this
|
|
204
|
-
// mapping basing on a timed out request stored previously in
|
|
205
|
-
// `pendingRedemptions` mapping.
|
|
206
|
-
mapping(uint256 => Redemption.RedemptionRequest) timedOutRedemptions;
|
|
164
|
+
uint64 redemptionTimeoutNotifierRewardMultiplier;
|
|
207
165
|
// The amount of ETH in wei the party challenging the wallet for fraud
|
|
208
166
|
// needs to deposit.
|
|
209
|
-
|
|
167
|
+
uint96 fraudChallengeDepositAmount;
|
|
210
168
|
// The amount of time the wallet has to defeat a fraud challenge.
|
|
211
|
-
|
|
169
|
+
uint32 fraudChallengeDefeatTimeout;
|
|
212
170
|
// The amount of stake slashed from each member of a wallet for a fraud.
|
|
213
171
|
uint96 fraudSlashingAmount;
|
|
214
172
|
// The percentage of the notifier reward from the staking contract
|
|
215
173
|
// the notifier of a fraud receives. The value is in the range [0, 100].
|
|
216
|
-
|
|
217
|
-
// Collection of all submitted fraud challenges indexed by challenge
|
|
218
|
-
// key built as `keccak256(walletPublicKey|sighash)`.
|
|
219
|
-
mapping(uint256 => Fraud.FraudChallenge) fraudChallenges;
|
|
220
|
-
// Collection of main UTXOs that are honestly spent indexed by
|
|
221
|
-
// `keccak256(fundingTxHash | fundingOutputIndex)`. The `fundingTxHash`
|
|
222
|
-
// is `bytes32` (ordered as in Bitcoin internally) and
|
|
223
|
-
// `fundingOutputIndex` an `uint32`. A main UTXO is considered honestly
|
|
224
|
-
// spent if it was used as an input of a transaction that have been
|
|
225
|
-
// proven in the Bridge.
|
|
226
|
-
mapping(uint256 => bool) spentMainUTXOs;
|
|
174
|
+
uint32 fraudNotifierRewardMultiplier;
|
|
227
175
|
// Determines how frequently a new wallet creation can be requested.
|
|
228
176
|
// Value in seconds.
|
|
229
177
|
uint32 walletCreationPeriod;
|
|
@@ -259,6 +207,66 @@ library BridgeState {
|
|
|
259
207
|
// of deposit fraud challenges. This value is in seconds and should be
|
|
260
208
|
// greater than the deposit refund time plus some time margin.
|
|
261
209
|
uint32 walletClosingPeriod;
|
|
210
|
+
// Collection of all revealed deposits indexed by
|
|
211
|
+
// `keccak256(fundingTxHash | fundingOutputIndex)`.
|
|
212
|
+
// The `fundingTxHash` is `bytes32` (ordered as in Bitcoin internally)
|
|
213
|
+
// and `fundingOutputIndex` an `uint32`. This mapping may contain valid
|
|
214
|
+
// and invalid deposits and the wallet is responsible for validating
|
|
215
|
+
// them before attempting to execute a sweep.
|
|
216
|
+
mapping(uint256 => Deposit.DepositRequest) deposits;
|
|
217
|
+
// Indicates if the vault with the given address is trusted or not.
|
|
218
|
+
// Depositors can route their revealed deposits only to trusted vaults
|
|
219
|
+
// and have trusted vaults notified about new deposits as soon as these
|
|
220
|
+
// deposits get swept. Vaults not trusted by the Bridge can still be
|
|
221
|
+
// used by Bank balance owners on their own responsibility - anyone can
|
|
222
|
+
// approve their Bank balance to any address.
|
|
223
|
+
mapping(address => bool) isVaultTrusted;
|
|
224
|
+
// Collection of all moved funds sweep requests indexed by
|
|
225
|
+
// `keccak256(movingFundsTxHash | movingFundsOutputIndex)`.
|
|
226
|
+
// The `movingFundsTxHash` is `bytes32` (ordered as in Bitcoin
|
|
227
|
+
// internally) and `movingFundsOutputIndex` an `uint32`. Each entry
|
|
228
|
+
// is actually an UTXO representing the moved funds and is supposed
|
|
229
|
+
// to be swept with the current main UTXO of the recipient wallet.
|
|
230
|
+
mapping(uint256 => MovingFunds.MovedFundsSweepRequest) movedFundsSweepRequests;
|
|
231
|
+
// Collection of all pending redemption requests indexed by
|
|
232
|
+
// redemption key built as
|
|
233
|
+
// `keccak256(walletPubKeyHash | redeemerOutputScript)`.
|
|
234
|
+
// The `walletPubKeyHash` is the 20-byte wallet's public key hash
|
|
235
|
+
// (computed using Bitcoin HASH160 over the compressed ECDSA
|
|
236
|
+
// public key) and `redeemerOutputScript` is a Bitcoin script
|
|
237
|
+
// (P2PKH, P2WPKH, P2SH or P2WSH) that will be used to lock
|
|
238
|
+
// redeemed BTC as requested by the redeemer. Requests are added
|
|
239
|
+
// to this mapping by the `requestRedemption` method (duplicates
|
|
240
|
+
// not allowed) and are removed by one of the following methods:
|
|
241
|
+
// - `submitRedemptionProof` in case the request was handled
|
|
242
|
+
// successfully,
|
|
243
|
+
// - `notifyRedemptionTimeout` in case the request was reported
|
|
244
|
+
// to be timed out.
|
|
245
|
+
mapping(uint256 => Redemption.RedemptionRequest) pendingRedemptions;
|
|
246
|
+
// Collection of all timed out redemptions requests indexed by
|
|
247
|
+
// redemption key built as
|
|
248
|
+
// `keccak256(walletPubKeyHash | redeemerOutputScript)`. The
|
|
249
|
+
// `walletPubKeyHash` is the 20-byte wallet's public key hash
|
|
250
|
+
// (computed using Bitcoin HASH160 over the compressed ECDSA
|
|
251
|
+
// public key) and `redeemerOutputScript` is the Bitcoin script
|
|
252
|
+
// (P2PKH, P2WPKH, P2SH or P2WSH) that is involved in the timed
|
|
253
|
+
// out request. Timed out requests are stored in this mapping to
|
|
254
|
+
// avoid slashing the wallets multiple times for the same timeout.
|
|
255
|
+
// Only one method can add to this mapping:
|
|
256
|
+
// - `notifyRedemptionTimeout` which puts the redemption key to this
|
|
257
|
+
// mapping basing on a timed out request stored previously in
|
|
258
|
+
// `pendingRedemptions` mapping.
|
|
259
|
+
mapping(uint256 => Redemption.RedemptionRequest) timedOutRedemptions;
|
|
260
|
+
// Collection of all submitted fraud challenges indexed by challenge
|
|
261
|
+
// key built as `keccak256(walletPublicKey|sighash)`.
|
|
262
|
+
mapping(uint256 => Fraud.FraudChallenge) fraudChallenges;
|
|
263
|
+
// Collection of main UTXOs that are honestly spent indexed by
|
|
264
|
+
// `keccak256(fundingTxHash | fundingOutputIndex)`. The `fundingTxHash`
|
|
265
|
+
// is `bytes32` (ordered as in Bitcoin internally) and
|
|
266
|
+
// `fundingOutputIndex` an `uint32`. A main UTXO is considered honestly
|
|
267
|
+
// spent if it was used as an input of a transaction that have been
|
|
268
|
+
// proven in the Bridge.
|
|
269
|
+
mapping(uint256 => bool) spentMainUTXOs;
|
|
262
270
|
// Maps the 20-byte wallet public key hash (computed using Bitcoin
|
|
263
271
|
// HASH160 over the compressed ECDSA public key) to the basic wallet
|
|
264
272
|
// information like state and pending redemptions value.
|
|
@@ -425,9 +433,9 @@ library BridgeState {
|
|
|
425
433
|
uint64 _redemptionDustThreshold,
|
|
426
434
|
uint64 _redemptionTreasuryFeeDivisor,
|
|
427
435
|
uint64 _redemptionTxMaxFee,
|
|
428
|
-
|
|
436
|
+
uint64 _redemptionTimeout,
|
|
429
437
|
uint96 _redemptionTimeoutSlashingAmount,
|
|
430
|
-
|
|
438
|
+
uint64 _redemptionTimeoutNotifierRewardMultiplier
|
|
431
439
|
) internal {
|
|
432
440
|
require(
|
|
433
441
|
_redemptionDustThreshold > self.movingFundsDustThreshold,
|
|
@@ -546,7 +554,7 @@ library BridgeState {
|
|
|
546
554
|
uint64 _movedFundsSweepTxMaxTotalFee,
|
|
547
555
|
uint32 _movedFundsSweepTimeout,
|
|
548
556
|
uint96 _movedFundsSweepTimeoutSlashingAmount,
|
|
549
|
-
|
|
557
|
+
uint64 _movedFundsSweepTimeoutNotifierRewardMultiplier
|
|
550
558
|
) internal {
|
|
551
559
|
require(
|
|
552
560
|
_movingFundsTxMaxTotalFee > 0,
|
|
@@ -709,10 +717,10 @@ library BridgeState {
|
|
|
709
717
|
/// - Fraud notifier reward multiplier must be in the range [0, 100].
|
|
710
718
|
function updateFraudParameters(
|
|
711
719
|
Storage storage self,
|
|
712
|
-
|
|
713
|
-
|
|
720
|
+
uint96 _fraudChallengeDepositAmount,
|
|
721
|
+
uint32 _fraudChallengeDefeatTimeout,
|
|
714
722
|
uint96 _fraudSlashingAmount,
|
|
715
|
-
|
|
723
|
+
uint32 _fraudNotifierRewardMultiplier
|
|
716
724
|
) internal {
|
|
717
725
|
require(
|
|
718
726
|
_fraudChallengeDefeatTimeout > 0,
|
|
@@ -149,6 +149,9 @@ library DepositSweep {
|
|
|
149
149
|
BitcoinTx.UTXO calldata mainUtxo,
|
|
150
150
|
address vault
|
|
151
151
|
) external {
|
|
152
|
+
// Wallet state validation is performed in the
|
|
153
|
+
// `resolveDepositSweepingWallet` function.
|
|
154
|
+
|
|
152
155
|
// The actual transaction proof is performed here. After that point, we
|
|
153
156
|
// can assume the transaction happened on Bitcoin chain and has
|
|
154
157
|
// a sufficient number of confirmations as determined by
|
|
@@ -384,6 +384,8 @@ library Fraud {
|
|
|
384
384
|
uint32[] calldata walletMembersIDs,
|
|
385
385
|
bytes memory preimageSha256
|
|
386
386
|
) external {
|
|
387
|
+
// Wallet state is validated in `notifyWalletFraudChallengeDefeatTimeout`.
|
|
388
|
+
|
|
387
389
|
bytes32 sighash = sha256(preimageSha256);
|
|
388
390
|
|
|
389
391
|
uint256 challengeKey = uint256(
|
|
@@ -421,38 +423,11 @@ library Fraud {
|
|
|
421
423
|
);
|
|
422
424
|
bytes20 walletPubKeyHash = compressedWalletPublicKey.hash160View();
|
|
423
425
|
|
|
424
|
-
|
|
425
|
-
walletPubKeyHash
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
if (
|
|
431
|
-
walletState == Wallets.WalletState.Live ||
|
|
432
|
-
walletState == Wallets.WalletState.MovingFunds ||
|
|
433
|
-
walletState == Wallets.WalletState.Closing
|
|
434
|
-
) {
|
|
435
|
-
self.ecdsaWalletRegistry.seize(
|
|
436
|
-
self.fraudSlashingAmount,
|
|
437
|
-
self.fraudNotifierRewardMultiplier,
|
|
438
|
-
challenge.challenger,
|
|
439
|
-
wallet.ecdsaWalletID,
|
|
440
|
-
walletMembersIDs
|
|
441
|
-
);
|
|
442
|
-
|
|
443
|
-
self.terminateWallet(walletPubKeyHash);
|
|
444
|
-
} else if (walletState == Wallets.WalletState.Terminated) {
|
|
445
|
-
// This is a special case when the wallet was already terminated
|
|
446
|
-
// due to a previous deliberate protocol violation. In that
|
|
447
|
-
// case, this function should be still callable for other fraud
|
|
448
|
-
// challenges timeouts in order to let the challenger unlock its
|
|
449
|
-
// ETH deposit back. However, the wallet termination logic is
|
|
450
|
-
// not called and the challenger is not rewarded.
|
|
451
|
-
} else {
|
|
452
|
-
revert(
|
|
453
|
-
"Wallet must be in Live or MovingFunds or Closing or Terminated state"
|
|
454
|
-
);
|
|
455
|
-
}
|
|
426
|
+
self.notifyWalletFraudChallengeDefeatTimeout(
|
|
427
|
+
walletPubKeyHash,
|
|
428
|
+
walletMembersIDs,
|
|
429
|
+
challenge.challenger
|
|
430
|
+
);
|
|
456
431
|
|
|
457
432
|
// slither-disable-next-line reentrancy-events
|
|
458
433
|
emit FraudChallengeDefeatTimedOut(walletPubKeyHash, sighash);
|
|
@@ -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
|
-
|
|
552
|
-
walletPubKeyHash
|
|
553
|
-
];
|
|
571
|
+
// Wallet state is validated in `notifyWalletMovingFundsTimeout`.
|
|
554
572
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
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,
|