@keep-network/tbtc-v2 0.1.1-dev.78 → 0.1.1-dev.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/artifacts/Bank.json +18 -13
- package/artifacts/Bridge.json +11 -11
- package/artifacts/Deposit.json +7 -7
- package/artifacts/DepositSweep.json +7 -7
- package/artifacts/EcdsaDkgValidator.json +1 -1
- package/artifacts/EcdsaInactivity.json +1 -1
- package/artifacts/EcdsaSortitionPool.json +2 -2
- package/artifacts/Fraud.json +7 -7
- package/artifacts/KeepRegistry.json +1 -1
- package/artifacts/KeepStake.json +2 -2
- package/artifacts/KeepToken.json +2 -2
- package/artifacts/KeepTokenStaking.json +1 -1
- package/artifacts/MovingFunds.json +7 -7
- package/artifacts/NuCypherStakingEscrow.json +1 -1
- package/artifacts/NuCypherToken.json +2 -2
- package/artifacts/RandomBeaconStub.json +1 -1
- package/artifacts/Redemption.json +7 -7
- package/artifacts/ReimbursementPool.json +2 -2
- package/artifacts/Relay.json +9 -9
- package/artifacts/T.json +2 -2
- package/artifacts/TBTC.json +3 -3
- package/artifacts/TBTCToken.json +3 -3
- package/artifacts/TBTCVault.json +462 -0
- package/artifacts/TokenStaking.json +1 -1
- package/artifacts/TokenholderGovernor.json +9 -9
- package/artifacts/TokenholderTimelock.json +8 -8
- package/artifacts/VendingMachine.json +10 -10
- package/artifacts/VendingMachineKeep.json +1 -1
- package/artifacts/VendingMachineNuCypher.json +1 -1
- package/artifacts/WalletRegistry.json +5 -5
- package/artifacts/WalletRegistryGovernance.json +2 -2
- package/artifacts/Wallets.json +7 -7
- package/artifacts/solcInputs/{53b3428138f3e1a8f29707c3a3799af0.json → 4f6d4f5cd1e3d835e20ed55926a445cd.json} +4 -4
- package/build/contracts/GovernanceUtils.sol/GovernanceUtils.dbg.json +1 -1
- package/build/contracts/bank/Bank.sol/Bank.dbg.json +1 -1
- package/build/contracts/bank/Bank.sol/Bank.json +7 -2
- package/build/contracts/bank/IReceiveBalanceApproval.sol/IReceiveBalanceApproval.dbg.json +1 -1
- package/build/contracts/bank/IReceiveBalanceApproval.sol/IReceiveBalanceApproval.json +5 -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 +2 -2
- package/build/contracts/bridge/BridgeState.sol/BridgeState.dbg.json +1 -1
- package/build/contracts/bridge/BridgeState.sol/BridgeState.json +2 -2
- package/build/contracts/bridge/Deposit.sol/Deposit.dbg.json +1 -1
- package/build/contracts/bridge/Deposit.sol/Deposit.json +2 -2
- package/build/contracts/bridge/DepositSweep.sol/DepositSweep.dbg.json +1 -1
- package/build/contracts/bridge/DepositSweep.sol/DepositSweep.json +2 -2
- package/build/contracts/bridge/EcdsaLib.sol/EcdsaLib.dbg.json +1 -1
- package/build/contracts/bridge/Fraud.sol/Fraud.dbg.json +1 -1
- package/build/contracts/bridge/Fraud.sol/Fraud.json +2 -2
- package/build/contracts/bridge/Heartbeat.sol/Heartbeat.dbg.json +1 -1
- package/build/contracts/bridge/IRelay.sol/IRelay.dbg.json +1 -1
- package/build/contracts/bridge/MovingFunds.sol/MovingFunds.dbg.json +1 -1
- package/build/contracts/bridge/MovingFunds.sol/MovingFunds.json +2 -2
- package/build/contracts/bridge/Redemption.sol/OutboundTx.dbg.json +1 -1
- package/build/contracts/bridge/Redemption.sol/OutboundTx.json +2 -2
- package/build/contracts/bridge/Redemption.sol/Redemption.dbg.json +1 -1
- package/build/contracts/bridge/Redemption.sol/Redemption.json +2 -2
- package/build/contracts/bridge/VendingMachine.sol/VendingMachine.dbg.json +1 -1
- package/build/contracts/bridge/Wallets.sol/Wallets.dbg.json +1 -1
- package/build/contracts/bridge/Wallets.sol/Wallets.json +2 -2
- package/build/contracts/token/TBTC.sol/TBTC.dbg.json +1 -1
- package/build/contracts/vault/DonationVault.sol/DonationVault.dbg.json +1 -1
- package/build/contracts/vault/DonationVault.sol/DonationVault.json +7 -2
- 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 +7 -2
- package/contracts/bank/Bank.sol +7 -2
- package/contracts/bank/IReceiveBalanceApproval.sol +6 -1
- package/contracts/vault/DonationVault.sol +5 -5
- package/contracts/vault/TBTCVault.sol +5 -5
- package/deploy/06_deploy_tbtc_vault.ts +30 -0
- package/deploy/{06_bank_update_bridge.ts → 07_bank_update_bridge.ts} +0 -0
- package/deploy/{07_transfer_ownership.ts → 08_transfer_ownership.ts} +0 -0
- package/deploy/{08_transfer_governance.ts → 09_transfer_governance.ts} +0 -0
- package/deploy/{09_transfer_proxy_admin_ownership.ts → 10_transfer_proxy_admin_ownership.ts} +0 -0
- package/deploy/{10_deploy_proxy_admin_with_deputy.ts → 11_deploy_proxy_admin_with_deputy.ts} +0 -0
- package/export.json +281 -0
- package/package.json +1 -1
package/contracts/bank/Bank.sol
CHANGED
|
@@ -125,11 +125,16 @@ contract Bank is Ownable {
|
|
|
125
125
|
/// both the old and the new allowance by unfortunate transaction
|
|
126
126
|
/// ordering. Please use `increaseBalanceAllowance` and
|
|
127
127
|
/// `decreaseBalanceAllowance` to eliminate the risk.
|
|
128
|
-
function approveBalanceAndCall(
|
|
128
|
+
function approveBalanceAndCall(
|
|
129
|
+
address spender,
|
|
130
|
+
uint256 amount,
|
|
131
|
+
bytes memory extraData
|
|
132
|
+
) external {
|
|
129
133
|
_approveBalance(msg.sender, spender, amount);
|
|
130
134
|
IReceiveBalanceApproval(spender).receiveBalanceApproval(
|
|
131
135
|
msg.sender,
|
|
132
|
-
amount
|
|
136
|
+
amount,
|
|
137
|
+
extraData
|
|
133
138
|
);
|
|
134
139
|
}
|
|
135
140
|
|
|
@@ -29,6 +29,7 @@ interface IReceiveBalanceApproval {
|
|
|
29
29
|
/// balance to be used by the contract.
|
|
30
30
|
/// @param amount The amount of the Bank balance approved by the owner
|
|
31
31
|
/// to be used by the contract.
|
|
32
|
+
/// @param extraData The `extraData` passed to `Bank.approveBalanceAndCall`.
|
|
32
33
|
// @dev The implementation must ensure this function can only be called
|
|
33
34
|
/// by the Bank. The Bank does _not_ guarantee that the `amount`
|
|
34
35
|
/// approved by the `owner` currently exists on their balance. That is,
|
|
@@ -36,5 +37,9 @@ interface IReceiveBalanceApproval {
|
|
|
36
37
|
/// This works the same as `Bank.approve` function. The contract must
|
|
37
38
|
/// ensure the actual balance is checked before performing any action
|
|
38
39
|
/// based on it.
|
|
39
|
-
function receiveBalanceApproval(
|
|
40
|
+
function receiveBalanceApproval(
|
|
41
|
+
address owner,
|
|
42
|
+
uint256 amount,
|
|
43
|
+
bytes memory extraData
|
|
44
|
+
) external;
|
|
40
45
|
}
|
|
@@ -80,11 +80,11 @@ contract DonationVault is IVault {
|
|
|
80
80
|
/// - Can only be called by the Bank via `approveBalanceAndCall`,
|
|
81
81
|
/// - The `owner` balance in the Bank must be greater than or equal
|
|
82
82
|
/// to the `amount`.
|
|
83
|
-
function receiveBalanceApproval(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
{
|
|
83
|
+
function receiveBalanceApproval(
|
|
84
|
+
address owner,
|
|
85
|
+
uint256 amount,
|
|
86
|
+
bytes memory
|
|
87
|
+
) external override onlyBank {
|
|
88
88
|
require(
|
|
89
89
|
bank.balanceOf(owner) >= amount,
|
|
90
90
|
"Amount exceeds balance in the bank"
|
|
@@ -107,11 +107,11 @@ contract TBTCVault is IVault, Governable {
|
|
|
107
107
|
/// @dev Can only be called by the Bank via `approveBalanceAndCall`.
|
|
108
108
|
/// @param owner The owner who approved their Bank balance.
|
|
109
109
|
/// @param amount Amount of TBTC to mint.
|
|
110
|
-
function receiveBalanceApproval(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
{
|
|
110
|
+
function receiveBalanceApproval(
|
|
111
|
+
address owner,
|
|
112
|
+
uint256 amount,
|
|
113
|
+
bytes memory
|
|
114
|
+
) external override onlyBank {
|
|
115
115
|
require(
|
|
116
116
|
bank.balanceOf(owner) >= amount,
|
|
117
117
|
"Amount exceeds balance in the bank"
|
|
@@ -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"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/deploy/{09_transfer_proxy_admin_ownership.ts → 10_transfer_proxy_admin_ownership.ts}
RENAMED
|
File without changes
|
package/deploy/{10_deploy_proxy_admin_with_deputy.ts → 11_deploy_proxy_admin_with_deputy.ts}
RENAMED
|
File without changes
|
package/export.json
CHANGED
|
@@ -13377,6 +13377,11 @@
|
|
|
13377
13377
|
"internalType": "uint256",
|
|
13378
13378
|
"name": "amount",
|
|
13379
13379
|
"type": "uint256"
|
|
13380
|
+
},
|
|
13381
|
+
{
|
|
13382
|
+
"internalType": "bytes",
|
|
13383
|
+
"name": "extraData",
|
|
13384
|
+
"type": "bytes"
|
|
13380
13385
|
}
|
|
13381
13386
|
],
|
|
13382
13387
|
"name": "approveBalanceAndCall",
|
|
@@ -16779,6 +16784,282 @@
|
|
|
16779
16784
|
]
|
|
16780
16785
|
}
|
|
16781
16786
|
]
|
|
16787
|
+
},
|
|
16788
|
+
"TBTCVault": {
|
|
16789
|
+
"address": "0xDadd1125B8Df98A66Abd5EB302C0d9Ca5A061dC2",
|
|
16790
|
+
"abi": [
|
|
16791
|
+
{
|
|
16792
|
+
"inputs": [
|
|
16793
|
+
{
|
|
16794
|
+
"internalType": "contract Bank",
|
|
16795
|
+
"name": "_bank",
|
|
16796
|
+
"type": "address"
|
|
16797
|
+
},
|
|
16798
|
+
{
|
|
16799
|
+
"internalType": "contract TBTC",
|
|
16800
|
+
"name": "_tbtcToken",
|
|
16801
|
+
"type": "address"
|
|
16802
|
+
}
|
|
16803
|
+
],
|
|
16804
|
+
"stateMutability": "nonpayable",
|
|
16805
|
+
"type": "constructor"
|
|
16806
|
+
},
|
|
16807
|
+
{
|
|
16808
|
+
"anonymous": false,
|
|
16809
|
+
"inputs": [
|
|
16810
|
+
{
|
|
16811
|
+
"indexed": false,
|
|
16812
|
+
"internalType": "address",
|
|
16813
|
+
"name": "oldGovernance",
|
|
16814
|
+
"type": "address"
|
|
16815
|
+
},
|
|
16816
|
+
{
|
|
16817
|
+
"indexed": false,
|
|
16818
|
+
"internalType": "address",
|
|
16819
|
+
"name": "newGovernance",
|
|
16820
|
+
"type": "address"
|
|
16821
|
+
}
|
|
16822
|
+
],
|
|
16823
|
+
"name": "GovernanceTransferred",
|
|
16824
|
+
"type": "event"
|
|
16825
|
+
},
|
|
16826
|
+
{
|
|
16827
|
+
"anonymous": false,
|
|
16828
|
+
"inputs": [
|
|
16829
|
+
{
|
|
16830
|
+
"indexed": true,
|
|
16831
|
+
"internalType": "address",
|
|
16832
|
+
"name": "to",
|
|
16833
|
+
"type": "address"
|
|
16834
|
+
},
|
|
16835
|
+
{
|
|
16836
|
+
"indexed": false,
|
|
16837
|
+
"internalType": "uint256",
|
|
16838
|
+
"name": "amount",
|
|
16839
|
+
"type": "uint256"
|
|
16840
|
+
}
|
|
16841
|
+
],
|
|
16842
|
+
"name": "Minted",
|
|
16843
|
+
"type": "event"
|
|
16844
|
+
},
|
|
16845
|
+
{
|
|
16846
|
+
"anonymous": false,
|
|
16847
|
+
"inputs": [
|
|
16848
|
+
{
|
|
16849
|
+
"indexed": true,
|
|
16850
|
+
"internalType": "address",
|
|
16851
|
+
"name": "from",
|
|
16852
|
+
"type": "address"
|
|
16853
|
+
},
|
|
16854
|
+
{
|
|
16855
|
+
"indexed": false,
|
|
16856
|
+
"internalType": "uint256",
|
|
16857
|
+
"name": "amount",
|
|
16858
|
+
"type": "uint256"
|
|
16859
|
+
}
|
|
16860
|
+
],
|
|
16861
|
+
"name": "Redeemed",
|
|
16862
|
+
"type": "event"
|
|
16863
|
+
},
|
|
16864
|
+
{
|
|
16865
|
+
"inputs": [],
|
|
16866
|
+
"name": "bank",
|
|
16867
|
+
"outputs": [
|
|
16868
|
+
{
|
|
16869
|
+
"internalType": "contract Bank",
|
|
16870
|
+
"name": "",
|
|
16871
|
+
"type": "address"
|
|
16872
|
+
}
|
|
16873
|
+
],
|
|
16874
|
+
"stateMutability": "view",
|
|
16875
|
+
"type": "function"
|
|
16876
|
+
},
|
|
16877
|
+
{
|
|
16878
|
+
"inputs": [],
|
|
16879
|
+
"name": "governance",
|
|
16880
|
+
"outputs": [
|
|
16881
|
+
{
|
|
16882
|
+
"internalType": "address",
|
|
16883
|
+
"name": "",
|
|
16884
|
+
"type": "address"
|
|
16885
|
+
}
|
|
16886
|
+
],
|
|
16887
|
+
"stateMutability": "view",
|
|
16888
|
+
"type": "function"
|
|
16889
|
+
},
|
|
16890
|
+
{
|
|
16891
|
+
"inputs": [
|
|
16892
|
+
{
|
|
16893
|
+
"internalType": "uint256",
|
|
16894
|
+
"name": "amount",
|
|
16895
|
+
"type": "uint256"
|
|
16896
|
+
}
|
|
16897
|
+
],
|
|
16898
|
+
"name": "mint",
|
|
16899
|
+
"outputs": [],
|
|
16900
|
+
"stateMutability": "nonpayable",
|
|
16901
|
+
"type": "function"
|
|
16902
|
+
},
|
|
16903
|
+
{
|
|
16904
|
+
"inputs": [
|
|
16905
|
+
{
|
|
16906
|
+
"internalType": "address",
|
|
16907
|
+
"name": "from",
|
|
16908
|
+
"type": "address"
|
|
16909
|
+
},
|
|
16910
|
+
{
|
|
16911
|
+
"internalType": "uint256",
|
|
16912
|
+
"name": "amount",
|
|
16913
|
+
"type": "uint256"
|
|
16914
|
+
},
|
|
16915
|
+
{
|
|
16916
|
+
"internalType": "address",
|
|
16917
|
+
"name": "token",
|
|
16918
|
+
"type": "address"
|
|
16919
|
+
},
|
|
16920
|
+
{
|
|
16921
|
+
"internalType": "bytes",
|
|
16922
|
+
"name": "",
|
|
16923
|
+
"type": "bytes"
|
|
16924
|
+
}
|
|
16925
|
+
],
|
|
16926
|
+
"name": "receiveApproval",
|
|
16927
|
+
"outputs": [],
|
|
16928
|
+
"stateMutability": "nonpayable",
|
|
16929
|
+
"type": "function"
|
|
16930
|
+
},
|
|
16931
|
+
{
|
|
16932
|
+
"inputs": [
|
|
16933
|
+
{
|
|
16934
|
+
"internalType": "address",
|
|
16935
|
+
"name": "owner",
|
|
16936
|
+
"type": "address"
|
|
16937
|
+
},
|
|
16938
|
+
{
|
|
16939
|
+
"internalType": "uint256",
|
|
16940
|
+
"name": "amount",
|
|
16941
|
+
"type": "uint256"
|
|
16942
|
+
},
|
|
16943
|
+
{
|
|
16944
|
+
"internalType": "bytes",
|
|
16945
|
+
"name": "",
|
|
16946
|
+
"type": "bytes"
|
|
16947
|
+
}
|
|
16948
|
+
],
|
|
16949
|
+
"name": "receiveBalanceApproval",
|
|
16950
|
+
"outputs": [],
|
|
16951
|
+
"stateMutability": "nonpayable",
|
|
16952
|
+
"type": "function"
|
|
16953
|
+
},
|
|
16954
|
+
{
|
|
16955
|
+
"inputs": [
|
|
16956
|
+
{
|
|
16957
|
+
"internalType": "address[]",
|
|
16958
|
+
"name": "depositors",
|
|
16959
|
+
"type": "address[]"
|
|
16960
|
+
},
|
|
16961
|
+
{
|
|
16962
|
+
"internalType": "uint256[]",
|
|
16963
|
+
"name": "depositedAmounts",
|
|
16964
|
+
"type": "uint256[]"
|
|
16965
|
+
}
|
|
16966
|
+
],
|
|
16967
|
+
"name": "receiveBalanceIncrease",
|
|
16968
|
+
"outputs": [],
|
|
16969
|
+
"stateMutability": "nonpayable",
|
|
16970
|
+
"type": "function"
|
|
16971
|
+
},
|
|
16972
|
+
{
|
|
16973
|
+
"inputs": [
|
|
16974
|
+
{
|
|
16975
|
+
"internalType": "contract IERC20",
|
|
16976
|
+
"name": "token",
|
|
16977
|
+
"type": "address"
|
|
16978
|
+
},
|
|
16979
|
+
{
|
|
16980
|
+
"internalType": "address",
|
|
16981
|
+
"name": "recipient",
|
|
16982
|
+
"type": "address"
|
|
16983
|
+
},
|
|
16984
|
+
{
|
|
16985
|
+
"internalType": "uint256",
|
|
16986
|
+
"name": "amount",
|
|
16987
|
+
"type": "uint256"
|
|
16988
|
+
}
|
|
16989
|
+
],
|
|
16990
|
+
"name": "recoverERC20",
|
|
16991
|
+
"outputs": [],
|
|
16992
|
+
"stateMutability": "nonpayable",
|
|
16993
|
+
"type": "function"
|
|
16994
|
+
},
|
|
16995
|
+
{
|
|
16996
|
+
"inputs": [
|
|
16997
|
+
{
|
|
16998
|
+
"internalType": "contract IERC721",
|
|
16999
|
+
"name": "token",
|
|
17000
|
+
"type": "address"
|
|
17001
|
+
},
|
|
17002
|
+
{
|
|
17003
|
+
"internalType": "address",
|
|
17004
|
+
"name": "recipient",
|
|
17005
|
+
"type": "address"
|
|
17006
|
+
},
|
|
17007
|
+
{
|
|
17008
|
+
"internalType": "uint256",
|
|
17009
|
+
"name": "tokenId",
|
|
17010
|
+
"type": "uint256"
|
|
17011
|
+
},
|
|
17012
|
+
{
|
|
17013
|
+
"internalType": "bytes",
|
|
17014
|
+
"name": "data",
|
|
17015
|
+
"type": "bytes"
|
|
17016
|
+
}
|
|
17017
|
+
],
|
|
17018
|
+
"name": "recoverERC721",
|
|
17019
|
+
"outputs": [],
|
|
17020
|
+
"stateMutability": "nonpayable",
|
|
17021
|
+
"type": "function"
|
|
17022
|
+
},
|
|
17023
|
+
{
|
|
17024
|
+
"inputs": [
|
|
17025
|
+
{
|
|
17026
|
+
"internalType": "uint256",
|
|
17027
|
+
"name": "amount",
|
|
17028
|
+
"type": "uint256"
|
|
17029
|
+
}
|
|
17030
|
+
],
|
|
17031
|
+
"name": "redeem",
|
|
17032
|
+
"outputs": [],
|
|
17033
|
+
"stateMutability": "nonpayable",
|
|
17034
|
+
"type": "function"
|
|
17035
|
+
},
|
|
17036
|
+
{
|
|
17037
|
+
"inputs": [],
|
|
17038
|
+
"name": "tbtcToken",
|
|
17039
|
+
"outputs": [
|
|
17040
|
+
{
|
|
17041
|
+
"internalType": "contract TBTC",
|
|
17042
|
+
"name": "",
|
|
17043
|
+
"type": "address"
|
|
17044
|
+
}
|
|
17045
|
+
],
|
|
17046
|
+
"stateMutability": "view",
|
|
17047
|
+
"type": "function"
|
|
17048
|
+
},
|
|
17049
|
+
{
|
|
17050
|
+
"inputs": [
|
|
17051
|
+
{
|
|
17052
|
+
"internalType": "address",
|
|
17053
|
+
"name": "newGovernance",
|
|
17054
|
+
"type": "address"
|
|
17055
|
+
}
|
|
17056
|
+
],
|
|
17057
|
+
"name": "transferGovernance",
|
|
17058
|
+
"outputs": [],
|
|
17059
|
+
"stateMutability": "nonpayable",
|
|
17060
|
+
"type": "function"
|
|
17061
|
+
}
|
|
17062
|
+
]
|
|
16782
17063
|
}
|
|
16783
17064
|
}
|
|
16784
17065
|
}
|