Skip to content

Commit

Permalink
add more readability
Browse files Browse the repository at this point in the history
  • Loading branch information
YouStillAlive committed Sep 11, 2024
1 parent a14d9f8 commit f77bdbd
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 30 deletions.
69 changes: 39 additions & 30 deletions scripts/curve.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ethers } from "hardhat"
import { FeeAmount, v3PartyFactory, deployContracts, bnbPartyFactory, BNBPositionManager, v3Factory, positionManager, maxAndMinWBNB } from "../test/helper"
import {FeeAmount, v3PartyFactory, deployContracts, bnbPartyFactory, positionManager, BNBPositionManager, v3Factory, maxAndMinWBNB} from "../test/helper"
import { IUniswapV3Pool } from "../typechain-types"
import BigNumber from "bignumber.js"
import * as csvWriter from "csv-writer"
import { getPrice } from "./get-price"

const BNB_PRICE = 600 // BNB price in USD
let lpContract: IUniswapV3Pool
Expand All @@ -15,8 +16,8 @@ const csv = createCsvWriter({
{ id: "MEMEAmount", title: "MEME Amount" },
{ id: "WBNBAmount", title: "WBNB Amount" },
{ id: "SqrtPriceX96", title: "sqrtPriceX96" },
{ id: "priceMemeInWbnb", title: "Price of MEME in WBNB" },
{ id: "priceWbnbInMeme", title: "Price of WBNB in MEME" },
{ id: "priceMemeInWbnb", title: "Amount of WBNB required to purchase one unit of the MEME" },
{ id: "priceWbnbInMeme", title: "Amount of MEME tokens required to purchase one unit of WBNB" },
{ id: "wbnbValueInLp", title: "WBNB Value in USD" },
{ id: "memeValueInLp", title: "MEME Value in USD" },
{ id: "marketCap", title: "Market Cap in USD" },
Expand All @@ -35,42 +36,36 @@ async function createLiquidityPool(wbnbAddress: string) {
return { MEME, position }
}

function calculatePrices(sqrtPriceX96: BigNumber, token0: string, token1: string, meme: string) {
const priceX96 = sqrtPriceX96.pow(2)
const priceToken0InToken1 = priceX96.dividedBy(new BigNumber(2).pow(192))
const priceToken1InToken0 = new BigNumber(1).div(priceToken0InToken1)
return token0 === meme
? { priceMemeInWbnb: priceToken0InToken1, priceWbnbInMeme: priceToken1InToken0 }
: { priceMemeInWbnb: priceToken1InToken0, priceWbnbInMeme: priceToken0InToken1 }
}

async function getTokenBalances(lpAddress: string, token: any, wbnbAddress: string) {
const wbnb = await ethers.getContractAt("IWBNB", wbnbAddress)
const [MEMEAmount, WBNBAmount, wethAddress] = await Promise.all([
token.balanceOf(lpAddress),
wbnb.balanceOf(lpAddress),
wbnb.getAddress(),
])
const [MEMEAmount, WBNBAmount] = await Promise.all([token.balanceOf(lpAddress), wbnb.balanceOf(lpAddress)])

const lpPool = await ethers.getContractAt("UniswapV3Pool", lpAddress)
const token0 = await lpPool.token0()
const isPartyPool = await bnbPartyFactory.isTokenOnPartyLP(token0 === wethAddress ? await token.getAddress() : token0)
const isPartyPool = await bnbPartyFactory.isTokenOnPartyLP(
token0 === wbnbAddress ? await token.getAddress() : token0
)

const [feeGrowthGlobal0X128, feeGrowthGlobal1X128, liquidity, getFeeGlobal] = await Promise.all([
lpPool.feeGrowthGlobal0X128(),
lpPool.feeGrowthGlobal1X128(),
lpPool.liquidity(),
bnbPartyFactory.getFeeGrowthInsideLastX128(lpAddress, isPartyPool ? BNBPositionManager : positionManager),
])

let wbnbFee, memeFee
if (token0 === wethAddress) {
if (token0 === wbnbAddress) {
wbnbFee = await bnbPartyFactory.calculateFees(liquidity, feeGrowthGlobal0X128 - getFeeGlobal.feeGrowthInside0LastX128)
memeFee = await bnbPartyFactory.calculateFees(liquidity, feeGrowthGlobal1X128 - getFeeGlobal.feeGrowthInside1LastX128)
} else {
memeFee = await bnbPartyFactory.calculateFees(liquidity, feeGrowthGlobal0X128 - getFeeGlobal.feeGrowthInside0LastX128)
wbnbFee = await bnbPartyFactory.calculateFees(liquidity, feeGrowthGlobal1X128 - getFeeGlobal.feeGrowthInside1LastX128)
}

return { WBNBAmount: new BigNumber((WBNBAmount - wbnbFee).toString()), MEMEAmount: new BigNumber((MEMEAmount - memeFee).toString()) }
return {
WBNBAmount: new BigNumber((WBNBAmount - wbnbFee).toString()),
MEMEAmount: new BigNumber((MEMEAmount - memeFee).toString()),
}
}

async function logData(
Expand All @@ -84,7 +79,10 @@ async function logData(
) {
const wbnbValueUSD = WBNBAmount.div(new BigNumber(10).pow(18)).multipliedBy(BNB_PRICE)
const memeValueUSD = MEMEAmount.div(new BigNumber(10).pow(18)).multipliedBy(priceMemeInWbnb).multipliedBy(BNB_PRICE)
const marketCap = initialMEMEAmount.div(new BigNumber(10).pow(18)).multipliedBy(priceMemeInWbnb).multipliedBy(BNB_PRICE)
const marketCap = initialMEMEAmount
.div(new BigNumber(10).pow(18))
.multipliedBy(priceMemeInWbnb)
.multipliedBy(BNB_PRICE)
const remainingMEMEPercentage = MEMEAmount.div(initialMEMEAmount).multipliedBy(100).toFixed(2)
const memeMarketCapInBnb = initialMEMEAmount.div(new BigNumber(10).pow(18)).multipliedBy(priceMemeInWbnb)

Expand All @@ -93,8 +91,8 @@ async function logData(
MEMEAmount: MEMEAmount.toString(),
WBNBAmount: WBNBAmount.toString(),
SqrtPriceX96: sqrtPriceX96.toString(),
priceMemeInWbnb: priceMemeInWbnb.toString(),
priceWbnbInMeme: priceWbnbInMeme.toString(),
priceMemeInWbnb: priceMemeInWbnb.toString(10),
priceWbnbInMeme: priceWbnbInMeme.toString(10),
wbnbValueInLp: wbnbValueUSD.toString(),
memeValueInLp: memeValueUSD.toString(),
marketCap: marketCap.toString(),
Expand All @@ -109,32 +107,43 @@ async function logData(
async function test() {
const target = ethers.parseEther("13")
const wbnbAddresses = await maxAndMinWBNB()
const wbnbAddress = wbnbAddresses.maxAddress
const wbnbAddress = wbnbAddresses.minAddress
await deployContracts(target, wbnbAddress)
const { MEME, position } = await createLiquidityPool(wbnbAddress)
const token = await ethers.getContractAt("ERC20Token", MEME)
const lpAddress = await v3PartyFactory.getPool(position.token0, position.token1, FeeAmount.HIGH)
lpContract = (await ethers.getContractAt("UniswapV3Pool", lpAddress)) as any as IUniswapV3Pool

const { MEMEAmount: initialMEMEAmount, } = await getTokenBalances(lpAddress, token, wbnbAddress)
const { MEMEAmount: initialMEMEAmount } = await getTokenBalances(lpAddress, token, wbnbAddress)
const segments = 26
for (let i = 0; i <= segments; ++i) {
const swapAmount = ethers.parseUnits("5.06", 17)
if( i !== 0) await bnbPartyFactory.joinParty(MEME, 0, { value: swapAmount })
if (i !== 0) await bnbPartyFactory.joinParty(MEME, 0, { value: swapAmount })
const isParty = await bnbPartyFactory.isTokenOnPartyLP(MEME)
if (isParty) {
const { MEMEAmount, WBNBAmount } = await getTokenBalances(lpAddress, token, wbnbAddress)
const slot0 = await lpContract.slot0()
const sqrtPriceX96 = new BigNumber(slot0.sqrtPriceX96.toString())
const { priceMemeInWbnb, priceWbnbInMeme } = calculatePrices(sqrtPriceX96, await lpContract.token0(), await lpContract.token1(), MEME)
let { priceToken0InToken1: priceMemeInWbnb, priceToken1InToken0: priceWbnbInMeme } = getPrice(sqrtPriceX96)
if (wbnbAddress === wbnbAddresses.minAddress) {
// replace the price of MEME in WBNB with the price of WBNB in MEME
const temp = priceMemeInWbnb
priceMemeInWbnb = priceWbnbInMeme
priceWbnbInMeme = temp
}
await logData(i, MEMEAmount, WBNBAmount, sqrtPriceX96, priceMemeInWbnb, priceWbnbInMeme, initialMEMEAmount)
}
else {
} else {
const newLPPool = await v3Factory.getPool(wbnbAddress, MEME, FeeAmount.HIGH)
const lpContract = (await ethers.getContractAt("UniswapV3Pool", newLPPool)) as any as IUniswapV3Pool
const slot0 = await lpContract.slot0()
const sqrtPriceX96 = new BigNumber(slot0.sqrtPriceX96.toString())
const { priceMemeInWbnb, priceWbnbInMeme } = calculatePrices(sqrtPriceX96, await lpContract.token0(), await lpContract.token1(), MEME)
let { priceToken0InToken1: priceMemeInWbnb, priceToken1InToken0: priceWbnbInMeme } = getPrice(sqrtPriceX96)
if (wbnbAddress === wbnbAddresses.minAddress) {
// replace the price of MEME in WBNB with the price of WBNB in MEME
const temp = priceMemeInWbnb
priceMemeInWbnb = priceWbnbInMeme
priceWbnbInMeme = temp
}
const { MEMEAmount, WBNBAmount } = await getTokenBalances(newLPPool, token, wbnbAddress)
await logData(i, MEMEAmount, WBNBAmount, sqrtPriceX96, priceMemeInWbnb, priceWbnbInMeme, initialMEMEAmount)
}
Expand Down
16 changes: 16 additions & 0 deletions scripts/encodePrice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import BigNumber from "bignumber.js" // Import BigNumber.js for precise calculations

// Configure BigNumber.js for high precision
BigNumber.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 })

// Function to calculate sqrtPriceX96
export function encodePriceSqrt(reserve1: string, reserve0: string): bigint {
return BigInt(
new BigNumber(reserve1) // Convert reserve1 to a BigNumber
.div(reserve0) // Divide by reserve0
.sqrt() // Take the square root of the result
.multipliedBy(new BigNumber(2).pow(96)) // Multiply by 2^96
.integerValue(BigNumber.ROUND_DOWN) // Round down to the nearest integer
.toString() // Convert to string
)
}
20 changes: 20 additions & 0 deletions scripts/get-price.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import BigNumber from "bignumber.js"

export function getPrice(sqrtPriceX96: BigNumber) {
// Calculate price of token0 in terms of token1
const buyOneOfToken0 = sqrtPriceX96.dividedBy(new BigNumber(2).pow(96)).pow(2)

// Calculate price of token1 in terms of token0
const buyOneOfToken1 = new BigNumber(1).dividedBy(buyOneOfToken0)

// Convert to smallest unit (wei)
const buyOneOfToken0Wei = buyOneOfToken0.multipliedBy(new BigNumber(10).pow(18)).integerValue(BigNumber.ROUND_DOWN).toString(10)
const buyOneOfToken1Wei = buyOneOfToken1.multipliedBy(new BigNumber(10).pow(18)).integerValue(BigNumber.ROUND_DOWN).toString(10)

return {
priceToken0InToken1: buyOneOfToken0, // Price of token0 in terms of token1
priceToken1InToken0: buyOneOfToken1, // Price of token1 in terms of token0
priceToken0InToken1Wei: buyOneOfToken0Wei, // Price of token0 in lowest decimal (wei)
priceToken1InToken0Wei: buyOneOfToken1Wei, // Price of token1 in lowest decimal (wei)
}
}

0 comments on commit f77bdbd

Please sign in to comment.