@mrgnlabs/marginfi-client-v2
Advanced tools
Comparing version 2.1.1 to 2.1.2
@@ -191,3 +191,6 @@ /// <reference types="node" /> | ||
getFreeCollateral(): BigNumber; | ||
private _getHealthComponentsWithoutBias; | ||
getHealthComponentsWithoutBias(marginReqType: MarginRequirementType): { | ||
assets: BigNumber; | ||
liabilities: BigNumber; | ||
}; | ||
computeNetApy(): number; | ||
@@ -194,0 +197,0 @@ /** |
@@ -490,3 +490,3 @@ "use strict"; | ||
} | ||
_getHealthComponentsWithoutBias(marginReqType) { | ||
getHealthComponentsWithoutBias(marginReqType) { | ||
const [assets, liabilities] = this.activeBalances | ||
@@ -506,3 +506,3 @@ .map((accountBalance) => { | ||
computeNetApy() { | ||
const { assets, liabilities } = this._getHealthComponentsWithoutBias(MarginRequirementType.Equity); | ||
const { assets, liabilities } = this.getHealthComponentsWithoutBias(MarginRequirementType.Equity); | ||
const totalUsdValue = assets.minus(liabilities); | ||
@@ -595,3 +595,3 @@ const apr = this.activeBalances | ||
}, | ||
...this.getHealthCheckAccounts([liabBank, assetBank]), | ||
...this.getHealthCheckAccounts([assetBank, liabBank]), | ||
...liquidateeMarginfiAccount.getHealthCheckAccounts(), | ||
@@ -598,0 +598,0 @@ ]); |
import { Address, AnchorProvider } from "@coral-xyz/anchor"; | ||
import { Commitment, ConfirmOptions, Connection, Keypair, PublicKey, Signer, Transaction, TransactionSignature, VersionedTransaction } from "@solana/web3.js"; | ||
import { Commitment, ConfirmOptions, Connection, PublicKey, Signer, Transaction, TransactionSignature, VersionedTransaction } from "@solana/web3.js"; | ||
import { AccountType, Environment, MarginfiConfig, MarginfiProgram } from "./types"; | ||
@@ -21,2 +21,3 @@ import { InstructionsWrapper, TransactionOptions, Wallet } from "@mrgnlabs/mrgn-common"; | ||
oraclePrices: OraclePriceMap; | ||
private addressLookupTables; | ||
/** | ||
@@ -86,3 +87,3 @@ * @internal | ||
*/ | ||
makeCreateMarginfiAccountIx(marginfiAccountKeypair?: Keypair): Promise<InstructionsWrapper>; | ||
makeCreateMarginfiAccountIx(marginfiAccountPk: PublicKey): Promise<InstructionsWrapper>; | ||
/** | ||
@@ -93,3 +94,5 @@ * Create a new marginfi account under the authority of the user. | ||
*/ | ||
createMarginfiAccount(opts?: TransactionOptions): Promise<MarginfiAccountWrapper>; | ||
createMarginfiAccount(opts?: TransactionOptions, createOpts?: { | ||
newAccountKey?: PublicKey | undefined; | ||
}): Promise<MarginfiAccountWrapper>; | ||
processTransaction(transaction: Transaction | VersionedTransaction, signers?: Array<Signer>, opts?: TransactionOptions): Promise<TransactionSignature>; | ||
@@ -96,0 +99,0 @@ } |
@@ -28,3 +28,3 @@ "use strict"; | ||
*/ | ||
constructor(config, program, wallet, isReadOnly, group, banks, priceInfos) { | ||
constructor(config, program, wallet, isReadOnly, group, banks, priceInfos, addressLookupTables) { | ||
this.config = config; | ||
@@ -37,2 +37,3 @@ this.program = program; | ||
this.oraclePrices = priceInfos; | ||
this.addressLookupTables = addressLookupTables ?? []; | ||
} | ||
@@ -60,3 +61,8 @@ /** | ||
const { marginfiGroup, banks, priceInfos } = await this.fetchGroupData(program, config.groupPk, opts?.commitment); | ||
return new MarginfiClient(config, program, wallet, readOnly, marginfiGroup, banks, priceInfos); | ||
const addressLookupTableAddresses = _1.ADDRESS_LOOKUP_TABLE_FOR_GROUP[config.groupPk.toString()] ?? []; | ||
debug("Fetching address lookup tables for %s", addressLookupTableAddresses); | ||
const addressLookupTables = (await Promise.all(addressLookupTableAddresses.map((address) => connection.getAddressLookupTable(address)))) | ||
.map((response) => response.value) | ||
.filter((table) => table !== null); | ||
return new MarginfiClient(config, program, wallet, readOnly, marginfiGroup, banks, priceInfos, addressLookupTables); | ||
} | ||
@@ -250,9 +256,8 @@ static async fromEnv(overrides) { | ||
*/ | ||
async makeCreateMarginfiAccountIx(marginfiAccountKeypair) { | ||
async makeCreateMarginfiAccountIx(marginfiAccountPk) { | ||
const dbg = require("debug")("mfi:client"); | ||
const accountKeypair = marginfiAccountKeypair || web3_js_1.Keypair.generate(); | ||
dbg("Generating marginfi account ix for %s", accountKeypair.publicKey); | ||
dbg("Generating marginfi account ix for %s", marginfiAccountPk); | ||
const initMarginfiAccountIx = await instructions_1.default.makeInitMarginfiAccountIx(this.program, { | ||
marginfiGroupPk: this.groupAddress, | ||
marginfiAccountPk: accountKeypair.publicKey, | ||
marginfiAccountPk, | ||
authorityPk: this.provider.wallet.publicKey, | ||
@@ -264,3 +269,3 @@ feePayerPk: this.provider.wallet.publicKey, | ||
instructions: ixs, | ||
keys: [accountKeypair], | ||
keys: [], | ||
}; | ||
@@ -273,12 +278,17 @@ } | ||
*/ | ||
async createMarginfiAccount(opts) { | ||
async createMarginfiAccount(opts, createOpts) { | ||
const dbg = require("debug")("mfi:client"); | ||
const accountKeypair = web3_js_1.Keypair.generate(); | ||
const ixs = await this.makeCreateMarginfiAccountIx(accountKeypair); | ||
const newAccountKey = createOpts?.newAccountKey ?? accountKeypair.publicKey; | ||
const ixs = await this.makeCreateMarginfiAccountIx(newAccountKey); | ||
const signers = [...ixs.keys]; | ||
// If there was no newAccountKey provided, we need to sign with the ephemeraKeypair we generated. | ||
if (!createOpts?.newAccountKey) | ||
signers.push(accountKeypair); | ||
const tx = new web3_js_1.Transaction().add(...ixs.instructions); | ||
const sig = await this.processTransaction(tx, ixs.keys, opts); | ||
const sig = await this.processTransaction(tx, signers, opts); | ||
dbg("Created Marginfi account %s", sig); | ||
return opts?.dryRun | ||
? Promise.resolve(undefined) | ||
: wrapper_1.MarginfiAccountWrapper.fetch(accountKeypair.publicKey, this, opts?.commitment); | ||
: wrapper_1.MarginfiAccountWrapper.fetch(newAccountKey, this, opts?.commitment); | ||
} | ||
@@ -300,3 +310,3 @@ // -------------------------------------------------------------------------- | ||
}); | ||
versionedTransaction = new web3_js_1.VersionedTransaction(versionedMessage.compileToV0Message([])); | ||
versionedTransaction = new web3_js_1.VersionedTransaction(versionedMessage.compileToV0Message(this.addressLookupTables)); | ||
} | ||
@@ -303,0 +313,0 @@ else { |
/// <reference types="node" /> | ||
import { PublicKey } from "@solana/web3.js"; | ||
import BigNumber from "bignumber.js"; | ||
@@ -12,2 +13,5 @@ export declare const PDA_BANK_LIQUIDITY_VAULT_AUTH_SEED: Buffer; | ||
export declare const USDC_DECIMALS = 6; | ||
export declare const ADDRESS_LOOKUP_TABLE_FOR_GROUP: { | ||
[key: string]: [PublicKey]; | ||
}; | ||
//# sourceMappingURL=constants.d.ts.map |
@@ -6,3 +6,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.USDC_DECIMALS = exports.SWB_PRICE_CONF_INTERVALS = exports.PYTH_PRICE_CONF_INTERVALS = exports.PDA_BANK_FEE_VAULT_SEED = exports.PDA_BANK_INSURANCE_VAULT_SEED = exports.PDA_BANK_LIQUIDITY_VAULT_SEED = exports.PDA_BANK_FEE_VAULT_AUTH_SEED = exports.PDA_BANK_INSURANCE_VAULT_AUTH_SEED = exports.PDA_BANK_LIQUIDITY_VAULT_AUTH_SEED = void 0; | ||
exports.ADDRESS_LOOKUP_TABLE_FOR_GROUP = exports.USDC_DECIMALS = exports.SWB_PRICE_CONF_INTERVALS = exports.PYTH_PRICE_CONF_INTERVALS = exports.PDA_BANK_FEE_VAULT_SEED = exports.PDA_BANK_INSURANCE_VAULT_SEED = exports.PDA_BANK_LIQUIDITY_VAULT_SEED = exports.PDA_BANK_FEE_VAULT_AUTH_SEED = exports.PDA_BANK_INSURANCE_VAULT_AUTH_SEED = exports.PDA_BANK_LIQUIDITY_VAULT_AUTH_SEED = void 0; | ||
const web3_js_1 = require("@solana/web3.js"); | ||
const bignumber_js_1 = __importDefault(require("bignumber.js")); | ||
@@ -18,1 +19,4 @@ exports.PDA_BANK_LIQUIDITY_VAULT_AUTH_SEED = Buffer.from("liquidity_vault_auth"); | ||
exports.USDC_DECIMALS = 6; | ||
exports.ADDRESS_LOOKUP_TABLE_FOR_GROUP = { | ||
"4qp6Fx6tnZkY5Wropq9wUYgtFxXKwE6viZxFHg3rdAG8": [new web3_js_1.PublicKey("Ed6FZFDbVPFjjfqFZmVnyLNxicnsRuzkYp6tqxRZzbwe")], | ||
}; |
@@ -150,20 +150,26 @@ "use strict"; | ||
const _volatilityFactor = opts?.volatilityFactor ?? 1; | ||
const assetWeight = bank.getAssetWeight(MarginRequirementType.Initial); | ||
const initAssetWeight = bank.getAssetWeight(MarginRequirementType.Initial); | ||
const maintAssetWeight = bank.getAssetWeight(MarginRequirementType.Maintenance); | ||
const balance = this.getBalance(bankAddress); | ||
if (assetWeight.eq(0)) { | ||
return balance.computeQuantityUi(bank).assets; | ||
const freeCollateral = this.computeFreeCollateral(banks, oraclePrices); | ||
const collateralForBank = bank.computeAssetUsdValue(priceInfo, balance.assetShares, MarginRequirementType.Initial, price_1.PriceBias.Lowest); | ||
const entireBalance = balance.computeQuantityUi(bank).assets; | ||
const { liabilities: liabilitiesInit } = this.computeHealthComponents(banks, oraclePrices, MarginRequirementType.Initial); | ||
if (liabilitiesInit.isZero() || collateralForBank.eq(freeCollateral)) { | ||
return entireBalance; | ||
} | ||
let untiedCollateralForBank; | ||
if (collateralForBank.lt(freeCollateral)) { | ||
untiedCollateralForBank = collateralForBank; | ||
} | ||
else { | ||
const freeCollateral = this.computeFreeCollateral(banks, oraclePrices); | ||
const collateralForBank = bank.computeAssetUsdValue(priceInfo, balance.assetShares, MarginRequirementType.Initial, price_1.PriceBias.Lowest); | ||
let untiedCollateralForBank; | ||
if (collateralForBank.lte(freeCollateral)) { | ||
untiedCollateralForBank = collateralForBank; | ||
} | ||
else { | ||
untiedCollateralForBank = freeCollateral.times(_volatilityFactor); | ||
} | ||
const priceLowestBias = bank.getPrice(priceInfo, price_1.PriceBias.Lowest); | ||
return untiedCollateralForBank.div(priceLowestBias.times(assetWeight)); | ||
untiedCollateralForBank = freeCollateral.times(_volatilityFactor); | ||
} | ||
const { liabilities: liabilitiesMaint, assets: assetsMaint } = this.computeHealthComponents(banks, oraclePrices, MarginRequirementType.Maintenance); | ||
const maintMargin = assetsMaint.minus(liabilitiesMaint); | ||
const priceLowestBias = bank.getPrice(priceInfo, price_1.PriceBias.Lowest); | ||
const initWeightedPrice = priceLowestBias.times(initAssetWeight); | ||
const maintWeightedPrice = priceLowestBias.times(maintAssetWeight); | ||
const maxWithdraw = initWeightedPrice.isZero() ? maintMargin.div(maintWeightedPrice) : untiedCollateralForBank.div(initWeightedPrice); | ||
return maxWithdraw; | ||
} | ||
@@ -338,3 +344,3 @@ // Calculate the max amount of collateral to liquidate to bring an account maint health to 0 (assuming negative health). | ||
} | ||
const userAta = (0, mrgn_common_1.getAssociatedTokenAddressSync)(bank.mint, this.authority); | ||
const userAta = (0, mrgn_common_1.getAssociatedTokenAddressSync)(bank.mint, this.authority, true); | ||
const createAtaIdempotentIx = (0, mrgn_common_1.createAssociatedTokenAccountIdempotentInstruction)(this.authority, userAta, this.authority, bank.mint); | ||
@@ -341,0 +347,0 @@ ixs.push(createAtaIdempotentIx); |
@@ -74,3 +74,6 @@ "use strict"; | ||
const emissionsRate = new bignumber_js_1.default(bank.emissionsRate); | ||
const emissions = period.times(balanceAmount).times(emissionsRate).div(31536000 * Math.pow(10, bank.mintDecimals)); | ||
const emissions = period | ||
.times(balanceAmount) | ||
.times(emissionsRate) | ||
.div(31536000 * Math.pow(10, bank.mintDecimals)); | ||
const emissionsReal = bignumber_js_1.default.min(emissions, new bignumber_js_1.default(bank.emissionsRemaining)); | ||
@@ -77,0 +80,0 @@ return emissionsReal; |
@@ -102,2 +102,3 @@ import { WrappedI80F48 } from "@mrgnlabs/mrgn-common"; | ||
getLiabilityWeight(marginRequirementType: MarginRequirementType): BigNumber; | ||
computeTvl(oraclePrice: OraclePrice): BigNumber; | ||
computeInterestRates(): { | ||
@@ -104,0 +105,0 @@ lendingRate: BigNumber; |
@@ -146,2 +146,5 @@ "use strict"; | ||
} | ||
computeTvl(oraclePrice) { | ||
return this.computeAssetUsdValue(oraclePrice, this.totalAssetShares, account_1.MarginRequirementType.Equity, price_1.PriceBias.None).minus(this.computeLiabilityUsdValue(oraclePrice, this.totalLiabilityShares, account_1.MarginRequirementType.Equity, price_1.PriceBias.None)); | ||
} | ||
computeInterestRates() { | ||
@@ -148,0 +151,0 @@ const { insuranceFeeFixedApr, insuranceIrFee, protocolFixedFeeApr, protocolIrFee } = this.config.interestRateConfig; |
@@ -5,2 +5,3 @@ /// <reference types="node" /> | ||
interface OraclePrice { | ||
priceRealtime?: BigNumber; | ||
price: BigNumber; | ||
@@ -7,0 +8,0 @@ confidenceInterval: BigNumber; |
@@ -23,2 +23,3 @@ "use strict"; | ||
const pythPriceData = (0, pyth_1.parsePriceData)(rawData); | ||
const pythPriceRealtime = new bignumber_js_1.default(pythPriceData.price); | ||
const pythPrice = new bignumber_js_1.default(pythPriceData.emaPrice.value); | ||
@@ -29,2 +30,3 @@ const pythConfInterval = new bignumber_js_1.default(pythPriceData.emaConfidence.value); | ||
return { | ||
priceRealtime: pythPriceRealtime, | ||
price: pythPrice, | ||
@@ -31,0 +33,0 @@ confidenceInterval: pythConfInterval, |
@@ -41,3 +41,3 @@ "use strict"; | ||
function makeWrapSolIxs(walletAddress, amount) { | ||
const address = (0, mrgn_common_1.getAssociatedTokenAddressSync)(mrgn_common_1.NATIVE_MINT, walletAddress); | ||
const address = (0, mrgn_common_1.getAssociatedTokenAddressSync)(mrgn_common_1.NATIVE_MINT, walletAddress, true); | ||
const ixs = [(0, mrgn_common_1.createAssociatedTokenAccountIdempotentInstruction)(walletAddress, address, walletAddress, mrgn_common_1.NATIVE_MINT)]; | ||
@@ -44,0 +44,0 @@ if (amount.gt(0)) { |
{ | ||
"name": "@mrgnlabs/marginfi-client-v2", | ||
"version": "2.1.1", | ||
"version": "2.1.2", | ||
"main": "dist/index.js", | ||
@@ -5,0 +5,0 @@ "types": "dist/index.d.ts", |
import { Address, AnchorProvider, BorshAccountsCoder, Program, translateAddress } from "@coral-xyz/anchor"; | ||
import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes"; | ||
import { | ||
AddressLookupTableAccount, | ||
Commitment, | ||
@@ -30,3 +31,3 @@ ConfirmOptions, | ||
import { MarginfiGroup } from "./models/group"; | ||
import { BankRaw, parseOracleSetup, parsePriceInfo, Bank, OraclePrice } from "."; | ||
import { BankRaw, parseOracleSetup, parsePriceInfo, Bank, OraclePrice, ADDRESS_LOOKUP_TABLE_FOR_GROUP } from "."; | ||
import { MarginfiAccountWrapper } from "./models/account/wrapper"; | ||
@@ -44,2 +45,3 @@ | ||
public oraclePrices: OraclePriceMap; | ||
private addressLookupTables: AddressLookupTableAccount[]; | ||
@@ -60,3 +62,4 @@ // -------------------------------------------------------------------------- | ||
banks: BankMap, | ||
priceInfos: OraclePriceMap | ||
priceInfos: OraclePriceMap, | ||
addressLookupTables?: AddressLookupTableAccount[] | ||
) { | ||
@@ -66,2 +69,3 @@ this.group = group; | ||
this.oraclePrices = priceInfos; | ||
this.addressLookupTables = addressLookupTables ?? []; | ||
} | ||
@@ -104,3 +108,11 @@ | ||
return new MarginfiClient(config, program, wallet, readOnly, marginfiGroup, banks, priceInfos); | ||
const addressLookupTableAddresses = ADDRESS_LOOKUP_TABLE_FOR_GROUP[config.groupPk.toString()] ?? []; | ||
debug("Fetching address lookup tables for %s", addressLookupTableAddresses); | ||
const addressLookupTables = ( | ||
await Promise.all(addressLookupTableAddresses.map((address) => connection.getAddressLookupTable(address))) | ||
) | ||
.map((response) => response!.value) | ||
.filter((table) => table !== null) as AddressLookupTableAccount[]; | ||
return new MarginfiClient(config, program, wallet, readOnly, marginfiGroup, banks, priceInfos, addressLookupTables); | ||
} | ||
@@ -354,11 +366,10 @@ | ||
*/ | ||
async makeCreateMarginfiAccountIx(marginfiAccountKeypair?: Keypair): Promise<InstructionsWrapper> { | ||
async makeCreateMarginfiAccountIx(marginfiAccountPk: PublicKey): Promise<InstructionsWrapper> { | ||
const dbg = require("debug")("mfi:client"); | ||
const accountKeypair = marginfiAccountKeypair || Keypair.generate(); | ||
dbg("Generating marginfi account ix for %s", accountKeypair.publicKey); | ||
dbg("Generating marginfi account ix for %s", marginfiAccountPk); | ||
const initMarginfiAccountIx = await instructions.makeInitMarginfiAccountIx(this.program, { | ||
marginfiGroupPk: this.groupAddress, | ||
marginfiAccountPk: accountKeypair.publicKey, | ||
marginfiAccountPk, | ||
authorityPk: this.provider.wallet.publicKey, | ||
@@ -372,3 +383,3 @@ feePayerPk: this.provider.wallet.publicKey, | ||
instructions: ixs, | ||
keys: [accountKeypair], | ||
keys: [], | ||
}; | ||
@@ -382,10 +393,18 @@ } | ||
*/ | ||
async createMarginfiAccount(opts?: TransactionOptions): Promise<MarginfiAccountWrapper> { | ||
async createMarginfiAccount( | ||
opts?: TransactionOptions, | ||
createOpts?: { newAccountKey?: PublicKey | undefined } | ||
): Promise<MarginfiAccountWrapper> { | ||
const dbg = require("debug")("mfi:client"); | ||
const accountKeypair = Keypair.generate(); | ||
const newAccountKey = createOpts?.newAccountKey ?? accountKeypair.publicKey; | ||
const ixs = await this.makeCreateMarginfiAccountIx(accountKeypair); | ||
const ixs = await this.makeCreateMarginfiAccountIx(newAccountKey); | ||
const signers = [...ixs.keys]; | ||
// If there was no newAccountKey provided, we need to sign with the ephemeraKeypair we generated. | ||
if (!createOpts?.newAccountKey) signers.push(accountKeypair); | ||
const tx = new Transaction().add(...ixs.instructions); | ||
const sig = await this.processTransaction(tx, ixs.keys, opts); | ||
const sig = await this.processTransaction(tx, signers, opts); | ||
@@ -396,3 +415,3 @@ dbg("Created Marginfi account %s", sig); | ||
? Promise.resolve(undefined as unknown as MarginfiAccountWrapper) | ||
: MarginfiAccountWrapper.fetch(accountKeypair.publicKey, this, opts?.commitment); | ||
: MarginfiAccountWrapper.fetch(newAccountKey, this, opts?.commitment); | ||
} | ||
@@ -427,3 +446,3 @@ | ||
versionedTransaction = new VersionedTransaction(versionedMessage.compileToV0Message([])); | ||
versionedTransaction = new VersionedTransaction(versionedMessage.compileToV0Message(this.addressLookupTables)); | ||
} else { | ||
@@ -430,0 +449,0 @@ versionedTransaction = transaction; |
@@ -0,1 +1,2 @@ | ||
import { PublicKey } from "@solana/web3.js"; | ||
import BigNumber from "bignumber.js"; | ||
@@ -14,1 +15,5 @@ | ||
export const USDC_DECIMALS = 6; | ||
export const ADDRESS_LOOKUP_TABLE_FOR_GROUP: { [key: string]: [PublicKey] } = { | ||
"4qp6Fx6tnZkY5Wropq9wUYgtFxXKwE6viZxFHg3rdAG8": [new PublicKey("Ed6FZFDbVPFjjfqFZmVnyLNxicnsRuzkYp6tqxRZzbwe")], | ||
}; |
@@ -19,3 +19,3 @@ import { | ||
import { Balance, BalanceRaw } from "../balance"; | ||
import { BankMap, OraclePriceMap } from "../.."; | ||
import { BankMap, OraclePriceMap, RiskTier } from "../.."; | ||
@@ -238,26 +238,38 @@ // ---------------------------------------------------------------------------- | ||
const assetWeight = bank.getAssetWeight(MarginRequirementType.Initial); | ||
const initAssetWeight = bank.getAssetWeight(MarginRequirementType.Initial); | ||
const maintAssetWeight = bank.getAssetWeight(MarginRequirementType.Maintenance); | ||
const balance = this.getBalance(bankAddress); | ||
if (assetWeight.eq(0)) { | ||
return balance.computeQuantityUi(bank).assets; | ||
const freeCollateral = this.computeFreeCollateral(banks, oraclePrices); | ||
const collateralForBank = bank.computeAssetUsdValue( | ||
priceInfo, | ||
balance.assetShares, | ||
MarginRequirementType.Initial, | ||
PriceBias.Lowest | ||
); | ||
const entireBalance = balance.computeQuantityUi(bank).assets; | ||
const { liabilities: liabilitiesInit } = this.computeHealthComponents(banks, oraclePrices, MarginRequirementType.Initial); | ||
if (liabilitiesInit.isZero() || collateralForBank.eq(freeCollateral)) { | ||
return entireBalance; | ||
} | ||
let untiedCollateralForBank: BigNumber; | ||
if (collateralForBank.lt(freeCollateral)) { | ||
untiedCollateralForBank = collateralForBank; | ||
} else { | ||
const freeCollateral = this.computeFreeCollateral(banks, oraclePrices); | ||
const collateralForBank = bank.computeAssetUsdValue( | ||
priceInfo, | ||
balance.assetShares, | ||
MarginRequirementType.Initial, | ||
PriceBias.Lowest | ||
); | ||
let untiedCollateralForBank: BigNumber; | ||
if (collateralForBank.lte(freeCollateral)) { | ||
untiedCollateralForBank = collateralForBank; | ||
} else { | ||
untiedCollateralForBank = freeCollateral.times(_volatilityFactor); | ||
} | ||
untiedCollateralForBank = freeCollateral.times(_volatilityFactor); | ||
} | ||
const priceLowestBias = bank.getPrice(priceInfo, PriceBias.Lowest); | ||
const { liabilities: liabilitiesMaint, assets: assetsMaint } = this.computeHealthComponents(banks, oraclePrices, MarginRequirementType.Maintenance); | ||
const maintMargin = assetsMaint.minus(liabilitiesMaint); | ||
return untiedCollateralForBank.div(priceLowestBias.times(assetWeight)); | ||
} | ||
const priceLowestBias = bank.getPrice(priceInfo, PriceBias.Lowest); | ||
const initWeightedPrice = priceLowestBias.times(initAssetWeight); | ||
const maintWeightedPrice = priceLowestBias.times(maintAssetWeight); | ||
const maxWithdraw = initWeightedPrice.isZero() ? maintMargin.div(maintWeightedPrice) : untiedCollateralForBank.div(initWeightedPrice); | ||
return maxWithdraw; | ||
} | ||
@@ -507,3 +519,3 @@ | ||
const userAta = getAssociatedTokenAddressSync(bank.mint, this.authority); | ||
const userAta = getAssociatedTokenAddressSync(bank.mint, this.authority, true); | ||
const createAtaIdempotentIx = createAssociatedTokenAccountIdempotentInstruction( | ||
@@ -510,0 +522,0 @@ this.authority, |
@@ -145,3 +145,6 @@ import { WrappedI80F48, wrappedI80F48toBigNumber, nativeToUi } from "@mrgnlabs/mrgn-common"; | ||
const emissionsRate = new BigNumber(bank.emissionsRate); | ||
const emissions = period.times(balanceAmount).times(emissionsRate).div(31_536_000 * Math.pow(10, bank.mintDecimals)); | ||
const emissions = period | ||
.times(balanceAmount) | ||
.times(emissionsRate) | ||
.div(31_536_000 * Math.pow(10, bank.mintDecimals)); | ||
const emissionsReal = BigNumber.min(emissions, new BigNumber(bank.emissionsRemaining)); | ||
@@ -148,0 +151,0 @@ |
@@ -357,2 +357,18 @@ import { WrappedI80F48, nativeToUi, wrappedI80F48toBigNumber } from "@mrgnlabs/mrgn-common"; | ||
computeTvl(oraclePrice: OraclePrice): BigNumber { | ||
return this.computeAssetUsdValue( | ||
oraclePrice, | ||
this.totalAssetShares, | ||
MarginRequirementType.Equity, | ||
PriceBias.None | ||
).minus( | ||
this.computeLiabilityUsdValue( | ||
oraclePrice, | ||
this.totalLiabilityShares, | ||
MarginRequirementType.Equity, | ||
PriceBias.None | ||
) | ||
); | ||
} | ||
computeInterestRates(): { | ||
@@ -359,0 +375,0 @@ lendingRate: BigNumber; |
@@ -8,2 +8,3 @@ import { parsePriceData } from "../vendor/pyth"; | ||
interface OraclePrice { | ||
priceRealtime?: BigNumber; | ||
price: BigNumber; | ||
@@ -26,2 +27,3 @@ confidenceInterval: BigNumber; | ||
const pythPriceRealtime = new BigNumber(pythPriceData.price!); | ||
const pythPrice = new BigNumber(pythPriceData.emaPrice.value); | ||
@@ -33,2 +35,3 @@ const pythConfInterval = new BigNumber(pythPriceData.emaConfidence.value); | ||
return { | ||
priceRealtime: pythPriceRealtime, | ||
price: pythPrice, | ||
@@ -35,0 +38,0 @@ confidenceInterval: pythConfInterval, |
@@ -59,3 +59,3 @@ import { PublicKey, SystemProgram, TransactionInstruction } from "@solana/web3.js"; | ||
export function makeWrapSolIxs(walletAddress: PublicKey, amount: BigNumber): TransactionInstruction[] { | ||
const address = getAssociatedTokenAddressSync(NATIVE_MINT, walletAddress); | ||
const address = getAssociatedTokenAddressSync(NATIVE_MINT, walletAddress, true); | ||
const ixs = [createAssociatedTokenAccountIdempotentInstruction(walletAddress, address, walletAddress, NATIVE_MINT)]; | ||
@@ -62,0 +62,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
837552
22721