@keep-network/tbtc-v2 0.1.1-dev.8 → 0.1.1-dev.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.adoc +12 -0
  2. package/artifacts/Bank.json +817 -0
  3. package/artifacts/Bridge.json +2644 -0
  4. package/artifacts/Deposit.json +117 -0
  5. package/artifacts/DepositSweep.json +77 -0
  6. package/artifacts/EcdsaDkgValidator.json +532 -0
  7. package/artifacts/EcdsaInactivity.json +156 -0
  8. package/artifacts/EcdsaSortitionPool.json +1004 -0
  9. package/artifacts/Fraud.json +164 -0
  10. package/artifacts/KeepRegistry.json +99 -0
  11. package/artifacts/KeepStake.json +286 -0
  12. package/artifacts/KeepToken.json +711 -0
  13. package/artifacts/KeepTokenStaking.json +483 -0
  14. package/artifacts/MovingFunds.json +249 -0
  15. package/artifacts/NuCypherStakingEscrow.json +256 -0
  16. package/artifacts/NuCypherToken.json +711 -0
  17. package/artifacts/RandomBeaconStub.json +141 -0
  18. package/artifacts/Redemption.json +162 -0
  19. package/artifacts/ReimbursementPool.json +509 -0
  20. package/artifacts/Relay.json +123 -0
  21. package/artifacts/T.json +1148 -0
  22. package/artifacts/TBTC.json +27 -26
  23. package/artifacts/TBTCToken.json +27 -26
  24. package/artifacts/TBTCVault.json +462 -0
  25. package/artifacts/TokenStaking.json +2288 -0
  26. package/artifacts/TokenholderGovernor.json +1795 -0
  27. package/artifacts/TokenholderTimelock.json +1058 -0
  28. package/artifacts/VendingMachine.json +30 -29
  29. package/artifacts/VendingMachineKeep.json +400 -0
  30. package/artifacts/VendingMachineNuCypher.json +400 -0
  31. package/artifacts/WalletRegistry.json +1843 -0
  32. package/artifacts/WalletRegistryGovernance.json +2754 -0
  33. package/artifacts/Wallets.json +186 -0
  34. package/artifacts/solcInputs/5cd0a97e230d515eacf46fb60ea8963a.json +311 -0
  35. package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
  36. package/build/contracts/GovernanceUtils.sol/GovernanceUtils.json +2 -2
  37. package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
  38. package/build/contracts/bank/Bank.sol/Bank.json +27 -4
  39. package/build/contracts/bank/IReceiveBalanceApproval.sol/IReceiveBalanceApproval.dbg.json +4 -0
  40. package/build/contracts/bank/IReceiveBalanceApproval.sol/IReceiveBalanceApproval.json +34 -0
  41. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +1 -1
  42. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.json +2 -2
  43. package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
  44. package/build/contracts/bridge/Bridge.sol/Bridge.json +2516 -196
  45. package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +4 -0
  46. package/build/contracts/bridge/BridgeState.sol/BridgeState.json +226 -0
  47. package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +4 -0
  48. package/build/contracts/bridge/Deposit.sol/Deposit.json +72 -0
  49. package/build/contracts/bridge/DepositSweep.sol/DepositSweep.dbg.json +4 -0
  50. package/build/contracts/bridge/DepositSweep.sol/DepositSweep.json +30 -0
  51. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +4 -0
  52. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.json +10 -0
  53. package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +4 -0
  54. package/build/contracts/bridge/Fraud.sol/Fraud.json +86 -0
  55. package/build/contracts/bridge/Heartbeat.sol/Heartbeat.dbg.json +4 -0
  56. package/build/contracts/bridge/Heartbeat.sol/Heartbeat.json +10 -0
  57. package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +4 -0
  58. package/build/contracts/bridge/IRelay.sol/IRelay.json +37 -0
  59. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +4 -0
  60. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.json +138 -0
  61. package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +4 -0
  62. package/build/contracts/bridge/Redemption.sol/OutboundTx.json +10 -0
  63. package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +4 -0
  64. package/build/contracts/bridge/Redemption.sol/Redemption.json +92 -0
  65. package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
  66. package/build/contracts/bridge/VendingMachine.sol/VendingMachine.json +2 -2
  67. package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +4 -0
  68. package/build/contracts/bridge/Wallets.sol/Wallets.json +112 -0
  69. package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
  70. package/build/contracts/token/TBTC.sol/TBTC.json +2 -2
  71. package/build/contracts/vault/DonationVault.sol/DonationVault.dbg.json +4 -0
  72. package/build/contracts/vault/DonationVault.sol/DonationVault.json +108 -0
  73. package/build/contracts/vault/IVault.sol/IVault.dbg.json +1 -1
  74. package/build/contracts/vault/IVault.sol/IVault.json +24 -1
  75. package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
  76. package/build/contracts/vault/TBTCVault.sol/TBTCVault.json +137 -18
  77. package/contracts/GovernanceUtils.sol +4 -4
  78. package/contracts/bank/Bank.sol +119 -57
  79. package/contracts/bank/IReceiveBalanceApproval.sol +45 -0
  80. package/contracts/bridge/BitcoinTx.sol +232 -10
  81. package/contracts/bridge/Bridge.sol +1601 -244
  82. package/contracts/bridge/BridgeState.sol +739 -0
  83. package/contracts/bridge/Deposit.sol +269 -0
  84. package/contracts/bridge/DepositSweep.sol +571 -0
  85. package/contracts/bridge/EcdsaLib.sol +45 -0
  86. package/contracts/bridge/Fraud.sol +604 -0
  87. package/contracts/bridge/Heartbeat.sol +112 -0
  88. package/contracts/bridge/IRelay.sol +28 -0
  89. package/contracts/bridge/MovingFunds.sol +1089 -0
  90. package/contracts/bridge/Redemption.sol +867 -0
  91. package/contracts/bridge/VendingMachine.sol +1 -1
  92. package/contracts/bridge/Wallets.sol +553 -0
  93. package/contracts/hardhat-dependency-compiler/.hardhat-dependency-compiler +1 -0
  94. package/contracts/hardhat-dependency-compiler/@keep-network/ecdsa/contracts/WalletRegistry.sol +3 -0
  95. package/contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol +3 -0
  96. package/contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol +3 -0
  97. package/contracts/token/TBTC.sol +1 -1
  98. package/contracts/vault/DonationVault.sol +125 -0
  99. package/contracts/vault/IVault.sol +19 -13
  100. package/contracts/vault/TBTCVault.sol +69 -19
  101. package/deploy/00_resolve_relay.ts +28 -0
  102. package/deploy/04_deploy_bank.ts +27 -0
  103. package/deploy/05_deploy_bridge.ts +80 -0
  104. package/deploy/06_deploy_tbtc_vault.ts +30 -0
  105. package/deploy/07_bank_update_bridge.ts +19 -0
  106. package/deploy/08_transfer_ownership.ts +15 -0
  107. package/deploy/09_transfer_governance.ts +20 -0
  108. package/deploy/10_transfer_proxy_admin_ownership.ts +30 -0
  109. package/deploy/11_deploy_proxy_admin_with_deputy.ts +33 -0
  110. package/export.json +15993 -475
  111. package/package.json +32 -25
  112. package/artifacts/solcInputs/4cf328e09411ac69d75a3c381680bc2c.json +0 -128
@@ -0,0 +1,269 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ // ██████████████ ▐████▌ ██████████████
4
+ // ██████████████ ▐████▌ ██████████████
5
+ // ▐████▌ ▐████▌
6
+ // ▐████▌ ▐████▌
7
+ // ██████████████ ▐████▌ ██████████████
8
+ // ██████████████ ▐████▌ ██████████████
9
+ // ▐████▌ ▐████▌
10
+ // ▐████▌ ▐████▌
11
+ // ▐████▌ ▐████▌
12
+ // ▐████▌ ▐████▌
13
+ // ▐████▌ ▐████▌
14
+ // ▐████▌ ▐████▌
15
+
16
+ pragma solidity ^0.8.9;
17
+
18
+ import {BTCUtils} from "@keep-network/bitcoin-spv-sol/contracts/BTCUtils.sol";
19
+ import {BytesLib} from "@keep-network/bitcoin-spv-sol/contracts/BytesLib.sol";
20
+
21
+ import "./BitcoinTx.sol";
22
+ import "./BridgeState.sol";
23
+ import "./Wallets.sol";
24
+
25
+ /// @title Bridge deposit
26
+ /// @notice The library handles the logic for revealing Bitcoin deposits to
27
+ /// the Bridge.
28
+ /// @dev The depositor puts together a P2SH or P2WSH address to deposit the
29
+ /// funds. This script is unique to each depositor and looks like this:
30
+ ///
31
+ /// ```
32
+ /// <depositorAddress> DROP
33
+ /// <blindingFactor> DROP
34
+ /// DUP HASH160 <walletPubKeyHash> EQUAL
35
+ /// IF
36
+ /// CHECKSIG
37
+ /// ELSE
38
+ /// DUP HASH160 <refundPubkeyHash> EQUALVERIFY
39
+ /// <refundLocktime> CHECKLOCKTIMEVERIFY DROP
40
+ /// CHECKSIG
41
+ /// ENDIF
42
+ /// ```
43
+ ///
44
+ /// Since each depositor has their own Ethereum address and their own
45
+ /// secret blinding factor, each depositor’s script is unique, and the hash
46
+ /// of each depositor’s script is unique.
47
+ library Deposit {
48
+ using BTCUtils for bytes;
49
+ using BytesLib for bytes;
50
+
51
+ /// @notice Represents data which must be revealed by the depositor during
52
+ /// deposit reveal.
53
+ struct DepositRevealInfo {
54
+ // Index of the funding output belonging to the funding transaction.
55
+ uint32 fundingOutputIndex;
56
+ // Ethereum depositor address.
57
+ address depositor;
58
+ // The blinding factor as 8 bytes. Byte endianness doesn't matter
59
+ // as this factor is not interpreted as uint.
60
+ bytes8 blindingFactor;
61
+ // The compressed Bitcoin public key (33 bytes and 02 or 03 prefix)
62
+ // of the deposit's wallet hashed in the HASH160 Bitcoin opcode style.
63
+ bytes20 walletPubKeyHash;
64
+ // The compressed Bitcoin public key (33 bytes and 02 or 03 prefix)
65
+ // that can be used to make the deposit refund after the refund
66
+ // locktime passes. Hashed in the HASH160 Bitcoin opcode style.
67
+ bytes20 refundPubKeyHash;
68
+ // The refund locktime (4-byte LE). Interpreted according to locktime
69
+ // parsing rules described in:
70
+ // https://developer.bitcoin.org/devguide/transactions.html#locktime-and-sequence-number
71
+ // and used with OP_CHECKLOCKTIMEVERIFY opcode as described in:
72
+ // https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki
73
+ bytes4 refundLocktime;
74
+ // Address of the Bank vault to which the deposit is routed to.
75
+ // Optional, can be 0x0. The vault must be trusted by the Bridge.
76
+ address vault;
77
+ // This struct doesn't contain `__gap` property as the structure is not
78
+ // stored, it is used as a function's calldata argument.
79
+ }
80
+
81
+ /// @notice Represents tBTC deposit request data.
82
+ struct DepositRequest {
83
+ // Ethereum depositor address.
84
+ address depositor;
85
+ // Deposit amount in satoshi.
86
+ uint64 amount;
87
+ // UNIX timestamp the deposit was revealed at.
88
+ uint32 revealedAt;
89
+ // Address of the Bank vault the deposit is routed to.
90
+ // Optional, can be 0x0.
91
+ address vault;
92
+ // Treasury TBTC fee in satoshi at the moment of deposit reveal.
93
+ uint64 treasuryFee;
94
+ // UNIX timestamp the deposit was swept at. Note this is not the
95
+ // time when the deposit was swept on the Bitcoin chain but actually
96
+ // the time when the sweep proof was delivered to the Ethereum chain.
97
+ uint32 sweptAt;
98
+ // This struct doesn't contain `__gap` property as the structure is stored
99
+ // in a mapping, mappings store values in different slots and they are
100
+ // not contiguous with other values.
101
+ }
102
+
103
+ event DepositRevealed(
104
+ bytes32 fundingTxHash,
105
+ uint32 fundingOutputIndex,
106
+ address indexed depositor,
107
+ uint64 amount,
108
+ bytes8 blindingFactor,
109
+ bytes20 indexed walletPubKeyHash,
110
+ bytes20 refundPubKeyHash,
111
+ bytes4 refundLocktime,
112
+ address vault
113
+ );
114
+
115
+ /// @notice Used by the depositor to reveal information about their P2(W)SH
116
+ /// Bitcoin deposit to the Bridge on Ethereum chain. The off-chain
117
+ /// wallet listens for revealed deposit events and may decide to
118
+ /// include the revealed deposit in the next executed sweep.
119
+ /// Information about the Bitcoin deposit can be revealed before or
120
+ /// after the Bitcoin transaction with P2(W)SH deposit is mined on
121
+ /// the Bitcoin chain. Worth noting, the gas cost of this function
122
+ /// scales with the number of P2(W)SH transaction inputs and
123
+ /// outputs. The deposit may be routed to one of the trusted vaults.
124
+ /// When a deposit is routed to a vault, vault gets notified when
125
+ /// the deposit gets swept and it may execute the appropriate action.
126
+ /// @param fundingTx Bitcoin funding transaction data, see `BitcoinTx.Info`.
127
+ /// @param reveal Deposit reveal data, see `RevealInfo struct.
128
+ /// @dev Requirements:
129
+ /// - `reveal.walletPubKeyHash` must identify a `Live` wallet,
130
+ /// - `reveal.vault` must be 0x0 or point to a trusted vault,
131
+ /// - `reveal.fundingOutputIndex` must point to the actual P2(W)SH
132
+ /// output of the BTC deposit transaction,
133
+ /// - `reveal.depositor` must be the Ethereum address used in the
134
+ /// P2(W)SH BTC deposit transaction,
135
+ /// - `reveal.blindingFactor` must be the blinding factor used in the
136
+ /// P2(W)SH BTC deposit transaction,
137
+ /// - `reveal.walletPubKeyHash` must be the wallet pub key hash used in
138
+ /// the P2(W)SH BTC deposit transaction,
139
+ /// - `reveal.refundPubKeyHash` must be the refund pub key hash used in
140
+ /// the P2(W)SH BTC deposit transaction,
141
+ /// - `reveal.refundLocktime` must be the refund locktime used in the
142
+ /// P2(W)SH BTC deposit transaction,
143
+ /// - BTC deposit for the given `fundingTxHash`, `fundingOutputIndex`
144
+ /// can be revealed only one time.
145
+ ///
146
+ /// If any of these requirements is not met, the wallet _must_ refuse
147
+ /// to sweep the deposit and the depositor has to wait until the
148
+ /// deposit script unlocks to receive their BTC back.
149
+ function revealDeposit(
150
+ BridgeState.Storage storage self,
151
+ BitcoinTx.Info calldata fundingTx,
152
+ DepositRevealInfo calldata reveal
153
+ ) external {
154
+ require(
155
+ self.registeredWallets[reveal.walletPubKeyHash].state ==
156
+ Wallets.WalletState.Live,
157
+ "Wallet must be in Live state"
158
+ );
159
+
160
+ require(
161
+ reveal.vault == address(0) || self.isVaultTrusted[reveal.vault],
162
+ "Vault is not trusted"
163
+ );
164
+
165
+ bytes memory expectedScript = abi.encodePacked(
166
+ hex"14", // Byte length of depositor Ethereum address.
167
+ reveal.depositor,
168
+ hex"75", // OP_DROP
169
+ hex"08", // Byte length of blinding factor value.
170
+ reveal.blindingFactor,
171
+ hex"75", // OP_DROP
172
+ hex"76", // OP_DUP
173
+ hex"a9", // OP_HASH160
174
+ hex"14", // Byte length of a compressed Bitcoin public key hash.
175
+ reveal.walletPubKeyHash,
176
+ hex"87", // OP_EQUAL
177
+ hex"63", // OP_IF
178
+ hex"ac", // OP_CHECKSIG
179
+ hex"67", // OP_ELSE
180
+ hex"76", // OP_DUP
181
+ hex"a9", // OP_HASH160
182
+ hex"14", // Byte length of a compressed Bitcoin public key hash.
183
+ reveal.refundPubKeyHash,
184
+ hex"88", // OP_EQUALVERIFY
185
+ hex"04", // Byte length of refund locktime value.
186
+ reveal.refundLocktime,
187
+ hex"b1", // OP_CHECKLOCKTIMEVERIFY
188
+ hex"75", // OP_DROP
189
+ hex"ac", // OP_CHECKSIG
190
+ hex"68" // OP_ENDIF
191
+ );
192
+
193
+ bytes memory fundingOutput = fundingTx
194
+ .outputVector
195
+ .extractOutputAtIndex(reveal.fundingOutputIndex);
196
+ bytes memory fundingOutputHash = fundingOutput.extractHash();
197
+
198
+ if (fundingOutputHash.length == 20) {
199
+ // A 20-byte output hash is used by P2SH. That hash is constructed
200
+ // by applying OP_HASH160 on the locking script. A 20-byte output
201
+ // hash is used as well by P2PKH and P2WPKH (OP_HASH160 on the
202
+ // public key). However, since we compare the actual output hash
203
+ // with an expected locking script hash, this check will succeed only
204
+ // for P2SH transaction type with expected script hash value. For
205
+ // P2PKH and P2WPKH, it will fail on the output hash comparison with
206
+ // the expected locking script hash.
207
+ require(
208
+ fundingOutputHash.slice20(0) == expectedScript.hash160View(),
209
+ "Wrong 20-byte script hash"
210
+ );
211
+ } else if (fundingOutputHash.length == 32) {
212
+ // A 32-byte output hash is used by P2WSH. That hash is constructed
213
+ // by applying OP_SHA256 on the locking script.
214
+ require(
215
+ fundingOutputHash.toBytes32() == sha256(expectedScript),
216
+ "Wrong 32-byte script hash"
217
+ );
218
+ } else {
219
+ revert("Wrong script hash length");
220
+ }
221
+
222
+ // Resulting TX hash is in native Bitcoin little-endian format.
223
+ bytes32 fundingTxHash = abi
224
+ .encodePacked(
225
+ fundingTx.version,
226
+ fundingTx.inputVector,
227
+ fundingTx.outputVector,
228
+ fundingTx.locktime
229
+ )
230
+ .hash256View();
231
+
232
+ DepositRequest storage deposit = self.deposits[
233
+ uint256(
234
+ keccak256(
235
+ abi.encodePacked(fundingTxHash, reveal.fundingOutputIndex)
236
+ )
237
+ )
238
+ ];
239
+ require(deposit.revealedAt == 0, "Deposit already revealed");
240
+
241
+ uint64 fundingOutputAmount = fundingOutput.extractValue();
242
+
243
+ require(
244
+ fundingOutputAmount >= self.depositDustThreshold,
245
+ "Deposit amount too small"
246
+ );
247
+
248
+ deposit.amount = fundingOutputAmount;
249
+ deposit.depositor = reveal.depositor;
250
+ /* solhint-disable-next-line not-rely-on-time */
251
+ deposit.revealedAt = uint32(block.timestamp);
252
+ deposit.vault = reveal.vault;
253
+ deposit.treasuryFee = self.depositTreasuryFeeDivisor > 0
254
+ ? fundingOutputAmount / self.depositTreasuryFeeDivisor
255
+ : 0;
256
+ // slither-disable-next-line reentrancy-events
257
+ emit DepositRevealed(
258
+ fundingTxHash,
259
+ reveal.fundingOutputIndex,
260
+ reveal.depositor,
261
+ fundingOutputAmount,
262
+ reveal.blindingFactor,
263
+ reveal.walletPubKeyHash,
264
+ reveal.refundPubKeyHash,
265
+ reveal.refundLocktime,
266
+ reveal.vault
267
+ );
268
+ }
269
+ }