@wireio/stake 0.2.4 → 0.3.0
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/lib/stake.browser.js +5991 -4340
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +74 -60
- package/lib/stake.js +9782 -8054
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +5991 -4340
- package/lib/stake.m.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/BeaconState.sol/BeaconState.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/BeaconState.sol/BeaconState.json +807 -0
- package/src/assets/ethereum/ABI/liqEth/DepositManager.sol/DepositManager.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/DepositManager.sol/DepositManager.json +184 -346
- package/src/assets/ethereum/ABI/liqEth/LiqEthAuthority.sol/LiqEthAuthority.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthAuthority.sol/LiqEthAuthority.json +1289 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IAccounting.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositContract.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositManager.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthUpgradeable.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthUpgradeable.json +29 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20.json +36 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20Pausable.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20Pausable.json +263 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IStakingModule.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IStakingModule.json +226 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IValidatorBalanceVerifier.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IValidatorBalanceVerifier.json +59 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IWithdrawalRecord.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IWithdrawalRecord.json +14 -12
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/LiqEthCommon.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/LiqEthCommon.json +2 -2
- package/src/assets/ethereum/ABI/liqEth/LiqEthManaged.sol/LiqEthManaged.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthManaged.sol/LiqEthManaged.json +229 -0
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20.sol/RewardsERC20Upgradeable.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/{RewardsERC20Pausable.sol/RewardsERC20Pausable.json → RewardsERC20.sol/RewardsERC20Upgradeable.json} +140 -78
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20Pausable.sol/RewardsERC20PausableUpgradeable.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/{RewardsERC20.sol/RewardsERC20.json → RewardsERC20Pausable.sol/RewardsERC20PausableUpgradeable.json} +218 -30
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/BeaconRoots.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/BeaconRoots.json +2 -2
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZ.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZ.json +2 -2
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZExtras.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZExtras.json +10 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZVec48.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZVec48.json +10 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/ValidatorBalanceVerifier.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/ValidatorBalanceVerifier.json +121 -55
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/YieldOracle.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/YieldOracle.json +836 -273
- package/src/assets/ethereum/ABI/liqEth/accounting.sol/Accounting.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/accounting.sol/Accounting.json +150 -168
- package/src/assets/ethereum/ABI/liqEth/liqEth.sol/LiqEthToken.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/liqEth.sol/LiqEthToken.json +301 -186
- package/src/assets/ethereum/ABI/liqEth/stakingModule.sol/StakingModule.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/stakingModule.sol/StakingModule.json +814 -206
- package/src/assets/ethereum/ABI/liqEth/withdrawalQueue.sol/WithdrawalQueue.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/withdrawalQueue.sol/WithdrawalQueue.json +244 -198
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/Uint64BE.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/Uint64BE.json +2 -2
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/WithdrawalVault.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/WithdrawalVault.json +165 -152
- package/src/assets/ethereum/ABI/outpost/Aggregator.sol/Aggregator.json +82 -0
- package/src/assets/ethereum/ABI/outpost/Depositor.sol/Depositor.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/Depositor.sol/Depositor.json +167 -282
- package/src/assets/ethereum/ABI/outpost/EthUsdPriceConsumer.sol/AggregatorV3Interface.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/EthUsdPriceConsumer.sol/EthUsdPriceConsumer.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/EthUsdPriceConsumer.sol/EthUsdPriceConsumer.json +2 -54
- package/src/assets/ethereum/ABI/outpost/OPP.sol/OPP.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/OPP.sol/OPP.json +26 -8
- package/src/assets/ethereum/ABI/outpost/OPPInbound.sol/OPPInbound.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/OPPInbound.sol/OPPInbound.json +2 -2
- package/src/assets/ethereum/ABI/outpost/Pretoken.sol/Pretoken.dbg.json +4 -0
- package/src/assets/ethereum/ABI/outpost/Pretoken.sol/Pretoken.json +1650 -0
- package/src/assets/ethereum/ABI/outpost/ReceiptNFT.sol/ReceiptNFT.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/ReceiptNFT.sol/ReceiptNFT.json +2 -22
- package/src/assets/ethereum/ABI/outpost/interfaces/IPretoken.sol/IPretoken.dbg.json +4 -0
- package/src/assets/ethereum/ABI/outpost/interfaces/IPretoken.sol/IPretoken.json +29 -0
- package/src/assets/ethereum/ABI/outpost/interfaces/IWarrant.sol/IWarrant.dbg.json +1 -1
- package/src/networks/ethereum/clients/deposit.client.ts +86 -8
- package/src/networks/ethereum/clients/liq.client.ts +47 -0
- package/src/networks/ethereum/clients/pretoken.client.ts +127 -0
- package/src/networks/ethereum/clients/stake.client.ts +87 -24
- package/src/networks/ethereum/contract.ts +34 -48
- package/src/networks/ethereum/ethereum.ts +219 -96
- package/src/networks/ethereum/types.ts +9 -6
- package/src/networks/ethereum/utils.ts +308 -0
- package/src/networks/solana/clients/token.client.ts +0 -1
- package/src/networks/solana/solana.ts +44 -146
- package/src/networks/solana/types.ts +6 -2
- package/src/networks/solana/utils.ts +4 -6
- package/src/staker/types.ts +62 -0
- package/src/types.ts +18 -33
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20.sol/RewardsERC20.dbg.json +0 -4
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20Pausable.sol/RewardsERC20Pausable.dbg.json +0 -4
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/BeaconRoots.dbg.json +0 -4
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/BeaconRoots.json +0 -10
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/SSZ.dbg.json +0 -4
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/SSZ.json +0 -10
- package/src/assets/ethereum/ABI/outpost/Warrant.sol/Warrant.dbg.json +0 -4
- package/src/assets/ethereum/ABI/outpost/Warrant.sol/Warrant.json +0 -1650
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import { BigNumber, ethers } from 'ethers';
|
|
2
|
-
import { IStakingClient, Portfolio,
|
|
3
|
-
import { PublicKey as WirePubKey } from '@wireio/core';
|
|
2
|
+
import { IStakingClient, Portfolio, StakerConfig, TrancheSnapshot } from '../../types';
|
|
3
|
+
import { ChainID, EvmChainID, PublicKey as WirePubKey } from '@wireio/core';
|
|
4
4
|
import { EthereumContractService } from './contract';
|
|
5
|
-
import { preLaunchReceipt
|
|
5
|
+
import { preLaunchReceipt } from './types';
|
|
6
6
|
import { DepositClient } from './clients/deposit.client';
|
|
7
7
|
import { StakeClient } from './clients/stake.client';
|
|
8
|
+
import { PretokenClient } from './clients/pretoken.client';
|
|
9
|
+
import { buildEthereumTrancheSnapshot } from './utils';
|
|
10
|
+
import { LiqClient } from './clients/liq.client';
|
|
11
|
+
|
|
8
12
|
|
|
9
13
|
|
|
10
14
|
|
|
11
15
|
export class EthereumStakingClient implements IStakingClient {
|
|
12
|
-
public readonly pubKey
|
|
16
|
+
public readonly pubKey?: WirePubKey;
|
|
13
17
|
private readonly provider: ethers.providers.Web3Provider;
|
|
14
18
|
private readonly signer: ethers.Signer;
|
|
15
19
|
private readonly contractService: EthereumContractService;
|
|
16
20
|
|
|
17
21
|
private depositClient: DepositClient;
|
|
22
|
+
private liqClient: LiqClient;
|
|
23
|
+
private pretokenClient: PretokenClient;
|
|
18
24
|
private stakeClient: StakeClient;
|
|
19
25
|
|
|
26
|
+
|
|
20
27
|
get contract() { return this.contractService.contract; }
|
|
21
28
|
get network() { return this.config.network; }
|
|
22
29
|
|
|
@@ -24,13 +31,16 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
24
31
|
try {
|
|
25
32
|
this.provider = config.provider as ethers.providers.Web3Provider;
|
|
26
33
|
this.signer = this.provider.getSigner();
|
|
27
|
-
this.pubKey = config.pubKey
|
|
34
|
+
this.pubKey = config.pubKey;
|
|
28
35
|
|
|
29
36
|
this.contractService = new EthereumContractService({
|
|
30
37
|
provider: this.provider,
|
|
31
38
|
signer: this.signer,
|
|
32
39
|
});
|
|
40
|
+
|
|
33
41
|
this.depositClient = new DepositClient(this.contractService);
|
|
42
|
+
this.liqClient = new LiqClient(this.contractService);
|
|
43
|
+
this.pretokenClient = new PretokenClient(this.contractService);
|
|
34
44
|
this.stakeClient = new StakeClient(this.contractService);
|
|
35
45
|
}
|
|
36
46
|
catch (error) {
|
|
@@ -39,6 +49,8 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
39
49
|
}
|
|
40
50
|
}
|
|
41
51
|
|
|
52
|
+
|
|
53
|
+
|
|
42
54
|
// ---------------------------------------------------------------------
|
|
43
55
|
// Public IStakingClient Interface Methods
|
|
44
56
|
// ---------------------------------------------------------------------
|
|
@@ -59,18 +71,29 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
59
71
|
}
|
|
60
72
|
|
|
61
73
|
|
|
62
|
-
// TODO - In progress
|
|
63
|
-
async withdraw(amount: number | string | bigint | BigNumber): Promise<string> {
|
|
64
|
-
const amountWei = BigNumber.isBigNumber(amount)
|
|
65
|
-
? amount
|
|
66
|
-
: BigNumber.from(amount);
|
|
67
74
|
|
|
68
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Withdraw native ETH from the liqETH protocol via the liqeth safeBurn function, which burns the LiqETH and adds the user to the withdrawal queue.
|
|
77
|
+
* @param amount Amount in wei (or something convertible to BigNumber).
|
|
78
|
+
* @returns transaction hash
|
|
79
|
+
*/
|
|
80
|
+
async withdraw(amount: bigint): Promise<string> {
|
|
81
|
+
const address = await this.signer.getAddress();
|
|
82
|
+
const amountWei = BigNumber.from(amount);
|
|
83
|
+
// const chainId = this.network?.chainId ?? (await this.provider.getNetwork()).chainId;
|
|
84
|
+
// const result = await this.depositClient.requestWithdraw(amountWei, this.signer, chainId);
|
|
85
|
+
|
|
86
|
+
const result = await this.liqClient.safeBurn(address, amountWei)
|
|
69
87
|
return result.txHash;
|
|
70
88
|
}
|
|
71
89
|
|
|
72
90
|
|
|
73
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Stake liqETH via DepositManager.
|
|
93
|
+
* @param amount Amount in wei
|
|
94
|
+
* Keep this as a bigint / string in the caller; avoid JS floats.
|
|
95
|
+
* @returns transaction hash
|
|
96
|
+
*/
|
|
74
97
|
async stake(amount: bigint): Promise<string> {
|
|
75
98
|
const walletAddress = await this.signer.getAddress();
|
|
76
99
|
const amountWei = BigNumber.from(amount);
|
|
@@ -85,7 +108,13 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
85
108
|
throw new Error("Method not yet implemented.");
|
|
86
109
|
}
|
|
87
110
|
|
|
88
|
-
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* ETH Prelaunch function to unstake liqEth
|
|
114
|
+
* @param tokenId ReceiptNFT tokenId for the owned NFT that will be burned
|
|
115
|
+
* @param recipient Address to receive the liqEth funds linked to the burned NFT
|
|
116
|
+
* @returns the transaction hash
|
|
117
|
+
*/
|
|
89
118
|
async unstakePrelaunch(tokenId: bigint, recipient: string): Promise<string> {
|
|
90
119
|
const tokenIdBigNum = BigNumber.from(tokenId)
|
|
91
120
|
const result = await this.stakeClient.performWithdrawStake(tokenIdBigNum, recipient);
|
|
@@ -93,6 +122,69 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
93
122
|
}
|
|
94
123
|
|
|
95
124
|
|
|
125
|
+
|
|
126
|
+
async buy(amount: bigint): Promise<string> {
|
|
127
|
+
const buyer = await this.signer.getAddress();
|
|
128
|
+
const amountBigNum = BigNumber.from(amount)
|
|
129
|
+
|
|
130
|
+
// ! Hoodi only - check if the mock aggregator price is stale, and if so, update it before submitting the buy request
|
|
131
|
+
await this.updateMockAggregatorPrice();
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
const bal = await this.contract.LiqEth.balanceOf(buyer);
|
|
135
|
+
const paused = await this.contract.Depositor.paused();
|
|
136
|
+
if(paused) {
|
|
137
|
+
throw new Error("Error - Depositor is in a paused state");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// if current liq balance is less than the requested buy amount, throw an error
|
|
141
|
+
if (bal.lt(amount)) {
|
|
142
|
+
throw new Error(`Balance insufficient for pre-token purchase`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
//check that the contract has allowance for the token
|
|
146
|
+
const depositorAddr = this.contract.Depositor.address;
|
|
147
|
+
const allowance = await this.contract.LiqEth.allowance(buyer, depositorAddr);
|
|
148
|
+
|
|
149
|
+
// if allowance is less than the requested stake amount, request permission to spend LiqEth
|
|
150
|
+
if (allowance.lt(amount)) {
|
|
151
|
+
const liqWrite = this.contractService.getWrite('LiqEth');
|
|
152
|
+
|
|
153
|
+
// currently requested unlimited amount - potentially change to only request up to the current amount?
|
|
154
|
+
const approveAmount = ethers.constants.MaxUint256;
|
|
155
|
+
|
|
156
|
+
console.warn(`allowance insufficient (${allowance.toString()} < ${amount.toString()}); sending approve(${depositorAddr}, ${approveAmount.toString()})`);
|
|
157
|
+
|
|
158
|
+
const approveTx = await liqWrite.approve(depositorAddr, approveAmount);
|
|
159
|
+
await approveTx.wait(1);
|
|
160
|
+
|
|
161
|
+
// re-read allowance to ensure approval succeeded
|
|
162
|
+
const newAllowance = await this.contract.LiqEth.allowance(buyer, depositorAddr);
|
|
163
|
+
if (newAllowance.lt(amount)) {
|
|
164
|
+
throw new Error('Approval failed or allowance still insufficient after approve');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
let result = await this.pretokenClient.purchasePretokensWithLiqETH(amountBigNum, buyer);
|
|
170
|
+
|
|
171
|
+
return result && result.txHash ? result.txHash : "Error - no resulting txHash";
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
async getOPPStatus(): Promise<any> {
|
|
178
|
+
return await this.stakeClient.getOppStatus();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* ETH Prelaunch function to list the ReceiptNFTs owned by a specific user
|
|
185
|
+
* @param address address to query the receipts for
|
|
186
|
+
* @returns array of receipts
|
|
187
|
+
*/
|
|
96
188
|
async fetchPrelaunchReceipts(address?: string): Promise<preLaunchReceipt[]> {
|
|
97
189
|
if(address === undefined) address = await this.signer.getAddress();
|
|
98
190
|
|
|
@@ -114,17 +206,6 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
114
206
|
}
|
|
115
207
|
}
|
|
116
208
|
|
|
117
|
-
// TODO
|
|
118
|
-
buy(amount: bigint, purchaseAsset: PurchaseAsset): Promise<string> {
|
|
119
|
-
throw new Error("Method not yet implemented.");
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// TODO
|
|
123
|
-
getBuyQuote(amount: bigint, purchaseAsset: PurchaseAsset): Promise<PurchaseQuote> {
|
|
124
|
-
throw new Error("Method not yet implemented.");
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
209
|
/**
|
|
129
210
|
* Resolve the user's ETH + liqETH balances.
|
|
130
211
|
*
|
|
@@ -178,94 +259,136 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
178
259
|
},
|
|
179
260
|
chainID: this.network.chainId
|
|
180
261
|
}
|
|
181
|
-
// console.log('ETH PORTFOLIO', portfolio);
|
|
182
262
|
return portfolio;
|
|
183
263
|
}
|
|
184
264
|
|
|
265
|
+
|
|
185
266
|
/**
|
|
186
|
-
* Program-level prelaunch WIRE / tranche snapshot for
|
|
187
|
-
* Uses the same OutpostWireStateSnapshot primitive as getPortfolio().
|
|
188
|
-
* TODO! for eth
|
|
267
|
+
* Program-level prelaunch WIRE / tranche snapshot for Ethereum
|
|
189
268
|
*/
|
|
190
|
-
async getTrancheSnapshot(
|
|
191
|
-
|
|
269
|
+
async getTrancheSnapshot(options?: {
|
|
270
|
+
chainID?: ChainID;
|
|
271
|
+
windowBefore?: number;
|
|
272
|
+
windowAfter?: number;
|
|
273
|
+
}): Promise<TrancheSnapshot> {
|
|
274
|
+
const {
|
|
275
|
+
chainID = EvmChainID.Hoodi,
|
|
276
|
+
windowBefore,
|
|
277
|
+
windowAfter,
|
|
278
|
+
} = options ?? {};
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
const blockNumber = await this.provider.getBlockNumber();
|
|
282
|
+
const blockTag = { blockTag: blockNumber };
|
|
283
|
+
|
|
284
|
+
// Fetch all required contract data
|
|
285
|
+
const [totalSharesBn, indexBn, trancheNumberBn, trancheSupplyBn, tranchePriceWadBn, totalSupplyBn, supplyGrowthBps, priceGrowthBps, minPriceUsd, maxPriceUsd] = await Promise.all([
|
|
286
|
+
this.contract.Depositor.totalShares(blockTag),
|
|
287
|
+
this.contract.Depositor.index(blockTag),
|
|
288
|
+
this.contract.Pretoken.trancheNumber(blockTag),
|
|
289
|
+
this.contract.Pretoken.trancheSupply(blockTag),
|
|
290
|
+
this.contract.Pretoken.tranchePriceUsd(blockTag),
|
|
291
|
+
this.contract.Pretoken.totalSupply(blockTag),
|
|
292
|
+
this.contract.Pretoken.supplyGrowthBps(blockTag),
|
|
293
|
+
this.contract.Pretoken.priceGrowthBps(blockTag),
|
|
294
|
+
this.contract.EthUsdPriceConsumer.MIN_PRICE(),
|
|
295
|
+
this.contract.EthUsdPriceConsumer.MAX_PRICE(),
|
|
296
|
+
]);
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
const totalTrancheSupply = BigInt(totalSupplyBn.toString()) / BigInt(1e10);
|
|
300
|
+
const currentTrancheSupply = BigInt(trancheSupplyBn.toString()) / BigInt(1e10);
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
// fetch price and timestamp from aggregator
|
|
304
|
+
const [ roundId, answer, startedAt, updatedAt, answeredInRound ] = await this.contract.Aggregator.latestRoundData();
|
|
305
|
+
let ethPriceUsd: bigint = BigInt(answer.toString());
|
|
306
|
+
let nativePriceTimestamp: number = Number(updatedAt);
|
|
307
|
+
|
|
308
|
+
// ! Placeholder from hoodi deployment - don't think this can be fetched dynamically
|
|
309
|
+
const initialTrancheSupply = BigInt(60000) * BigInt(1e8);
|
|
310
|
+
|
|
311
|
+
return buildEthereumTrancheSnapshot({
|
|
312
|
+
chainID,
|
|
313
|
+
totalSharesBn,
|
|
314
|
+
indexBn,
|
|
315
|
+
trancheNumberBn,
|
|
316
|
+
currentTrancheSupply,
|
|
317
|
+
tranchePriceWadBn,
|
|
318
|
+
totalTrancheSupply,
|
|
319
|
+
initialTrancheSupply,
|
|
320
|
+
supplyGrowthBps,
|
|
321
|
+
priceGrowthBps,
|
|
322
|
+
minPriceUsd,
|
|
323
|
+
maxPriceUsd,
|
|
324
|
+
|
|
325
|
+
ethPriceUsd,
|
|
326
|
+
nativePriceTimestamp,
|
|
327
|
+
ladderWindowBefore: windowBefore,
|
|
328
|
+
ladderWindowAfter: windowAfter,
|
|
329
|
+
});
|
|
192
330
|
}
|
|
193
331
|
|
|
332
|
+
|
|
333
|
+
|
|
194
334
|
|
|
195
335
|
// ---------------------------------------------------------------------
|
|
196
336
|
// Internal ETH Staking client helper functions
|
|
197
337
|
// ---------------------------------------------------------------------
|
|
198
338
|
|
|
199
|
-
private async requestWithdraw(amountWei: BigNumber): Promise<WithdrawResult> {
|
|
200
|
-
// deadline is a period of time in the future that the signature is valid for
|
|
201
|
-
const deadline = Math.floor(Date.now() / 1000) + 3600;
|
|
202
|
-
const liqEth = this.contract.LiqEth;
|
|
203
|
-
const owner = await this.signer.getAddress();
|
|
204
|
-
const liqEthAddress = this.contractService.getAddress('LiqEth');
|
|
205
|
-
|
|
206
|
-
const nonce: BigNumber = await liqEth.nonces(owner);
|
|
207
|
-
const chainId = this.network?.chainId ?? (await this.provider.getNetwork()).chainId;
|
|
208
|
-
const domain = {
|
|
209
|
-
name: await liqEth.name(),
|
|
210
|
-
version: '1',
|
|
211
|
-
chainId,
|
|
212
|
-
verifyingContract: liqEthAddress,
|
|
213
|
-
} as any;
|
|
214
|
-
|
|
215
|
-
const types = {
|
|
216
|
-
Permit: [
|
|
217
|
-
{ name: 'owner', type: 'address' },
|
|
218
|
-
{ name: 'spender', type: 'address' },
|
|
219
|
-
{ name: 'value', type: 'uint256' },
|
|
220
|
-
{ name: 'nonce', type: 'uint256' },
|
|
221
|
-
{ name: 'deadline', type: 'uint256' },
|
|
222
|
-
],
|
|
223
|
-
} as any;
|
|
224
|
-
|
|
225
|
-
const values = {
|
|
226
|
-
owner,
|
|
227
|
-
spender: this.contractService.getAddress('DepositManager'),
|
|
228
|
-
value: amountWei,
|
|
229
|
-
nonce: nonce,
|
|
230
|
-
deadline,
|
|
231
|
-
} as any;
|
|
232
|
-
|
|
233
|
-
const signature = await (this.signer as any)._signTypedData(domain, types, values);
|
|
234
|
-
const split = ethers.utils.splitSignature(signature);
|
|
235
|
-
|
|
236
|
-
const tx = await this.contract.DepositManager.requestWithdrawal(
|
|
237
|
-
amountWei,
|
|
238
|
-
deadline,
|
|
239
|
-
split.v,
|
|
240
|
-
split.r,
|
|
241
|
-
split.s
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
// wait for 1 confirmation
|
|
245
|
-
const receipt = await tx.wait(1);
|
|
246
|
-
|
|
247
|
-
// if WithdrawRequested event exists, parse it and get arguments
|
|
248
|
-
let withdrawRequested: WithdrawRequestedEvent | undefined;
|
|
249
|
-
const ev = receipt.events?.find((e) => e.event === 'WithdrawRequested');
|
|
250
|
-
|
|
251
|
-
if (ev && ev.args) {
|
|
252
|
-
const { user, ethAmount, nftId, readyAt } = ev.args;
|
|
253
|
-
withdrawRequested = {
|
|
254
|
-
user,
|
|
255
|
-
ethAmount: BigNumber.from(ethAmount),
|
|
256
|
-
nftId: BigNumber.from(nftId),
|
|
257
|
-
readyAt: readyAt,
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
339
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
// ! This is a temporary measure for Hoodi testnet because there is no aggregator deployed
|
|
343
|
+
private async updateMockAggregatorPrice() {
|
|
344
|
+
const aggregator = this.contract.Aggregator;
|
|
345
|
+
|
|
346
|
+
// read latest round & compute age
|
|
347
|
+
const [roundId, answer, startedAt, updatedAt, answeredInRound] = await aggregator.latestRoundData();
|
|
348
|
+
const now = (await this.provider.getBlock("latest")).timestamp;
|
|
349
|
+
const ageSec = Number(now) - Number(updatedAt);
|
|
350
|
+
|
|
351
|
+
const ONE_HOUR = 1 * 3600;
|
|
352
|
+
// const ONE_HOUR = 10;
|
|
353
|
+
if (ageSec > ONE_HOUR) {
|
|
354
|
+
// safety check - only run in non-production contexts
|
|
355
|
+
const network = await this.provider.getNetwork();
|
|
356
|
+
const chainId = network.chainId;
|
|
357
|
+
const allowedTestChains = new Set([560048]);
|
|
358
|
+
if (!allowedTestChains.has(chainId)) {
|
|
359
|
+
console.warn(`MockAggregator is stale (${ageSec}s) but chainId ${chainId} is not a test/local network — skipping update.`);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
//fetch the current ETH / USD price
|
|
365
|
+
const res = await fetch('https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd');
|
|
366
|
+
const data = await res.json();
|
|
367
|
+
const ethUsd = data.ethereum.usd;
|
|
368
|
+
|
|
369
|
+
const currentEthPrice = ethers.utils.parseUnits(ethUsd.toString(), 8);
|
|
370
|
+
|
|
371
|
+
try {
|
|
372
|
+
//update to be intentionally stale
|
|
373
|
+
// const alttx = await aggregator.updateStale(currentEthPrice, now - 7200);
|
|
374
|
+
// const altreceipt = await alttx.wait(1);
|
|
375
|
+
// console.log('stale update receipt', altreceipt)
|
|
376
|
+
|
|
377
|
+
//update answer with current timestamp
|
|
378
|
+
const tx = await aggregator.updateAnswer(currentEthPrice);
|
|
379
|
+
const txreceipt = await tx.wait(1);
|
|
380
|
+
// console.log('MockAggregator answer updated - receipt:', txreceipt)
|
|
381
|
+
} catch (err: any) {
|
|
382
|
+
console.error('MockAggregator updateAnswer failed', err?.message || err);
|
|
383
|
+
}
|
|
384
|
+
} else {
|
|
385
|
+
console.log(`MockAggregator updated ${ageSec}s ago — no update needed`);
|
|
386
|
+
}
|
|
266
387
|
}
|
|
267
388
|
|
|
268
389
|
|
|
269
390
|
|
|
391
|
+
|
|
392
|
+
|
|
270
393
|
// TODO: implement claimRewards, etc.
|
|
271
394
|
}
|
|
@@ -5,14 +5,9 @@ export const CONTRACT_NAMES = [
|
|
|
5
5
|
'Accounting',
|
|
6
6
|
'DepositManager',
|
|
7
7
|
'LiqEth',
|
|
8
|
-
// 'LiqEthBurn',
|
|
9
|
-
// 'LiqEthMint',
|
|
10
|
-
// 'RewardsERC20',
|
|
11
8
|
'StakingModule',
|
|
12
|
-
// 'ValidatorBalance',
|
|
13
9
|
'WithdrawalQueue',
|
|
14
10
|
'WithdrawalVault',
|
|
15
|
-
// 'Yield',
|
|
16
11
|
|
|
17
12
|
//Outpost contracts
|
|
18
13
|
'Depositor',
|
|
@@ -22,7 +17,9 @@ export const CONTRACT_NAMES = [
|
|
|
22
17
|
'OPP',
|
|
23
18
|
'OPPCommon',
|
|
24
19
|
'OPPInbound',
|
|
25
|
-
'
|
|
20
|
+
'Pretoken',
|
|
21
|
+
'Aggregator',
|
|
22
|
+
'EthUsdPriceConsumer',
|
|
26
23
|
|
|
27
24
|
] as const;
|
|
28
25
|
|
|
@@ -87,6 +84,12 @@ export interface WithdrawnStakeResult extends Result {
|
|
|
87
84
|
|
|
88
85
|
}
|
|
89
86
|
|
|
87
|
+
export interface SharesBurnedEvent {
|
|
88
|
+
from: string;
|
|
89
|
+
shares: BigNumber;
|
|
90
|
+
tokenValue: BigNumber;
|
|
91
|
+
}
|
|
92
|
+
|
|
90
93
|
export interface preLaunchReceipt {
|
|
91
94
|
tokenId: bigint;
|
|
92
95
|
receipt: {
|