Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion programs/zap/src/math/price_math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub fn get_price_from_id(active_id: i32, bin_step: u16) -> Result<u128> {

// get price base factor
pub fn get_price_base_factor(bin_step: u16) -> Result<u128> {
// Make bin_step into Q64x64, and divided by BASIS_POINT_MAX. If bin_step = 1, we get 0.0001 in Q64x64
// Make bin_step into Q64x64, and divided by MAX_BASIS_POINT. If bin_step = 1, we get 0.0001 in Q64x64
let bps = u128::from(bin_step)
.safe_shl(SCALE_OFFSET.into())?
.safe_div(MAX_BASIS_POINT as u128)?;
Expand Down
23 changes: 14 additions & 9 deletions programs/zap/src/utils/dlmm_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,10 +308,7 @@ impl StrategyHandler for CurveHandler {

if min_delta_id == max_delta_id {
let bin_id = active_id.safe_add(min_delta_id)?;
let pm = U256::from(get_price_from_id(bin_id, bin_step)?);
let x0 = U256::from(amount_x).safe_mul(pm)?.safe_shr(64)?;
let x0: i128 = x0.try_into().map_err(|_| ZapError::TypeCastFailed)?;
return Ok((x0, 0));
return find_x0_and_delta_x_single_bin(bin_id, bin_step, amount_x);
}

let mut b = U256::ZERO;
Expand Down Expand Up @@ -405,14 +402,11 @@ impl StrategyHandler for BidAskHandler {
// C = (m1 * p(m1) + ... + m2 * p(m2))
// delta_x = sum(amounts) / (C-B)
// note: in bid ask strategy: x0 <= 0 and delta_x >= 0
// except for the case min_delta_id == max_delta_id, x0 > 0 and delta_x = 0 (using the same result from curve strategy)

if min_delta_id == max_delta_id {
let bin_id = active_id.safe_add(min_delta_id)?;
let pm = get_price_from_id(bin_id.neg(), bin_step)?;
let denominator = U256::from(min_delta_id).safe_mul(U256::from(pm))?;
let delta_x = U256::from(amount_x).safe_shl(64)?.safe_div(denominator)?;
let delta_x: i128 = delta_x.try_into().map_err(|_| ZapError::TypeCastFailed)?;
return Ok((0, delta_x));
return find_x0_and_delta_x_single_bin(bin_id, bin_step, amount_x);
}

let mut b = U256::ZERO;
Expand Down Expand Up @@ -443,3 +437,14 @@ impl StrategyHandler for BidAskHandler {
Ok((x0, delta_x))
}
}

fn find_x0_and_delta_x_single_bin(
bin_id: i32,
bin_step: u16,
amount_x: u64,
) -> Result<(i128, i128)> {
let pm = U256::from(get_price_from_id(bin_id, bin_step)?);
let x0 = U256::from(amount_x).safe_mul(pm)?.safe_shr(64)?;
let x0: i128 = x0.try_into().map_err(|_| ZapError::TypeCastFailed)?;
return Ok((x0, 0));
}
69 changes: 68 additions & 1 deletion tests/test_zapin/zapin_dlmm_initialize_position.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,66 @@ describe("Zapin DLMM with initialize position", () => {
});
});

it("Zapin dlmm single bin with Curve strategy", async () => {
await initializeBinArrayBitmapExtension(svm, lbPair, admin);
const position = await createDlmmPosition(svm, user, lbPair, lowerBinId);

const amountTokenA = new BN(LAMPORTS_PER_SOL);
const amountSwap = amountTokenA.divn(2);

const binArrays = getBinArrayAccountMetaByBinRange(
lbPair,
new BN(lowerBinId),
new BN(upperBinId)
);

await zapInDlmmFullFlow({
svm,
user,
lbPair,
position,
inputTokenMint: tokenXMint,
outputTokenMint: tokenYMint,
totalAmount: amountTokenA,
amountSwap,
minDeltaId: 0,
maxDeltaId: 0,
strategy: StrategyType.Curve,
binArrays,
remainingAccountInfo: { slices: [] },
});
});

it("Zapin dlmm single bin with Bid/ask strategy", async () => {
await initializeBinArrayBitmapExtension(svm, lbPair, admin);
const position = await createDlmmPosition(svm, user, lbPair, lowerBinId);

const amountTokenA = new BN(LAMPORTS_PER_SOL);
const amountSwap = amountTokenA.divn(2);

const binArrays = getBinArrayAccountMetaByBinRange(
lbPair,
new BN(lowerBinId),
new BN(upperBinId)
);

await zapInDlmmFullFlow({
svm,
user,
lbPair,
position,
inputTokenMint: tokenXMint,
outputTokenMint: tokenYMint,
totalAmount: amountTokenA,
amountSwap,
minDeltaId: 0,
maxDeltaId: 0,
strategy: StrategyType.BidAsk,
binArrays,
remainingAccountInfo: { slices: [] },
});
});

it("Zapin dlmm without bin array bitmap extension", async () => {
const position = await createDlmmPosition(svm, user, lbPair, lowerBinId);
const amountTokenA = new BN(LAMPORTS_PER_SOL);
Expand Down Expand Up @@ -370,5 +430,12 @@ async function zapInDlmmFullFlow(params: {
expect(result).instanceOf(TransactionMetadata);

let liquidities = getPositionTotalLiquidityAllBin(svm, position);
console.log(babar(liquidities));
if (liquidities.length > 1) {
// there is a bug in babar that we could draw single bin
console.log(babar(liquidities));
} else {
console.log("Liquidity distribution (bin_index, liquidity)");
console.log(liquidities);
}

}
Loading