@keep-network/tbtc-v2 0.1.0 → 0.1.1-dev
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/README.adoc +12 -0
- package/artifacts/.chainId +1 -1
- package/artifacts/Bank.json +807 -0
- package/artifacts/Bridge.json +2300 -0
- package/artifacts/Deposit.json +117 -0
- package/artifacts/DepositSweep.json +77 -0
- package/artifacts/EcdsaDkgValidator.json +532 -0
- package/artifacts/EcdsaInactivity.json +156 -0
- package/artifacts/EcdsaSortitionPool.json +1004 -0
- package/artifacts/Fraud.json +164 -0
- package/artifacts/KeepRegistry.json +99 -0
- package/artifacts/KeepStake.json +286 -0
- package/artifacts/KeepToken.json +711 -0
- package/artifacts/KeepTokenStaking.json +483 -0
- package/artifacts/MovingFunds.json +249 -0
- package/artifacts/NuCypherStakingEscrow.json +256 -0
- package/artifacts/NuCypherToken.json +711 -0
- package/artifacts/RandomBeaconStub.json +141 -0
- package/artifacts/Redemption.json +174 -0
- package/artifacts/ReimbursementPool.json +509 -0
- package/artifacts/Relay.json +123 -0
- package/artifacts/T.json +1148 -0
- package/artifacts/TBTC.json +36 -35
- package/artifacts/TBTCToken.json +738 -0
- package/artifacts/TBTCVault.json +691 -0
- package/artifacts/TokenStaking.json +2288 -0
- package/artifacts/TokenholderGovernor.json +1795 -0
- package/artifacts/TokenholderTimelock.json +1058 -0
- package/artifacts/VendingMachine.json +34 -33
- package/artifacts/VendingMachineKeep.json +400 -0
- package/artifacts/VendingMachineNuCypher.json +400 -0
- package/artifacts/WalletRegistry.json +1843 -0
- package/artifacts/WalletRegistryGovernance.json +2754 -0
- package/artifacts/Wallets.json +186 -0
- package/artifacts/solcInputs/5e62cff1ead0900b07facca4b559e818.json +314 -0
- package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
- package/build/contracts/GovernanceUtils.sol/GovernanceUtils.json +2 -2
- package/build/contracts/bank/Bank.sol/Bank.dbg.json +4 -0
- package/build/contracts/bank/Bank.sol/Bank.json +542 -0
- package/build/contracts/bank/IReceiveBalanceApproval.sol/IReceiveBalanceApproval.dbg.json +4 -0
- package/build/contracts/bank/IReceiveBalanceApproval.sol/IReceiveBalanceApproval.json +34 -0
- package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.dbg.json +4 -0
- package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.json +10 -0
- package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +4 -0
- package/build/contracts/bridge/Bridge.sol/Bridge.json +2686 -0
- package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +4 -0
- package/build/contracts/bridge/BridgeState.sol/BridgeState.json +226 -0
- package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +4 -0
- package/build/contracts/bridge/Deposit.sol/Deposit.json +72 -0
- package/build/contracts/bridge/DepositSweep.sol/DepositSweep.dbg.json +4 -0
- package/build/contracts/bridge/DepositSweep.sol/DepositSweep.json +30 -0
- package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +4 -0
- package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.json +10 -0
- package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +4 -0
- package/build/contracts/bridge/Fraud.sol/Fraud.json +86 -0
- package/build/contracts/bridge/Heartbeat.sol/Heartbeat.dbg.json +4 -0
- package/build/contracts/bridge/Heartbeat.sol/Heartbeat.json +10 -0
- package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +4 -0
- package/build/contracts/bridge/IRelay.sol/IRelay.json +37 -0
- package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +4 -0
- package/build/contracts/bridge/MovingFunds.sol/MovingFunds.json +138 -0
- package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +4 -0
- package/build/contracts/bridge/Redemption.sol/OutboundTx.json +10 -0
- package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +4 -0
- package/build/contracts/bridge/Redemption.sol/Redemption.json +92 -0
- package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
- package/build/contracts/bridge/VendingMachine.sol/VendingMachine.json +2 -2
- package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +4 -0
- package/build/contracts/bridge/Wallets.sol/Wallets.json +112 -0
- package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
- package/build/contracts/token/TBTC.sol/TBTC.json +4 -4
- package/build/contracts/vault/DonationVault.sol/DonationVault.dbg.json +4 -0
- package/build/contracts/vault/DonationVault.sol/DonationVault.json +108 -0
- package/build/contracts/vault/IVault.sol/IVault.dbg.json +4 -0
- package/build/contracts/vault/IVault.sol/IVault.json +52 -0
- package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +4 -0
- package/build/contracts/vault/TBTCVault.sol/TBTCVault.json +449 -0
- package/contracts/GovernanceUtils.sol +4 -4
- package/contracts/bank/Bank.sol +436 -0
- package/contracts/bank/IReceiveBalanceApproval.sol +45 -0
- package/contracts/bridge/BitcoinTx.sol +326 -0
- package/contracts/bridge/Bridge.sol +1793 -0
- package/contracts/bridge/BridgeState.sol +739 -0
- package/contracts/bridge/Deposit.sol +269 -0
- package/contracts/bridge/DepositSweep.sol +574 -0
- package/contracts/bridge/EcdsaLib.sol +45 -0
- package/contracts/bridge/Fraud.sol +579 -0
- package/contracts/bridge/Heartbeat.sol +112 -0
- package/contracts/bridge/IRelay.sol +28 -0
- package/contracts/bridge/MovingFunds.sol +1077 -0
- package/contracts/bridge/Redemption.sol +1020 -0
- package/contracts/bridge/VendingMachine.sol +2 -2
- package/contracts/bridge/Wallets.sol +719 -0
- package/contracts/hardhat-dependency-compiler/.hardhat-dependency-compiler +1 -0
- package/contracts/hardhat-dependency-compiler/@keep-network/ecdsa/contracts/WalletRegistry.sol +3 -0
- package/contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol +3 -0
- package/contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol +3 -0
- package/contracts/token/TBTC.sol +1 -1
- package/contracts/vault/DonationVault.sol +125 -0
- package/contracts/vault/IVault.sol +44 -0
- package/contracts/vault/TBTCVault.sol +305 -0
- package/deploy/00_resolve_relay.ts +28 -0
- package/deploy/00_resolve_tbtc_v1_token.ts +1 -1
- package/deploy/01_deploy_tbtc_v2_token.ts +8 -1
- package/deploy/02_deploy_vending_machine.ts +7 -0
- package/deploy/{03_transfer_roles.ts → 03_transfer_vending_machine_roles.ts} +1 -1
- package/deploy/04_deploy_bank.ts +27 -0
- package/deploy/05_deploy_bridge.ts +80 -0
- package/deploy/06_deploy_tbtc_vault.ts +30 -0
- package/deploy/07_bank_update_bridge.ts +19 -0
- package/deploy/08_transfer_bank_ownership.ts +15 -0
- package/deploy/09_transfer_tbtc_vault_ownership.ts +15 -0
- package/deploy/10_transfer_bridge_governance.ts +20 -0
- package/deploy/11_initialize_wallet_owner.ts +18 -0
- package/deploy/11_transfer_proxy_admin_ownership.ts +30 -0
- package/deploy/12_deploy_proxy_admin_with_deputy.ts +33 -0
- package/export/deploy/00_resolve_relay.js +24 -0
- package/export/deploy/00_resolve_tbtc_v1_token.js +24 -0
- package/export/deploy/01_deploy_tbtc_v2_token.js +19 -0
- package/export/deploy/02_deploy_vending_machine.js +25 -0
- package/export/deploy/03_transfer_vending_machine_roles.js +19 -0
- package/export/deploy/04_deploy_bank.js +21 -0
- package/export/deploy/05_deploy_bridge.js +69 -0
- package/export/deploy/06_deploy_tbtc_vault.js +24 -0
- package/export/deploy/07_bank_update_bridge.js +13 -0
- package/export/deploy/08_transfer_bank_ownership.js +11 -0
- package/export/deploy/09_transfer_tbtc_vault_ownership.js +11 -0
- package/export/deploy/10_transfer_bridge_governance.js +11 -0
- package/export/deploy/11_initialize_wallet_owner.js +14 -0
- package/export/deploy/11_transfer_proxy_admin_ownership.js +23 -0
- package/export/deploy/12_deploy_proxy_admin_with_deputy.js +22 -0
- package/export/hardhat.config.js +169 -0
- package/export/test/bank/Bank.test.js +1012 -0
- package/export/test/bridge/Bridge.Deployment.test.js +76 -0
- package/export/test/bridge/Bridge.Deposit.test.js +1834 -0
- package/export/test/bridge/Bridge.Frauds.test.js +1349 -0
- package/export/test/bridge/Bridge.MovingFunds.test.js +2437 -0
- package/export/test/bridge/Bridge.Parameters.test.js +400 -0
- package/export/test/bridge/Bridge.Redemption.test.js +2523 -0
- package/export/test/bridge/Bridge.Vaults.test.js +74 -0
- package/export/test/bridge/Bridge.Wallets.test.js +1017 -0
- package/export/test/bridge/EcdsaLib.test.js +46 -0
- package/export/test/bridge/Heartbeat.test.js +77 -0
- package/export/test/bridge/VendingMachine.Upgrade.test.js +160 -0
- package/export/test/bridge/VendingMachine.test.js +762 -0
- package/export/test/data/deposit-sweep.js +655 -0
- package/export/test/data/ecdsa.js +18 -0
- package/export/test/data/fraud.js +158 -0
- package/export/test/data/moving-funds.js +815 -0
- package/export/test/data/redemption.js +1011 -0
- package/export/test/fixtures/bridge.js +54 -0
- package/export/test/fixtures/index.js +57 -0
- package/export/test/helpers/contract-test-helpers.js +18 -0
- package/export/test/integration/Slashing.test.js +279 -0
- package/export/test/integration/WalleCreation.test.js +66 -0
- package/export/test/integration/utils/ecdsa-wallet-registry.js +137 -0
- package/export/test/integration/utils/fixture.js +77 -0
- package/export/test/integration/utils/gas.js +36 -0
- package/export/test/integration/utils/random-beacon.js +26 -0
- package/export/test/integration/utils/staking.js +19 -0
- package/export/test/vault/DonationVault.test.js +202 -0
- package/export/test/vault/TBTCVault.Redemption.test.js +357 -0
- package/export/test/vault/TBTCVault.test.js +768 -0
- package/export/typechain/BTCUtils.js +2 -0
- package/export/typechain/Bank.js +2 -0
- package/export/typechain/BankStub.js +2 -0
- package/export/typechain/Bridge.js +2 -0
- package/export/typechain/BridgeState.js +2 -0
- package/export/typechain/BridgeStub.js +2 -0
- package/export/typechain/Deposit.js +2 -0
- package/export/typechain/DepositSweep.js +2 -0
- package/export/typechain/DonationVault.js +2 -0
- package/export/typechain/ERC165.js +2 -0
- package/export/typechain/ERC1967Proxy.js +2 -0
- package/export/typechain/ERC1967Upgrade.js +2 -0
- package/export/typechain/ERC20WithPermit.js +2 -0
- package/export/typechain/ERC721.js +2 -0
- package/export/typechain/EcdsaAuthorization.js +2 -0
- package/export/typechain/EcdsaDkg.js +2 -0
- package/export/typechain/EcdsaDkgValidator.js +2 -0
- package/export/typechain/EcdsaInactivity.js +2 -0
- package/export/typechain/Fraud.js +2 -0
- package/export/typechain/Governable.js +2 -0
- package/export/typechain/HeartbeatStub.js +2 -0
- package/export/typechain/IApplication.js +2 -0
- package/export/typechain/IApproveAndCall.js +2 -0
- package/export/typechain/IBeacon.js +2 -0
- package/export/typechain/IERC165.js +2 -0
- package/export/typechain/IERC1822Proxiable.js +2 -0
- package/export/typechain/IERC20.js +2 -0
- package/export/typechain/IERC20Metadata.js +2 -0
- package/export/typechain/IERC20WithPermit.js +2 -0
- package/export/typechain/IERC721.js +2 -0
- package/export/typechain/IERC721Metadata.js +2 -0
- package/export/typechain/IERC721Receiver.js +2 -0
- package/export/typechain/IRandomBeacon.js +2 -0
- package/export/typechain/IRandomBeaconConsumer.js +2 -0
- package/export/typechain/IReceiveApproval.js +2 -0
- package/export/typechain/IReceiveBalanceApproval.js +2 -0
- package/export/typechain/IRelay.js +2 -0
- package/export/typechain/IStaking.js +2 -0
- package/export/typechain/IVault.js +2 -0
- package/export/typechain/IWalletOwner.js +2 -0
- package/export/typechain/IWalletRegistry.js +2 -0
- package/export/typechain/Initializable.js +2 -0
- package/export/typechain/MisfundRecovery.js +2 -0
- package/export/typechain/MovingFunds.js +2 -0
- package/export/typechain/Ownable.js +2 -0
- package/export/typechain/Proxy.js +2 -0
- package/export/typechain/ProxyAdmin.js +2 -0
- package/export/typechain/ReceiveApprovalStub.js +2 -0
- package/export/typechain/Redemption.js +2 -0
- package/export/typechain/Reimbursable.js +2 -0
- package/export/typechain/ReimbursementPool.js +2 -0
- package/export/typechain/Rewards.js +2 -0
- package/export/typechain/SortitionPool.js +2 -0
- package/export/typechain/SortitionTree.js +2 -0
- package/export/typechain/TBTC.js +2 -0
- package/export/typechain/TBTCVault.js +2 -0
- package/export/typechain/TestERC20.js +2 -0
- package/export/typechain/TestERC721.js +2 -0
- package/export/typechain/TestEcdsaLib.js +2 -0
- package/export/typechain/TestRelay.js +2 -0
- package/export/typechain/TransparentUpgradeableProxy.js +2 -0
- package/export/typechain/VendingMachine.js +2 -0
- package/export/typechain/WalletRegistry.js +2 -0
- package/export/typechain/Wallets.js +2 -0
- package/export/typechain/common.js +2 -0
- package/export/typechain/factories/BTCUtils__factory.js +94 -0
- package/export/typechain/factories/BankStub__factory.js +586 -0
- package/export/typechain/factories/Bank__factory.js +573 -0
- package/export/typechain/factories/BridgeState__factory.js +257 -0
- package/export/typechain/factories/BridgeStub__factory.js +2912 -0
- package/export/typechain/factories/Bridge__factory.js +2526 -0
- package/export/typechain/factories/DepositSweep__factory.js +61 -0
- package/export/typechain/factories/Deposit__factory.js +103 -0
- package/export/typechain/factories/DonationVault__factory.js +139 -0
- package/export/typechain/factories/ERC165__factory.js +38 -0
- package/export/typechain/factories/ERC1967Proxy__factory.js +111 -0
- package/export/typechain/factories/ERC1967Upgrade__factory.js +64 -0
- package/export/typechain/factories/ERC20WithPermit__factory.js +524 -0
- package/export/typechain/factories/ERC721__factory.js +388 -0
- package/export/typechain/factories/EcdsaAuthorization__factory.js +211 -0
- package/export/typechain/factories/EcdsaDkgValidator__factory.js +441 -0
- package/export/typechain/factories/EcdsaDkg__factory.js +192 -0
- package/export/typechain/factories/EcdsaInactivity__factory.js +134 -0
- package/export/typechain/factories/Fraud__factory.js +117 -0
- package/export/typechain/factories/Governable__factory.js +64 -0
- package/export/typechain/factories/HeartbeatStub__factory.js +61 -0
- package/export/typechain/factories/IApplication__factory.js +152 -0
- package/export/typechain/factories/IApproveAndCall__factory.js +48 -0
- package/export/typechain/factories/IBeacon__factory.js +32 -0
- package/export/typechain/factories/IERC165__factory.js +38 -0
- package/export/typechain/factories/IERC1822Proxiable__factory.js +32 -0
- package/export/typechain/factories/IERC20Metadata__factory.js +241 -0
- package/export/typechain/factories/IERC20WithPermit__factory.js +389 -0
- package/export/typechain/factories/IERC20__factory.js +202 -0
- package/export/typechain/factories/IERC721Metadata__factory.js +349 -0
- package/export/typechain/factories/IERC721Receiver__factory.js +53 -0
- package/export/typechain/factories/IERC721__factory.js +304 -0
- package/export/typechain/factories/IRandomBeaconConsumer__factory.js +37 -0
- package/export/typechain/factories/IRandomBeacon__factory.js +32 -0
- package/export/typechain/factories/IReceiveApproval__factory.js +47 -0
- package/export/typechain/factories/IReceiveBalanceApproval__factory.js +42 -0
- package/export/typechain/factories/IRelay__factory.js +45 -0
- package/export/typechain/factories/IStaking__factory.js +722 -0
- package/export/typechain/factories/IVault__factory.js +60 -0
- package/export/typechain/factories/IWalletOwner__factory.js +65 -0
- package/export/typechain/factories/IWalletRegistry__factory.js +138 -0
- package/export/typechain/factories/Initializable__factory.js +32 -0
- package/export/typechain/factories/MisfundRecovery__factory.js +145 -0
- package/export/typechain/factories/MovingFunds__factory.js +169 -0
- package/export/typechain/factories/Ownable__factory.js +71 -0
- package/export/typechain/factories/ProxyAdmin__factory.js +191 -0
- package/export/typechain/factories/Proxy__factory.js +27 -0
- package/export/typechain/factories/ReceiveApprovalStub__factory.js +127 -0
- package/export/typechain/factories/Redemption__factory.js +123 -0
- package/export/typechain/factories/Reimbursable__factory.js +58 -0
- package/export/typechain/factories/ReimbursementPool__factory.js +350 -0
- package/export/typechain/factories/Rewards__factory.js +117 -0
- package/export/typechain/factories/SortitionPool__factory.js +610 -0
- package/export/typechain/factories/SortitionTree__factory.js +149 -0
- package/export/typechain/factories/TBTCVault__factory.js +480 -0
- package/export/typechain/factories/TBTC__factory.js +564 -0
- package/export/typechain/factories/TestERC20__factory.js +539 -0
- package/export/typechain/factories/TestERC721__factory.js +421 -0
- package/export/typechain/factories/TestEcdsaLib__factory.js +66 -0
- package/export/typechain/factories/TestRelay__factory.js +94 -0
- package/export/typechain/factories/TransparentUpgradeableProxy__factory.js +186 -0
- package/export/typechain/factories/VendingMachine__factory.js +549 -0
- package/export/typechain/factories/WalletRegistry__factory.js +1919 -0
- package/export/typechain/factories/Wallets__factory.js +143 -0
- package/export/typechain/index.js +132 -0
- package/export.json +15932 -503
- package/package.json +47 -26
- package/artifacts/solcInputs/7cc3eda3cb3ff2522d18b5e7b31ea228.json +0 -104
|
@@ -0,0 +1,1017 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
/* eslint-disable no-underscore-dangle */
|
|
30
|
+
const hardhat_1 = require("hardhat");
|
|
31
|
+
const chai_1 = __importStar(require("chai"));
|
|
32
|
+
const smock_1 = require("@defi-wonderland/smock");
|
|
33
|
+
const deposit_sweep_1 = require("../data/deposit-sweep");
|
|
34
|
+
const ecdsa_1 = require("../data/ecdsa");
|
|
35
|
+
const fixtures_1 = require("../fixtures");
|
|
36
|
+
const bridge_1 = __importDefault(require("../fixtures/bridge"));
|
|
37
|
+
chai_1.default.use(smock_1.smock.matchers);
|
|
38
|
+
const { createSnapshot, restoreSnapshot } = hardhat_1.helpers.snapshot;
|
|
39
|
+
const { lastBlockTime, increaseTime } = hardhat_1.helpers.time;
|
|
40
|
+
describe("Bridge - Wallets", () => {
|
|
41
|
+
let thirdParty;
|
|
42
|
+
let walletRegistry;
|
|
43
|
+
let bridge;
|
|
44
|
+
before(async () => {
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-extra-semi
|
|
46
|
+
;
|
|
47
|
+
({ thirdParty, walletRegistry, bridge } = await hardhat_1.waffle.loadFixture(bridge_1.default));
|
|
48
|
+
});
|
|
49
|
+
describe("requestNewWallet", () => {
|
|
50
|
+
before(async () => {
|
|
51
|
+
await createSnapshot();
|
|
52
|
+
});
|
|
53
|
+
after(async () => {
|
|
54
|
+
walletRegistry.requestNewWallet.reset();
|
|
55
|
+
await restoreSnapshot();
|
|
56
|
+
});
|
|
57
|
+
context("when called by a third party", async () => {
|
|
58
|
+
context("when wallet creation is not in progress", () => {
|
|
59
|
+
before(async () => {
|
|
60
|
+
await createSnapshot();
|
|
61
|
+
walletRegistry.getWalletCreationState.returns(fixtures_1.ecdsaDkgState.IDLE);
|
|
62
|
+
});
|
|
63
|
+
after(async () => {
|
|
64
|
+
walletRegistry.getWalletCreationState.reset();
|
|
65
|
+
await restoreSnapshot();
|
|
66
|
+
});
|
|
67
|
+
context("when active wallet is not set", () => {
|
|
68
|
+
let tx;
|
|
69
|
+
before(async () => {
|
|
70
|
+
await createSnapshot();
|
|
71
|
+
tx = await bridge.connect(thirdParty).requestNewWallet(deposit_sweep_1.NO_MAIN_UTXO);
|
|
72
|
+
});
|
|
73
|
+
after(async () => {
|
|
74
|
+
walletRegistry.requestNewWallet.reset();
|
|
75
|
+
await restoreSnapshot();
|
|
76
|
+
});
|
|
77
|
+
it("should emit NewWalletRequested event", async () => {
|
|
78
|
+
await (0, chai_1.expect)(tx).to.emit(bridge, "NewWalletRequested");
|
|
79
|
+
});
|
|
80
|
+
it("should call ECDSA Wallet Registry's requestNewWallet function", async () => {
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
82
|
+
(0, chai_1.expect)(walletRegistry.requestNewWallet).to.have.been.calledOnce;
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
context("when active wallet is set", () => {
|
|
86
|
+
before(async () => {
|
|
87
|
+
await createSnapshot();
|
|
88
|
+
await bridge.setActiveWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
89
|
+
await bridge.setWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, {
|
|
90
|
+
ecdsaWalletID: ecdsa_1.ecdsaWalletTestData.walletID,
|
|
91
|
+
mainUtxoHash: hardhat_1.ethers.constants.HashZero,
|
|
92
|
+
pendingRedemptionsValue: 0,
|
|
93
|
+
createdAt: await lastBlockTime(),
|
|
94
|
+
movingFundsRequestedAt: 0,
|
|
95
|
+
closingStartedAt: 0,
|
|
96
|
+
pendingMovedFundsSweepRequestsCount: 0,
|
|
97
|
+
state: fixtures_1.walletState.Live,
|
|
98
|
+
movingFundsTargetWalletsCommitmentHash: hardhat_1.ethers.constants.HashZero,
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
after(async () => {
|
|
102
|
+
await restoreSnapshot();
|
|
103
|
+
});
|
|
104
|
+
context("when active wallet has a main UTXO set", () => {
|
|
105
|
+
context("when the active wallet main UTXO data are valid", () => {
|
|
106
|
+
context("when wallet creation conditions are met", () => {
|
|
107
|
+
context("when active wallet is old enough and its balance is greater or equal the minimum BTC balance threshold", () => {
|
|
108
|
+
let tx;
|
|
109
|
+
before(async () => {
|
|
110
|
+
await createSnapshot();
|
|
111
|
+
// Make the wallet old enough.
|
|
112
|
+
await increaseTime(fixtures_1.constants.walletCreationPeriod);
|
|
113
|
+
// Simulate the wallet has a BTC balance equal to the
|
|
114
|
+
// minimum BTC amount threshold by preparing the wallet's
|
|
115
|
+
// main UTXO accordingly.
|
|
116
|
+
const activeWalletMainUtxo = {
|
|
117
|
+
txHash: "0xc9e58780c6c289c25ae1fe293f85a4db4d0af4f305172f2a1868ddd917458bdf",
|
|
118
|
+
txOutputIndex: 1,
|
|
119
|
+
txOutputValue: fixtures_1.constants.walletCreationMinBtcBalance,
|
|
120
|
+
};
|
|
121
|
+
await bridge.setWalletMainUtxo(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, activeWalletMainUtxo);
|
|
122
|
+
tx = await bridge.requestNewWallet(activeWalletMainUtxo);
|
|
123
|
+
});
|
|
124
|
+
after(async () => {
|
|
125
|
+
walletRegistry.requestNewWallet.reset();
|
|
126
|
+
await restoreSnapshot();
|
|
127
|
+
});
|
|
128
|
+
it("should emit NewWalletRequested event", async () => {
|
|
129
|
+
await (0, chai_1.expect)(tx).to.emit(bridge, "NewWalletRequested");
|
|
130
|
+
});
|
|
131
|
+
it("should call ECDSA Wallet Registry's requestNewWallet function", async () => {
|
|
132
|
+
await (0, chai_1.expect)(walletRegistry.requestNewWallet).to.have.been
|
|
133
|
+
.calledOnce;
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
context("when active wallet is not old enough but its balance is greater or equal the maximum BTC balance threshold", () => {
|
|
137
|
+
let tx;
|
|
138
|
+
before(async () => {
|
|
139
|
+
await createSnapshot();
|
|
140
|
+
// Simulate the wallet has a BTC balance equal to the
|
|
141
|
+
// maximum BTC amount threshold by preparing the wallet's
|
|
142
|
+
// main UTXO accordingly. Note that the time is not
|
|
143
|
+
// increased at all so the wallet is not old enough
|
|
144
|
+
// for sure.
|
|
145
|
+
const activeWalletMainUtxo = {
|
|
146
|
+
txHash: "0xc9e58780c6c289c25ae1fe293f85a4db4d0af4f305172f2a1868ddd917458bdf",
|
|
147
|
+
txOutputIndex: 1,
|
|
148
|
+
txOutputValue: fixtures_1.constants.walletCreationMaxBtcBalance,
|
|
149
|
+
};
|
|
150
|
+
await bridge.setWalletMainUtxo(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, activeWalletMainUtxo);
|
|
151
|
+
tx = await bridge.requestNewWallet(activeWalletMainUtxo);
|
|
152
|
+
});
|
|
153
|
+
after(async () => {
|
|
154
|
+
walletRegistry.requestNewWallet.reset();
|
|
155
|
+
await restoreSnapshot();
|
|
156
|
+
});
|
|
157
|
+
it("should emit NewWalletRequested event", async () => {
|
|
158
|
+
await (0, chai_1.expect)(tx).to.emit(bridge, "NewWalletRequested");
|
|
159
|
+
});
|
|
160
|
+
it("should call ECDSA Wallet Registry's requestNewWallet function", async () => {
|
|
161
|
+
await (0, chai_1.expect)(walletRegistry.requestNewWallet).to.have.been
|
|
162
|
+
.calledOnce;
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
context("when active wallet is not old enough and its balance is greater or equal the minimum but lesser than the maximum BTC balance threshold", () => {
|
|
167
|
+
let tx;
|
|
168
|
+
before(async () => {
|
|
169
|
+
await createSnapshot();
|
|
170
|
+
// Simulate the wallet has a BTC balance between the minimum
|
|
171
|
+
// and maximum BTC amount thresholds by preparing the
|
|
172
|
+
// wallet's main UTXO accordingly. Note that the time is not
|
|
173
|
+
// increased at all so the wallet is not old enough for sure.
|
|
174
|
+
const activeWalletMainUtxo = {
|
|
175
|
+
txHash: "0xc9e58780c6c289c25ae1fe293f85a4db4d0af4f305172f2a1868ddd917458bdf",
|
|
176
|
+
txOutputIndex: 1,
|
|
177
|
+
txOutputValue: fixtures_1.constants.walletCreationMaxBtcBalance.sub(1),
|
|
178
|
+
};
|
|
179
|
+
await bridge.setWalletMainUtxo(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, activeWalletMainUtxo);
|
|
180
|
+
tx = bridge.requestNewWallet(activeWalletMainUtxo);
|
|
181
|
+
});
|
|
182
|
+
after(async () => {
|
|
183
|
+
await restoreSnapshot();
|
|
184
|
+
});
|
|
185
|
+
it("should revert", async () => {
|
|
186
|
+
await (0, chai_1.expect)(tx).to.be.revertedWith("Wallet creation conditions are not met");
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
context("when active wallet is old enough but its balance is lesser than the minimum BTC balance threshold", () => {
|
|
190
|
+
let tx;
|
|
191
|
+
before(async () => {
|
|
192
|
+
await createSnapshot();
|
|
193
|
+
// Make the wallet old enough.
|
|
194
|
+
await increaseTime(fixtures_1.constants.walletCreationPeriod);
|
|
195
|
+
// Simulate the wallet has a BTC balance below the minimum
|
|
196
|
+
// BTC amount threshold by preparing the wallet's main
|
|
197
|
+
// UTXO accordingly.
|
|
198
|
+
const activeWalletMainUtxo = {
|
|
199
|
+
txHash: "0xc9e58780c6c289c25ae1fe293f85a4db4d0af4f305172f2a1868ddd917458bdf",
|
|
200
|
+
txOutputIndex: 1,
|
|
201
|
+
txOutputValue: fixtures_1.constants.walletCreationMinBtcBalance.sub(1),
|
|
202
|
+
};
|
|
203
|
+
await bridge.setWalletMainUtxo(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, activeWalletMainUtxo);
|
|
204
|
+
tx = bridge.requestNewWallet(activeWalletMainUtxo);
|
|
205
|
+
});
|
|
206
|
+
after(async () => {
|
|
207
|
+
await restoreSnapshot();
|
|
208
|
+
});
|
|
209
|
+
it("should revert", async () => {
|
|
210
|
+
await (0, chai_1.expect)(tx).to.be.revertedWith("Wallet creation conditions are not met");
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
context("when the active wallet main UTXO data are invalid", () => {
|
|
215
|
+
const activeWalletMainUtxo = {
|
|
216
|
+
txHash: "0xc9e58780c6c289c25ae1fe293f85a4db4d0af4f305172f2a1868ddd917458bdf",
|
|
217
|
+
txOutputIndex: 1,
|
|
218
|
+
txOutputValue: fixtures_1.constants.walletCreationMaxBtcBalance,
|
|
219
|
+
};
|
|
220
|
+
before(async () => {
|
|
221
|
+
await createSnapshot();
|
|
222
|
+
await bridge.setWalletMainUtxo(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, activeWalletMainUtxo);
|
|
223
|
+
});
|
|
224
|
+
after(async () => {
|
|
225
|
+
await restoreSnapshot();
|
|
226
|
+
});
|
|
227
|
+
it("should revert", async () => {
|
|
228
|
+
const corruptedActiveWalletMainUtxo = {
|
|
229
|
+
...activeWalletMainUtxo,
|
|
230
|
+
txOutputIndex: 0,
|
|
231
|
+
};
|
|
232
|
+
await (0, chai_1.expect)(bridge.requestNewWallet(corruptedActiveWalletMainUtxo)).to.be.revertedWith("Invalid wallet main UTXO data");
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
context("when active wallet has no main UTXO set", () => {
|
|
237
|
+
before(async () => {
|
|
238
|
+
await createSnapshot();
|
|
239
|
+
});
|
|
240
|
+
after(async () => {
|
|
241
|
+
await restoreSnapshot();
|
|
242
|
+
});
|
|
243
|
+
// If the wallet has 0 BTC, the function must revert.
|
|
244
|
+
// This is because the active wallet's balance must be above the
|
|
245
|
+
// minimum BTC balance threshold and that threshold is guaranteed
|
|
246
|
+
// to be always greater than zero.
|
|
247
|
+
it("should revert", async () => {
|
|
248
|
+
await (0, chai_1.expect)(bridge.requestNewWallet(deposit_sweep_1.NO_MAIN_UTXO)).to.be.revertedWith("Wallet creation conditions are not met");
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
context("when wallet creation is already in progress", () => {
|
|
254
|
+
const testData = [
|
|
255
|
+
{
|
|
256
|
+
testName: "when wallet creation state is AWAITING_SEED",
|
|
257
|
+
walletCreationState: fixtures_1.ecdsaDkgState.AWAITING_SEED,
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
testName: "when wallet creation state is AWAITING_RESULT",
|
|
261
|
+
walletCreationState: fixtures_1.ecdsaDkgState.AWAITING_RESULT,
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
testName: "when wallet creation state is CHALLENGE",
|
|
265
|
+
walletCreationState: fixtures_1.ecdsaDkgState.CHALLENGE,
|
|
266
|
+
},
|
|
267
|
+
];
|
|
268
|
+
testData.forEach((test) => {
|
|
269
|
+
context(test.testName, () => {
|
|
270
|
+
before(async () => {
|
|
271
|
+
await createSnapshot();
|
|
272
|
+
walletRegistry.getWalletCreationState.returns(test.walletCreationState);
|
|
273
|
+
});
|
|
274
|
+
after(async () => {
|
|
275
|
+
walletRegistry.getWalletCreationState.reset();
|
|
276
|
+
await restoreSnapshot();
|
|
277
|
+
});
|
|
278
|
+
it("should revert", async () => {
|
|
279
|
+
await (0, chai_1.expect)(bridge.requestNewWallet(deposit_sweep_1.NO_MAIN_UTXO)).to.be.revertedWith("Wallet creation already in progress");
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
describe("__ecdsaWalletCreatedCallback", () => {
|
|
287
|
+
context("when called by a third party", async () => {
|
|
288
|
+
it("should revert", async () => {
|
|
289
|
+
await (0, chai_1.expect)(bridge
|
|
290
|
+
.connect(thirdParty)
|
|
291
|
+
.__ecdsaWalletCreatedCallback(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.publicKeyX, ecdsa_1.ecdsaWalletTestData.publicKeyY)).to.be.revertedWith("Caller is not the ECDSA Wallet Registry");
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
context("when called by the ECDSA Wallet Registry", async () => {
|
|
295
|
+
context("when called with a valid ECDSA Wallet details", async () => {
|
|
296
|
+
let tx;
|
|
297
|
+
before(async () => {
|
|
298
|
+
await createSnapshot();
|
|
299
|
+
tx = await bridge
|
|
300
|
+
.connect(walletRegistry.wallet)
|
|
301
|
+
.__ecdsaWalletCreatedCallback(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.publicKeyX, ecdsa_1.ecdsaWalletTestData.publicKeyY);
|
|
302
|
+
});
|
|
303
|
+
after(async () => {
|
|
304
|
+
await restoreSnapshot();
|
|
305
|
+
});
|
|
306
|
+
it("should register ECDSA wallet reference", async () => {
|
|
307
|
+
(0, chai_1.expect)((await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160))
|
|
308
|
+
.ecdsaWalletID).equals(ecdsa_1.ecdsaWalletTestData.walletID);
|
|
309
|
+
});
|
|
310
|
+
it("should transition wallet to Live state", async () => {
|
|
311
|
+
(0, chai_1.expect)((await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160)).state).equals(fixtures_1.walletState.Live);
|
|
312
|
+
});
|
|
313
|
+
it("should set the created at timestamp", async () => {
|
|
314
|
+
(0, chai_1.expect)((await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160)).createdAt).equals(await lastBlockTime());
|
|
315
|
+
});
|
|
316
|
+
it("should set the wallet as the active one", async () => {
|
|
317
|
+
(0, chai_1.expect)(await bridge.activeWalletPubKeyHash()).equals(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
318
|
+
});
|
|
319
|
+
it("should emit NewWalletRegistered event", async () => {
|
|
320
|
+
await (0, chai_1.expect)(tx)
|
|
321
|
+
.to.emit(bridge, "NewWalletRegistered")
|
|
322
|
+
.withArgs(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
323
|
+
});
|
|
324
|
+
it("should increase the live wallets counter", async () => {
|
|
325
|
+
(0, chai_1.expect)(await bridge.liveWalletsCount()).to.be.equal(1);
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
context("when called with the ECDSA Wallet already registered", async () => {
|
|
329
|
+
before(async () => {
|
|
330
|
+
await createSnapshot();
|
|
331
|
+
await bridge
|
|
332
|
+
.connect(walletRegistry.wallet)
|
|
333
|
+
.__ecdsaWalletCreatedCallback(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.publicKeyX, ecdsa_1.ecdsaWalletTestData.publicKeyY);
|
|
334
|
+
});
|
|
335
|
+
after(async () => {
|
|
336
|
+
await restoreSnapshot();
|
|
337
|
+
});
|
|
338
|
+
const testData = [
|
|
339
|
+
{
|
|
340
|
+
testName: "with unique wallet ID and unique public key",
|
|
341
|
+
walletID: hardhat_1.ethers.utils.randomBytes(32),
|
|
342
|
+
publicKeyX: hardhat_1.ethers.utils.randomBytes(32),
|
|
343
|
+
publicKeyY: hardhat_1.ethers.utils.randomBytes(32),
|
|
344
|
+
expectedError: undefined,
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
testName: "with duplicated wallet ID and unique public key",
|
|
348
|
+
walletID: ecdsa_1.ecdsaWalletTestData.walletID,
|
|
349
|
+
publicKeyX: hardhat_1.ethers.utils.randomBytes(32),
|
|
350
|
+
publicKeyY: hardhat_1.ethers.utils.randomBytes(32),
|
|
351
|
+
expectedError: undefined,
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
testName: "with unique wallet ID, unique public key X and duplicated public key Y",
|
|
355
|
+
walletID: hardhat_1.ethers.utils.randomBytes(32),
|
|
356
|
+
publicKeyX: hardhat_1.ethers.utils.randomBytes(32),
|
|
357
|
+
publicKeyY: ecdsa_1.ecdsaWalletTestData.publicKeyY,
|
|
358
|
+
expectedError: undefined,
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
testName: "with unique wallet ID, unique public key Y and duplicated public key X",
|
|
362
|
+
walletID: hardhat_1.ethers.utils.randomBytes(32),
|
|
363
|
+
publicKeyX: ecdsa_1.ecdsaWalletTestData.publicKeyY,
|
|
364
|
+
publicKeyY: hardhat_1.ethers.utils.randomBytes(32),
|
|
365
|
+
expectedError: undefined,
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
testName: "with unique wallet ID and duplicated public key",
|
|
369
|
+
walletID: hardhat_1.ethers.utils.randomBytes(32),
|
|
370
|
+
publicKeyX: ecdsa_1.ecdsaWalletTestData.publicKeyX,
|
|
371
|
+
publicKeyY: ecdsa_1.ecdsaWalletTestData.publicKeyY,
|
|
372
|
+
expectedError: "ECDSA wallet has been already registered",
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
testName: "with duplicated wallet ID and duplicated public key",
|
|
376
|
+
walletID: ecdsa_1.ecdsaWalletTestData.walletID,
|
|
377
|
+
publicKeyX: ecdsa_1.ecdsaWalletTestData.publicKeyX,
|
|
378
|
+
publicKeyY: ecdsa_1.ecdsaWalletTestData.publicKeyY,
|
|
379
|
+
expectedError: "ECDSA wallet has been already registered",
|
|
380
|
+
},
|
|
381
|
+
];
|
|
382
|
+
testData.forEach((test) => {
|
|
383
|
+
context(test.testName, async () => {
|
|
384
|
+
beforeEach(async () => {
|
|
385
|
+
await createSnapshot();
|
|
386
|
+
});
|
|
387
|
+
afterEach(async () => {
|
|
388
|
+
await restoreSnapshot();
|
|
389
|
+
});
|
|
390
|
+
it(test.expectedError ? "should revert" : "should not revert", async () => {
|
|
391
|
+
const tx = bridge
|
|
392
|
+
.connect(walletRegistry.wallet)
|
|
393
|
+
.__ecdsaWalletCreatedCallback(test.walletID, test.publicKeyX, test.publicKeyY);
|
|
394
|
+
if (test.expectedError) {
|
|
395
|
+
await (0, chai_1.expect)(tx).to.be.revertedWith(test.expectedError);
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
await (0, chai_1.expect)(tx).not.to.be.reverted;
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
describe("__ecdsaWalletHeartbeatFailedCallback", () => {
|
|
407
|
+
context("when called by the ECDSA Wallet Registry", () => {
|
|
408
|
+
context("when wallet is in Live state", () => {
|
|
409
|
+
before(async () => {
|
|
410
|
+
await createSnapshot();
|
|
411
|
+
await bridge.setWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, {
|
|
412
|
+
ecdsaWalletID: ecdsa_1.ecdsaWalletTestData.walletID,
|
|
413
|
+
mainUtxoHash: hardhat_1.ethers.constants.HashZero,
|
|
414
|
+
pendingRedemptionsValue: 0,
|
|
415
|
+
createdAt: await lastBlockTime(),
|
|
416
|
+
movingFundsRequestedAt: 0,
|
|
417
|
+
closingStartedAt: 0,
|
|
418
|
+
pendingMovedFundsSweepRequestsCount: 0,
|
|
419
|
+
state: fixtures_1.walletState.Live,
|
|
420
|
+
movingFundsTargetWalletsCommitmentHash: hardhat_1.ethers.constants.HashZero,
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
after(async () => {
|
|
424
|
+
await restoreSnapshot();
|
|
425
|
+
});
|
|
426
|
+
context("when wallet balance is zero", () => {
|
|
427
|
+
context("when wallet is the active one", () => {
|
|
428
|
+
let tx;
|
|
429
|
+
before(async () => {
|
|
430
|
+
await createSnapshot();
|
|
431
|
+
// Set the tested wallet as the active one.
|
|
432
|
+
await bridge.setActiveWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
433
|
+
tx = await bridge
|
|
434
|
+
.connect(walletRegistry.wallet)
|
|
435
|
+
.__ecdsaWalletHeartbeatFailedCallback(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.publicKeyX, ecdsa_1.ecdsaWalletTestData.publicKeyY);
|
|
436
|
+
});
|
|
437
|
+
after(async () => {
|
|
438
|
+
await restoreSnapshot();
|
|
439
|
+
});
|
|
440
|
+
it("should change wallet's state to Closing", async () => {
|
|
441
|
+
const { state } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
442
|
+
(0, chai_1.expect)(state).to.be.equal(fixtures_1.walletState.Closing);
|
|
443
|
+
});
|
|
444
|
+
it("should set the wallet's closing started timestamp", async () => {
|
|
445
|
+
const wallet = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
446
|
+
(0, chai_1.expect)(wallet.closingStartedAt).to.be.equal(await lastBlockTime());
|
|
447
|
+
});
|
|
448
|
+
it("should emit WalletClosing event", async () => {
|
|
449
|
+
await (0, chai_1.expect)(tx)
|
|
450
|
+
.to.emit(bridge, "WalletClosing")
|
|
451
|
+
.withArgs(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
452
|
+
});
|
|
453
|
+
it("should unset the active wallet", async () => {
|
|
454
|
+
(0, chai_1.expect)(await bridge.activeWalletPubKeyHash()).to.be.equal("0x0000000000000000000000000000000000000000");
|
|
455
|
+
});
|
|
456
|
+
it("should decrease the live wallets counter", async () => {
|
|
457
|
+
(0, chai_1.expect)(await bridge.liveWalletsCount()).to.be.equal(0);
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
context("when wallet is not the active one", () => {
|
|
461
|
+
let tx;
|
|
462
|
+
before(async () => {
|
|
463
|
+
await createSnapshot();
|
|
464
|
+
// Set the active wallet to be different than the tested one.
|
|
465
|
+
await bridge.setActiveWallet(hardhat_1.ethers.utils.ripemd160(ecdsa_1.ecdsaWalletTestData.pubKeyHash160));
|
|
466
|
+
tx = await bridge
|
|
467
|
+
.connect(walletRegistry.wallet)
|
|
468
|
+
.__ecdsaWalletHeartbeatFailedCallback(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.publicKeyX, ecdsa_1.ecdsaWalletTestData.publicKeyY);
|
|
469
|
+
});
|
|
470
|
+
after(async () => {
|
|
471
|
+
await restoreSnapshot();
|
|
472
|
+
});
|
|
473
|
+
it("should change wallet's state to Closing", async () => {
|
|
474
|
+
const { state } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
475
|
+
(0, chai_1.expect)(state).to.be.equal(fixtures_1.walletState.Closing);
|
|
476
|
+
});
|
|
477
|
+
it("should set the wallet's closing started timestamp", async () => {
|
|
478
|
+
const wallet = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
479
|
+
(0, chai_1.expect)(wallet.closingStartedAt).to.be.equal(await lastBlockTime());
|
|
480
|
+
});
|
|
481
|
+
it("should emit WalletClosing event", async () => {
|
|
482
|
+
await (0, chai_1.expect)(tx)
|
|
483
|
+
.to.emit(bridge, "WalletClosing")
|
|
484
|
+
.withArgs(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
485
|
+
});
|
|
486
|
+
it("should not unset the active wallet", async () => {
|
|
487
|
+
(0, chai_1.expect)(await bridge.activeWalletPubKeyHash()).to.be.equal(hardhat_1.ethers.utils.ripemd160(ecdsa_1.ecdsaWalletTestData.pubKeyHash160));
|
|
488
|
+
});
|
|
489
|
+
it("should decrease the live wallets counter", async () => {
|
|
490
|
+
(0, chai_1.expect)(await bridge.liveWalletsCount()).to.be.equal(0);
|
|
491
|
+
});
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
context("when wallet balance is greater than zero", () => {
|
|
495
|
+
before(async () => {
|
|
496
|
+
await createSnapshot();
|
|
497
|
+
await bridge.setWalletMainUtxo(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, {
|
|
498
|
+
txHash: "0xc9e58780c6c289c25ae1fe293f85a4db4d0af4f305172f2a1868ddd917458bdf",
|
|
499
|
+
txOutputIndex: 0,
|
|
500
|
+
txOutputValue: 1,
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
after(async () => {
|
|
504
|
+
await restoreSnapshot();
|
|
505
|
+
});
|
|
506
|
+
context("when wallet is the active one", () => {
|
|
507
|
+
let tx;
|
|
508
|
+
before(async () => {
|
|
509
|
+
await createSnapshot();
|
|
510
|
+
// Set the tested wallet as the active one.
|
|
511
|
+
await bridge.setActiveWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
512
|
+
tx = await bridge
|
|
513
|
+
.connect(walletRegistry.wallet)
|
|
514
|
+
.__ecdsaWalletHeartbeatFailedCallback(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.publicKeyX, ecdsa_1.ecdsaWalletTestData.publicKeyY);
|
|
515
|
+
});
|
|
516
|
+
after(async () => {
|
|
517
|
+
await restoreSnapshot();
|
|
518
|
+
});
|
|
519
|
+
it("should change wallet's state to MovingFunds", async () => {
|
|
520
|
+
const { state } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
521
|
+
(0, chai_1.expect)(state).to.be.equal(fixtures_1.walletState.MovingFunds);
|
|
522
|
+
});
|
|
523
|
+
it("should set move funds requested at timestamp", async () => {
|
|
524
|
+
const { movingFundsRequestedAt } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
525
|
+
(0, chai_1.expect)(movingFundsRequestedAt).to.be.equal(await lastBlockTime());
|
|
526
|
+
});
|
|
527
|
+
it("should emit WalletMovingFunds event", async () => {
|
|
528
|
+
await (0, chai_1.expect)(tx)
|
|
529
|
+
.to.emit(bridge, "WalletMovingFunds")
|
|
530
|
+
.withArgs(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
531
|
+
});
|
|
532
|
+
it("should unset the active wallet", async () => {
|
|
533
|
+
(0, chai_1.expect)(await bridge.activeWalletPubKeyHash()).to.be.equal("0x0000000000000000000000000000000000000000");
|
|
534
|
+
});
|
|
535
|
+
it("should decrease the live wallets counter", async () => {
|
|
536
|
+
(0, chai_1.expect)(await bridge.liveWalletsCount()).to.be.equal(0);
|
|
537
|
+
});
|
|
538
|
+
});
|
|
539
|
+
context("when wallet is not the active one", () => {
|
|
540
|
+
let tx;
|
|
541
|
+
before(async () => {
|
|
542
|
+
await createSnapshot();
|
|
543
|
+
// Set the active wallet to be different than the tested one.
|
|
544
|
+
await bridge.setActiveWallet(hardhat_1.ethers.utils.ripemd160(ecdsa_1.ecdsaWalletTestData.pubKeyHash160));
|
|
545
|
+
tx = await bridge
|
|
546
|
+
.connect(walletRegistry.wallet)
|
|
547
|
+
.__ecdsaWalletHeartbeatFailedCallback(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.publicKeyX, ecdsa_1.ecdsaWalletTestData.publicKeyY);
|
|
548
|
+
});
|
|
549
|
+
after(async () => {
|
|
550
|
+
await restoreSnapshot();
|
|
551
|
+
});
|
|
552
|
+
it("should change wallet's state to MovingFunds", async () => {
|
|
553
|
+
const { state } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
554
|
+
(0, chai_1.expect)(state).to.be.equal(fixtures_1.walletState.MovingFunds);
|
|
555
|
+
});
|
|
556
|
+
it("should set move funds requested at timestamp", async () => {
|
|
557
|
+
const { movingFundsRequestedAt } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
558
|
+
(0, chai_1.expect)(movingFundsRequestedAt).to.be.equal(await lastBlockTime());
|
|
559
|
+
});
|
|
560
|
+
it("should emit WalletMovingFunds event", async () => {
|
|
561
|
+
await (0, chai_1.expect)(tx)
|
|
562
|
+
.to.emit(bridge, "WalletMovingFunds")
|
|
563
|
+
.withArgs(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
564
|
+
});
|
|
565
|
+
it("should not unset the active wallet", async () => {
|
|
566
|
+
(0, chai_1.expect)(await bridge.activeWalletPubKeyHash()).to.be.equal(hardhat_1.ethers.utils.ripemd160(ecdsa_1.ecdsaWalletTestData.pubKeyHash160));
|
|
567
|
+
});
|
|
568
|
+
it("should decrease the live wallets counter", async () => {
|
|
569
|
+
(0, chai_1.expect)(await bridge.liveWalletsCount()).to.be.equal(0);
|
|
570
|
+
});
|
|
571
|
+
});
|
|
572
|
+
});
|
|
573
|
+
});
|
|
574
|
+
context("when wallet is not in Live state", () => {
|
|
575
|
+
const testData = [
|
|
576
|
+
{
|
|
577
|
+
testName: "when wallet state is Unknown",
|
|
578
|
+
walletState: fixtures_1.walletState.Unknown,
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
testName: "when wallet state is MovingFunds",
|
|
582
|
+
walletState: fixtures_1.walletState.MovingFunds,
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
testName: "when wallet state is Closing",
|
|
586
|
+
walletState: fixtures_1.walletState.Closing,
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
testName: "when wallet state is Closed",
|
|
590
|
+
walletState: fixtures_1.walletState.Closed,
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
testName: "when wallet state is Terminated",
|
|
594
|
+
walletState: fixtures_1.walletState.Terminated,
|
|
595
|
+
},
|
|
596
|
+
];
|
|
597
|
+
testData.forEach((test) => {
|
|
598
|
+
context(test.testName, () => {
|
|
599
|
+
before(async () => {
|
|
600
|
+
await createSnapshot();
|
|
601
|
+
await bridge.setWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, {
|
|
602
|
+
ecdsaWalletID: ecdsa_1.ecdsaWalletTestData.walletID,
|
|
603
|
+
mainUtxoHash: hardhat_1.ethers.constants.HashZero,
|
|
604
|
+
pendingRedemptionsValue: 0,
|
|
605
|
+
createdAt: 0,
|
|
606
|
+
movingFundsRequestedAt: 0,
|
|
607
|
+
closingStartedAt: 0,
|
|
608
|
+
pendingMovedFundsSweepRequestsCount: 0,
|
|
609
|
+
state: test.walletState,
|
|
610
|
+
movingFundsTargetWalletsCommitmentHash: hardhat_1.ethers.constants.HashZero,
|
|
611
|
+
});
|
|
612
|
+
});
|
|
613
|
+
after(async () => {
|
|
614
|
+
await restoreSnapshot();
|
|
615
|
+
});
|
|
616
|
+
it("should revert", async () => {
|
|
617
|
+
await (0, chai_1.expect)(bridge
|
|
618
|
+
.connect(walletRegistry.wallet)
|
|
619
|
+
.__ecdsaWalletHeartbeatFailedCallback(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.publicKeyX, ecdsa_1.ecdsaWalletTestData.publicKeyY)).to.be.revertedWith("Wallet must be in Live state");
|
|
620
|
+
});
|
|
621
|
+
});
|
|
622
|
+
});
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
context("when called by a third party", () => {
|
|
626
|
+
it("should revert", async () => {
|
|
627
|
+
it("should revert", async () => {
|
|
628
|
+
await (0, chai_1.expect)(bridge
|
|
629
|
+
.connect(thirdParty)
|
|
630
|
+
.__ecdsaWalletHeartbeatFailedCallback(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.publicKeyX, ecdsa_1.ecdsaWalletTestData.publicKeyY)).to.be.revertedWith("Caller is not the ECDSA Wallet Registry");
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
});
|
|
634
|
+
});
|
|
635
|
+
describe("notifyWalletCloseable", () => {
|
|
636
|
+
context("when the reported wallet is not the active one", () => {
|
|
637
|
+
context("when wallet is in Live state", () => {
|
|
638
|
+
before(async () => {
|
|
639
|
+
await createSnapshot();
|
|
640
|
+
await bridge.setWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, {
|
|
641
|
+
ecdsaWalletID: ecdsa_1.ecdsaWalletTestData.walletID,
|
|
642
|
+
mainUtxoHash: hardhat_1.ethers.constants.HashZero,
|
|
643
|
+
pendingRedemptionsValue: 0,
|
|
644
|
+
createdAt: await lastBlockTime(),
|
|
645
|
+
movingFundsRequestedAt: 0,
|
|
646
|
+
closingStartedAt: 0,
|
|
647
|
+
pendingMovedFundsSweepRequestsCount: 0,
|
|
648
|
+
state: fixtures_1.walletState.Live,
|
|
649
|
+
movingFundsTargetWalletsCommitmentHash: hardhat_1.ethers.constants.HashZero,
|
|
650
|
+
});
|
|
651
|
+
});
|
|
652
|
+
after(async () => {
|
|
653
|
+
await restoreSnapshot();
|
|
654
|
+
});
|
|
655
|
+
context("when wallet reached the maximum age", () => {
|
|
656
|
+
before(async () => {
|
|
657
|
+
await createSnapshot();
|
|
658
|
+
await increaseTime((await bridge.walletParameters()).walletMaxAge);
|
|
659
|
+
});
|
|
660
|
+
after(async () => {
|
|
661
|
+
await restoreSnapshot();
|
|
662
|
+
});
|
|
663
|
+
context("when wallet balance is zero", () => {
|
|
664
|
+
let tx;
|
|
665
|
+
before(async () => {
|
|
666
|
+
await createSnapshot();
|
|
667
|
+
tx = await bridge
|
|
668
|
+
.connect(walletRegistry.wallet)
|
|
669
|
+
.notifyWalletCloseable(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, deposit_sweep_1.NO_MAIN_UTXO);
|
|
670
|
+
});
|
|
671
|
+
after(async () => {
|
|
672
|
+
await restoreSnapshot();
|
|
673
|
+
});
|
|
674
|
+
it("should change wallet's state to Closing", async () => {
|
|
675
|
+
const { state } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
676
|
+
(0, chai_1.expect)(state).to.be.equal(fixtures_1.walletState.Closing);
|
|
677
|
+
});
|
|
678
|
+
it("should set the wallet's closing started timestamp", async () => {
|
|
679
|
+
const wallet = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
680
|
+
(0, chai_1.expect)(wallet.closingStartedAt).to.be.equal(await lastBlockTime());
|
|
681
|
+
});
|
|
682
|
+
it("should emit WalletClosing event", async () => {
|
|
683
|
+
await (0, chai_1.expect)(tx)
|
|
684
|
+
.to.emit(bridge, "WalletClosing")
|
|
685
|
+
.withArgs(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
686
|
+
});
|
|
687
|
+
it("should decrease the live wallets counter", async () => {
|
|
688
|
+
(0, chai_1.expect)(await bridge.liveWalletsCount()).to.be.equal(0);
|
|
689
|
+
});
|
|
690
|
+
});
|
|
691
|
+
context("when wallet balance is greater than zero", () => {
|
|
692
|
+
const walletMainUtxo = {
|
|
693
|
+
txHash: "0xc9e58780c6c289c25ae1fe293f85a4db4d0af4f305172f2a1868ddd917458bdf",
|
|
694
|
+
txOutputIndex: 0,
|
|
695
|
+
txOutputValue: 1,
|
|
696
|
+
};
|
|
697
|
+
let tx;
|
|
698
|
+
before(async () => {
|
|
699
|
+
await createSnapshot();
|
|
700
|
+
await bridge.setWalletMainUtxo(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, walletMainUtxo);
|
|
701
|
+
tx = await bridge
|
|
702
|
+
.connect(walletRegistry.wallet)
|
|
703
|
+
.notifyWalletCloseable(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, walletMainUtxo);
|
|
704
|
+
});
|
|
705
|
+
after(async () => {
|
|
706
|
+
await restoreSnapshot();
|
|
707
|
+
});
|
|
708
|
+
it("should change wallet's state to MovingFunds", async () => {
|
|
709
|
+
const { state } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
710
|
+
(0, chai_1.expect)(state).to.be.equal(fixtures_1.walletState.MovingFunds);
|
|
711
|
+
});
|
|
712
|
+
it("should set move funds requested at timestamp", async () => {
|
|
713
|
+
const { movingFundsRequestedAt } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
714
|
+
(0, chai_1.expect)(movingFundsRequestedAt).to.be.equal(await lastBlockTime());
|
|
715
|
+
});
|
|
716
|
+
it("should emit WalletMovingFunds event", async () => {
|
|
717
|
+
await (0, chai_1.expect)(tx)
|
|
718
|
+
.to.emit(bridge, "WalletMovingFunds")
|
|
719
|
+
.withArgs(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
720
|
+
});
|
|
721
|
+
it("should decrease the live wallets counter", async () => {
|
|
722
|
+
(0, chai_1.expect)(await bridge.liveWalletsCount()).to.be.equal(0);
|
|
723
|
+
});
|
|
724
|
+
});
|
|
725
|
+
});
|
|
726
|
+
context("when wallet did not reach the maximum age but their balance is lesser than the minimum threshold", () => {
|
|
727
|
+
context("when wallet balance is zero", () => {
|
|
728
|
+
let tx;
|
|
729
|
+
before(async () => {
|
|
730
|
+
await createSnapshot();
|
|
731
|
+
tx = await bridge
|
|
732
|
+
.connect(walletRegistry.wallet)
|
|
733
|
+
.notifyWalletCloseable(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, deposit_sweep_1.NO_MAIN_UTXO);
|
|
734
|
+
});
|
|
735
|
+
after(async () => {
|
|
736
|
+
await restoreSnapshot();
|
|
737
|
+
});
|
|
738
|
+
it("should change wallet's state to Closing", async () => {
|
|
739
|
+
const { state } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
740
|
+
(0, chai_1.expect)(state).to.be.equal(fixtures_1.walletState.Closing);
|
|
741
|
+
});
|
|
742
|
+
it("should set the wallet's closing started timestamp", async () => {
|
|
743
|
+
const wallet = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
744
|
+
(0, chai_1.expect)(wallet.closingStartedAt).to.be.equal(await lastBlockTime());
|
|
745
|
+
});
|
|
746
|
+
it("should emit WalletClosing event", async () => {
|
|
747
|
+
await (0, chai_1.expect)(tx)
|
|
748
|
+
.to.emit(bridge, "WalletClosing")
|
|
749
|
+
.withArgs(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
750
|
+
});
|
|
751
|
+
it("should decrease the live wallets counter", async () => {
|
|
752
|
+
(0, chai_1.expect)(await bridge.liveWalletsCount()).to.be.equal(0);
|
|
753
|
+
});
|
|
754
|
+
});
|
|
755
|
+
context("when wallet balance is greater than zero", () => {
|
|
756
|
+
const walletMainUtxo = {
|
|
757
|
+
txHash: "0xc9e58780c6c289c25ae1fe293f85a4db4d0af4f305172f2a1868ddd917458bdf",
|
|
758
|
+
txOutputIndex: 0,
|
|
759
|
+
txOutputValue: fixtures_1.constants.walletClosureMinBtcBalance.sub(1),
|
|
760
|
+
};
|
|
761
|
+
let tx;
|
|
762
|
+
before(async () => {
|
|
763
|
+
await createSnapshot();
|
|
764
|
+
await bridge.setWalletMainUtxo(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, walletMainUtxo);
|
|
765
|
+
tx = await bridge
|
|
766
|
+
.connect(walletRegistry.wallet)
|
|
767
|
+
.notifyWalletCloseable(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, walletMainUtxo);
|
|
768
|
+
});
|
|
769
|
+
after(async () => {
|
|
770
|
+
await restoreSnapshot();
|
|
771
|
+
});
|
|
772
|
+
it("should change wallet's state to MovingFunds", async () => {
|
|
773
|
+
const { state } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
774
|
+
(0, chai_1.expect)(state).to.be.equal(fixtures_1.walletState.MovingFunds);
|
|
775
|
+
});
|
|
776
|
+
it("should set move funds requested at timestamp", async () => {
|
|
777
|
+
const { movingFundsRequestedAt } = await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
778
|
+
(0, chai_1.expect)(movingFundsRequestedAt).to.be.equal(await lastBlockTime());
|
|
779
|
+
});
|
|
780
|
+
it("should emit WalletMovingFunds event", async () => {
|
|
781
|
+
await (0, chai_1.expect)(tx)
|
|
782
|
+
.to.emit(bridge, "WalletMovingFunds")
|
|
783
|
+
.withArgs(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
784
|
+
});
|
|
785
|
+
it("should decrease the live wallets counter", async () => {
|
|
786
|
+
(0, chai_1.expect)(await bridge.liveWalletsCount()).to.be.equal(0);
|
|
787
|
+
});
|
|
788
|
+
});
|
|
789
|
+
});
|
|
790
|
+
context("when wallet did not reach the maximum age and their balance is greater or equal the minimum threshold", () => {
|
|
791
|
+
const walletMainUtxo = {
|
|
792
|
+
txHash: "0xc9e58780c6c289c25ae1fe293f85a4db4d0af4f305172f2a1868ddd917458bdf",
|
|
793
|
+
txOutputIndex: 0,
|
|
794
|
+
txOutputValue: fixtures_1.constants.walletClosureMinBtcBalance,
|
|
795
|
+
};
|
|
796
|
+
before(async () => {
|
|
797
|
+
await createSnapshot();
|
|
798
|
+
await bridge.setWalletMainUtxo(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, walletMainUtxo);
|
|
799
|
+
});
|
|
800
|
+
after(async () => {
|
|
801
|
+
await restoreSnapshot();
|
|
802
|
+
});
|
|
803
|
+
it("should revert", async () => {
|
|
804
|
+
await (0, chai_1.expect)(bridge
|
|
805
|
+
.connect(walletRegistry.wallet)
|
|
806
|
+
.notifyWalletCloseable(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, walletMainUtxo)).to.be.revertedWith("Wallet needs to be old enough or have too few satoshis");
|
|
807
|
+
});
|
|
808
|
+
});
|
|
809
|
+
context("when wallet did not reach the maximum age and invalid main UTXO data is passed", () => {
|
|
810
|
+
const walletMainUtxo = {
|
|
811
|
+
txHash: "0xc9e58780c6c289c25ae1fe293f85a4db4d0af4f305172f2a1868ddd917458bdf",
|
|
812
|
+
txOutputIndex: 0,
|
|
813
|
+
txOutputValue: fixtures_1.constants.walletClosureMinBtcBalance,
|
|
814
|
+
};
|
|
815
|
+
before(async () => {
|
|
816
|
+
await createSnapshot();
|
|
817
|
+
await bridge.setWalletMainUtxo(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, walletMainUtxo);
|
|
818
|
+
});
|
|
819
|
+
after(async () => {
|
|
820
|
+
await restoreSnapshot();
|
|
821
|
+
});
|
|
822
|
+
it("should revert", async () => {
|
|
823
|
+
const corruptedWalletMainUtxo = {
|
|
824
|
+
...walletMainUtxo,
|
|
825
|
+
txOutputIndex: 1,
|
|
826
|
+
};
|
|
827
|
+
await (0, chai_1.expect)(bridge
|
|
828
|
+
.connect(walletRegistry.wallet)
|
|
829
|
+
.notifyWalletCloseable(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, corruptedWalletMainUtxo)).to.be.revertedWith("Invalid wallet main UTXO data");
|
|
830
|
+
});
|
|
831
|
+
});
|
|
832
|
+
});
|
|
833
|
+
context("when wallet is not in Live state", () => {
|
|
834
|
+
const testData = [
|
|
835
|
+
{
|
|
836
|
+
testName: "when wallet state is Unknown",
|
|
837
|
+
walletState: fixtures_1.walletState.Unknown,
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
testName: "when wallet state is MovingFunds",
|
|
841
|
+
walletState: fixtures_1.walletState.MovingFunds,
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
testName: "when wallet state is Closing",
|
|
845
|
+
walletState: fixtures_1.walletState.Closing,
|
|
846
|
+
},
|
|
847
|
+
{
|
|
848
|
+
testName: "when wallet state is Closed",
|
|
849
|
+
walletState: fixtures_1.walletState.Closed,
|
|
850
|
+
},
|
|
851
|
+
{
|
|
852
|
+
testName: "when wallet state is Terminated",
|
|
853
|
+
walletState: fixtures_1.walletState.Terminated,
|
|
854
|
+
},
|
|
855
|
+
];
|
|
856
|
+
testData.forEach((test) => {
|
|
857
|
+
context(test.testName, () => {
|
|
858
|
+
before(async () => {
|
|
859
|
+
await createSnapshot();
|
|
860
|
+
await bridge.setWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, {
|
|
861
|
+
ecdsaWalletID: ecdsa_1.ecdsaWalletTestData.walletID,
|
|
862
|
+
mainUtxoHash: hardhat_1.ethers.constants.HashZero,
|
|
863
|
+
pendingRedemptionsValue: 0,
|
|
864
|
+
createdAt: 0,
|
|
865
|
+
movingFundsRequestedAt: 0,
|
|
866
|
+
closingStartedAt: 0,
|
|
867
|
+
pendingMovedFundsSweepRequestsCount: 0,
|
|
868
|
+
state: test.walletState,
|
|
869
|
+
movingFundsTargetWalletsCommitmentHash: hardhat_1.ethers.constants.HashZero,
|
|
870
|
+
});
|
|
871
|
+
});
|
|
872
|
+
after(async () => {
|
|
873
|
+
await restoreSnapshot();
|
|
874
|
+
});
|
|
875
|
+
it("should revert", async () => {
|
|
876
|
+
await (0, chai_1.expect)(bridge
|
|
877
|
+
.connect(walletRegistry.wallet)
|
|
878
|
+
.notifyWalletCloseable(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, deposit_sweep_1.NO_MAIN_UTXO)).to.be.revertedWith("Wallet must be in Live state");
|
|
879
|
+
});
|
|
880
|
+
});
|
|
881
|
+
});
|
|
882
|
+
});
|
|
883
|
+
});
|
|
884
|
+
context("when the reported wallet is the active one", () => {
|
|
885
|
+
before(async () => {
|
|
886
|
+
await createSnapshot();
|
|
887
|
+
// Set the checked wallet as the active one.
|
|
888
|
+
await bridge.setActiveWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
889
|
+
await bridge.setWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, {
|
|
890
|
+
ecdsaWalletID: ecdsa_1.ecdsaWalletTestData.walletID,
|
|
891
|
+
mainUtxoHash: hardhat_1.ethers.constants.HashZero,
|
|
892
|
+
pendingRedemptionsValue: 0,
|
|
893
|
+
createdAt: await lastBlockTime(),
|
|
894
|
+
movingFundsRequestedAt: 0,
|
|
895
|
+
closingStartedAt: 0,
|
|
896
|
+
pendingMovedFundsSweepRequestsCount: 0,
|
|
897
|
+
state: fixtures_1.walletState.Live,
|
|
898
|
+
movingFundsTargetWalletsCommitmentHash: hardhat_1.ethers.constants.HashZero,
|
|
899
|
+
});
|
|
900
|
+
});
|
|
901
|
+
after(async () => {
|
|
902
|
+
await restoreSnapshot();
|
|
903
|
+
});
|
|
904
|
+
it("should revert", async () => {
|
|
905
|
+
await (0, chai_1.expect)(bridge
|
|
906
|
+
.connect(walletRegistry.wallet)
|
|
907
|
+
.notifyWalletCloseable(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, deposit_sweep_1.NO_MAIN_UTXO)).to.be.revertedWith("Active wallet cannot be considered closeable");
|
|
908
|
+
});
|
|
909
|
+
});
|
|
910
|
+
});
|
|
911
|
+
describe("notifyWalletClosingPeriodElapsed", () => {
|
|
912
|
+
const walletDraft = {
|
|
913
|
+
ecdsaWalletID: ecdsa_1.ecdsaWalletTestData.walletID,
|
|
914
|
+
mainUtxoHash: hardhat_1.ethers.constants.HashZero,
|
|
915
|
+
pendingRedemptionsValue: 0,
|
|
916
|
+
createdAt: 0,
|
|
917
|
+
movingFundsRequestedAt: 0,
|
|
918
|
+
closingStartedAt: 0,
|
|
919
|
+
pendingMovedFundsSweepRequestsCount: 0,
|
|
920
|
+
state: fixtures_1.walletState.Unknown,
|
|
921
|
+
movingFundsTargetWalletsCommitmentHash: hardhat_1.ethers.constants.HashZero,
|
|
922
|
+
};
|
|
923
|
+
context("when the wallet is in the Closing state", () => {
|
|
924
|
+
before(async () => {
|
|
925
|
+
await createSnapshot();
|
|
926
|
+
await bridge.setWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, {
|
|
927
|
+
...walletDraft,
|
|
928
|
+
state: fixtures_1.walletState.Live,
|
|
929
|
+
});
|
|
930
|
+
// Switches the wallet to Closing state because the wallet has
|
|
931
|
+
// no main UTXO set.
|
|
932
|
+
await bridge
|
|
933
|
+
.connect(walletRegistry.wallet)
|
|
934
|
+
.__ecdsaWalletHeartbeatFailedCallback(ecdsa_1.ecdsaWalletTestData.walletID, ecdsa_1.ecdsaWalletTestData.publicKeyX, ecdsa_1.ecdsaWalletTestData.publicKeyY);
|
|
935
|
+
});
|
|
936
|
+
after(async () => {
|
|
937
|
+
await restoreSnapshot();
|
|
938
|
+
});
|
|
939
|
+
context("when closing period has elapsed", () => {
|
|
940
|
+
let tx;
|
|
941
|
+
before(async () => {
|
|
942
|
+
await createSnapshot();
|
|
943
|
+
await increaseTime((await bridge.walletParameters()).walletClosingPeriod);
|
|
944
|
+
tx = await bridge.notifyWalletClosingPeriodElapsed(ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
945
|
+
});
|
|
946
|
+
after(async () => {
|
|
947
|
+
await walletRegistry.closeWallet.reset();
|
|
948
|
+
await restoreSnapshot();
|
|
949
|
+
});
|
|
950
|
+
it("should set wallet state to Closed", async () => {
|
|
951
|
+
(0, chai_1.expect)((await bridge.wallets(ecdsa_1.ecdsaWalletTestData.pubKeyHash160)).state).to.be.equal(fixtures_1.walletState.Closed);
|
|
952
|
+
});
|
|
953
|
+
it("should emit WalletClosed event", async () => {
|
|
954
|
+
await (0, chai_1.expect)(tx)
|
|
955
|
+
.to.emit(bridge, "WalletClosed")
|
|
956
|
+
.withArgs(walletDraft.ecdsaWalletID, ecdsa_1.ecdsaWalletTestData.pubKeyHash160);
|
|
957
|
+
});
|
|
958
|
+
it("should call the ECDSA wallet registry's closeWallet function", async () => {
|
|
959
|
+
(0, chai_1.expect)(walletRegistry.closeWallet).to.have.been.calledOnceWith(walletDraft.ecdsaWalletID);
|
|
960
|
+
});
|
|
961
|
+
});
|
|
962
|
+
context("when closing period has not elapsed yet", () => {
|
|
963
|
+
before(async () => {
|
|
964
|
+
await createSnapshot();
|
|
965
|
+
await increaseTime((await bridge.walletParameters()).walletClosingPeriod - 1);
|
|
966
|
+
});
|
|
967
|
+
after(async () => {
|
|
968
|
+
await restoreSnapshot();
|
|
969
|
+
});
|
|
970
|
+
it("should revert", async () => {
|
|
971
|
+
await (0, chai_1.expect)(bridge.notifyWalletClosingPeriodElapsed(ecdsa_1.ecdsaWalletTestData.pubKeyHash160)).to.be.revertedWith("Closing period has not elapsed yet");
|
|
972
|
+
});
|
|
973
|
+
});
|
|
974
|
+
});
|
|
975
|
+
context("when the wallet is not in the Closing state", () => {
|
|
976
|
+
const testData = [
|
|
977
|
+
{
|
|
978
|
+
testName: "when wallet state is Unknown",
|
|
979
|
+
walletState: fixtures_1.walletState.Unknown,
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
testName: "when wallet state is Live",
|
|
983
|
+
walletState: fixtures_1.walletState.Live,
|
|
984
|
+
},
|
|
985
|
+
{
|
|
986
|
+
testName: "when wallet state is MovingFunds",
|
|
987
|
+
walletState: fixtures_1.walletState.MovingFunds,
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
testName: "when wallet state is Closed",
|
|
991
|
+
walletState: fixtures_1.walletState.Closed,
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
testName: "when wallet state is Terminated",
|
|
995
|
+
walletState: fixtures_1.walletState.Terminated,
|
|
996
|
+
},
|
|
997
|
+
];
|
|
998
|
+
testData.forEach((test) => {
|
|
999
|
+
context(test.testName, () => {
|
|
1000
|
+
before(async () => {
|
|
1001
|
+
await createSnapshot();
|
|
1002
|
+
await bridge.setWallet(ecdsa_1.ecdsaWalletTestData.pubKeyHash160, {
|
|
1003
|
+
...walletDraft,
|
|
1004
|
+
state: test.walletState,
|
|
1005
|
+
});
|
|
1006
|
+
});
|
|
1007
|
+
after(async () => {
|
|
1008
|
+
await restoreSnapshot();
|
|
1009
|
+
});
|
|
1010
|
+
it("should revert", async () => {
|
|
1011
|
+
await (0, chai_1.expect)(bridge.notifyWalletClosingPeriodElapsed(ecdsa_1.ecdsaWalletTestData.pubKeyHash160)).to.be.revertedWith("Wallet must be in Closing state");
|
|
1012
|
+
});
|
|
1013
|
+
});
|
|
1014
|
+
});
|
|
1015
|
+
});
|
|
1016
|
+
});
|
|
1017
|
+
});
|