Skip to content

Commit d4f3833

Browse files
Merge pull request #66 from bnb-party/scripts
add more readability
2 parents a14d9f8 + f77bdbd commit d4f3833

File tree

3 files changed

+75
-30
lines changed

3 files changed

+75
-30
lines changed

scripts/curve.ts

+39-30
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { ethers } from "hardhat"
2-
import { FeeAmount, v3PartyFactory, deployContracts, bnbPartyFactory, BNBPositionManager, v3Factory, positionManager, maxAndMinWBNB } from "../test/helper"
2+
import {FeeAmount, v3PartyFactory, deployContracts, bnbPartyFactory, positionManager, BNBPositionManager, v3Factory, maxAndMinWBNB} from "../test/helper"
33
import { IUniswapV3Pool } from "../typechain-types"
44
import BigNumber from "bignumber.js"
55
import * as csvWriter from "csv-writer"
6+
import { getPrice } from "./get-price"
67

78
const BNB_PRICE = 600 // BNB price in USD
89
let lpContract: IUniswapV3Pool
@@ -15,8 +16,8 @@ const csv = createCsvWriter({
1516
{ id: "MEMEAmount", title: "MEME Amount" },
1617
{ id: "WBNBAmount", title: "WBNB Amount" },
1718
{ id: "SqrtPriceX96", title: "sqrtPriceX96" },
18-
{ id: "priceMemeInWbnb", title: "Price of MEME in WBNB" },
19-
{ id: "priceWbnbInMeme", title: "Price of WBNB in MEME" },
19+
{ id: "priceMemeInWbnb", title: "Amount of WBNB required to purchase one unit of the MEME" },
20+
{ id: "priceWbnbInMeme", title: "Amount of MEME tokens required to purchase one unit of WBNB" },
2021
{ id: "wbnbValueInLp", title: "WBNB Value in USD" },
2122
{ id: "memeValueInLp", title: "MEME Value in USD" },
2223
{ id: "marketCap", title: "Market Cap in USD" },
@@ -35,42 +36,36 @@ async function createLiquidityPool(wbnbAddress: string) {
3536
return { MEME, position }
3637
}
3738

38-
function calculatePrices(sqrtPriceX96: BigNumber, token0: string, token1: string, meme: string) {
39-
const priceX96 = sqrtPriceX96.pow(2)
40-
const priceToken0InToken1 = priceX96.dividedBy(new BigNumber(2).pow(192))
41-
const priceToken1InToken0 = new BigNumber(1).div(priceToken0InToken1)
42-
return token0 === meme
43-
? { priceMemeInWbnb: priceToken0InToken1, priceWbnbInMeme: priceToken1InToken0 }
44-
: { priceMemeInWbnb: priceToken1InToken0, priceWbnbInMeme: priceToken0InToken1 }
45-
}
46-
4739
async function getTokenBalances(lpAddress: string, token: any, wbnbAddress: string) {
4840
const wbnb = await ethers.getContractAt("IWBNB", wbnbAddress)
49-
const [MEMEAmount, WBNBAmount, wethAddress] = await Promise.all([
50-
token.balanceOf(lpAddress),
51-
wbnb.balanceOf(lpAddress),
52-
wbnb.getAddress(),
53-
])
41+
const [MEMEAmount, WBNBAmount] = await Promise.all([token.balanceOf(lpAddress), wbnb.balanceOf(lpAddress)])
5442

5543
const lpPool = await ethers.getContractAt("UniswapV3Pool", lpAddress)
5644
const token0 = await lpPool.token0()
57-
const isPartyPool = await bnbPartyFactory.isTokenOnPartyLP(token0 === wethAddress ? await token.getAddress() : token0)
45+
const isPartyPool = await bnbPartyFactory.isTokenOnPartyLP(
46+
token0 === wbnbAddress ? await token.getAddress() : token0
47+
)
48+
5849
const [feeGrowthGlobal0X128, feeGrowthGlobal1X128, liquidity, getFeeGlobal] = await Promise.all([
5950
lpPool.feeGrowthGlobal0X128(),
6051
lpPool.feeGrowthGlobal1X128(),
6152
lpPool.liquidity(),
6253
bnbPartyFactory.getFeeGrowthInsideLastX128(lpAddress, isPartyPool ? BNBPositionManager : positionManager),
6354
])
55+
6456
let wbnbFee, memeFee
65-
if (token0 === wethAddress) {
57+
if (token0 === wbnbAddress) {
6658
wbnbFee = await bnbPartyFactory.calculateFees(liquidity, feeGrowthGlobal0X128 - getFeeGlobal.feeGrowthInside0LastX128)
6759
memeFee = await bnbPartyFactory.calculateFees(liquidity, feeGrowthGlobal1X128 - getFeeGlobal.feeGrowthInside1LastX128)
6860
} else {
6961
memeFee = await bnbPartyFactory.calculateFees(liquidity, feeGrowthGlobal0X128 - getFeeGlobal.feeGrowthInside0LastX128)
7062
wbnbFee = await bnbPartyFactory.calculateFees(liquidity, feeGrowthGlobal1X128 - getFeeGlobal.feeGrowthInside1LastX128)
7163
}
7264

73-
return { WBNBAmount: new BigNumber((WBNBAmount - wbnbFee).toString()), MEMEAmount: new BigNumber((MEMEAmount - memeFee).toString()) }
65+
return {
66+
WBNBAmount: new BigNumber((WBNBAmount - wbnbFee).toString()),
67+
MEMEAmount: new BigNumber((MEMEAmount - memeFee).toString()),
68+
}
7469
}
7570

7671
async function logData(
@@ -84,7 +79,10 @@ async function logData(
8479
) {
8580
const wbnbValueUSD = WBNBAmount.div(new BigNumber(10).pow(18)).multipliedBy(BNB_PRICE)
8681
const memeValueUSD = MEMEAmount.div(new BigNumber(10).pow(18)).multipliedBy(priceMemeInWbnb).multipliedBy(BNB_PRICE)
87-
const marketCap = initialMEMEAmount.div(new BigNumber(10).pow(18)).multipliedBy(priceMemeInWbnb).multipliedBy(BNB_PRICE)
82+
const marketCap = initialMEMEAmount
83+
.div(new BigNumber(10).pow(18))
84+
.multipliedBy(priceMemeInWbnb)
85+
.multipliedBy(BNB_PRICE)
8886
const remainingMEMEPercentage = MEMEAmount.div(initialMEMEAmount).multipliedBy(100).toFixed(2)
8987
const memeMarketCapInBnb = initialMEMEAmount.div(new BigNumber(10).pow(18)).multipliedBy(priceMemeInWbnb)
9088

@@ -93,8 +91,8 @@ async function logData(
9391
MEMEAmount: MEMEAmount.toString(),
9492
WBNBAmount: WBNBAmount.toString(),
9593
SqrtPriceX96: sqrtPriceX96.toString(),
96-
priceMemeInWbnb: priceMemeInWbnb.toString(),
97-
priceWbnbInMeme: priceWbnbInMeme.toString(),
94+
priceMemeInWbnb: priceMemeInWbnb.toString(10),
95+
priceWbnbInMeme: priceWbnbInMeme.toString(10),
9896
wbnbValueInLp: wbnbValueUSD.toString(),
9997
memeValueInLp: memeValueUSD.toString(),
10098
marketCap: marketCap.toString(),
@@ -109,32 +107,43 @@ async function logData(
109107
async function test() {
110108
const target = ethers.parseEther("13")
111109
const wbnbAddresses = await maxAndMinWBNB()
112-
const wbnbAddress = wbnbAddresses.maxAddress
110+
const wbnbAddress = wbnbAddresses.minAddress
113111
await deployContracts(target, wbnbAddress)
114112
const { MEME, position } = await createLiquidityPool(wbnbAddress)
115113
const token = await ethers.getContractAt("ERC20Token", MEME)
116114
const lpAddress = await v3PartyFactory.getPool(position.token0, position.token1, FeeAmount.HIGH)
117115
lpContract = (await ethers.getContractAt("UniswapV3Pool", lpAddress)) as any as IUniswapV3Pool
118116

119-
const { MEMEAmount: initialMEMEAmount, } = await getTokenBalances(lpAddress, token, wbnbAddress)
117+
const { MEMEAmount: initialMEMEAmount } = await getTokenBalances(lpAddress, token, wbnbAddress)
120118
const segments = 26
121119
for (let i = 0; i <= segments; ++i) {
122120
const swapAmount = ethers.parseUnits("5.06", 17)
123-
if( i !== 0) await bnbPartyFactory.joinParty(MEME, 0, { value: swapAmount })
121+
if (i !== 0) await bnbPartyFactory.joinParty(MEME, 0, { value: swapAmount })
124122
const isParty = await bnbPartyFactory.isTokenOnPartyLP(MEME)
125123
if (isParty) {
126124
const { MEMEAmount, WBNBAmount } = await getTokenBalances(lpAddress, token, wbnbAddress)
127125
const slot0 = await lpContract.slot0()
128126
const sqrtPriceX96 = new BigNumber(slot0.sqrtPriceX96.toString())
129-
const { priceMemeInWbnb, priceWbnbInMeme } = calculatePrices(sqrtPriceX96, await lpContract.token0(), await lpContract.token1(), MEME)
127+
let { priceToken0InToken1: priceMemeInWbnb, priceToken1InToken0: priceWbnbInMeme } = getPrice(sqrtPriceX96)
128+
if (wbnbAddress === wbnbAddresses.minAddress) {
129+
// replace the price of MEME in WBNB with the price of WBNB in MEME
130+
const temp = priceMemeInWbnb
131+
priceMemeInWbnb = priceWbnbInMeme
132+
priceWbnbInMeme = temp
133+
}
130134
await logData(i, MEMEAmount, WBNBAmount, sqrtPriceX96, priceMemeInWbnb, priceWbnbInMeme, initialMEMEAmount)
131-
}
132-
else {
135+
} else {
133136
const newLPPool = await v3Factory.getPool(wbnbAddress, MEME, FeeAmount.HIGH)
134137
const lpContract = (await ethers.getContractAt("UniswapV3Pool", newLPPool)) as any as IUniswapV3Pool
135138
const slot0 = await lpContract.slot0()
136139
const sqrtPriceX96 = new BigNumber(slot0.sqrtPriceX96.toString())
137-
const { priceMemeInWbnb, priceWbnbInMeme } = calculatePrices(sqrtPriceX96, await lpContract.token0(), await lpContract.token1(), MEME)
140+
let { priceToken0InToken1: priceMemeInWbnb, priceToken1InToken0: priceWbnbInMeme } = getPrice(sqrtPriceX96)
141+
if (wbnbAddress === wbnbAddresses.minAddress) {
142+
// replace the price of MEME in WBNB with the price of WBNB in MEME
143+
const temp = priceMemeInWbnb
144+
priceMemeInWbnb = priceWbnbInMeme
145+
priceWbnbInMeme = temp
146+
}
138147
const { MEMEAmount, WBNBAmount } = await getTokenBalances(newLPPool, token, wbnbAddress)
139148
await logData(i, MEMEAmount, WBNBAmount, sqrtPriceX96, priceMemeInWbnb, priceWbnbInMeme, initialMEMEAmount)
140149
}

scripts/encodePrice.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import BigNumber from "bignumber.js" // Import BigNumber.js for precise calculations
2+
3+
// Configure BigNumber.js for high precision
4+
BigNumber.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 })
5+
6+
// Function to calculate sqrtPriceX96
7+
export function encodePriceSqrt(reserve1: string, reserve0: string): bigint {
8+
return BigInt(
9+
new BigNumber(reserve1) // Convert reserve1 to a BigNumber
10+
.div(reserve0) // Divide by reserve0
11+
.sqrt() // Take the square root of the result
12+
.multipliedBy(new BigNumber(2).pow(96)) // Multiply by 2^96
13+
.integerValue(BigNumber.ROUND_DOWN) // Round down to the nearest integer
14+
.toString() // Convert to string
15+
)
16+
}

scripts/get-price.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import BigNumber from "bignumber.js"
2+
3+
export function getPrice(sqrtPriceX96: BigNumber) {
4+
// Calculate price of token0 in terms of token1
5+
const buyOneOfToken0 = sqrtPriceX96.dividedBy(new BigNumber(2).pow(96)).pow(2)
6+
7+
// Calculate price of token1 in terms of token0
8+
const buyOneOfToken1 = new BigNumber(1).dividedBy(buyOneOfToken0)
9+
10+
// Convert to smallest unit (wei)
11+
const buyOneOfToken0Wei = buyOneOfToken0.multipliedBy(new BigNumber(10).pow(18)).integerValue(BigNumber.ROUND_DOWN).toString(10)
12+
const buyOneOfToken1Wei = buyOneOfToken1.multipliedBy(new BigNumber(10).pow(18)).integerValue(BigNumber.ROUND_DOWN).toString(10)
13+
14+
return {
15+
priceToken0InToken1: buyOneOfToken0, // Price of token0 in terms of token1
16+
priceToken1InToken0: buyOneOfToken1, // Price of token1 in terms of token0
17+
priceToken0InToken1Wei: buyOneOfToken0Wei, // Price of token0 in lowest decimal (wei)
18+
priceToken1InToken0Wei: buyOneOfToken1Wei, // Price of token1 in lowest decimal (wei)
19+
}
20+
}

0 commit comments

Comments
 (0)