@keep-network/tbtc-v2 0.1.1-dev.10 → 0.1.1-dev.102
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/Bank.json +807 -0
- package/artifacts/Bridge.json +2300 -0
- package/artifacts/BridgeGovernance.json +2931 -0
- package/artifacts/BridgeGovernanceParameters.json +1445 -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/MaintainerProxy.json +1522 -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 +27 -26
- package/artifacts/TBTCToken.json +27 -26
- 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 +31 -30
- 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/f53bc10568b6d3c32d2989742aa1c456.json +323 -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 +1 -1
- package/build/contracts/bank/Bank.sol/Bank.json +10 -5
- 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 +1 -1
- package/build/contracts/bridge/BitcoinTx.sol/BitcoinTx.json +2 -2
- package/build/contracts/bridge/Bridge.sol/Bridge.dbg.json +1 -1
- package/build/contracts/bridge/Bridge.sol/Bridge.json +2549 -198
- package/build/contracts/bridge/BridgeGovernance.sol/BridgeGovernance.dbg.json +4 -0
- package/build/contracts/bridge/BridgeGovernance.sol/BridgeGovernance.json +2246 -0
- package/build/contracts/bridge/BridgeGovernanceParameters.sol/BridgeGovernanceParameters.dbg.json +4 -0
- package/build/contracts/bridge/BridgeGovernanceParameters.sol/BridgeGovernanceParameters.json +971 -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/maintainer/MaintainerProxy.sol/MaintainerProxy.dbg.json +4 -0
- package/build/contracts/maintainer/MaintainerProxy.sol/MaintainerProxy.json +1111 -0
- package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
- package/build/contracts/token/TBTC.sol/TBTC.json +2 -2
- 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 +1 -1
- package/build/contracts/vault/IVault.sol/IVault.json +5 -0
- package/build/contracts/vault/TBTCVault.sol/TBTCVault.dbg.json +1 -1
- package/build/contracts/vault/TBTCVault.sol/TBTCVault.json +273 -5
- package/contracts/GovernanceUtils.sol +4 -4
- package/contracts/bank/Bank.sol +113 -66
- package/contracts/bank/IReceiveBalanceApproval.sol +45 -0
- package/contracts/bridge/BitcoinTx.sol +267 -10
- package/contracts/bridge/Bridge.sol +1698 -245
- package/contracts/bridge/BridgeGovernance.sol +1533 -0
- package/contracts/bridge/BridgeGovernanceParameters.sol +1695 -0
- package/contracts/bridge/BridgeState.sol +768 -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 +1058 -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/maintainer/MaintainerProxy.sol +512 -0
- package/contracts/token/TBTC.sol +1 -1
- package/contracts/vault/DonationVault.sol +125 -0
- package/contracts/vault/IVault.sol +6 -22
- package/contracts/vault/TBTCVault.sol +188 -29
- package/deploy/00_resolve_relay.ts +28 -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_deploy_bridge_governance.ts +40 -0
- package/deploy/08_deploy_maintainer_proxy.ts +30 -0
- package/deploy/09_bank_update_bridge.ts +19 -0
- package/deploy/10_transfer_bank_ownership.ts +15 -0
- package/deploy/11_transfer_bridge_governance.ts +22 -0
- package/deploy/12_transfer_bridge_governance_ownership.ts +19 -0
- package/deploy/13_transfer_tbtc_vault_ownership.ts +15 -0
- package/deploy/14_transfer_maintainer_proxy_ownership.ts +19 -0
- package/deploy/15_initialize_wallet_owner.ts +18 -0
- package/deploy/16_transfer_proxy_admin_ownership.ts +30 -0
- package/deploy/17_authorize_maintainer_proxy.ts +22 -0
- package/deploy/18_transfer_reimbursement_pool_ownership.ts +19 -0
- package/deploy/19_deploy_proxy_admin_with_deputy.ts +33 -0
- package/export.json +19544 -404
- package/package.json +34 -26
- package/artifacts/solcInputs/524094faac10a04084fcc411e06dab84.json +0 -128
|
@@ -13,30 +13,14 @@
|
|
|
13
13
|
// ▐████▌ ▐████▌
|
|
14
14
|
// ▐████▌ ▐████▌
|
|
15
15
|
|
|
16
|
-
pragma solidity 0.8.
|
|
16
|
+
pragma solidity ^0.8.9;
|
|
17
|
+
|
|
18
|
+
import "../bank/IReceiveBalanceApproval.sol";
|
|
17
19
|
|
|
18
20
|
/// @title Bank Vault interface
|
|
19
21
|
/// @notice `IVault` is an interface for a smart contract consuming Bank
|
|
20
22
|
/// balances of other contracts or externally owned accounts (EOA).
|
|
21
|
-
interface IVault {
|
|
22
|
-
/// @notice Called by the Bank in `approveBalanceAndCall` function after
|
|
23
|
-
/// the balance `owner` approved `amount` of their balance in the
|
|
24
|
-
/// Bank for the vault. This way, the depositor can approve balance
|
|
25
|
-
/// and call the vault to use the approved balance in a single
|
|
26
|
-
/// transaction.
|
|
27
|
-
/// @param owner Address of the Bank balance owner who approved their
|
|
28
|
-
/// balance to be used by the vault
|
|
29
|
-
/// @param amount The amount of the Bank balance approved by the owner
|
|
30
|
-
/// to be used by the vault
|
|
31
|
-
// @dev The implementation must ensure this function can only be called
|
|
32
|
-
/// by the Bank. The Bank does _not_ guarantee that the `amount`
|
|
33
|
-
/// approved by the `owner` currently exists on their balance. That is,
|
|
34
|
-
/// the `owner` could approve more balance than they currently have.
|
|
35
|
-
/// This works the same as `Bank.approve` function. The vault must
|
|
36
|
-
/// ensure the actual balance is checked before performing any action
|
|
37
|
-
/// based on it.
|
|
38
|
-
function receiveBalanceApproval(address owner, uint256 amount) external;
|
|
39
|
-
|
|
23
|
+
interface IVault is IReceiveBalanceApproval {
|
|
40
24
|
/// @notice Called by the Bank in `increaseBalanceAndCall` function after
|
|
41
25
|
/// increasing the balance in the Bank for the vault. It happens in
|
|
42
26
|
/// the same transaction in which deposits were swept by the Bridge.
|
|
@@ -46,9 +30,9 @@ interface IVault {
|
|
|
46
30
|
/// depositor does not have to execute additional transaction after
|
|
47
31
|
/// the deposit gets swept by the Bridge to approve and transfer
|
|
48
32
|
/// their balance to the vault.
|
|
49
|
-
/// @param depositors Addresses of depositors whose deposits have been swept
|
|
33
|
+
/// @param depositors Addresses of depositors whose deposits have been swept.
|
|
50
34
|
/// @param depositedAmounts Amounts deposited by individual depositors and
|
|
51
|
-
/// swept
|
|
35
|
+
/// swept.
|
|
52
36
|
/// @dev The implementation must ensure this function can only be called
|
|
53
37
|
/// by the Bank. The Bank guarantees that the vault's balance was
|
|
54
38
|
/// increased by the sum of all deposited amounts before this function
|
|
@@ -13,33 +13,63 @@
|
|
|
13
13
|
// ▐████▌ ▐████▌
|
|
14
14
|
// ▐████▌ ▐████▌
|
|
15
15
|
|
|
16
|
-
pragma solidity 0.8.
|
|
16
|
+
pragma solidity ^0.8.9;
|
|
17
|
+
|
|
18
|
+
import "@openzeppelin/contracts/access/Ownable.sol";
|
|
17
19
|
|
|
18
20
|
import "./IVault.sol";
|
|
19
21
|
import "../bank/Bank.sol";
|
|
20
22
|
import "../token/TBTC.sol";
|
|
23
|
+
import "../GovernanceUtils.sol";
|
|
21
24
|
|
|
22
25
|
/// @title TBTC application vault
|
|
23
26
|
/// @notice TBTC is a fully Bitcoin-backed ERC-20 token pegged to the price of
|
|
24
27
|
/// Bitcoin. It facilitates Bitcoin holders to act on the Ethereum
|
|
25
28
|
/// blockchain and access the decentralized finance (DeFi) ecosystem.
|
|
26
|
-
/// TBTC Vault mints and
|
|
29
|
+
/// TBTC Vault mints and unmints TBTC based on Bitcoin balances in the
|
|
27
30
|
/// Bank.
|
|
28
31
|
/// @dev TBTC Vault is the owner of TBTC token contract and is the only contract
|
|
29
32
|
/// minting the token.
|
|
30
|
-
contract TBTCVault is IVault {
|
|
33
|
+
contract TBTCVault is IVault, Ownable {
|
|
34
|
+
using SafeERC20 for IERC20;
|
|
35
|
+
|
|
36
|
+
/// @notice The time delay that needs to pass between initializing and
|
|
37
|
+
/// finalizing upgrade to a new vault. The time delay forces the
|
|
38
|
+
/// upgrading party to reflect on the vault address it is upgrading
|
|
39
|
+
/// to and lets all TBTC holders notice the planned
|
|
40
|
+
/// upgrade.
|
|
41
|
+
uint256 public constant UPGRADE_GOVERNANCE_DELAY = 24 hours;
|
|
42
|
+
|
|
31
43
|
Bank public bank;
|
|
32
44
|
TBTC public tbtcToken;
|
|
33
45
|
|
|
46
|
+
/// @notice The address of a new TBTC vault. Set only when the upgrade
|
|
47
|
+
/// process is pending. Once the upgrade gets finalized, the new
|
|
48
|
+
/// TBTC vault will become an owner of TBTC token.
|
|
49
|
+
address public newVault;
|
|
50
|
+
/// @notice The timestamp at which an upgrade to a new TBTC vault was
|
|
51
|
+
/// initiated. Set only when the upgrade process is pending.
|
|
52
|
+
uint256 public upgradeInitiatedTimestamp;
|
|
53
|
+
|
|
34
54
|
event Minted(address indexed to, uint256 amount);
|
|
55
|
+
event Unminted(address indexed from, uint256 amount);
|
|
35
56
|
|
|
36
|
-
event
|
|
57
|
+
event UpgradeInitiated(address newVault, uint256 timestamp);
|
|
58
|
+
event UpgradeFinalized(address newVault);
|
|
37
59
|
|
|
38
60
|
modifier onlyBank() {
|
|
39
61
|
require(msg.sender == address(bank), "Caller is not the Bank");
|
|
40
62
|
_;
|
|
41
63
|
}
|
|
42
64
|
|
|
65
|
+
modifier onlyAfterUpgradeGovernanceDelay() {
|
|
66
|
+
GovernanceUtils.onlyAfterGovernanceDelay(
|
|
67
|
+
upgradeInitiatedTimestamp,
|
|
68
|
+
UPGRADE_GOVERNANCE_DELAY
|
|
69
|
+
);
|
|
70
|
+
_;
|
|
71
|
+
}
|
|
72
|
+
|
|
43
73
|
constructor(Bank _bank, TBTC _tbtcToken) {
|
|
44
74
|
require(
|
|
45
75
|
address(_bank) != address(0),
|
|
@@ -59,7 +89,7 @@ contract TBTCVault is IVault {
|
|
|
59
89
|
/// to TBTC Vault, and mints `amount` of TBTC to the caller.
|
|
60
90
|
/// @dev TBTC Vault must have an allowance for caller's balance in the Bank
|
|
61
91
|
/// for at least `amount`.
|
|
62
|
-
/// @param amount Amount of TBTC to mint
|
|
92
|
+
/// @param amount Amount of TBTC to mint.
|
|
63
93
|
function mint(uint256 amount) external {
|
|
64
94
|
address minter = msg.sender;
|
|
65
95
|
require(
|
|
@@ -73,13 +103,13 @@ contract TBTCVault is IVault {
|
|
|
73
103
|
/// @notice Transfers the given `amount` of the Bank balance from the caller
|
|
74
104
|
/// to TBTC Vault and mints `amount` of TBTC to the caller.
|
|
75
105
|
/// @dev Can only be called by the Bank via `approveBalanceAndCall`.
|
|
76
|
-
/// @param owner The owner who approved their Bank balance
|
|
77
|
-
/// @param amount Amount of TBTC to mint
|
|
78
|
-
function receiveBalanceApproval(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
{
|
|
106
|
+
/// @param owner The owner who approved their Bank balance.
|
|
107
|
+
/// @param amount Amount of TBTC to mint.
|
|
108
|
+
function receiveBalanceApproval(
|
|
109
|
+
address owner,
|
|
110
|
+
uint256 amount,
|
|
111
|
+
bytes calldata
|
|
112
|
+
) external override onlyBank {
|
|
83
113
|
require(
|
|
84
114
|
bank.balanceOf(owner) >= amount,
|
|
85
115
|
"Amount exceeds balance in the bank"
|
|
@@ -104,32 +134,151 @@ contract TBTCVault is IVault {
|
|
|
104
134
|
}
|
|
105
135
|
}
|
|
106
136
|
|
|
107
|
-
/// @notice Burns `amount` of TBTC from the caller's
|
|
137
|
+
/// @notice Burns `amount` of TBTC from the caller's balance and transfers
|
|
108
138
|
/// `amount` back to the caller's balance in the Bank.
|
|
109
139
|
/// @dev Caller must have at least `amount` of TBTC approved to
|
|
110
140
|
/// TBTC Vault.
|
|
111
|
-
/// @param amount Amount of TBTC to
|
|
112
|
-
function
|
|
113
|
-
|
|
141
|
+
/// @param amount Amount of TBTC to unmint.
|
|
142
|
+
function unmint(uint256 amount) external {
|
|
143
|
+
_unmint(msg.sender, amount);
|
|
114
144
|
}
|
|
115
145
|
|
|
116
|
-
/// @notice Burns `amount` of TBTC from the caller's
|
|
117
|
-
/// `amount`
|
|
118
|
-
///
|
|
119
|
-
///
|
|
120
|
-
///
|
|
121
|
-
/// @param
|
|
122
|
-
/// @param
|
|
123
|
-
///
|
|
146
|
+
/// @notice Burns `amount` of TBTC from the caller's balance and transfers
|
|
147
|
+
/// `amount` of Bank balance to the Bridge requesting redemption
|
|
148
|
+
/// based on the provided `redemptionData`.
|
|
149
|
+
/// @dev Caller must have at least `amount` of TBTC approved to
|
|
150
|
+
/// TBTC Vault.
|
|
151
|
+
/// @param amount Amount of TBTC to unmint and request to redeem in Bridge.
|
|
152
|
+
/// @param redemptionData Redemption data in a format expected from
|
|
153
|
+
/// `redemptionData` parameter of Bridge's `receiveBalanceApproval`
|
|
154
|
+
/// function.
|
|
155
|
+
function unmintAndRedeem(uint256 amount, bytes calldata redemptionData)
|
|
156
|
+
external
|
|
157
|
+
{
|
|
158
|
+
_unmintAndRedeem(msg.sender, amount, redemptionData);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/// @notice Burns `amount` of TBTC from the caller's balance. If `extraData`
|
|
162
|
+
/// is empty, transfers `amount` back to the caller's balance in the
|
|
163
|
+
/// Bank. If `extraData` is not empty, requests redemption in the
|
|
164
|
+
/// Bridge using the `extraData` as a `redemptionData` parameter to
|
|
165
|
+
/// Bridge's `receiveBalanceApproval` function.
|
|
166
|
+
/// @dev This function is doing the same as `unmint` or `unmintAndRedeem`
|
|
167
|
+
/// (depending on `extraData` parameter) but it allows to execute
|
|
168
|
+
/// unminting without a separate approval transaction. The function can
|
|
169
|
+
/// be called only via `approveAndCall` of TBTC token.
|
|
170
|
+
/// @param from TBTC token holder executing unminting.
|
|
171
|
+
/// @param amount Amount of TBTC to unmint.
|
|
172
|
+
/// @param token TBTC token address.
|
|
173
|
+
/// @param extraData Redemption data in a format expected from
|
|
174
|
+
/// `redemptionData` parameter of Bridge's `receiveBalanceApproval`
|
|
175
|
+
/// function. If empty, `receiveApproval` is not requesting a
|
|
176
|
+
/// redemption of Bank balance but is instead performing just TBTC
|
|
177
|
+
/// unminting to a Bank balance.
|
|
124
178
|
function receiveApproval(
|
|
125
179
|
address from,
|
|
126
180
|
uint256 amount,
|
|
127
181
|
address token,
|
|
128
|
-
bytes calldata
|
|
182
|
+
bytes calldata extraData
|
|
129
183
|
) external {
|
|
130
184
|
require(token == address(tbtcToken), "Token is not TBTC");
|
|
131
185
|
require(msg.sender == token, "Only TBTC caller allowed");
|
|
132
|
-
|
|
186
|
+
if (extraData.length == 0) {
|
|
187
|
+
_unmint(from, amount);
|
|
188
|
+
} else {
|
|
189
|
+
_unmintAndRedeem(from, amount, extraData);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/// @notice Initiates vault upgrade process. The upgrade process needs to be
|
|
194
|
+
/// finalized with a call to `finalizeUpgrade` function after the
|
|
195
|
+
/// `UPGRADE_GOVERNANCE_DELAY` passes. Only the governance can
|
|
196
|
+
/// initiate the upgrade.
|
|
197
|
+
/// @param _newVault The new vault address.
|
|
198
|
+
function initiateUpgrade(address _newVault) external onlyOwner {
|
|
199
|
+
require(_newVault != address(0), "New vault address cannot be zero");
|
|
200
|
+
/* solhint-disable-next-line not-rely-on-time */
|
|
201
|
+
emit UpgradeInitiated(_newVault, block.timestamp);
|
|
202
|
+
/* solhint-disable-next-line not-rely-on-time */
|
|
203
|
+
upgradeInitiatedTimestamp = block.timestamp;
|
|
204
|
+
newVault = _newVault;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/// @notice Allows the governance to finalize vault upgrade process. The
|
|
208
|
+
/// upgrade process needs to be first initiated with a call to
|
|
209
|
+
/// `initiateUpgrade` and the `UPGRADE_GOVERNANCE_DELAY` needs to
|
|
210
|
+
/// pass. Once the upgrade is finalized, the new vault becomes the
|
|
211
|
+
/// owner of the TBTC token and receives the whole Bank balance of
|
|
212
|
+
/// this vault.
|
|
213
|
+
function finalizeUpgrade()
|
|
214
|
+
external
|
|
215
|
+
onlyOwner
|
|
216
|
+
onlyAfterUpgradeGovernanceDelay
|
|
217
|
+
{
|
|
218
|
+
emit UpgradeFinalized(newVault);
|
|
219
|
+
// slither-disable-next-line reentrancy-no-eth
|
|
220
|
+
tbtcToken.transferOwnership(newVault);
|
|
221
|
+
bank.transferBalance(newVault, bank.balanceOf(address(this)));
|
|
222
|
+
newVault = address(0);
|
|
223
|
+
upgradeInitiatedTimestamp = 0;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/// @notice Allows the governance of the TBTCVault to recover any ERC20
|
|
227
|
+
/// token sent mistakenly to the TBTC token contract address.
|
|
228
|
+
/// @param token Address of the recovered ERC20 token contract.
|
|
229
|
+
/// @param recipient Address the recovered token should be sent to.
|
|
230
|
+
/// @param amount Recovered amount.
|
|
231
|
+
function recoverERC20FromToken(
|
|
232
|
+
IERC20 token,
|
|
233
|
+
address recipient,
|
|
234
|
+
uint256 amount
|
|
235
|
+
) external onlyOwner {
|
|
236
|
+
tbtcToken.recoverERC20(token, recipient, amount);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/// @notice Allows the governance of the TBTCVault to recover any ERC721
|
|
240
|
+
/// token sent mistakenly to the TBTC token contract address.
|
|
241
|
+
/// @param token Address of the recovered ERC721 token contract.
|
|
242
|
+
/// @param recipient Address the recovered token should be sent to.
|
|
243
|
+
/// @param tokenId Identifier of the recovered token.
|
|
244
|
+
/// @param data Additional data.
|
|
245
|
+
function recoverERC721FromToken(
|
|
246
|
+
IERC721 token,
|
|
247
|
+
address recipient,
|
|
248
|
+
uint256 tokenId,
|
|
249
|
+
bytes calldata data
|
|
250
|
+
) external onlyOwner {
|
|
251
|
+
tbtcToken.recoverERC721(token, recipient, tokenId, data);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/// @notice Allows the governance of the TBTCVault to recover any ERC20
|
|
255
|
+
/// token sent - mistakenly or not - to the vault address. This
|
|
256
|
+
/// function should be used to withdraw TBTC v1 tokens transferred
|
|
257
|
+
/// to TBTCVault as a result of VendingMachine > TBTCVault upgrade.
|
|
258
|
+
/// @param token Address of the recovered ERC20 token contract.
|
|
259
|
+
/// @param recipient Address the recovered token should be sent to.
|
|
260
|
+
/// @param amount Recovered amount.
|
|
261
|
+
function recoverERC20(
|
|
262
|
+
IERC20 token,
|
|
263
|
+
address recipient,
|
|
264
|
+
uint256 amount
|
|
265
|
+
) external onlyOwner {
|
|
266
|
+
token.safeTransfer(recipient, amount);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/// @notice Allows the governance of the TBTCVault to recover any ERC721
|
|
270
|
+
/// token sent mistakenly to the vault address.
|
|
271
|
+
/// @param token Address of the recovered ERC721 token contract.
|
|
272
|
+
/// @param recipient Address the recovered token should be sent to.
|
|
273
|
+
/// @param tokenId Identifier of the recovered token.
|
|
274
|
+
/// @param data Additional data.
|
|
275
|
+
function recoverERC721(
|
|
276
|
+
IERC721 token,
|
|
277
|
+
address recipient,
|
|
278
|
+
uint256 tokenId,
|
|
279
|
+
bytes calldata data
|
|
280
|
+
) external onlyOwner {
|
|
281
|
+
token.safeTransferFrom(address(this), recipient, tokenId, data);
|
|
133
282
|
}
|
|
134
283
|
|
|
135
284
|
// slither-disable-next-line calls-loop
|
|
@@ -138,9 +287,19 @@ contract TBTCVault is IVault {
|
|
|
138
287
|
tbtcToken.mint(minter, amount);
|
|
139
288
|
}
|
|
140
289
|
|
|
141
|
-
function
|
|
142
|
-
emit
|
|
290
|
+
function _unmint(address unminter, uint256 amount) internal {
|
|
291
|
+
emit Unminted(unminter, amount);
|
|
292
|
+
tbtcToken.burnFrom(unminter, amount);
|
|
293
|
+
bank.transferBalance(unminter, amount);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function _unmintAndRedeem(
|
|
297
|
+
address redeemer,
|
|
298
|
+
uint256 amount,
|
|
299
|
+
bytes calldata redemptionData
|
|
300
|
+
) internal {
|
|
301
|
+
emit Unminted(redeemer, amount);
|
|
143
302
|
tbtcToken.burnFrom(redeemer, amount);
|
|
144
|
-
bank.
|
|
303
|
+
bank.approveBalanceAndCall(bank.bridge(), amount, redemptionData);
|
|
145
304
|
}
|
|
146
305
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { getNamedAccounts, deployments, helpers } = hre
|
|
6
|
+
const { log } = deployments
|
|
7
|
+
const { deployer } = await getNamedAccounts()
|
|
8
|
+
|
|
9
|
+
const Relay = await deployments.getOrNull("Relay")
|
|
10
|
+
|
|
11
|
+
if (Relay && helpers.address.isValid(Relay.address)) {
|
|
12
|
+
log(`using external Relay at ${Relay.address}`)
|
|
13
|
+
} else if (hre.network.name !== "hardhat") {
|
|
14
|
+
throw new Error("deployed Relay contract not found")
|
|
15
|
+
} else {
|
|
16
|
+
log("deploying Relay stub")
|
|
17
|
+
|
|
18
|
+
await deployments.deploy("Relay", {
|
|
19
|
+
contract: "TestRelay",
|
|
20
|
+
from: deployer,
|
|
21
|
+
log: true,
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default func
|
|
27
|
+
|
|
28
|
+
func.tags = ["Relay"]
|
|
@@ -38,7 +38,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
|
38
38
|
|
|
39
39
|
export default func
|
|
40
40
|
|
|
41
|
-
func.tags = ["
|
|
41
|
+
func.tags = ["TransferVendingMachineRoles"]
|
|
42
42
|
func.dependencies = ["TBTC", "VendingMachine"]
|
|
43
43
|
func.runAtTheEnd = true
|
|
44
44
|
func.skip = async function (hre: HardhatRuntimeEnvironment): Promise<boolean> {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { deployments, getNamedAccounts } = hre
|
|
6
|
+
const { deploy } = deployments
|
|
7
|
+
const { deployer } = await getNamedAccounts()
|
|
8
|
+
|
|
9
|
+
const Bank = await deploy("Bank", {
|
|
10
|
+
contract:
|
|
11
|
+
process.env.TEST_USE_STUBS_TBTC === "true" ? "BankStub" : undefined,
|
|
12
|
+
from: deployer,
|
|
13
|
+
args: [],
|
|
14
|
+
log: true,
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
if (hre.network.tags.tenderly) {
|
|
18
|
+
await hre.tenderly.verify({
|
|
19
|
+
name: "Bank",
|
|
20
|
+
address: Bank.address,
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default func
|
|
26
|
+
|
|
27
|
+
func.tags = ["Bank"]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { ethers, helpers, deployments, getNamedAccounts } = hre
|
|
6
|
+
const { deploy } = deployments
|
|
7
|
+
const { deployer, treasury } = await getNamedAccounts()
|
|
8
|
+
|
|
9
|
+
const Bank = await deployments.get("Bank")
|
|
10
|
+
const Relay = await deployments.get("Relay")
|
|
11
|
+
|
|
12
|
+
// TODO: Test for mainnet deployment that when `WalletRegistry` is provided
|
|
13
|
+
// in `external/mainnet/` directory it gets resolved correctly, and the deployment
|
|
14
|
+
// script from `@keep-network/ecdsa` is not invoked once again.
|
|
15
|
+
const WalletRegistry = await deployments.get("WalletRegistry")
|
|
16
|
+
|
|
17
|
+
// For local tests use `1`.
|
|
18
|
+
const txProofDifficultyFactor =
|
|
19
|
+
deployments.getNetworkName() === "hardhat" ? 1 : 6
|
|
20
|
+
|
|
21
|
+
const Deposit = await deploy("Deposit", { from: deployer, log: true })
|
|
22
|
+
const DepositSweep = await deploy("DepositSweep", {
|
|
23
|
+
from: deployer,
|
|
24
|
+
log: true,
|
|
25
|
+
})
|
|
26
|
+
const Redemption = await deploy("Redemption", { from: deployer, log: true })
|
|
27
|
+
const Wallets = await deploy("Wallets", {
|
|
28
|
+
contract: "contracts/bridge/Wallets.sol:Wallets",
|
|
29
|
+
from: deployer,
|
|
30
|
+
log: true,
|
|
31
|
+
})
|
|
32
|
+
const Fraud = await deploy("Fraud", { from: deployer, log: true })
|
|
33
|
+
const MovingFunds = await deploy("MovingFunds", {
|
|
34
|
+
from: deployer,
|
|
35
|
+
log: true,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const bridge = await helpers.upgrades.deployProxy("Bridge", {
|
|
39
|
+
contractName:
|
|
40
|
+
process.env.TEST_USE_STUBS_TBTC === "true" ? "BridgeStub" : undefined,
|
|
41
|
+
initializerArgs: [
|
|
42
|
+
Bank.address,
|
|
43
|
+
Relay.address,
|
|
44
|
+
treasury,
|
|
45
|
+
WalletRegistry.address,
|
|
46
|
+
txProofDifficultyFactor,
|
|
47
|
+
],
|
|
48
|
+
factoryOpts: {
|
|
49
|
+
signer: await ethers.getSigner(deployer),
|
|
50
|
+
libraries: {
|
|
51
|
+
Deposit: Deposit.address,
|
|
52
|
+
DepositSweep: DepositSweep.address,
|
|
53
|
+
Redemption: Redemption.address,
|
|
54
|
+
Wallets: Wallets.address,
|
|
55
|
+
Fraud: Fraud.address,
|
|
56
|
+
MovingFunds: MovingFunds.address,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
proxyOpts: {
|
|
60
|
+
kind: "transparent",
|
|
61
|
+
// Allow external libraries linking. We need to ensure manually that the
|
|
62
|
+
// external libraries we link are upgrade safe, as the OpenZeppelin plugin
|
|
63
|
+
// doesn't perform such a validation yet.
|
|
64
|
+
// See: https://docs.openzeppelin.com/upgrades-plugins/1.x/faq#why-cant-i-use-external-libraries
|
|
65
|
+
unsafeAllow: ["external-library-linking"],
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
if (hre.network.tags.tenderly) {
|
|
70
|
+
await hre.tenderly.verify({
|
|
71
|
+
name: "Bridge",
|
|
72
|
+
address: bridge.address,
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export default func
|
|
78
|
+
|
|
79
|
+
func.tags = ["Bridge"]
|
|
80
|
+
func.dependencies = ["Bank", "Relay", "Treasury", "WalletRegistry"]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { deployments, getNamedAccounts } = hre
|
|
6
|
+
const { deploy } = deployments
|
|
7
|
+
const { deployer } = await getNamedAccounts()
|
|
8
|
+
|
|
9
|
+
const Bank = await deployments.get("Bank")
|
|
10
|
+
const TBTC = await deployments.get("TBTC")
|
|
11
|
+
|
|
12
|
+
const TBTCVault = await deploy("TBTCVault", {
|
|
13
|
+
contract: "TBTCVault",
|
|
14
|
+
from: deployer,
|
|
15
|
+
args: [Bank.address, TBTC.address],
|
|
16
|
+
log: true,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
if (hre.network.tags.tenderly) {
|
|
20
|
+
await hre.tenderly.verify({
|
|
21
|
+
name: "TBTCVault",
|
|
22
|
+
address: TBTCVault.address,
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default func
|
|
28
|
+
|
|
29
|
+
func.tags = ["TBTCVault"]
|
|
30
|
+
func.dependencies = ["Bank", "TBTC"]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { deployments, getNamedAccounts } = hre
|
|
6
|
+
const { deploy } = deployments
|
|
7
|
+
const { deployer } = await getNamedAccounts()
|
|
8
|
+
|
|
9
|
+
const Bridge = await deployments.get("Bridge")
|
|
10
|
+
|
|
11
|
+
const BridgeGovernanceParameters = await deployments.deploy(
|
|
12
|
+
"BridgeGovernanceParameters",
|
|
13
|
+
{
|
|
14
|
+
from: deployer,
|
|
15
|
+
log: true,
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
const GOVERNANCE_DELAY = 604800 // 1 week
|
|
20
|
+
|
|
21
|
+
const BridgeGovernance = await deploy("BridgeGovernance", {
|
|
22
|
+
from: deployer,
|
|
23
|
+
args: [Bridge.address, GOVERNANCE_DELAY],
|
|
24
|
+
log: true,
|
|
25
|
+
libraries: {
|
|
26
|
+
BridgeGovernanceParameters: BridgeGovernanceParameters.address,
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
if (hre.network.tags.tenderly) {
|
|
31
|
+
await hre.tenderly.verify({
|
|
32
|
+
name: "BridgeGovernance",
|
|
33
|
+
address: BridgeGovernance.address,
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default func
|
|
39
|
+
|
|
40
|
+
func.tags = ["BridgeGovernance"]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { deployments, getNamedAccounts } = hre
|
|
6
|
+
const { deploy } = deployments
|
|
7
|
+
const { deployer } = await getNamedAccounts()
|
|
8
|
+
|
|
9
|
+
const Bridge = await deployments.get("Bridge")
|
|
10
|
+
const ReimbursementPool = await deployments.get("ReimbursementPool")
|
|
11
|
+
|
|
12
|
+
const MaintainerProxy = await deploy("MaintainerProxy", {
|
|
13
|
+
contract: "MaintainerProxy",
|
|
14
|
+
from: deployer,
|
|
15
|
+
args: [Bridge.address, ReimbursementPool.address],
|
|
16
|
+
log: true,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
if (hre.network.tags.tenderly) {
|
|
20
|
+
await hre.tenderly.verify({
|
|
21
|
+
name: "MaintainerProxy",
|
|
22
|
+
address: MaintainerProxy.address,
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default func
|
|
28
|
+
|
|
29
|
+
func.tags = ["MaintainerProxy"]
|
|
30
|
+
func.dependencies = ["Bridge", "ReimbursementPool"]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { getNamedAccounts, deployments } = hre
|
|
6
|
+
const { execute, log } = deployments
|
|
7
|
+
const { deployer } = await getNamedAccounts()
|
|
8
|
+
|
|
9
|
+
const Bridge = await deployments.get("Bridge")
|
|
10
|
+
|
|
11
|
+
log("updating Bridge in Bank")
|
|
12
|
+
|
|
13
|
+
await execute("Bank", { from: deployer }, "updateBridge", Bridge.address)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default func
|
|
17
|
+
|
|
18
|
+
func.tags = ["BankUpdateBridge"]
|
|
19
|
+
func.dependencies = ["Bank", "Bridge"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { getNamedAccounts, helpers } = hre
|
|
6
|
+
const { deployer, governance } = await getNamedAccounts()
|
|
7
|
+
|
|
8
|
+
await helpers.ownable.transferOwnership("Bank", governance, deployer)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default func
|
|
12
|
+
|
|
13
|
+
func.tags = ["TransferBankOwnership"]
|
|
14
|
+
func.dependencies = ["Bank"]
|
|
15
|
+
func.runAtTheEnd = true
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { getNamedAccounts, deployments } = hre
|
|
6
|
+
const { deployer } = await getNamedAccounts()
|
|
7
|
+
|
|
8
|
+
const BridgeGovernance = await deployments.get("BridgeGovernance")
|
|
9
|
+
|
|
10
|
+
await deployments.execute(
|
|
11
|
+
"Bridge",
|
|
12
|
+
{ from: deployer },
|
|
13
|
+
"transferGovernance",
|
|
14
|
+
BridgeGovernance.address
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default func
|
|
19
|
+
|
|
20
|
+
func.tags = ["TransferBridgeGovernance"]
|
|
21
|
+
func.dependencies = ["Bridge"]
|
|
22
|
+
func.runAtTheEnd = true
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { HardhatRuntimeEnvironment } from "hardhat/types"
|
|
2
|
+
import { DeployFunction } from "hardhat-deploy/types"
|
|
3
|
+
|
|
4
|
+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
5
|
+
const { getNamedAccounts, helpers } = hre
|
|
6
|
+
const { deployer, governance } = await getNamedAccounts()
|
|
7
|
+
|
|
8
|
+
await helpers.ownable.transferOwnership(
|
|
9
|
+
"BridgeGovernance",
|
|
10
|
+
governance,
|
|
11
|
+
deployer
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default func
|
|
16
|
+
|
|
17
|
+
func.tags = ["BridgeGovernanceOwnership"]
|
|
18
|
+
func.dependencies = ["BridgeGovernance"]
|
|
19
|
+
func.runAtTheEnd = true
|