Skip to content

Instantly share code, notes, and snippets.

@losman0s
Last active March 7, 2024 02:45
Show Gist options
  • Save losman0s/c3128fe89b8d9110b580ba1cb024ad75 to your computer and use it in GitHub Desktop.
Save losman0s/c3128fe89b8d9110b580ba1cb024ad75 to your computer and use it in GitHub Desktop.
import { Amount, toBigNumber } from "@mrgnlabs/mrgn-common";
import { getMarginfiClient } from "./utils";
import { Bank, OraclePrice } from "../src";
import BigNumber from "bignumber.js";
async function main() {
const client = await getMarginfiClient();
const uxdBank = client.getBankByTokenSymbol("UXD");
if (!uxdBank) {
throw new Error("UXD bank not found");
}
const uxdPriceInfo = client.getOraclePriceByBank(uxdBank.address);
if (!uxdPriceInfo) {
throw new Error("UXD oracle price not found");
}
const usdcBank = client.getBankByTokenSymbol("USDC");
if (!usdcBank) {
throw new Error("USDC bank not found");
}
const usdcPriceInfo = client.getOraclePriceByBank(usdcBank.address);
if (!usdcPriceInfo) {
throw new Error("USDC oracle price not found");
}
const { maxDeposit, maxBorrow, leverage, maintHealth, netAccountValue } = computeLeverParams(
100,
uxdBank,
usdcBank,
uxdPriceInfo,
usdcPriceInfo,
);
console.log("Max deposit:", maxDeposit.toFixed());
console.log("Max borrow:", maxBorrow.toFixed());
console.log("Leverage:", leverage);
console.log("Final health", maintHealth * 100);
console.log("Net value:", netAccountValue.toFixed());
}
function computeLeverParams(
initialCollateral: Amount,
depositBank: Bank,
borrowBank: Bank,
depositOracleInfo: OraclePrice,
borrowOracleInfo: OraclePrice,
): { maxBorrow: BigNumber; maxDeposit: BigNumber; leverage: number, maintHealth: number, netAccountValue: BigNumber } {
const _initialCollateral = toBigNumber(initialCollateral);
const depositInitWeight = depositBank.config.assetWeightInit;
const borrowInitWeight = borrowBank.config.liabilityWeightInit;
const ltv = depositInitWeight.div(borrowInitWeight);
console.log("LTV:", ltv.toFixed());
const depositPriceLow = depositOracleInfo.priceWeighted.lowestPrice;
const borrowPriceHigh = borrowOracleInfo.priceWeighted.highestPrice;
const initialCollateralValue = _initialCollateral.times(depositPriceLow);
const maxDepositValue = initialCollateralValue.div(new BigNumber(1).minus(ltv));
const maxBorrowValue = maxDepositValue.times(ltv);
const maxDeposit = maxDepositValue.div(depositPriceLow);
const maxBorrow = maxBorrowValue.div(borrowPriceHigh);
const leverage = maxDeposit.div(_initialCollateral).toNumber();
const finalMaintWeightedDeposits = maxDeposit.times(depositBank.config.assetWeightMaint).times(depositPriceLow);
const finalMaintWeightedBorrows = maxBorrow.times(borrowBank.config.liabilityWeightMaint).times(borrowPriceHigh);
const maintHealth = finalMaintWeightedDeposits.minus(finalMaintWeightedBorrows).div(finalMaintWeightedDeposits).toNumber();
const netAccountValue = maxDepositValue.minus(maxBorrowValue);
return { maxBorrow, maxDeposit, leverage, maintHealth, netAccountValue };
}
main();
@losman0s
Copy link
Author

losman0s commented Mar 7, 2024

If you add these to the logs you can see that the calculation is wrong because one can't end up with a higher net position value than what you started with.

  console.log(
    'Net position:',
    maxDeposit
      .times(uxdPriceInfo.priceRealtime.price)
      .minus(maxBorrow.times(usdcPriceInfo.priceRealtime.price))
      .toFixed()
  );
  console.log(
    'Final Health:',
    maxDeposit.minus(maxBorrow).dividedBy(maxDeposit).toFixed()
  );```

I had inverted:

  const maxDepositValue = initialCollateralValue.div(new BigNumber(1).minus(ltv));
  const maxBorrowValue = maxDepositValue.times(ltv);

Fixed now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment