@keep-network/tbtc-v2 0.1.1-dev.65 → 0.1.1-dev.68

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 (85) hide show
  1. package/artifacts/Bank.json +17 -17
  2. package/artifacts/Bridge.json +1307 -2747
  3. package/artifacts/DefaultProxyAdmin.json +259 -0
  4. package/artifacts/Deposit.json +10 -10
  5. package/artifacts/DepositSweep.json +10 -10
  6. package/artifacts/EcdsaDkgValidator.json +17 -16
  7. package/artifacts/EcdsaInactivity.json +11 -11
  8. package/artifacts/Fraud.json +10 -10
  9. package/artifacts/KeepRegistry.json +1 -1
  10. package/artifacts/KeepStake.json +2 -2
  11. package/artifacts/KeepToken.json +2 -2
  12. package/artifacts/KeepTokenStaking.json +1 -1
  13. package/artifacts/MovingFunds.json +34 -12
  14. package/artifacts/NuCypherStakingEscrow.json +1 -1
  15. package/artifacts/NuCypherToken.json +2 -2
  16. package/artifacts/RandomBeaconStub.json +18 -18
  17. package/artifacts/Redemption.json +10 -10
  18. package/artifacts/ReimbursementPool.json +17 -17
  19. package/artifacts/Relay.json +14 -14
  20. package/artifacts/SortitionPool.json +99 -38
  21. package/artifacts/T.json +2 -2
  22. package/artifacts/TBTC.json +19 -19
  23. package/artifacts/TBTCToken.json +19 -19
  24. package/artifacts/TokenStaking.json +1 -1
  25. package/artifacts/TokenholderGovernor.json +9 -9
  26. package/artifacts/TokenholderTimelock.json +8 -8
  27. package/artifacts/VendingMachine.json +24 -24
  28. package/artifacts/VendingMachineKeep.json +1 -1
  29. package/artifacts/VendingMachineNuCypher.json +1 -1
  30. package/artifacts/WalletRegistry.json +310 -902
  31. package/artifacts/WalletRegistry_Implementation.json +2824 -0
  32. package/artifacts/WalletRegistry_Proxy.json +259 -0
  33. package/artifacts/Wallets.json +12 -12
  34. package/artifacts/solcInputs/1635d55d57a0a2552952c0d22586ed23.json +56 -0
  35. package/artifacts/solcInputs/849676ae534cda0adec6ccf4d074608c.json +269 -0
  36. package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
  37. package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
  38. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +1 -1
  39. package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.json +2 -2
  40. package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
  41. package/build/contracts/bridge/Bridge.sol/Bridge.json +120 -71
  42. package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
  43. package/build/contracts/bridge/BridgeState.sol/BridgeState.json +2 -2
  44. package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +1 -1
  45. package/build/contracts/bridge/Deposit.sol/Deposit.json +2 -2
  46. package/build/contracts/bridge/DepositSweep.sol/DepositSweep.dbg.json +1 -1
  47. package/build/contracts/bridge/DepositSweep.sol/DepositSweep.json +2 -2
  48. package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +1 -1
  49. package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +1 -1
  50. package/build/contracts/bridge/Fraud.sol/Fraud.json +2 -2
  51. package/build/contracts/bridge/Heartbeat.sol/Heartbeat.dbg.json +1 -1
  52. package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +1 -1
  53. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +1 -1
  54. package/build/contracts/bridge/MovingFunds.sol/MovingFunds.json +15 -2
  55. package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +1 -1
  56. package/build/contracts/bridge/Redemption.sol/OutboundTx.json +2 -2
  57. package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +1 -1
  58. package/build/contracts/bridge/Redemption.sol/Redemption.json +2 -2
  59. package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
  60. package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +1 -1
  61. package/build/contracts/bridge/Wallets.sol/Wallets.json +2 -2
  62. package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
  63. package/build/contracts/vault/DonationVault.sol/DonationVault.dbg.json +1 -1
  64. package/build/contracts/vault/IVault.sol/IVault.dbg.json +1 -1
  65. package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
  66. package/contracts/bridge/BitcoinTx.sol +8 -0
  67. package/contracts/bridge/Bridge.sol +32 -3
  68. package/contracts/bridge/BridgeState.sol +8 -0
  69. package/contracts/bridge/Deposit.sol +5 -0
  70. package/contracts/bridge/DepositSweep.sol +4 -0
  71. package/contracts/bridge/Fraud.sol +3 -0
  72. package/contracts/bridge/MovingFunds.sol +47 -4
  73. package/contracts/bridge/Redemption.sol +7 -0
  74. package/contracts/bridge/Wallets.sol +3 -0
  75. package/contracts/hardhat-dependency-compiler/.hardhat-dependency-compiler +1 -0
  76. package/contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol +3 -0
  77. package/contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol +3 -0
  78. package/deploy/00_resolve_wallet_registry.ts +83 -0
  79. package/deploy/05_deploy_bridge.ts +23 -14
  80. package/deploy/09_transfer_proxy_admin_ownership.ts +23 -0
  81. package/deploy/10_deploy_proxy_admin_with_deputy.ts +33 -0
  82. package/export.json +4124 -3615
  83. package/package.json +6 -2
  84. package/artifacts/WalletRegistryGovernance.json +0 -2364
  85. package/artifacts/solcInputs/a80c9f316a07a9460c9cb236187d2158.json +0 -227
@@ -56,6 +56,8 @@ library MovingFunds {
56
56
  // during the processing. The validation is usually done as part
57
57
  // of the `BitcoinTx.validateProof` call that checks the SPV proof.
58
58
  bytes movingFundsTxOutputVector;
59
+ // This struct doesn't contain `__gap` property as the structure is not
60
+ // stored, it is used as a function's memory argument.
59
61
  }
60
62
 
61
63
  /// @notice Represents moved funds sweep request state.
@@ -85,6 +87,9 @@ library MovingFunds {
85
87
  uint32 createdAt;
86
88
  // The current state of the request.
87
89
  MovedFundsSweepRequestState state;
90
+ // This struct doesn't contain `__gap` property as the structure is stored
91
+ // in a mapping, mappings store values in different slots and they are
92
+ // not contiguous with other values.
88
93
  }
89
94
 
90
95
  event MovingFundsCommitmentSubmitted(
@@ -93,6 +98,8 @@ library MovingFunds {
93
98
  address submitter
94
99
  );
95
100
 
101
+ event MovingFundsTimeoutReset(bytes20 walletPubKeyHash);
102
+
96
103
  event MovingFundsCompleted(
97
104
  bytes20 walletPubKeyHash,
98
105
  bytes32 movingFundsTxHash
@@ -206,10 +213,8 @@ library MovingFunds {
206
213
 
207
214
  // This requirement fails only when `liveWalletsCount` is zero. In
208
215
  // that case, the system cannot accept the commitment and must provide
209
- // new wallets first.
210
- //
211
- // TODO: Expose separate function to reset the moving funds timeout
212
- // if no Live wallets exist in the system.
216
+ // new wallets first. However, the wallet supposed to submit the
217
+ // commitment can keep resetting the moving funds timeout until then.
213
218
  require(expectedTargetWalletsCount > 0, "No target wallets available");
214
219
 
215
220
  require(
@@ -252,6 +257,44 @@ library MovingFunds {
252
257
  );
253
258
  }
254
259
 
260
+ /// @notice Resets the moving funds timeout for the given wallet if the
261
+ /// target wallet commitment cannot be submitted due to a lack
262
+ /// of live wallets in the system.
263
+ /// @param walletPubKeyHash 20-byte public key hash of the moving funds wallet
264
+ /// @dev Requirements:
265
+ /// - The wallet must be in the MovingFunds state
266
+ /// - The target wallets commitment must not be already submitted for
267
+ /// the given moving funds wallet
268
+ /// - Live wallets count must be zero
269
+ function resetMovingFundsTimeout(
270
+ BridgeState.Storage storage self,
271
+ bytes20 walletPubKeyHash
272
+ ) external {
273
+ Wallets.Wallet storage wallet = self.registeredWallets[
274
+ walletPubKeyHash
275
+ ];
276
+
277
+ require(
278
+ wallet.state == Wallets.WalletState.MovingFunds,
279
+ "ECDSA wallet must be in MovingFunds state"
280
+ );
281
+
282
+ // If the moving funds wallet already submitted their target wallets
283
+ // commitment, there is no point to reset the timeout since the
284
+ // wallet can make the BTC transaction and submit the proof.
285
+ require(
286
+ wallet.movingFundsTargetWalletsCommitmentHash == bytes32(0),
287
+ "Target wallets commitment already submitted"
288
+ );
289
+
290
+ require(self.liveWalletsCount == 0, "Live wallets count must be zero");
291
+
292
+ /* solhint-disable-next-line not-rely-on-time */
293
+ wallet.movingFundsRequestedAt = uint32(block.timestamp);
294
+
295
+ emit MovingFundsTimeoutReset(walletPubKeyHash);
296
+ }
297
+
255
298
  /// @notice Used by the wallet to prove the BTC moving funds transaction
256
299
  /// and to make the necessary state changes. Moving funds is only
257
300
  /// accepted if it satisfies SPV proof.
@@ -169,6 +169,9 @@ library Redemption {
169
169
  uint64 txMaxFee;
170
170
  // UNIX timestamp the request was created at.
171
171
  uint32 requestedAt;
172
+ // This struct doesn't contain `__gap` property as the structure is stored
173
+ // in a mapping, mappings store values in different slots and they are
174
+ // not contiguous with other values.
172
175
  }
173
176
 
174
177
  /// @notice Represents an outcome of the redemption Bitcoin transaction
@@ -187,6 +190,8 @@ library Redemption {
187
190
  uint32 changeIndex;
188
191
  // Value in satoshi of the change output.
189
192
  uint64 changeValue;
193
+ // This struct doesn't contain `__gap` property as the structure is not
194
+ // stored, it is used as a function's memory argument.
190
195
  }
191
196
 
192
197
  /// @notice Represents temporary information needed during the processing of
@@ -203,6 +208,8 @@ library Redemption {
203
208
  bytes32 walletP2PKHScriptKeccak;
204
209
  // P2WPKH script for the wallet. Needed to determine the change output.
205
210
  bytes32 walletP2WPKHScriptKeccak;
211
+ // This struct doesn't contain `__gap` property as the structure is not
212
+ // stored, it is used as a function's memory argument.
206
213
  }
207
214
 
208
215
  event RedemptionRequested(
@@ -86,6 +86,9 @@ library Wallets {
86
86
  // is built by applying the keccak256 hash over the list of 20-byte
87
87
  // public key hashes of the target wallets.
88
88
  bytes32 movingFundsTargetWalletsCommitmentHash;
89
+ // This struct doesn't contain `__gap` property as the structure is stored
90
+ // in a mapping, mappings store values in different slots and they are
91
+ // not contiguous with other values.
89
92
  }
90
93
 
91
94
  event NewWalletRequested();
@@ -0,0 +1 @@
1
+ directory approved for write access by hardhat-dependency-compiler
@@ -0,0 +1,3 @@
1
+ // SPDX-License-Identifier: UNLICENSED
2
+ pragma solidity >0.0.0;
3
+ import '@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol';
@@ -0,0 +1,3 @@
1
+ // SPDX-License-Identifier: UNLICENSED
2
+ pragma solidity >0.0.0;
3
+ import '@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol';
@@ -0,0 +1,83 @@
1
+ import { HardhatRuntimeEnvironment } from "hardhat/types"
2
+
3
+ import { DeployFunction } from "hardhat-deploy/types"
4
+
5
+ import deploySortitionPool from "@keep-network/ecdsa/export/deploy/01_deploy_sortition_pool"
6
+ import deployReimbursementPool from "@keep-network/ecdsa/export/deploy/02_deploy_reimbursement_pool"
7
+ import deployDkgValidator from "@keep-network/ecdsa/export/deploy/03_deploy_dkg_validator"
8
+
9
+ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
10
+ const { getNamedAccounts, deployments, helpers } = hre
11
+ const { log } = deployments
12
+ const { deployer } = await getNamedAccounts()
13
+
14
+ const WalletRegistry = await deployments.getOrNull("WalletRegistry")
15
+
16
+ if (WalletRegistry && helpers.address.isValid(WalletRegistry.address)) {
17
+ log(`using external WalletRegistry at ${WalletRegistry.address}`)
18
+ } else if (hre.network.name !== "hardhat") {
19
+ throw new Error("deployed WalletRegistry contract not found")
20
+ } else {
21
+ // FIXME: This is a workaround deployment. We expect that the `WalletRegistry`
22
+ // contract deployment will be imported from `@keep-network/ecdsa` deployment
23
+ // scripts. But due to some bug or incompatibility of the plugins we use
24
+ // the deployment fails. We need to investigate it further nad get working
25
+ // properly.
26
+ // https://github.com/keep-network/tbtc-v2/issues/267
27
+ log("deploying WalletRegistry")
28
+
29
+ await deploySortitionPool(hre)
30
+ await deployReimbursementPool(hre)
31
+ await deployDkgValidator(hre)
32
+
33
+ const SortitionPool = await deployments.get("SortitionPool")
34
+ const TokenStaking = await deployments.get("TokenStaking")
35
+ const ReimbursementPool = await deployments.get("ReimbursementPool")
36
+ const EcdsaDkgValidator = await deployments.get("EcdsaDkgValidator")
37
+
38
+ // TODO: RandomBeaconStub contract should be replaced by actual implementation of
39
+ // RandomBeacon contract, once @keep-network/random-beacon hardhat deployments
40
+ // scripts are implemented.
41
+ log("deploying RandomBeaconStub contract instead of RandomBeacon")
42
+ const RandomBeacon = await deployments.deploy("RandomBeaconStub", {
43
+ from: deployer,
44
+ log: true,
45
+ })
46
+
47
+ const EcdsaInactivity = await deployments.deploy("EcdsaInactivity", {
48
+ from: deployer,
49
+ log: true,
50
+ })
51
+
52
+ // Use `deployments.deploy` instead of `helpers.upgrades.deployProxy` as
53
+ // to workaround problem with a hardhat-gas-reporter problem described in
54
+ // https://github.com/keep-network/keep-core/pull/2970.
55
+ await deployments.deploy("WalletRegistry", {
56
+ from: deployer,
57
+ args: [SortitionPool.address, TokenStaking.address],
58
+ libraries: {
59
+ EcdsaInactivity: EcdsaInactivity.address,
60
+ },
61
+ proxy: {
62
+ proxyContract: "TransparentUpgradeableProxy",
63
+ viaAdminContract: "DefaultProxyAdmin",
64
+ owner: deployer,
65
+ execute: {
66
+ init: {
67
+ methodName: "initialize",
68
+ args: [
69
+ EcdsaDkgValidator.address,
70
+ RandomBeacon.address,
71
+ ReimbursementPool.address,
72
+ ],
73
+ },
74
+ },
75
+ },
76
+ log: true,
77
+ })
78
+ }
79
+ }
80
+
81
+ export default func
82
+
83
+ func.tags = ["WalletRegistry"]
@@ -2,7 +2,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types"
2
2
  import { DeployFunction } from "hardhat-deploy/types"
3
3
 
4
4
  const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
5
- const { deployments, getNamedAccounts } = hre
5
+ const { ethers, helpers, deployments, getNamedAccounts } = hre
6
6
  const { deploy } = deployments
7
7
  const { deployer, treasury } = await getNamedAccounts()
8
8
 
@@ -31,32 +31,41 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
31
31
  log: true,
32
32
  })
33
33
 
34
- const Bridge = await deploy("Bridge", {
35
- contract:
34
+ const bridge = await helpers.upgrades.deployProxy("Bridge", {
35
+ contractName:
36
36
  deployments.getNetworkName() === "hardhat" ? "BridgeStub" : undefined,
37
- from: deployer,
38
- args: [
37
+ initializerArgs: [
39
38
  Bank.address,
40
39
  Relay.address,
41
40
  treasury,
42
41
  WalletRegistry.address,
43
42
  txProofDifficultyFactor,
44
43
  ],
45
- libraries: {
46
- Deposit: Deposit.address,
47
- DepositSweep: DepositSweep.address,
48
- Redemption: Redemption.address,
49
- Wallets: Wallets.address,
50
- Fraud: Fraud.address,
51
- MovingFunds: MovingFunds.address,
44
+ factoryOpts: {
45
+ signer: await ethers.getSigner(deployer),
46
+ libraries: {
47
+ Deposit: Deposit.address,
48
+ DepositSweep: DepositSweep.address,
49
+ Redemption: Redemption.address,
50
+ Wallets: Wallets.address,
51
+ Fraud: Fraud.address,
52
+ MovingFunds: MovingFunds.address,
53
+ },
54
+ },
55
+ proxyOpts: {
56
+ kind: "transparent",
57
+ // Allow external libraries linking. We need to ensure manually that the
58
+ // external libraries we link are upgrade safe, as the OpenZeppelin plugin
59
+ // doesn't perform such a validation yet.
60
+ // See: https://docs.openzeppelin.com/upgrades-plugins/1.x/faq#why-cant-i-use-external-libraries
61
+ unsafeAllow: ["external-library-linking"],
52
62
  },
53
- log: true,
54
63
  })
55
64
 
56
65
  if (hre.network.tags.tenderly) {
57
66
  await hre.tenderly.verify({
58
67
  name: "Bridge",
59
- address: Bridge.address,
68
+ address: bridge.address,
60
69
  })
61
70
  }
62
71
  }
@@ -0,0 +1,23 @@
1
+ import type { HardhatRuntimeEnvironment } from "hardhat/types"
2
+ import type { DeployFunction } from "hardhat-deploy/types"
3
+
4
+ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
5
+ const { ethers, getNamedAccounts, upgrades, deployments } = hre
6
+ const { esdm } = await getNamedAccounts()
7
+ const { deployer } = await ethers.getNamedSigners()
8
+
9
+ // TODO: Once a DAO is established we want to switch to ProxyAdminWithDeputy and
10
+ // use the DAO as the proxy admin owner and ESDM as the deputy. Until then we
11
+ // use governance as the owner of ProxyAdmin contract.
12
+ const newProxyAdminOwner = esdm
13
+
14
+ deployments.log(`transferring ProxyAdmin ownership to ${newProxyAdminOwner}`)
15
+
16
+ const proxyAdmin = await upgrades.admin.getInstance()
17
+ await proxyAdmin.connect(deployer).transferOwnership(newProxyAdminOwner)
18
+ }
19
+
20
+ export default func
21
+
22
+ func.tags = ["TransferProxyAdminOwnership"]
23
+ func.dependencies = ["Bridge"]
@@ -0,0 +1,33 @@
1
+ import type { HardhatRuntimeEnvironment } from "hardhat/types"
2
+ import type { DeployFunction } from "hardhat-deploy/types"
3
+
4
+ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
5
+ const { ethers, getNamedAccounts, upgrades, deployments } = hre
6
+ const { deployer, dao, esdm } = await getNamedAccounts()
7
+
8
+ const BridgeProxyAdminWithDeputy = await deployments.deploy(
9
+ "BridgeProxyAdminWithDeputy",
10
+ {
11
+ contract: "ProxyAdminWithDeputy",
12
+ from: deployer,
13
+ args: [dao, esdm],
14
+ log: true,
15
+ }
16
+ )
17
+
18
+ const Bridge = await deployments.get("Bridge")
19
+
20
+ const proxyAdmin = await upgrades.admin.getInstance()
21
+
22
+ await proxyAdmin
23
+ .connect(await ethers.getSigner(esdm))
24
+ .changeProxyAdmin(Bridge.address, BridgeProxyAdminWithDeputy.address)
25
+ }
26
+
27
+ export default func
28
+
29
+ func.tags = ["BridgeProxyAdminWithDeputy"]
30
+ func.dependencies = ["Bridge"]
31
+
32
+ // TODO: For now we skip this script as DAO is not yet established.
33
+ func.skip = async () => true