@raac/rpc 2.0.0-beta.15 → 2.0.0-beta.17
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/dist/RPCLibrary.js +9 -0
- package/dist/configs/chains/11155111.json +15 -0
- package/dist/contracts/yearn/vault/_helpers.js +86 -0
- package/dist/contracts/yearn/vault/deposit.js +29 -0
- package/dist/contracts/yearn/vault/getApr.js +34 -0
- package/dist/contracts/yearn/vault/getUserInfo.js +48 -0
- package/dist/contracts/yearn/vault/getVaultInfo.js +71 -0
- package/dist/contracts/yearn/vault/getVaults.js +22 -0
- package/dist/contracts/yearn/vault/index.js +29 -0
- package/dist/contracts/yearn/vault/mint.js +29 -0
- package/dist/contracts/yearn/vault/previewDeposit.js +25 -0
- package/dist/contracts/yearn/vault/previewMint.js +25 -0
- package/dist/contracts/yearn/vault/previewRedeem.js +25 -0
- package/dist/contracts/yearn/vault/previewWithdraw.js +25 -0
- package/dist/contracts/yearn/vault/processReport.js +29 -0
- package/dist/contracts/yearn/vault/redeem.js +30 -0
- package/dist/contracts/yearn/vault/withdraw.js +30 -0
- package/dist/nfts/getPriceStaleness.js +51 -0
- package/dist/types/RPCLibrary.d.ts +7 -0
- package/dist/types/contracts/yearn/vault/_helpers.d.ts +24 -0
- package/dist/types/contracts/yearn/vault/deposit.d.ts +14 -0
- package/dist/types/contracts/yearn/vault/getApr.d.ts +14 -0
- package/dist/types/contracts/yearn/vault/getUserInfo.d.ts +29 -0
- package/dist/types/contracts/yearn/vault/getVaultInfo.d.ts +43 -0
- package/dist/types/contracts/yearn/vault/getVaults.d.ts +18 -0
- package/dist/types/contracts/yearn/vault/index.d.ts +13 -0
- package/dist/types/contracts/yearn/vault/mint.d.ts +14 -0
- package/dist/types/contracts/yearn/vault/previewDeposit.d.ts +13 -0
- package/dist/types/contracts/yearn/vault/previewMint.d.ts +13 -0
- package/dist/types/contracts/yearn/vault/previewRedeem.d.ts +13 -0
- package/dist/types/contracts/yearn/vault/previewWithdraw.d.ts +13 -0
- package/dist/types/contracts/yearn/vault/processReport.d.ts +14 -0
- package/dist/types/contracts/yearn/vault/redeem.d.ts +15 -0
- package/dist/types/contracts/yearn/vault/withdraw.d.ts +15 -0
- package/dist/types/nfts/getPriceStaleness.d.ts +22 -0
- package/dist/types/user/computeEffectiveReturn.d.ts +3 -3
- package/dist/types/user/getUserPortfolio.d.ts +12 -2
- package/dist/types/user/getUserSavings.d.ts +30 -0
- package/dist/types/user/index.d.ts +1 -0
- package/dist/user/getUserPortfolio.js +16 -6
- package/dist/user/getUserSavings.js +35 -0
- package/dist/user/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isHousePriceStale = isHousePriceStale;
|
|
4
|
+
const ethers_1 = require("ethers");
|
|
5
|
+
const contracts_1 = require("../utils/contracts");
|
|
6
|
+
const artifacts_1 = require("../utils/artifacts");
|
|
7
|
+
const rpcError_1 = require("../utils/rpcError");
|
|
8
|
+
// RAACNFT storage: token at slot 13, TRADE_FEE_PERCENTAGE at 17, PRICE_STALENESS_THRESHOLD at 18, feeCollector at 19.
|
|
9
|
+
const TOKEN_SLOT = 13;
|
|
10
|
+
const TRADE_FEE_SLOT = 17;
|
|
11
|
+
const THRESHOLD_SLOT = 18;
|
|
12
|
+
const FEE_COLLECTOR_SLOT = 19;
|
|
13
|
+
/**
|
|
14
|
+
* Reads RAACNFT's `PRICE_STALENESS_THRESHOLD`, the maximum age of a house price that `mint` accepts. The variable has
|
|
15
|
+
* no getter, so it is read from storage slot 18, trusted only when the neighbouring slots match `token()`,
|
|
16
|
+
* `TRADE_FEE_PERCENTAGE()` and `feeCollector()` (the layout is as expected).
|
|
17
|
+
* @param chainId The chain id.
|
|
18
|
+
* @param provider The provider to read with.
|
|
19
|
+
* @returns The threshold in seconds (0 turns the check off), or null when the storage layout could not be confirmed.
|
|
20
|
+
*/
|
|
21
|
+
async function getPriceStalenessThreshold(chainId, provider) {
|
|
22
|
+
const at = (0, contracts_1.getContractAddress)(chainId, "raacnft");
|
|
23
|
+
try {
|
|
24
|
+
const nft = new ethers_1.ethers.Contract(at, (0, artifacts_1.getABI)("raacnft"), provider);
|
|
25
|
+
const [token, tradeFee, feeCollector, ...slots] = await Promise.all([
|
|
26
|
+
nft.token(),
|
|
27
|
+
nft.TRADE_FEE_PERCENTAGE(),
|
|
28
|
+
nft.feeCollector(),
|
|
29
|
+
...[TOKEN_SLOT, TRADE_FEE_SLOT, FEE_COLLECTOR_SLOT, THRESHOLD_SLOT].map((slot) => provider.getStorage(at, slot)),
|
|
30
|
+
]);
|
|
31
|
+
const [tokenSlot, tradeFeeSlot, feeCollectorSlot, threshold] = slots.map((v) => BigInt(v));
|
|
32
|
+
const layoutOk = tokenSlot === BigInt(token) && tradeFeeSlot === tradeFee && feeCollectorSlot === BigInt(feeCollector);
|
|
33
|
+
return layoutOk ? Number(threshold) : null;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
throw (0, rpcError_1.toRpcError)("nfts.getPriceStalenessThreshold", error, { chainId, address: at });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Whether RAACNFT's `mint` would reject a house price as stale (`StalePriceData`), as `_validatePriceFreshness` decides:
|
|
41
|
+
* a price never set, or older than the threshold when the threshold is not 0. Only minting checks this; the lending
|
|
42
|
+
* pool's NFT adapter values collateral at the price whatever its age.
|
|
43
|
+
* @param priceTimestamp Unix seconds of the house price update; 0 when never priced.
|
|
44
|
+
* @param threshold `getPriceStalenessThreshold` in seconds.
|
|
45
|
+
* @param now Unix seconds to judge at, normally the latest block's timestamp.
|
|
46
|
+
* @returns True when a mint of this token would revert with `StalePriceData`.
|
|
47
|
+
*/
|
|
48
|
+
function isHousePriceStale(priceTimestamp, threshold, now) {
|
|
49
|
+
return priceTimestamp === 0 || (threshold > 0 && now > priceTimestamp + threshold);
|
|
50
|
+
}
|
|
51
|
+
exports.default = getPriceStalenessThreshold;
|
|
@@ -100,6 +100,7 @@ import getRawUserDepositInStabilityPool from "./pools/stabilityPool/getRawUserDe
|
|
|
100
100
|
import getEligibleUserDeposits from "./pools/lendingPool/getEligibleUserDeposits";
|
|
101
101
|
import getMintPrice from "./nfts/getMintPrice";
|
|
102
102
|
import getMintFeePercentage from "./nfts/getMintFeePercentage";
|
|
103
|
+
import getPriceStalenessThreshold, { isHousePriceStale } from "./nfts/getPriceStaleness";
|
|
103
104
|
import getAllTokens from "./nfts/getAllTokens";
|
|
104
105
|
import totalNFTSupply from "./nfts/totalNFTSupply";
|
|
105
106
|
import getTokenURI from "./nfts/getTokenURI";
|
|
@@ -159,6 +160,7 @@ import * as gaugeMethods from "./contracts/governance/gauge";
|
|
|
159
160
|
import * as controllerMethods from "./contracts/governance/gaugeController";
|
|
160
161
|
import * as gaugeSystemMethods from "./contracts/governance/gaugeSystems";
|
|
161
162
|
import * as curveCommonMethods from "./contracts/curve/common";
|
|
163
|
+
import * as yearnVaultMethods from "./contracts/yearn/vault";
|
|
162
164
|
import * as faucetMethods from "./contracts/faucet";
|
|
163
165
|
import * as userMethods from "./user";
|
|
164
166
|
import { cancel as cancelProposals } from "./contracts/governance/proposals/cancel";
|
|
@@ -341,6 +343,9 @@ declare class RPCLibrary {
|
|
|
341
343
|
curve: {
|
|
342
344
|
common: typeof curveCommonMethods;
|
|
343
345
|
};
|
|
346
|
+
yearn: {
|
|
347
|
+
vault: typeof yearnVaultMethods;
|
|
348
|
+
};
|
|
344
349
|
faucet: typeof faucetMethods;
|
|
345
350
|
user: typeof userMethods;
|
|
346
351
|
prices: {
|
|
@@ -379,6 +384,8 @@ declare class RPCLibrary {
|
|
|
379
384
|
totalSupply: typeof totalNFTSupply;
|
|
380
385
|
getMintPrice: typeof getMintPrice;
|
|
381
386
|
getMintFeePercentage: typeof getMintFeePercentage;
|
|
387
|
+
getPriceStalenessThreshold: typeof getPriceStalenessThreshold;
|
|
388
|
+
isHousePriceStale: typeof isHousePriceStale;
|
|
382
389
|
getAllTokens: typeof getAllTokens;
|
|
383
390
|
getTokenURI: typeof getTokenURI;
|
|
384
391
|
getTotalPropertiesCount: typeof getTotalPropertiesCount;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ethers, Provider, Signer } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
import { YearnVaultEntry, YearnVaults } from "../../../configs/chains/chain";
|
|
4
|
+
/**
|
|
5
|
+
* The Yearn V3 vault surface (VaultV3.vy, API 3.0.x) these methods use. ERC4626 calls use the standard
|
|
6
|
+
* signatures: Yearn's `withdraw` defaults to a 0 max loss and `redeem` to 100%, which only matter for a vault
|
|
7
|
+
* with strategies.
|
|
8
|
+
*/
|
|
9
|
+
export declare const YEARN_VAULT_ABI: string[];
|
|
10
|
+
/** `profitUnlockingRate` is shares per second scaled by this (VaultV3.vy `MAX_BPS_EXTENDED`). */
|
|
11
|
+
export declare const PROFIT_UNLOCKING_RATE_SCALE: bigint;
|
|
12
|
+
/**
|
|
13
|
+
* The APR the vault pays right now: the assets its locked profit releases per second, annualised, over total
|
|
14
|
+
* assets, as a WAD. Zero once the last reported profit has fully unlocked. It reflects the current stream only.
|
|
15
|
+
*/
|
|
16
|
+
export declare function aprFromUnlockingRate(contract: ethers.Contract, profitUnlockingRate: bigint, fullProfitUnlockDate: bigint, totalAssets: bigint, now: bigint): Promise<bigint>;
|
|
17
|
+
export declare const getYearnVaults: (chainId: ChainId) => YearnVaults;
|
|
18
|
+
/** Resolves a Yearn vault by its config key (any casing) or its address. */
|
|
19
|
+
export declare function resolveYearnVault(chainId: ChainId, vaultAddressOrId: string): YearnVaultEntry;
|
|
20
|
+
/** The vault contract bound to `runner`, or to the chain's default RPC when none is given. */
|
|
21
|
+
export declare function getYearnVaultContract(chainId: ChainId, vaultAddressOrId: string, runner?: Provider | Signer): {
|
|
22
|
+
entry: YearnVaultEntry;
|
|
23
|
+
contract: ethers.Contract;
|
|
24
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Signer } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
/**
|
|
4
|
+
* Deposits `assets` of the vault asset for shares. The signer approves the vault for the asset first
|
|
5
|
+
* (`wallet.assets.approveAsset(chainId, vault.asset, vault.contract, amount, signer)`).
|
|
6
|
+
*
|
|
7
|
+
* @param chainId - The chain/network to use.
|
|
8
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section, or its address.
|
|
9
|
+
* @param assets - Vault asset amount, in its base units.
|
|
10
|
+
* @param receiver - Who receives the shares.
|
|
11
|
+
* @param signer - The signer sending the transaction and paying the assets.
|
|
12
|
+
* @returns The mined transaction receipt.
|
|
13
|
+
*/
|
|
14
|
+
export declare const deposit: (chainId: ChainId, vaultAddressOrId: string, assets: bigint, receiver: string, signer: Signer) => Promise<any>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Provider } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
import { ScaledValue } from "../../../utils/amount";
|
|
4
|
+
/**
|
|
5
|
+
* The APR a Yearn V3 vault pays right now, from the profit still unlocking: assets released per second,
|
|
6
|
+
* annualised, over total assets. It is 0 once the last report has fully unlocked, so it reflects the current
|
|
7
|
+
* reward stream, not a historical average.
|
|
8
|
+
*
|
|
9
|
+
* @param chainId - The chain/network to use.
|
|
10
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section, or its address.
|
|
11
|
+
* @param provider - Optional ethers.js Provider instance.
|
|
12
|
+
* @returns The APR as a WAD (0.05e18 = 5%).
|
|
13
|
+
*/
|
|
14
|
+
export declare const getApr: (chainId: ChainId, vaultAddressOrId: string, provider?: Provider) => Promise<ScaledValue>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Provider } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
import { TokenAmount } from "../../../utils/amount";
|
|
4
|
+
export interface YearnVaultUserInfo {
|
|
5
|
+
/** Vault shares held. */
|
|
6
|
+
shares: TokenAmount;
|
|
7
|
+
/** What `shares` redeem for now, in the vault asset. */
|
|
8
|
+
assets: TokenAmount;
|
|
9
|
+
/** Wallet balance of the vault asset. */
|
|
10
|
+
assetBalance: TokenAmount;
|
|
11
|
+
/** Vault asset allowance to the vault, which `deposit` and `mint` pull from. */
|
|
12
|
+
assetAllowance: TokenAmount;
|
|
13
|
+
/** Most the user can deposit now, in the vault asset. */
|
|
14
|
+
maxDeposit: TokenAmount;
|
|
15
|
+
/** Most the user can withdraw now, in the vault asset. */
|
|
16
|
+
maxWithdraw: TokenAmount;
|
|
17
|
+
/** Most shares the user can redeem now; redeem `shares` instead for a full exit, as this can round 1 wei short. */
|
|
18
|
+
maxRedeem: TokenAmount;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Gets a user's position in a Yearn V3 vault, plus their vault asset balance and allowance.
|
|
22
|
+
*
|
|
23
|
+
* @param chainId - The chain/network to use.
|
|
24
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section (e.g. "spmusd"), or its address.
|
|
25
|
+
* @param account - Address of the user.
|
|
26
|
+
* @param provider - Optional ethers.js Provider instance.
|
|
27
|
+
* @returns The user's shares, their asset value, balances, allowance and limits, in base units.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getUserInfo(chainId: ChainId, vaultAddressOrId: string, account: string, provider?: Provider): Promise<YearnVaultUserInfo>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Provider } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
import { YearnVaultEntry } from "../../../configs/chains/chain";
|
|
4
|
+
import { ScaledValue, TokenAmount } from "../../../utils/amount";
|
|
5
|
+
export interface YearnVaultInfo extends YearnVaultEntry {
|
|
6
|
+
/** Address of the vault asset. */
|
|
7
|
+
assetAddress: string;
|
|
8
|
+
apiVersion: string;
|
|
9
|
+
totalAssets: TokenAmount;
|
|
10
|
+
totalSupply: TokenAmount;
|
|
11
|
+
/** Assets held by the vault itself; all of them for a vault without strategies. */
|
|
12
|
+
totalIdle: TokenAmount;
|
|
13
|
+
/** Assets lent to strategies. */
|
|
14
|
+
totalDebt: TokenAmount;
|
|
15
|
+
/** Assets per whole share, in the vault asset's decimals. */
|
|
16
|
+
pricePerShare: ScaledValue;
|
|
17
|
+
/** Current APR from the profit still unlocking, as a WAD (0.05e18 = 5%); 0 when nothing is unlocking. */
|
|
18
|
+
apr: ScaledValue;
|
|
19
|
+
/** Reported profit not yet released to depositors, in the vault asset. */
|
|
20
|
+
lockedProfit: TokenAmount;
|
|
21
|
+
/** Seconds a reported profit takes to unlock. */
|
|
22
|
+
profitMaxUnlockTime: number;
|
|
23
|
+
/** Unix timestamp the locked profit finishes unlocking; 0 or in the past when nothing is unlocking. */
|
|
24
|
+
fullProfitUnlockDate: number;
|
|
25
|
+
/** Unix timestamp of the last report. */
|
|
26
|
+
lastProfitUpdate: number;
|
|
27
|
+
depositLimit: TokenAmount;
|
|
28
|
+
isShutdown: boolean;
|
|
29
|
+
/** Null when no accountant is set (no fees). */
|
|
30
|
+
accountant: string | null;
|
|
31
|
+
roleManager: string;
|
|
32
|
+
/** The default withdrawal queue; empty for a vault without strategies. */
|
|
33
|
+
strategies: string[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Gets the vault-wide state of a Yearn V3 vault. For a user's position use `getUserInfo`.
|
|
37
|
+
*
|
|
38
|
+
* @param chainId - The chain/network to use.
|
|
39
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section (e.g. "spmusd"), or its address.
|
|
40
|
+
* @param provider - Optional ethers.js Provider instance.
|
|
41
|
+
* @returns The vault state, with amounts in base units.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getVaultInfo(chainId: ChainId, vaultAddressOrId: string, provider?: Provider): Promise<YearnVaultInfo>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ChainId } from "../../../configs/chains";
|
|
2
|
+
import { YearnVaultEntry } from "../../../configs/chains/chain";
|
|
3
|
+
/**
|
|
4
|
+
* Lists the Yearn V3 vaults in the chain config. Reads the config only; no RPC call is made.
|
|
5
|
+
*
|
|
6
|
+
* @param chainId - The chain/network to use.
|
|
7
|
+
* @returns Every configured vault; empty when the chain has none.
|
|
8
|
+
*/
|
|
9
|
+
export declare const getVaults: (chainId: ChainId) => YearnVaultEntry[];
|
|
10
|
+
/**
|
|
11
|
+
* Looks up one Yearn V3 vault in the chain config. Reads the config only; no RPC call is made.
|
|
12
|
+
*
|
|
13
|
+
* @param chainId - The chain/network to use.
|
|
14
|
+
* @param vaultAddressOrId - The vault's config key or its address.
|
|
15
|
+
* @returns The vault entry.
|
|
16
|
+
* @throws If the vault is not configured on the chain.
|
|
17
|
+
*/
|
|
18
|
+
export declare const getVault: (chainId: ChainId, vaultAddressOrId: string) => YearnVaultEntry;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from "./deposit";
|
|
2
|
+
export * from "./getApr";
|
|
3
|
+
export * from "./getUserInfo";
|
|
4
|
+
export * from "./getVaultInfo";
|
|
5
|
+
export * from "./getVaults";
|
|
6
|
+
export * from "./mint";
|
|
7
|
+
export * from "./previewDeposit";
|
|
8
|
+
export * from "./previewMint";
|
|
9
|
+
export * from "./previewRedeem";
|
|
10
|
+
export * from "./previewWithdraw";
|
|
11
|
+
export * from "./processReport";
|
|
12
|
+
export * from "./redeem";
|
|
13
|
+
export * from "./withdraw";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Signer } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
/**
|
|
4
|
+
* Mints exactly `shares`, pulling the assets they cost (see `previewMint`). The signer approves the vault for the
|
|
5
|
+
* asset first.
|
|
6
|
+
*
|
|
7
|
+
* @param chainId - The chain/network to use.
|
|
8
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section, or its address.
|
|
9
|
+
* @param shares - Share amount, in base units.
|
|
10
|
+
* @param receiver - Who receives the shares.
|
|
11
|
+
* @param signer - The signer sending the transaction and paying the assets.
|
|
12
|
+
* @returns The mined transaction receipt.
|
|
13
|
+
*/
|
|
14
|
+
export declare const mint: (chainId: ChainId, vaultAddressOrId: string, shares: bigint, receiver: string, signer: Signer) => Promise<any>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Provider } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
import { TokenAmount } from "../../../utils/amount";
|
|
4
|
+
/**
|
|
5
|
+
* Shares a deposit of `assets` would mint now.
|
|
6
|
+
*
|
|
7
|
+
* @param chainId - The chain/network to use.
|
|
8
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section, or its address.
|
|
9
|
+
* @param assets - Vault asset amount, in its base units.
|
|
10
|
+
* @param provider - Optional ethers.js Provider instance.
|
|
11
|
+
* @returns The shares, in base units.
|
|
12
|
+
*/
|
|
13
|
+
export declare const previewDeposit: (chainId: ChainId, vaultAddressOrId: string, assets: bigint, provider?: Provider) => Promise<TokenAmount>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Provider } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
import { TokenAmount } from "../../../utils/amount";
|
|
4
|
+
/**
|
|
5
|
+
* Assets a mint of `shares` would pull now.
|
|
6
|
+
*
|
|
7
|
+
* @param chainId - The chain/network to use.
|
|
8
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section, or its address.
|
|
9
|
+
* @param shares - Share amount, in base units.
|
|
10
|
+
* @param provider - Optional ethers.js Provider instance.
|
|
11
|
+
* @returns The vault asset amount, in its base units.
|
|
12
|
+
*/
|
|
13
|
+
export declare const previewMint: (chainId: ChainId, vaultAddressOrId: string, shares: bigint, provider?: Provider) => Promise<TokenAmount>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Provider } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
import { TokenAmount } from "../../../utils/amount";
|
|
4
|
+
/**
|
|
5
|
+
* Assets a redemption of `shares` would pay out now.
|
|
6
|
+
*
|
|
7
|
+
* @param chainId - The chain/network to use.
|
|
8
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section, or its address.
|
|
9
|
+
* @param shares - Share amount, in base units.
|
|
10
|
+
* @param provider - Optional ethers.js Provider instance.
|
|
11
|
+
* @returns The vault asset amount, in its base units.
|
|
12
|
+
*/
|
|
13
|
+
export declare const previewRedeem: (chainId: ChainId, vaultAddressOrId: string, shares: bigint, provider?: Provider) => Promise<TokenAmount>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Provider } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
import { TokenAmount } from "../../../utils/amount";
|
|
4
|
+
/**
|
|
5
|
+
* Shares a withdrawal of `assets` would burn now.
|
|
6
|
+
*
|
|
7
|
+
* @param chainId - The chain/network to use.
|
|
8
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section, or its address.
|
|
9
|
+
* @param assets - Vault asset amount, in its base units.
|
|
10
|
+
* @param provider - Optional ethers.js Provider instance.
|
|
11
|
+
* @returns The shares, in base units.
|
|
12
|
+
*/
|
|
13
|
+
export declare const previewWithdraw: (chainId: ChainId, vaultAddressOrId: string, assets: bigint, provider?: Provider) => Promise<TokenAmount>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Signer } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
/**
|
|
4
|
+
* Reports a strategy, or with no `strategy` the vault itself. A self-report books any vault asset sent to the vault
|
|
5
|
+
* since the last report as profit and streams it to depositors over `profitMaxUnlockTime`; this is how rewards
|
|
6
|
+
* reach a vault without strategies. The signer needs the vault's REPORTING_MANAGER role.
|
|
7
|
+
*
|
|
8
|
+
* @param chainId - The chain/network to use.
|
|
9
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section, or its address.
|
|
10
|
+
* @param strategy - The strategy to report; defaults to the vault (self-report).
|
|
11
|
+
* @param signer - The signer sending the transaction.
|
|
12
|
+
* @returns The mined transaction receipt.
|
|
13
|
+
*/
|
|
14
|
+
export declare const processReport: (chainId: ChainId, vaultAddressOrId: string, strategy: string | undefined, signer: Signer) => Promise<any>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Signer } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
/**
|
|
4
|
+
* Redeems `shares` for the vault asset (see `previewRedeem`). Use this, with the user's full share balance, to
|
|
5
|
+
* exit completely. Uses Yearn's default max loss of 100%, which only matters for a vault with strategies.
|
|
6
|
+
*
|
|
7
|
+
* @param chainId - The chain/network to use.
|
|
8
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section, or its address.
|
|
9
|
+
* @param shares - Share amount, in base units.
|
|
10
|
+
* @param receiver - Who receives the assets.
|
|
11
|
+
* @param owner - Whose shares are burnt; the signer, or an owner that approved the signer for the shares.
|
|
12
|
+
* @param signer - The signer sending the transaction.
|
|
13
|
+
* @returns The mined transaction receipt.
|
|
14
|
+
*/
|
|
15
|
+
export declare const redeem: (chainId: ChainId, vaultAddressOrId: string, shares: bigint, receiver: string, owner: string, signer: Signer) => Promise<any>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Signer } from "ethers";
|
|
2
|
+
import { ChainId } from "../../../configs/chains";
|
|
3
|
+
/**
|
|
4
|
+
* Withdraws exactly `assets` of the vault asset, burning the shares they cost (see `previewWithdraw`). Uses
|
|
5
|
+
* Yearn's default max loss of 0.
|
|
6
|
+
*
|
|
7
|
+
* @param chainId - The chain/network to use.
|
|
8
|
+
* @param vaultAddressOrId - The vault's key in the chain config's `yearn` section, or its address.
|
|
9
|
+
* @param assets - Vault asset amount, in its base units.
|
|
10
|
+
* @param receiver - Who receives the assets.
|
|
11
|
+
* @param owner - Whose shares are burnt; the signer, or an owner that approved the signer for the shares.
|
|
12
|
+
* @param signer - The signer sending the transaction.
|
|
13
|
+
* @returns The mined transaction receipt.
|
|
14
|
+
*/
|
|
15
|
+
export declare const withdraw: (chainId: ChainId, vaultAddressOrId: string, assets: bigint, receiver: string, owner: string, signer: Signer) => Promise<any>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Provider } from "ethers";
|
|
2
|
+
import { ChainId } from "../configs/chains/index";
|
|
3
|
+
/**
|
|
4
|
+
* Reads RAACNFT's `PRICE_STALENESS_THRESHOLD`, the maximum age of a house price that `mint` accepts. The variable has
|
|
5
|
+
* no getter, so it is read from storage slot 18, trusted only when the neighbouring slots match `token()`,
|
|
6
|
+
* `TRADE_FEE_PERCENTAGE()` and `feeCollector()` (the layout is as expected).
|
|
7
|
+
* @param chainId The chain id.
|
|
8
|
+
* @param provider The provider to read with.
|
|
9
|
+
* @returns The threshold in seconds (0 turns the check off), or null when the storage layout could not be confirmed.
|
|
10
|
+
*/
|
|
11
|
+
declare function getPriceStalenessThreshold(chainId: ChainId, provider: Provider): Promise<number | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Whether RAACNFT's `mint` would reject a house price as stale (`StalePriceData`), as `_validatePriceFreshness` decides:
|
|
14
|
+
* a price never set, or older than the threshold when the threshold is not 0. Only minting checks this; the lending
|
|
15
|
+
* pool's NFT adapter values collateral at the price whatever its age.
|
|
16
|
+
* @param priceTimestamp Unix seconds of the house price update; 0 when never priced.
|
|
17
|
+
* @param threshold `getPriceStalenessThreshold` in seconds.
|
|
18
|
+
* @param now Unix seconds to judge at, normally the latest block's timestamp.
|
|
19
|
+
* @returns True when a mint of this token would revert with `StalePriceData`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isHousePriceStale(priceTimestamp: number, threshold: number, now: number): boolean;
|
|
22
|
+
export default getPriceStalenessThreshold;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Whether a leg earns income or costs it. */
|
|
2
2
|
export type ReturnLegKind = "earning" | "cost";
|
|
3
3
|
/** What a leg earns or costs. A unit of capital earns each yield type at most once. */
|
|
4
|
-
export type ReturnLegYieldType = "supply" | "gauge" | "borrow";
|
|
4
|
+
export type ReturnLegYieldType = "supply" | "gauge" | "savings" | "borrow";
|
|
5
5
|
/**
|
|
6
6
|
* One income stream in the user's position, as {@link computeEffectiveReturn} consumes it. Adding a venue (a new
|
|
7
7
|
* gauge, another pmUSD venue) only means adding a leg; the calculator does not change.
|
|
@@ -14,7 +14,7 @@ export interface ReturnLeg {
|
|
|
14
14
|
kind: ReturnLegKind;
|
|
15
15
|
yieldType: ReturnLegYieldType;
|
|
16
16
|
/**
|
|
17
|
-
* True when the leg's value is money the user holds and counts towards net capital (supplied). False for the
|
|
17
|
+
* True when the leg's value is money the user holds and counts towards net capital (supplied, savings). False for the
|
|
18
18
|
* debt itself, and for overlays such as a gauge, whose staked value is already counted in another leg.
|
|
19
19
|
*/
|
|
20
20
|
countsAsCapital: boolean;
|
|
@@ -22,7 +22,7 @@ export interface ReturnLeg {
|
|
|
22
22
|
valueUsd: number;
|
|
23
23
|
/** The projected one-year rate as a fraction, e.g. 0.0077 for 0.77%. */
|
|
24
24
|
rate: number;
|
|
25
|
-
/** How `rate` is quoted: "apy" when it already compounds (borrow), "apr" when it does not (supply, gauge). */
|
|
25
|
+
/** How `rate` is quoted: "apy" when it already compounds (borrow), "apr" when it does not (supply, gauge, savings). */
|
|
26
26
|
rateKind: "apr" | "apy";
|
|
27
27
|
}
|
|
28
28
|
export interface ReturnLegWithIncome extends ReturnLeg {
|
|
@@ -6,6 +6,7 @@ import { UserDebt } from "./getUserDebt";
|
|
|
6
6
|
import { UserWalletBalances } from "./getUserWalletBalances";
|
|
7
7
|
import { UserFarming } from "./getUserFarming";
|
|
8
8
|
import { UserGovernance } from "./getUserGovernance";
|
|
9
|
+
import { UserSavingsVault } from "./getUserSavings";
|
|
9
10
|
import { Section, UsdPrices } from "./_helpers";
|
|
10
11
|
export interface PortfolioCollateral {
|
|
11
12
|
/** iREET deposited in the lending pool's iREET adapter. */
|
|
@@ -28,6 +29,13 @@ export interface PortfolioWallet extends UserWalletBalances {
|
|
|
28
29
|
suppliedUsd: number;
|
|
29
30
|
idleUsd: number;
|
|
30
31
|
}
|
|
32
|
+
export interface PortfolioSavingsVault extends UserSavingsVault {
|
|
33
|
+
valueUsd: number;
|
|
34
|
+
}
|
|
35
|
+
export interface PortfolioSavings {
|
|
36
|
+
vaults: PortfolioSavingsVault[];
|
|
37
|
+
valueUsd: number;
|
|
38
|
+
}
|
|
31
39
|
export interface UserPortfolio {
|
|
32
40
|
chainId: ChainId;
|
|
33
41
|
user: string;
|
|
@@ -37,6 +45,8 @@ export interface UserPortfolio {
|
|
|
37
45
|
wallet: Section<PortfolioWallet>;
|
|
38
46
|
farming: Section<UserFarming>;
|
|
39
47
|
governance: Section<UserGovernance>;
|
|
48
|
+
/** Savings vault (spmUSD) positions. */
|
|
49
|
+
savings: Section<PortfolioSavings>;
|
|
40
50
|
/** Collateral value + wallet RpmUSD + wallet DEpmUSD - debt, in USD. Lending pool only: LP and gauge positions are not included. */
|
|
41
51
|
netPositionUsd: Section<number>;
|
|
42
52
|
/** The legs the effective return is computed from; empty when any read it needs failed. */
|
|
@@ -45,7 +55,7 @@ export interface UserPortfolio {
|
|
|
45
55
|
}
|
|
46
56
|
/**
|
|
47
57
|
* The user's position across the app: iREET collateral, debt and health factor, wallet RpmUSD/DEpmUSD/pmUSD, LP and
|
|
48
|
-
* gauge positions, veRAAC governance power, and the projected effective return built from them. Each part is read
|
|
58
|
+
* gauge positions, savings vault positions, veRAAC governance power, and the projected effective return built from them. Each part is read
|
|
49
59
|
* independently, so one failing read shows as an `error` on that part and the rest still return.
|
|
50
60
|
*
|
|
51
61
|
* Only the user's position data is returned; pool parameters such as the liquidation threshold stay with the callers
|
|
@@ -54,7 +64,7 @@ export interface UserPortfolio {
|
|
|
54
64
|
* @param chainId - The chain/network to use.
|
|
55
65
|
* @param user - The user's address.
|
|
56
66
|
* @param prices - USD per whole token, keyed by lowercase symbol. iREET, pmUSD, RpmUSD, DEpmUSD and RAAC are needed,
|
|
57
|
-
* plus every coin of a Curve pool the user holds.
|
|
67
|
+
* plus every coin of a Curve pool the user holds. Savings positions are valued at their asset's price (pmUSD).
|
|
58
68
|
* @param provider - Optional ethers.js Provider instance. Read-only is enough.
|
|
59
69
|
* @returns Each part as `{ data, error }`, the effective return legs, and the computed effective return.
|
|
60
70
|
*/
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Provider } from "ethers";
|
|
2
|
+
import { ChainId } from "../configs/chains";
|
|
3
|
+
import { ScaledValue, TokenAmount } from "../utils/amount";
|
|
4
|
+
export interface UserSavingsVault {
|
|
5
|
+
/** The vault's key in the chain config's `yearn` section, e.g. "spmusd". */
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
/** Vault (share token) address. */
|
|
9
|
+
vault: string;
|
|
10
|
+
/** Vault shares held. */
|
|
11
|
+
shares: TokenAmount;
|
|
12
|
+
/** What `shares` redeem for now, in the vault asset. */
|
|
13
|
+
assets: TokenAmount;
|
|
14
|
+
/** The vault's current APR as a WAD, from the reward still unlocking; 0 once it has all unlocked. */
|
|
15
|
+
apr: ScaledValue;
|
|
16
|
+
}
|
|
17
|
+
export interface UserSavings {
|
|
18
|
+
/** Every vault in the chain config's `yearn` section the user holds shares in. */
|
|
19
|
+
vaults: UserSavingsVault[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The user's positions in the chain's savings vaults (the Yearn V3 vaults in the chain config, e.g. spmUSD). Vaults
|
|
23
|
+
* the user holds nothing in are left out; a chain without savings vaults returns none.
|
|
24
|
+
*
|
|
25
|
+
* @param chainId - The chain/network to use.
|
|
26
|
+
* @param user - The user's address.
|
|
27
|
+
* @param provider - Optional ethers.js Provider instance.
|
|
28
|
+
* @returns The vaults the user holds, with what the shares are worth and the vault's current APR.
|
|
29
|
+
*/
|
|
30
|
+
export declare const getUserSavings: (chainId: ChainId, user: string, provider?: Provider) => Promise<UserSavings>;
|
|
@@ -5,5 +5,6 @@ export * from "./getUserDebt";
|
|
|
5
5
|
export * from "./getUserFarming";
|
|
6
6
|
export * from "./getUserGovernance";
|
|
7
7
|
export * from "./getUserPortfolio";
|
|
8
|
+
export * from "./getUserSavings";
|
|
8
9
|
export * from "./getUserWalletBalances";
|
|
9
10
|
export type { UsdPrices, Section } from "./_helpers";
|
|
@@ -14,13 +14,14 @@ const getUserDebt_1 = require("./getUserDebt");
|
|
|
14
14
|
const getUserWalletBalances_1 = require("./getUserWalletBalances");
|
|
15
15
|
const getUserFarming_1 = require("./getUserFarming");
|
|
16
16
|
const getUserGovernance_1 = require("./getUserGovernance");
|
|
17
|
+
const getUserSavings_1 = require("./getUserSavings");
|
|
17
18
|
const _helpers_1 = require("./_helpers");
|
|
18
19
|
const unavailable = (what, sections) => {
|
|
19
20
|
const failed = sections.filter((section) => section.error);
|
|
20
21
|
return failed.length ? new Error(`${what} needs data that could not be read: ${failed.map((section) => section.error.message).join("; ")}`) : null;
|
|
21
22
|
};
|
|
22
23
|
/** Builds the effective return legs from the reads. Each unit of capital earns each yield once. */
|
|
23
|
-
function buildLegs(debt, rates, wallet, farming) {
|
|
24
|
+
function buildLegs(debt, rates, wallet, farming, savings) {
|
|
24
25
|
const legs = [];
|
|
25
26
|
if (debt.valueUsd > 0) {
|
|
26
27
|
legs.push({ id: "borrow", source: "Borrow pmUSD", kind: "cost", yieldType: "borrow", countsAsCapital: false, valueUsd: debt.valueUsd, rate: (0, amount_1.toNumber)(rates.borrowApy), rateKind: "apy" });
|
|
@@ -37,12 +38,16 @@ function buildLegs(debt, rates, wallet, farming) {
|
|
|
37
38
|
continue;
|
|
38
39
|
legs.push({ id: `gauge:${gauge.id}`, source: gauge.name, kind: "earning", yieldType: "gauge", countsAsCapital: false, valueUsd: gauge.valueUsd, rate: gauge.apr ?? 0, rateKind: "apr" });
|
|
39
40
|
}
|
|
41
|
+
// Savings shares are pmUSD the user holds, so they count as capital; the rate is the vault's current reward stream.
|
|
42
|
+
for (const vault of savings.vaults) {
|
|
43
|
+
legs.push({ id: `savings:${vault.id}`, source: vault.name, kind: "earning", yieldType: "savings", countsAsCapital: true, valueUsd: vault.valueUsd, rate: (0, amount_1.toNumber)(vault.apr), rateKind: "apr" });
|
|
44
|
+
}
|
|
40
45
|
const idleUsd = wallet.idleUsd + coins.filter((coin) => coin.yield === "none").reduce((sum, coin) => sum + coin.valueUsd, 0);
|
|
41
46
|
return { legs, idleUsd };
|
|
42
47
|
}
|
|
43
48
|
/**
|
|
44
49
|
* The user's position across the app: iREET collateral, debt and health factor, wallet RpmUSD/DEpmUSD/pmUSD, LP and
|
|
45
|
-
* gauge positions, veRAAC governance power, and the projected effective return built from them. Each part is read
|
|
50
|
+
* gauge positions, savings vault positions, veRAAC governance power, and the projected effective return built from them. Each part is read
|
|
46
51
|
* independently, so one failing read shows as an `error` on that part and the rest still return.
|
|
47
52
|
*
|
|
48
53
|
* Only the user's position data is returned; pool parameters such as the liquidation threshold stay with the callers
|
|
@@ -51,7 +56,7 @@ function buildLegs(debt, rates, wallet, farming) {
|
|
|
51
56
|
* @param chainId - The chain/network to use.
|
|
52
57
|
* @param user - The user's address.
|
|
53
58
|
* @param prices - USD per whole token, keyed by lowercase symbol. iREET, pmUSD, RpmUSD, DEpmUSD and RAAC are needed,
|
|
54
|
-
* plus every coin of a Curve pool the user holds.
|
|
59
|
+
* plus every coin of a Curve pool the user holds. Savings positions are valued at their asset's price (pmUSD).
|
|
55
60
|
* @param provider - Optional ethers.js Provider instance. Read-only is enough.
|
|
56
61
|
* @returns Each part as `{ data, error }`, the effective return legs, and the computed effective return.
|
|
57
62
|
*/
|
|
@@ -63,7 +68,7 @@ const getUserPortfolio = async (chainId, user, prices, provider) => {
|
|
|
63
68
|
const rpc = chains_1.default[chainId].rpcs[0];
|
|
64
69
|
provider = new ethers_1.ethers.JsonRpcProvider(rpc);
|
|
65
70
|
}
|
|
66
|
-
const [collateral, debt, rates, wallet, farming, governance] = await Promise.all([
|
|
71
|
+
const [collateral, debt, rates, wallet, farming, governance, savings] = await Promise.all([
|
|
67
72
|
(0, _helpers_1.settled)((0, getUserCollateral_1.getUserCollateral)(chainId, user, provider).then((amount) => ({ amount, valueUsd: (0, _helpers_1.requireUsd)(prices, amount, "rwaindextoken") }))),
|
|
68
73
|
(0, _helpers_1.settled)((0, getUserDebt_1.getUserDebt)(chainId, user, provider).then((debt) => ({ ...debt, valueUsd: (0, _helpers_1.requireUsd)(prices, debt.amount, chains_1.default[chainId].pools.lendingpool.asset ?? "debt") }))),
|
|
69
74
|
(0, _helpers_1.settled)((0, getLendingPoolInfo_1.default)(chainId, undefined, provider).then(({ borrowRate, borrowApy, supplyApy }) => ({ borrowRate, borrowApy, supplyApy }))),
|
|
@@ -74,6 +79,10 @@ const getUserPortfolio = async (chainId, user, prices, provider) => {
|
|
|
74
79
|
}))),
|
|
75
80
|
(0, _helpers_1.settled)((0, getUserFarming_1.getUserFarming)(chainId, user, prices, provider)),
|
|
76
81
|
(0, _helpers_1.settled)((0, getUserGovernance_1.getUserGovernance)(chainId, user, provider)),
|
|
82
|
+
(0, _helpers_1.settled)((0, getUserSavings_1.getUserSavings)(chainId, user, provider).then((read) => {
|
|
83
|
+
const vaults = read.vaults.map((vault) => ({ ...vault, valueUsd: (0, _helpers_1.requireUsd)(prices, vault.assets, vault.id) }));
|
|
84
|
+
return { vaults, valueUsd: vaults.reduce((sum, vault) => sum + vault.valueUsd, 0) };
|
|
85
|
+
})),
|
|
77
86
|
]);
|
|
78
87
|
const netPositionError = unavailable("Net RAACLend position", [collateral, debt, wallet]);
|
|
79
88
|
const netPositionUsd = netPositionError
|
|
@@ -83,12 +92,12 @@ const getUserPortfolio = async (chainId, user, prices, provider) => {
|
|
|
83
92
|
const farmingErrors = (farming.data?.errors ?? []).map(({ pool, error }) => ({ data: null, error: new Error(`Curve pool ${pool}: ${error.message}`) }));
|
|
84
93
|
let legs = [];
|
|
85
94
|
let effectiveReturn;
|
|
86
|
-
const returnError = unavailable("Effective return", [collateral, debt, rates, wallet, farming, ...farmingErrors]);
|
|
95
|
+
const returnError = unavailable("Effective return", [collateral, debt, rates, wallet, farming, savings, ...farmingErrors]);
|
|
87
96
|
if (returnError) {
|
|
88
97
|
effectiveReturn = { data: null, error: returnError };
|
|
89
98
|
}
|
|
90
99
|
else {
|
|
91
|
-
const built = buildLegs(debt.data, rates.data, wallet.data, farming.data);
|
|
100
|
+
const built = buildLegs(debt.data, rates.data, wallet.data, farming.data, savings.data);
|
|
92
101
|
legs = built.legs;
|
|
93
102
|
effectiveReturn = { data: (0, computeEffectiveReturn_1.computeEffectiveReturn)({ legs, collateralUsd: collateral.data.valueUsd, idleUsd: built.idleUsd }), error: null };
|
|
94
103
|
}
|
|
@@ -101,6 +110,7 @@ const getUserPortfolio = async (chainId, user, prices, provider) => {
|
|
|
101
110
|
wallet,
|
|
102
111
|
farming,
|
|
103
112
|
governance,
|
|
113
|
+
savings,
|
|
104
114
|
netPositionUsd,
|
|
105
115
|
legs,
|
|
106
116
|
effectiveReturn,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getUserSavings = void 0;
|
|
7
|
+
const ethers_1 = require("ethers");
|
|
8
|
+
const chains_1 = __importDefault(require("../configs/chains"));
|
|
9
|
+
const getApr_1 = require("../contracts/yearn/vault/getApr");
|
|
10
|
+
const getUserInfo_1 = require("../contracts/yearn/vault/getUserInfo");
|
|
11
|
+
const getVaults_1 = require("../contracts/yearn/vault/getVaults");
|
|
12
|
+
/**
|
|
13
|
+
* The user's positions in the chain's savings vaults (the Yearn V3 vaults in the chain config, e.g. spmUSD). Vaults
|
|
14
|
+
* the user holds nothing in are left out; a chain without savings vaults returns none.
|
|
15
|
+
*
|
|
16
|
+
* @param chainId - The chain/network to use.
|
|
17
|
+
* @param user - The user's address.
|
|
18
|
+
* @param provider - Optional ethers.js Provider instance.
|
|
19
|
+
* @returns The vaults the user holds, with what the shares are worth and the vault's current APR.
|
|
20
|
+
*/
|
|
21
|
+
const getUserSavings = async (chainId, user, provider) => {
|
|
22
|
+
if (!provider) {
|
|
23
|
+
const rpc = chains_1.default[chainId].rpcs[0];
|
|
24
|
+
provider = new ethers_1.ethers.JsonRpcProvider(rpc);
|
|
25
|
+
}
|
|
26
|
+
const held = await Promise.all((0, getVaults_1.getVaults)(chainId).map(async (entry) => {
|
|
27
|
+
const info = await (0, getUserInfo_1.getUserInfo)(chainId, entry.contract, user, provider);
|
|
28
|
+
if (info.shares.value === 0n)
|
|
29
|
+
return null;
|
|
30
|
+
const apr = await (0, getApr_1.getApr)(chainId, entry.contract, provider);
|
|
31
|
+
return { id: entry.id, name: entry.name, vault: entry.contract, shares: info.shares, assets: info.assets, apr };
|
|
32
|
+
}));
|
|
33
|
+
return { vaults: held.filter((vault) => vault !== null) };
|
|
34
|
+
};
|
|
35
|
+
exports.getUserSavings = getUserSavings;
|