@keep-network/tbtc-v2 0.1.1-dev.97 → 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 +25 -25
- 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 +7 -7
- package/artifacts/solcInputs/{5e62cff1ead0900b07facca4b559e818.json → becdd5668a2170e95004d124119e4fcb.json} +6 -6
- 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 +68 -68
- 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 +12 -12
- package/contracts/bridge/BridgeState.sol +83 -75
- package/contracts/bridge/Redemption.sol +84 -48
- package/export.json +12 -12
- 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);
|
|
@@ -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,
|
|
@@ -424,16 +424,14 @@ library Redemption {
|
|
|
424
424
|
);
|
|
425
425
|
|
|
426
426
|
// Validate if redeemer output script is a correct standard type
|
|
427
|
-
// (P2PKH, P2WPKH, P2SH or P2WSH). This is done by
|
|
428
|
-
//
|
|
429
|
-
//
|
|
430
|
-
//
|
|
431
|
-
//
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
.encodePacked(bytes8(0), redeemerOutputScript)
|
|
436
|
-
.extractHash();
|
|
427
|
+
// (P2PKH, P2WPKH, P2SH or P2WSH). This is done by using
|
|
428
|
+
// `BTCUtils.extractHashAt` on it. Such a function extracts the payload
|
|
429
|
+
// properly only from standard outputs so if it succeeds, we have a
|
|
430
|
+
// guarantee the redeemer output script is proper. The underlying way
|
|
431
|
+
// of validation is the same as in tBTC v1.
|
|
432
|
+
bytes memory redeemerOutputScriptPayload = redeemerOutputScript
|
|
433
|
+
.extractHashAt(0, redeemerOutputScript.length);
|
|
434
|
+
|
|
437
435
|
require(
|
|
438
436
|
redeemerOutputScriptPayload.length > 0,
|
|
439
437
|
"Redeemer output script must be a standard type"
|
|
@@ -441,8 +439,8 @@ library Redemption {
|
|
|
441
439
|
// Check if the redeemer output script payload does not point to the
|
|
442
440
|
// wallet public key hash.
|
|
443
441
|
require(
|
|
444
|
-
|
|
445
|
-
|
|
442
|
+
redeemerOutputScriptPayload.length != 20 ||
|
|
443
|
+
walletPubKeyHash != redeemerOutputScriptPayload.slice20(0),
|
|
446
444
|
"Redeemer output script must not point to the wallet PKH"
|
|
447
445
|
);
|
|
448
446
|
|
|
@@ -455,8 +453,9 @@ library Redemption {
|
|
|
455
453
|
// and redeemer output script pair. That means there can be only one
|
|
456
454
|
// request asking for redemption from the given wallet to the given
|
|
457
455
|
// BTC script at the same time.
|
|
458
|
-
uint256 redemptionKey =
|
|
459
|
-
|
|
456
|
+
uint256 redemptionKey = getRedemptionKey(
|
|
457
|
+
walletPubKeyHash,
|
|
458
|
+
redeemerOutputScript
|
|
460
459
|
);
|
|
461
460
|
|
|
462
461
|
// Check if given redemption key is not used by a pending redemption.
|
|
@@ -497,6 +496,7 @@ library Redemption {
|
|
|
497
496
|
uint32(block.timestamp)
|
|
498
497
|
);
|
|
499
498
|
|
|
499
|
+
// slither-disable-next-line reentrancy-events
|
|
500
500
|
emit RedemptionRequested(
|
|
501
501
|
walletPubKeyHash,
|
|
502
502
|
redeemerOutputScript,
|
|
@@ -674,7 +674,7 @@ library Redemption {
|
|
|
674
674
|
/// must be validated using e.g. `BTCUtils.validateVout` function
|
|
675
675
|
/// before it is passed here.
|
|
676
676
|
/// @param walletPubKeyHash 20-byte public key hash (computed using Bitcoin
|
|
677
|
-
|
|
677
|
+
/// HASH160 over the compressed ECDSA public key) of the wallet which
|
|
678
678
|
/// performed the redemption transaction.
|
|
679
679
|
/// @return info Outcomes of the processing.
|
|
680
680
|
function processRedemptionTxOutputs(
|
|
@@ -722,7 +722,7 @@ library Redemption {
|
|
|
722
722
|
// which matches the P2PKH structure as per:
|
|
723
723
|
// https://en.bitcoin.it/wiki/Transaction#Pay-to-PubkeyHash
|
|
724
724
|
bytes32 walletP2PKHScriptKeccak = keccak256(
|
|
725
|
-
abi.encodePacked(
|
|
725
|
+
abi.encodePacked(BitcoinTx.makeP2PKHScript(walletPubKeyHash))
|
|
726
726
|
);
|
|
727
727
|
// The P2WPKH script has the byte format: <0x160014> <20-byte PKH>.
|
|
728
728
|
// According to https://en.bitcoin.it/wiki/Script#Opcodes this translates to:
|
|
@@ -732,7 +732,7 @@ library Redemption {
|
|
|
732
732
|
// which matches the P2WPKH structure as per:
|
|
733
733
|
// https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#P2WPKH
|
|
734
734
|
bytes32 walletP2WPKHScriptKeccak = keccak256(
|
|
735
|
-
abi.encodePacked(
|
|
735
|
+
abi.encodePacked(BitcoinTx.makeP2WPKHScript(walletPubKeyHash))
|
|
736
736
|
);
|
|
737
737
|
|
|
738
738
|
return
|
|
@@ -751,7 +751,7 @@ library Redemption {
|
|
|
751
751
|
|
|
752
752
|
/// @notice Processes all outputs from the redemption transaction. Tries to
|
|
753
753
|
/// identify output as a change output, pending redemption request
|
|
754
|
-
|
|
754
|
+
/// or reported redemption. Reverts if one of the outputs cannot be
|
|
755
755
|
/// recognized properly. Marks each request as processed by removing
|
|
756
756
|
/// them from `pendingRedemptions` mapping.
|
|
757
757
|
/// @param redemptionTxOutputVector Bitcoin redemption transaction output
|
|
@@ -759,7 +759,7 @@ library Redemption {
|
|
|
759
759
|
/// must be validated using e.g. `BTCUtils.validateVout` function
|
|
760
760
|
/// before it is passed here.
|
|
761
761
|
/// @param walletPubKeyHash 20-byte public key hash (computed using Bitcoin
|
|
762
|
-
|
|
762
|
+
/// HASH160 over the compressed ECDSA public key) of the wallet which
|
|
763
763
|
/// performed the redemption transaction.
|
|
764
764
|
/// @param processInfo RedemptionTxOutputsProcessingInfo identifying output
|
|
765
765
|
/// starting index, the number of outputs and possible wallet change
|
|
@@ -783,24 +783,33 @@ library Redemption {
|
|
|
783
783
|
// https://github.com/keep-network/tbtc-v2/issues/257
|
|
784
784
|
uint256 outputLength = redemptionTxOutputVector
|
|
785
785
|
.determineOutputLengthAt(processInfo.outputStartingIndex);
|
|
786
|
-
bytes memory output = redemptionTxOutputVector.slice(
|
|
787
|
-
processInfo.outputStartingIndex,
|
|
788
|
-
outputLength
|
|
789
|
-
);
|
|
790
786
|
|
|
791
787
|
// Extract the value from given output.
|
|
792
|
-
uint64 outputValue =
|
|
788
|
+
uint64 outputValue = redemptionTxOutputVector.extractValueAt(
|
|
789
|
+
processInfo.outputStartingIndex
|
|
790
|
+
);
|
|
791
|
+
|
|
792
|
+
uint256 scriptLength = outputLength - 8;
|
|
793
|
+
|
|
793
794
|
// The output consists of an 8-byte value and a variable length
|
|
794
|
-
// script. To
|
|
795
|
+
// script. To hash that script we slice the output starting from
|
|
795
796
|
// 9th byte until the end.
|
|
796
|
-
|
|
797
|
+
|
|
798
|
+
uint256 outputScriptStart = processInfo.outputStartingIndex + 8;
|
|
799
|
+
|
|
800
|
+
bytes32 outputScriptHash;
|
|
801
|
+
/* solhint-disable-next-line no-inline-assembly */
|
|
802
|
+
assembly {
|
|
803
|
+
outputScriptHash := keccak256(
|
|
804
|
+
add(redemptionTxOutputVector, add(outputScriptStart, 32)),
|
|
805
|
+
scriptLength
|
|
806
|
+
)
|
|
807
|
+
}
|
|
797
808
|
|
|
798
809
|
if (
|
|
799
810
|
resultInfo.changeValue == 0 &&
|
|
800
|
-
(
|
|
801
|
-
processInfo.
|
|
802
|
-
keccak256(outputScript) ==
|
|
803
|
-
processInfo.walletP2WPKHScriptKeccak) &&
|
|
811
|
+
(outputScriptHash == processInfo.walletP2PKHScriptKeccak ||
|
|
812
|
+
outputScriptHash == processInfo.walletP2WPKHScriptKeccak) &&
|
|
804
813
|
outputValue > 0
|
|
805
814
|
) {
|
|
806
815
|
// If we entered here, that means the change output with a
|
|
@@ -815,8 +824,7 @@ library Redemption {
|
|
|
815
824
|
uint64 treasuryFee
|
|
816
825
|
) = processNonChangeRedemptionTxOutput(
|
|
817
826
|
self,
|
|
818
|
-
walletPubKeyHash,
|
|
819
|
-
outputScript,
|
|
827
|
+
_getRedemptionKey(walletPubKeyHash, outputScriptHash),
|
|
820
828
|
outputValue
|
|
821
829
|
);
|
|
822
830
|
resultInfo.totalBurnableValue += burnableValue;
|
|
@@ -847,10 +855,7 @@ library Redemption {
|
|
|
847
855
|
/// requested and reported timed-out redemption.
|
|
848
856
|
/// This function also marks each pending request as processed by
|
|
849
857
|
/// removing them from `pendingRedemptions` mapping.
|
|
850
|
-
/// @param
|
|
851
|
-
// HASH160 over the compressed ECDSA public key) of the wallet which
|
|
852
|
-
/// performed the redemption transaction.
|
|
853
|
-
/// @param outputScript Non-change output script to be processed.
|
|
858
|
+
/// @param redemptionKey Redemption key of the output being processed.
|
|
854
859
|
/// @param outputValue Value of the output being processed.
|
|
855
860
|
/// @return burnableValue The value burnable as a result of processing this
|
|
856
861
|
/// single redemption output. This value needs to be summed up with
|
|
@@ -864,17 +869,9 @@ library Redemption {
|
|
|
864
869
|
/// redemption request.
|
|
865
870
|
function processNonChangeRedemptionTxOutput(
|
|
866
871
|
BridgeState.Storage storage self,
|
|
867
|
-
|
|
868
|
-
bytes memory outputScript,
|
|
872
|
+
uint256 redemptionKey,
|
|
869
873
|
uint64 outputValue
|
|
870
874
|
) internal returns (uint64 burnableValue, uint64 treasuryFee) {
|
|
871
|
-
// This function should be called only if the given output is
|
|
872
|
-
// supposed to represent a redemption. Build the redemption key
|
|
873
|
-
// to perform that check.
|
|
874
|
-
uint256 redemptionKey = uint256(
|
|
875
|
-
keccak256(abi.encodePacked(walletPubKeyHash, outputScript))
|
|
876
|
-
);
|
|
877
|
-
|
|
878
875
|
if (self.pendingRedemptions[redemptionKey].requestedAt != 0) {
|
|
879
876
|
// If we entered here, that means the output was identified
|
|
880
877
|
// as a pending redemption request.
|
|
@@ -975,9 +972,9 @@ library Redemption {
|
|
|
975
972
|
bytes calldata redeemerOutputScript
|
|
976
973
|
) external {
|
|
977
974
|
// Wallet state is validated in `notifyWalletRedemptionTimeout`.
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
975
|
+
uint256 redemptionKey = getRedemptionKey(
|
|
976
|
+
walletPubKeyHash,
|
|
977
|
+
redeemerOutputScript
|
|
981
978
|
);
|
|
982
979
|
Redemption.RedemptionRequest memory request = self.pendingRedemptions[
|
|
983
980
|
redemptionKey
|
|
@@ -1017,4 +1014,43 @@ library Redemption {
|
|
|
1017
1014
|
// Return the requested amount of tokens to the redeemer
|
|
1018
1015
|
self.bank.transferBalance(request.redeemer, request.requestedAmount);
|
|
1019
1016
|
}
|
|
1017
|
+
|
|
1018
|
+
/// @notice Calculate redemption key without allocations.
|
|
1019
|
+
/// @param walletPubKeyHash the pubkey hash of the wallet.
|
|
1020
|
+
/// @param script the output script of the redemption.
|
|
1021
|
+
/// @return The key = keccak256(keccak256(script), walletPubKeyHash).
|
|
1022
|
+
function getRedemptionKey(bytes20 walletPubKeyHash, bytes memory script)
|
|
1023
|
+
internal
|
|
1024
|
+
pure
|
|
1025
|
+
returns (uint256)
|
|
1026
|
+
{
|
|
1027
|
+
bytes32 scriptHash = keccak256(script);
|
|
1028
|
+
uint256 key;
|
|
1029
|
+
/* solhint-disable-next-line no-inline-assembly */
|
|
1030
|
+
assembly {
|
|
1031
|
+
mstore(0, scriptHash)
|
|
1032
|
+
mstore(32, walletPubKeyHash)
|
|
1033
|
+
key := keccak256(0, 52)
|
|
1034
|
+
}
|
|
1035
|
+
return key;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/// @notice Finish calculating redemption key without allocations.
|
|
1039
|
+
/// @param walletPubKeyHash the pubkey hash of the wallet.
|
|
1040
|
+
/// @param scriptHash the output script hash of the redemption.
|
|
1041
|
+
/// @return The key = keccak256(scriptHash, walletPubKeyHash).
|
|
1042
|
+
function _getRedemptionKey(bytes20 walletPubKeyHash, bytes32 scriptHash)
|
|
1043
|
+
internal
|
|
1044
|
+
pure
|
|
1045
|
+
returns (uint256)
|
|
1046
|
+
{
|
|
1047
|
+
uint256 key;
|
|
1048
|
+
/* solhint-disable-next-line no-inline-assembly */
|
|
1049
|
+
assembly {
|
|
1050
|
+
mstore(0, scriptHash)
|
|
1051
|
+
mstore(32, walletPubKeyHash)
|
|
1052
|
+
key := keccak256(0, 52)
|
|
1053
|
+
}
|
|
1054
|
+
return key;
|
|
1055
|
+
}
|
|
1020
1056
|
}
|
package/export.json
CHANGED
|
@@ -15085,11 +15085,11 @@
|
|
|
15085
15085
|
"inputs": [],
|
|
15086
15086
|
"outputs": [
|
|
15087
15087
|
{
|
|
15088
|
-
"type": "
|
|
15088
|
+
"type": "uint96",
|
|
15089
15089
|
"name": "fraudChallengeDepositAmount"
|
|
15090
15090
|
},
|
|
15091
15091
|
{
|
|
15092
|
-
"type": "
|
|
15092
|
+
"type": "uint32",
|
|
15093
15093
|
"name": "fraudChallengeDefeatTimeout"
|
|
15094
15094
|
},
|
|
15095
15095
|
{
|
|
@@ -15097,7 +15097,7 @@
|
|
|
15097
15097
|
"name": "fraudSlashingAmount"
|
|
15098
15098
|
},
|
|
15099
15099
|
{
|
|
15100
|
-
"type": "
|
|
15100
|
+
"type": "uint32",
|
|
15101
15101
|
"name": "fraudNotifierRewardMultiplier"
|
|
15102
15102
|
}
|
|
15103
15103
|
]
|
|
@@ -15140,7 +15140,7 @@
|
|
|
15140
15140
|
"name": "_ecdsaWalletRegistry"
|
|
15141
15141
|
},
|
|
15142
15142
|
{
|
|
15143
|
-
"type": "
|
|
15143
|
+
"type": "uint96",
|
|
15144
15144
|
"name": "_txProofDifficultyFactor"
|
|
15145
15145
|
}
|
|
15146
15146
|
],
|
|
@@ -15514,7 +15514,7 @@
|
|
|
15514
15514
|
"name": "redemptionTxMaxFee"
|
|
15515
15515
|
},
|
|
15516
15516
|
{
|
|
15517
|
-
"type": "
|
|
15517
|
+
"type": "uint64",
|
|
15518
15518
|
"name": "redemptionTimeout"
|
|
15519
15519
|
},
|
|
15520
15520
|
{
|
|
@@ -15522,7 +15522,7 @@
|
|
|
15522
15522
|
"name": "redemptionTimeoutSlashingAmount"
|
|
15523
15523
|
},
|
|
15524
15524
|
{
|
|
15525
|
-
"type": "
|
|
15525
|
+
"type": "uint64",
|
|
15526
15526
|
"name": "redemptionTimeoutNotifierRewardMultiplier"
|
|
15527
15527
|
}
|
|
15528
15528
|
]
|
|
@@ -16190,11 +16190,11 @@
|
|
|
16190
16190
|
"gas": 29000000,
|
|
16191
16191
|
"inputs": [
|
|
16192
16192
|
{
|
|
16193
|
-
"type": "
|
|
16193
|
+
"type": "uint96",
|
|
16194
16194
|
"name": "fraudChallengeDepositAmount"
|
|
16195
16195
|
},
|
|
16196
16196
|
{
|
|
16197
|
-
"type": "
|
|
16197
|
+
"type": "uint32",
|
|
16198
16198
|
"name": "fraudChallengeDefeatTimeout"
|
|
16199
16199
|
},
|
|
16200
16200
|
{
|
|
@@ -16202,7 +16202,7 @@
|
|
|
16202
16202
|
"name": "fraudSlashingAmount"
|
|
16203
16203
|
},
|
|
16204
16204
|
{
|
|
16205
|
-
"type": "
|
|
16205
|
+
"type": "uint32",
|
|
16206
16206
|
"name": "fraudNotifierRewardMultiplier"
|
|
16207
16207
|
}
|
|
16208
16208
|
],
|
|
@@ -16252,7 +16252,7 @@
|
|
|
16252
16252
|
"name": "movedFundsSweepTimeoutSlashingAmount"
|
|
16253
16253
|
},
|
|
16254
16254
|
{
|
|
16255
|
-
"type": "
|
|
16255
|
+
"type": "uint64",
|
|
16256
16256
|
"name": "movedFundsSweepTimeoutNotifierRewardMultiplier"
|
|
16257
16257
|
}
|
|
16258
16258
|
],
|
|
@@ -16278,7 +16278,7 @@
|
|
|
16278
16278
|
"name": "redemptionTxMaxFee"
|
|
16279
16279
|
},
|
|
16280
16280
|
{
|
|
16281
|
-
"type": "
|
|
16281
|
+
"type": "uint64",
|
|
16282
16282
|
"name": "redemptionTimeout"
|
|
16283
16283
|
},
|
|
16284
16284
|
{
|
|
@@ -16286,7 +16286,7 @@
|
|
|
16286
16286
|
"name": "redemptionTimeoutSlashingAmount"
|
|
16287
16287
|
},
|
|
16288
16288
|
{
|
|
16289
|
-
"type": "
|
|
16289
|
+
"type": "uint64",
|
|
16290
16290
|
"name": "redemptionTimeoutNotifierRewardMultiplier"
|
|
16291
16291
|
}
|
|
16292
16292
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keep-network/tbtc-v2",
|
|
3
|
-
"version": "0.1.1-dev.
|
|
3
|
+
"version": "0.1.1-dev.98+main.f6402ddc3a00709426dc87405c889b433f8aef6b",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"artifacts/",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"prepublishOnly": "./scripts/prepare-artifacts.sh --network $npm_config_network"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@keep-network/bitcoin-spv-sol": "3.
|
|
30
|
+
"@keep-network/bitcoin-spv-sol": "3.4.0-solc-0.8",
|
|
31
31
|
"@keep-network/ecdsa": "development",
|
|
32
32
|
"@keep-network/random-beacon": "development",
|
|
33
33
|
"@keep-network/tbtc": ">1.1.2-dev <1.1.2-pre",
|