@keep-network/tbtc-v2 0.1.1-dev.20 → 0.1.1-dev.23
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/TBTC.json +3 -3
- package/artifacts/TBTCToken.json +3 -3
- package/artifacts/VendingMachine.json +10 -10
- package/artifacts/solcInputs/{5c08a447a71edda5755711e12ca577ad.json → f4cbe9fa0e3015c189ba0e793fa17f51.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/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +1 -1
- package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.json +89 -3
- package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
- package/build/contracts/bridge/Bridge.sol/Bridge.json +43 -4
- package/build/contracts/bridge/Bridge.sol/IRelay.dbg.json +1 -1
- package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
- 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/BitcoinTx.sol +107 -2
- package/contracts/bridge/Bridge.sol +97 -116
- package/package.json +2 -1
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
|
|
16
16
|
pragma solidity ^0.8.9;
|
|
17
17
|
|
|
18
|
+
import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
|
|
19
|
+
import {ValidateSPV} from "@keep-network/bitcoin-spv-sol/contracts/ValidateSPV.sol";
|
|
20
|
+
|
|
18
21
|
/// @title Bitcoin transaction
|
|
19
22
|
/// @notice Allows to reference Bitcoin raw transaction in Solidity.
|
|
20
23
|
/// @dev See https://developer.bitcoin.org/reference/transactions.html#raw-transaction-format
|
|
@@ -69,8 +72,12 @@ pragma solidity ^0.8.9;
|
|
|
69
72
|
/// (*) compactSize uint is often references as VarInt)
|
|
70
73
|
///
|
|
71
74
|
library BitcoinTx {
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
using BTCUtils for bytes;
|
|
76
|
+
using BTCUtils for uint256;
|
|
77
|
+
using ValidateSPV for bytes;
|
|
78
|
+
using ValidateSPV for bytes32;
|
|
79
|
+
|
|
80
|
+
/// @notice Represents Bitcoin transaction data.
|
|
74
81
|
struct Info {
|
|
75
82
|
/// @notice Bitcoin transaction version
|
|
76
83
|
/// @dev `version` from raw Bitcon transaction data.
|
|
@@ -113,6 +120,17 @@ library BitcoinTx {
|
|
|
113
120
|
bytes bitcoinHeaders;
|
|
114
121
|
}
|
|
115
122
|
|
|
123
|
+
/// @notice Determines the difficulty context for a Bitcoin SPV proof.
|
|
124
|
+
struct ProofDifficulty {
|
|
125
|
+
/// @notice Difficulty of the current epoch.
|
|
126
|
+
uint256 currentEpochDifficulty;
|
|
127
|
+
/// @notice Difficulty of the previous epoch.
|
|
128
|
+
uint256 previousEpochDifficulty;
|
|
129
|
+
/// @notice The number of confirmations on the Bitcoin chain required
|
|
130
|
+
/// to successfully evaluate an SPV proof.
|
|
131
|
+
uint256 difficultyFactor;
|
|
132
|
+
}
|
|
133
|
+
|
|
116
134
|
/// @notice Represents info about an unspent transaction output.
|
|
117
135
|
struct UTXO {
|
|
118
136
|
/// @notice Hash of the transaction the output belongs to.
|
|
@@ -123,4 +141,91 @@ library BitcoinTx {
|
|
|
123
141
|
/// @notice Value of the transaction output.
|
|
124
142
|
uint64 txOutputValue;
|
|
125
143
|
}
|
|
144
|
+
|
|
145
|
+
/// @notice Validates the SPV proof of the Bitcoin transaction.
|
|
146
|
+
/// Reverts in case the validation or proof verification fail.
|
|
147
|
+
/// @param txInfo Bitcoin transaction data
|
|
148
|
+
/// @param proof Bitcoin proof data
|
|
149
|
+
/// @param proofDifficulty Bitcoin proof difficulty context.
|
|
150
|
+
/// @return txHash Proven 32-byte transaction hash.
|
|
151
|
+
function validateProof(
|
|
152
|
+
Info calldata txInfo,
|
|
153
|
+
Proof calldata proof,
|
|
154
|
+
ProofDifficulty calldata proofDifficulty
|
|
155
|
+
) external view returns (bytes32 txHash) {
|
|
156
|
+
require(
|
|
157
|
+
txInfo.inputVector.validateVin(),
|
|
158
|
+
"Invalid input vector provided"
|
|
159
|
+
);
|
|
160
|
+
require(
|
|
161
|
+
txInfo.outputVector.validateVout(),
|
|
162
|
+
"Invalid output vector provided"
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
txHash = abi
|
|
166
|
+
.encodePacked(
|
|
167
|
+
txInfo.version,
|
|
168
|
+
txInfo.inputVector,
|
|
169
|
+
txInfo.outputVector,
|
|
170
|
+
txInfo.locktime
|
|
171
|
+
)
|
|
172
|
+
.hash256View();
|
|
173
|
+
|
|
174
|
+
require(
|
|
175
|
+
txHash.prove(
|
|
176
|
+
proof.bitcoinHeaders.extractMerkleRootLE(),
|
|
177
|
+
proof.merkleProof,
|
|
178
|
+
proof.txIndexInBlock
|
|
179
|
+
),
|
|
180
|
+
"Tx merkle proof is not valid for provided header and tx hash"
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
evaluateProofDifficulty(proof.bitcoinHeaders, proofDifficulty);
|
|
184
|
+
|
|
185
|
+
return txHash;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/// @notice Evaluates the given Bitcoin proof difficulty against the actual
|
|
189
|
+
/// Bitcoin chain difficulty provided by the relay oracle.
|
|
190
|
+
/// Reverts in case the evaluation fails.
|
|
191
|
+
/// @param bitcoinHeaders Bitcoin headers chain being part of the SPV
|
|
192
|
+
/// proof. Used to extract the observed proof difficulty
|
|
193
|
+
/// @param proofDifficulty Bitcoin proof difficulty context.
|
|
194
|
+
function evaluateProofDifficulty(
|
|
195
|
+
bytes memory bitcoinHeaders,
|
|
196
|
+
ProofDifficulty calldata proofDifficulty
|
|
197
|
+
) internal view {
|
|
198
|
+
uint256 requestedDiff = 0;
|
|
199
|
+
uint256 firstHeaderDiff = bitcoinHeaders
|
|
200
|
+
.extractTarget()
|
|
201
|
+
.calculateDifficulty();
|
|
202
|
+
|
|
203
|
+
if (firstHeaderDiff == proofDifficulty.currentEpochDifficulty) {
|
|
204
|
+
requestedDiff = proofDifficulty.currentEpochDifficulty;
|
|
205
|
+
} else if (firstHeaderDiff == proofDifficulty.previousEpochDifficulty) {
|
|
206
|
+
requestedDiff = proofDifficulty.previousEpochDifficulty;
|
|
207
|
+
} else {
|
|
208
|
+
revert("Not at current or previous difficulty");
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
uint256 observedDiff = bitcoinHeaders.validateHeaderChain();
|
|
212
|
+
|
|
213
|
+
require(
|
|
214
|
+
observedDiff != ValidateSPV.getErrBadLength(),
|
|
215
|
+
"Invalid length of the headers chain"
|
|
216
|
+
);
|
|
217
|
+
require(
|
|
218
|
+
observedDiff != ValidateSPV.getErrInvalidChain(),
|
|
219
|
+
"Invalid headers chain"
|
|
220
|
+
);
|
|
221
|
+
require(
|
|
222
|
+
observedDiff != ValidateSPV.getErrLowWork(),
|
|
223
|
+
"Insufficient work in a header"
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
require(
|
|
227
|
+
observedDiff >= requestedDiff * proofDifficulty.difficultyFactor,
|
|
228
|
+
"Insufficient accumulated difficulty in header chain"
|
|
229
|
+
);
|
|
230
|
+
}
|
|
126
231
|
}
|
|
@@ -19,7 +19,6 @@ import "@openzeppelin/contracts/access/Ownable.sol";
|
|
|
19
19
|
|
|
20
20
|
import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
|
|
21
21
|
import {BytesLib} from "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
|
|
22
|
-
import {ValidateSPV} from "@keep-network/bitcoin-spv-sol/contracts/ValidateSPV.sol";
|
|
23
22
|
|
|
24
23
|
import "../bank/Bank.sol";
|
|
25
24
|
import "./BitcoinTx.sol";
|
|
@@ -59,8 +58,6 @@ contract Bridge is Ownable {
|
|
|
59
58
|
using BTCUtils for bytes;
|
|
60
59
|
using BTCUtils for uint256;
|
|
61
60
|
using BytesLib for bytes;
|
|
62
|
-
using ValidateSPV for bytes;
|
|
63
|
-
using ValidateSPV for bytes32;
|
|
64
61
|
|
|
65
62
|
/// @notice Represents data which must be revealed by the depositor during
|
|
66
63
|
/// deposit reveal.
|
|
@@ -215,13 +212,21 @@ contract Bridge is Ownable {
|
|
|
215
212
|
/// Treasury takes part in the operators rewarding process.
|
|
216
213
|
address public immutable treasury;
|
|
217
214
|
|
|
215
|
+
/// TODO: Make it governable.
|
|
216
|
+
/// @notice The minimal amount that can be requested for deposit.
|
|
217
|
+
/// Value of this parameter must take into account the value of
|
|
218
|
+
/// `depositTreasuryFeeDivisor` and `depositTxMaxFee`
|
|
219
|
+
/// parameters in order to make requests that can incur the
|
|
220
|
+
/// treasury and transaction fee and still satisfy the depositor.
|
|
221
|
+
uint64 public depositDustThreshold;
|
|
222
|
+
|
|
218
223
|
/// TODO: Make it governable.
|
|
219
224
|
/// @notice Divisor used to compute the treasury fee taken from each
|
|
220
225
|
/// deposit and transferred to the treasury upon sweep proof
|
|
221
226
|
/// submission. That fee is computed as follows:
|
|
222
227
|
/// `treasuryFee = depositedAmount / depositTreasuryFeeDivisor`
|
|
223
228
|
/// For example, if the treasury fee needs to be 2% of each deposit,
|
|
224
|
-
/// the `
|
|
229
|
+
/// the `depositTreasuryFeeDivisor` should be set to `50`
|
|
225
230
|
/// because `1/50 = 0.02 = 2%`.
|
|
226
231
|
uint64 public depositTreasuryFeeDivisor;
|
|
227
232
|
|
|
@@ -384,6 +389,7 @@ contract Bridge is Ownable {
|
|
|
384
389
|
txProofDifficultyFactor = _txProofDifficultyFactor;
|
|
385
390
|
|
|
386
391
|
// TODO: Revisit initial values.
|
|
392
|
+
depositDustThreshold = 1000000; // 1000000 satoshi = 0.01 BTC
|
|
387
393
|
depositTxMaxFee = 1000; // 1000 satoshi
|
|
388
394
|
depositTreasuryFeeDivisor = 2000; // 1/2000 == 5bps == 0.05% == 0.0005
|
|
389
395
|
redemptionDustThreshold = 1000000; // 1000000 satoshi = 0.01 BTC
|
|
@@ -413,6 +419,22 @@ contract Bridge is Ownable {
|
|
|
413
419
|
emit VaultStatusUpdated(vault, isTrusted);
|
|
414
420
|
}
|
|
415
421
|
|
|
422
|
+
/// @notice Determines the current Bitcoin SPV proof difficulty context.
|
|
423
|
+
/// @return proofDifficulty Bitcoin proof difficulty context.
|
|
424
|
+
function proofDifficultyContext()
|
|
425
|
+
internal
|
|
426
|
+
view
|
|
427
|
+
returns (BitcoinTx.ProofDifficulty memory proofDifficulty)
|
|
428
|
+
{
|
|
429
|
+
proofDifficulty.currentEpochDifficulty = relay
|
|
430
|
+
.getCurrentEpochDifficulty();
|
|
431
|
+
proofDifficulty.previousEpochDifficulty = relay
|
|
432
|
+
.getPrevEpochDifficulty();
|
|
433
|
+
proofDifficulty.difficultyFactor = txProofDifficultyFactor;
|
|
434
|
+
|
|
435
|
+
return proofDifficulty;
|
|
436
|
+
}
|
|
437
|
+
|
|
416
438
|
/// @notice Used by the depositor to reveal information about their P2(W)SH
|
|
417
439
|
/// Bitcoin deposit to the Bridge on Ethereum chain. The off-chain
|
|
418
440
|
/// wallet listens for revealed deposit events and may decide to
|
|
@@ -536,7 +558,10 @@ contract Bridge is Ownable {
|
|
|
536
558
|
|
|
537
559
|
uint64 fundingOutputAmount = fundingOutput.extractValue();
|
|
538
560
|
|
|
539
|
-
|
|
561
|
+
require(
|
|
562
|
+
fundingOutputAmount >= depositDustThreshold,
|
|
563
|
+
"Deposit amount too small"
|
|
564
|
+
);
|
|
540
565
|
|
|
541
566
|
deposit.amount = fundingOutputAmount;
|
|
542
567
|
deposit.depositor = reveal.depositor;
|
|
@@ -608,7 +633,11 @@ contract Bridge is Ownable {
|
|
|
608
633
|
// can assume the transaction happened on Bitcoin chain and has
|
|
609
634
|
// a sufficient number of confirmations as determined by
|
|
610
635
|
// `txProofDifficultyFactor` constant.
|
|
611
|
-
bytes32 sweepTxHash =
|
|
636
|
+
bytes32 sweepTxHash = BitcoinTx.validateProof(
|
|
637
|
+
sweepTx,
|
|
638
|
+
sweepProof,
|
|
639
|
+
proofDifficultyContext()
|
|
640
|
+
);
|
|
612
641
|
|
|
613
642
|
// Process sweep transaction output and extract its target wallet
|
|
614
643
|
// public key hash and value.
|
|
@@ -653,20 +682,34 @@ contract Bridge is Ownable {
|
|
|
653
682
|
// all deposits.
|
|
654
683
|
uint256 totalTreasuryFee = 0;
|
|
655
684
|
|
|
656
|
-
//
|
|
657
|
-
//
|
|
658
|
-
//
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
685
|
+
// Determine the transaction fee that should be incurred by each deposit
|
|
686
|
+
// and the indivisible remainder that should be additionally incurred
|
|
687
|
+
// by the last deposit.
|
|
688
|
+
(
|
|
689
|
+
uint256 depositTxFee,
|
|
690
|
+
uint256 depositTxFeeRemainder
|
|
691
|
+
) = sweepTxFeeDistribution(
|
|
692
|
+
inputsInfo.inputsTotalValue,
|
|
693
|
+
sweepTxOutputValue,
|
|
694
|
+
inputsInfo.depositedAmounts.length
|
|
695
|
+
);
|
|
665
696
|
|
|
666
|
-
|
|
697
|
+
// Make sure the highest value of the deposit transaction fee does not
|
|
698
|
+
// exceed the maximum value limited by the governable parameter.
|
|
699
|
+
require(
|
|
700
|
+
depositTxFee + depositTxFeeRemainder <= depositTxMaxFee,
|
|
701
|
+
"Transaction fee is too high"
|
|
702
|
+
);
|
|
667
703
|
|
|
668
704
|
// Reduce each deposit amount by treasury fee and transaction fee.
|
|
669
705
|
for (uint256 i = 0; i < inputsInfo.depositedAmounts.length; i++) {
|
|
706
|
+
// The last deposit should incur the deposit transaction fee
|
|
707
|
+
// remainder.
|
|
708
|
+
uint256 depositTxFeeIncurred = i ==
|
|
709
|
+
inputsInfo.depositedAmounts.length - 1
|
|
710
|
+
? depositTxFee + depositTxFeeRemainder
|
|
711
|
+
: depositTxFee;
|
|
712
|
+
|
|
670
713
|
// There is no need to check whether
|
|
671
714
|
// `inputsInfo.depositedAmounts[i] - inputsInfo.treasuryFees[i] - txFee > 0`
|
|
672
715
|
// since the `depositDustThreshold` should force that condition
|
|
@@ -674,7 +717,7 @@ contract Bridge is Ownable {
|
|
|
674
717
|
inputsInfo.depositedAmounts[i] =
|
|
675
718
|
inputsInfo.depositedAmounts[i] -
|
|
676
719
|
inputsInfo.treasuryFees[i] -
|
|
677
|
-
|
|
720
|
+
depositTxFeeIncurred;
|
|
678
721
|
totalTreasuryFee += inputsInfo.treasuryFees[i];
|
|
679
722
|
}
|
|
680
723
|
|
|
@@ -698,103 +741,6 @@ contract Bridge is Ownable {
|
|
|
698
741
|
// TODO: Handle deposits having `vault` set.
|
|
699
742
|
}
|
|
700
743
|
|
|
701
|
-
/// @notice Validates the SPV proof of the Bitcoin transaction.
|
|
702
|
-
/// Reverts in case the validation or proof verification fail.
|
|
703
|
-
/// @param txInfo Bitcoin transaction data
|
|
704
|
-
/// @param proof Bitcoin proof data
|
|
705
|
-
/// @return txHash Proven 32-byte transaction hash.
|
|
706
|
-
function validateBitcoinTxProof(
|
|
707
|
-
BitcoinTx.Info calldata txInfo,
|
|
708
|
-
BitcoinTx.Proof calldata proof
|
|
709
|
-
) internal view returns (bytes32 txHash) {
|
|
710
|
-
require(
|
|
711
|
-
txInfo.inputVector.validateVin(),
|
|
712
|
-
"Invalid input vector provided"
|
|
713
|
-
);
|
|
714
|
-
require(
|
|
715
|
-
txInfo.outputVector.validateVout(),
|
|
716
|
-
"Invalid output vector provided"
|
|
717
|
-
);
|
|
718
|
-
|
|
719
|
-
txHash = abi
|
|
720
|
-
.encodePacked(
|
|
721
|
-
txInfo.version,
|
|
722
|
-
txInfo.inputVector,
|
|
723
|
-
txInfo.outputVector,
|
|
724
|
-
txInfo.locktime
|
|
725
|
-
)
|
|
726
|
-
.hash256View();
|
|
727
|
-
|
|
728
|
-
checkProofFromTxHash(txHash, proof);
|
|
729
|
-
|
|
730
|
-
return txHash;
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
/// @notice Checks the given Bitcoin transaction hash against the SPV proof.
|
|
734
|
-
/// Reverts in case the check fails.
|
|
735
|
-
/// @param txHash 32-byte hash of the checked Bitcoin transaction
|
|
736
|
-
/// @param proof Bitcoin proof data
|
|
737
|
-
function checkProofFromTxHash(
|
|
738
|
-
bytes32 txHash,
|
|
739
|
-
BitcoinTx.Proof calldata proof
|
|
740
|
-
) internal view {
|
|
741
|
-
require(
|
|
742
|
-
txHash.prove(
|
|
743
|
-
proof.bitcoinHeaders.extractMerkleRootLE(),
|
|
744
|
-
proof.merkleProof,
|
|
745
|
-
proof.txIndexInBlock
|
|
746
|
-
),
|
|
747
|
-
"Tx merkle proof is not valid for provided header and tx hash"
|
|
748
|
-
);
|
|
749
|
-
|
|
750
|
-
evaluateProofDifficulty(proof.bitcoinHeaders);
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
/// @notice Evaluates the given Bitcoin proof difficulty against the actual
|
|
754
|
-
/// Bitcoin chain difficulty provided by the relay oracle.
|
|
755
|
-
/// Reverts in case the evaluation fails.
|
|
756
|
-
/// @param bitcoinHeaders Bitcoin headers chain being part of the SPV
|
|
757
|
-
/// proof. Used to extract the observed proof difficulty
|
|
758
|
-
function evaluateProofDifficulty(bytes memory bitcoinHeaders)
|
|
759
|
-
internal
|
|
760
|
-
view
|
|
761
|
-
{
|
|
762
|
-
uint256 requestedDiff = 0;
|
|
763
|
-
uint256 currentDiff = relay.getCurrentEpochDifficulty();
|
|
764
|
-
uint256 previousDiff = relay.getPrevEpochDifficulty();
|
|
765
|
-
uint256 firstHeaderDiff = bitcoinHeaders
|
|
766
|
-
.extractTarget()
|
|
767
|
-
.calculateDifficulty();
|
|
768
|
-
|
|
769
|
-
if (firstHeaderDiff == currentDiff) {
|
|
770
|
-
requestedDiff = currentDiff;
|
|
771
|
-
} else if (firstHeaderDiff == previousDiff) {
|
|
772
|
-
requestedDiff = previousDiff;
|
|
773
|
-
} else {
|
|
774
|
-
revert("Not at current or previous difficulty");
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
uint256 observedDiff = bitcoinHeaders.validateHeaderChain();
|
|
778
|
-
|
|
779
|
-
require(
|
|
780
|
-
observedDiff != ValidateSPV.getErrBadLength(),
|
|
781
|
-
"Invalid length of the headers chain"
|
|
782
|
-
);
|
|
783
|
-
require(
|
|
784
|
-
observedDiff != ValidateSPV.getErrInvalidChain(),
|
|
785
|
-
"Invalid headers chain"
|
|
786
|
-
);
|
|
787
|
-
require(
|
|
788
|
-
observedDiff != ValidateSPV.getErrLowWork(),
|
|
789
|
-
"Insufficient work in a header"
|
|
790
|
-
);
|
|
791
|
-
|
|
792
|
-
require(
|
|
793
|
-
observedDiff >= requestedDiff * txProofDifficultyFactor,
|
|
794
|
-
"Insufficient accumulated difficulty in header chain"
|
|
795
|
-
);
|
|
796
|
-
}
|
|
797
|
-
|
|
798
744
|
/// @notice Processes the Bitcoin sweep transaction output vector by
|
|
799
745
|
/// extracting the single output and using it to gain additional
|
|
800
746
|
/// information required for further processing (e.g. value and
|
|
@@ -1012,6 +958,40 @@ contract Bridge is Ownable {
|
|
|
1012
958
|
return (outpointTxHash, outpointIndex, inputLength);
|
|
1013
959
|
}
|
|
1014
960
|
|
|
961
|
+
/// @notice Determines the distribution of the sweep transaction fee
|
|
962
|
+
/// over swept deposits.
|
|
963
|
+
/// @param sweepTxInputsTotalValue Total value of all sweep transaction inputs.
|
|
964
|
+
/// @param sweepTxOutputValue Value of the sweep transaction output.
|
|
965
|
+
/// @param depositsCount Count of the deposits swept by the sweep transaction.
|
|
966
|
+
/// @return depositTxFee Transaction fee per deposit determined by evenly
|
|
967
|
+
/// spreading the divisible part of the sweep transaction fee
|
|
968
|
+
/// over all deposits.
|
|
969
|
+
/// @return depositTxFeeRemainder The indivisible part of the sweep
|
|
970
|
+
/// transaction fee than cannot be distributed over all deposits.
|
|
971
|
+
/// @dev It is up to the caller to decide how the remainder should be
|
|
972
|
+
/// counted in. This function only computes its value.
|
|
973
|
+
function sweepTxFeeDistribution(
|
|
974
|
+
uint256 sweepTxInputsTotalValue,
|
|
975
|
+
uint256 sweepTxOutputValue,
|
|
976
|
+
uint256 depositsCount
|
|
977
|
+
)
|
|
978
|
+
internal
|
|
979
|
+
pure
|
|
980
|
+
returns (uint256 depositTxFee, uint256 depositTxFeeRemainder)
|
|
981
|
+
{
|
|
982
|
+
// The sweep transaction fee is just the difference between inputs
|
|
983
|
+
// amounts sum and the output amount.
|
|
984
|
+
uint256 sweepTxFee = sweepTxInputsTotalValue - sweepTxOutputValue;
|
|
985
|
+
// Compute the indivisible remainder that remains after dividing the
|
|
986
|
+
// sweep transaction fee over all deposits evenly.
|
|
987
|
+
depositTxFeeRemainder = sweepTxFee % depositsCount;
|
|
988
|
+
// Compute the transaction fee per deposit by dividing the sweep
|
|
989
|
+
// transaction fee (reduced by the remainder) by the number of deposits.
|
|
990
|
+
depositTxFee = (sweepTxFee - depositTxFeeRemainder) / depositsCount;
|
|
991
|
+
|
|
992
|
+
return (depositTxFee, depositTxFeeRemainder);
|
|
993
|
+
}
|
|
994
|
+
|
|
1015
995
|
/// @notice Requests redemption of the given amount from the specified
|
|
1016
996
|
/// wallet to the redeemer Bitcoin output script.
|
|
1017
997
|
/// @param walletPubKeyHash The 20-byte wallet public key hash (computed
|
|
@@ -1223,9 +1203,10 @@ contract Bridge is Ownable {
|
|
|
1223
1203
|
// can assume the transaction happened on Bitcoin chain and has
|
|
1224
1204
|
// a sufficient number of confirmations as determined by
|
|
1225
1205
|
// `txProofDifficultyFactor` constant.
|
|
1226
|
-
bytes32 redemptionTxHash =
|
|
1206
|
+
bytes32 redemptionTxHash = BitcoinTx.validateProof(
|
|
1227
1207
|
redemptionTx,
|
|
1228
|
-
redemptionProof
|
|
1208
|
+
redemptionProof,
|
|
1209
|
+
proofDifficultyContext()
|
|
1229
1210
|
);
|
|
1230
1211
|
|
|
1231
1212
|
// Perform validation of the redemption transaction input. Specifically,
|
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.23+main.853bc8ff0601c82bb02cfaa0c904ba98d7d92fe5",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"artifacts/",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"ethereum-waffle": "^3.4.0",
|
|
50
50
|
"ethers": "^5.4.7",
|
|
51
51
|
"hardhat": "^2.6.4",
|
|
52
|
+
"hardhat-contract-sizer": "^2.5.0",
|
|
52
53
|
"hardhat-deploy": "^0.8.11",
|
|
53
54
|
"hardhat-gas-reporter": "^1.0.4",
|
|
54
55
|
"prettier": "^2.5.1",
|