@meteora-ag/dlmm 1.6.0-rc.21 → 1.6.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +9 -57
- package/dist/index.js +1623 -2056
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1654 -2087
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
SystemProgram as SystemProgram2,
|
|
20
20
|
Transaction
|
|
21
21
|
} from "@solana/web3.js";
|
|
22
|
-
import
|
|
22
|
+
import Decimal7 from "decimal.js";
|
|
23
23
|
|
|
24
24
|
// src/dlmm/constants/index.ts
|
|
25
25
|
import { LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js";
|
|
@@ -11779,1863 +11779,1590 @@ function getTokenProgramId(lbPairState) {
|
|
|
11779
11779
|
};
|
|
11780
11780
|
}
|
|
11781
11781
|
|
|
11782
|
-
// src/dlmm/helpers/
|
|
11783
|
-
|
|
11784
|
-
|
|
11785
|
-
|
|
11786
|
-
function buildBitFlagAndNegateStrategyParameters(x0, y0, deltaX, deltaY) {
|
|
11787
|
-
let bitFlag = 0;
|
|
11788
|
-
if (x0.isNeg()) {
|
|
11789
|
-
bitFlag |= 1;
|
|
11790
|
-
x0 = x0.neg();
|
|
11791
|
-
}
|
|
11792
|
-
if (y0.isNeg()) {
|
|
11793
|
-
bitFlag |= 2;
|
|
11794
|
-
y0 = y0.neg();
|
|
11795
|
-
}
|
|
11796
|
-
if (deltaX.isNeg()) {
|
|
11797
|
-
bitFlag |= 4;
|
|
11798
|
-
deltaX = deltaX.neg();
|
|
11799
|
-
}
|
|
11800
|
-
if (deltaY.isNeg()) {
|
|
11801
|
-
bitFlag |= 8;
|
|
11802
|
-
deltaY = deltaY.neg();
|
|
11803
|
-
}
|
|
11804
|
-
return {
|
|
11805
|
-
bitFlag,
|
|
11806
|
-
x0,
|
|
11807
|
-
y0,
|
|
11808
|
-
deltaX,
|
|
11809
|
-
deltaY
|
|
11810
|
-
};
|
|
11811
|
-
}
|
|
11812
|
-
function toRebalancePositionBinData(positionData) {
|
|
11813
|
-
return positionData.positionBinData.map(
|
|
11814
|
-
({
|
|
11815
|
-
binId,
|
|
11816
|
-
price,
|
|
11817
|
-
pricePerToken,
|
|
11818
|
-
positionXAmount,
|
|
11819
|
-
positionYAmount,
|
|
11820
|
-
positionFeeXAmount,
|
|
11821
|
-
positionFeeYAmount,
|
|
11822
|
-
positionRewardAmount
|
|
11823
|
-
}) => {
|
|
11824
|
-
return {
|
|
11825
|
-
binId,
|
|
11826
|
-
price,
|
|
11827
|
-
pricePerToken,
|
|
11828
|
-
amountX: new BN11(positionXAmount),
|
|
11829
|
-
amountY: new BN11(positionYAmount),
|
|
11830
|
-
claimableRewardAmount: positionRewardAmount.map(
|
|
11831
|
-
(amount) => new BN11(amount)
|
|
11832
|
-
),
|
|
11833
|
-
claimableFeeXAmount: new BN11(positionFeeXAmount),
|
|
11834
|
-
claimableFeeYAmount: new BN11(positionFeeYAmount)
|
|
11835
|
-
};
|
|
11836
|
-
}
|
|
11782
|
+
// src/dlmm/helpers/index.ts
|
|
11783
|
+
function chunks(array, size) {
|
|
11784
|
+
return Array.apply(0, new Array(Math.ceil(array.length / size))).map(
|
|
11785
|
+
(_, index) => array.slice(index * size, (index + 1) * size)
|
|
11837
11786
|
);
|
|
11838
11787
|
}
|
|
11839
|
-
function
|
|
11840
|
-
const
|
|
11841
|
-
|
|
11842
|
-
const minBinId = activeId.add(minDeltaId);
|
|
11843
|
-
const maxBinId = activeId.add(maxDeltaId);
|
|
11844
|
-
for (let binId = minBinId.toNumber(); binId <= maxBinId.toNumber(); binId++) {
|
|
11845
|
-
uniqueBinId.add(binId);
|
|
11846
|
-
}
|
|
11847
|
-
}
|
|
11848
|
-
const binIds = Array.from(uniqueBinId);
|
|
11849
|
-
binIds.sort((a, b) => a - b);
|
|
11850
|
-
return binIds;
|
|
11788
|
+
function range(min, max, mapfn) {
|
|
11789
|
+
const length = max - min + 1;
|
|
11790
|
+
return Array.from({ length }, (_, i) => mapfn(min + i));
|
|
11851
11791
|
}
|
|
11852
|
-
function
|
|
11853
|
-
|
|
11854
|
-
|
|
11855
|
-
|
|
11856
|
-
|
|
11857
|
-
|
|
11858
|
-
|
|
11859
|
-
if (minBinId == null || binData.binId < minBinId) {
|
|
11860
|
-
minBinId = binData.binId;
|
|
11861
|
-
}
|
|
11862
|
-
if (maxBinId == null || binData.binId > maxBinId) {
|
|
11863
|
-
maxBinId = binData.binId;
|
|
11864
|
-
}
|
|
11865
|
-
}
|
|
11866
|
-
return [minBinId, maxBinId];
|
|
11792
|
+
async function chunkedFetchMultiplePoolAccount(program, pks, chunkSize = 100) {
|
|
11793
|
+
const accounts = (await Promise.all(
|
|
11794
|
+
chunks(pks, chunkSize).map(
|
|
11795
|
+
(chunk) => program.account.lbPair.fetchMultiple(chunk)
|
|
11796
|
+
)
|
|
11797
|
+
)).flat();
|
|
11798
|
+
return accounts.filter(Boolean);
|
|
11867
11799
|
}
|
|
11868
|
-
function
|
|
11869
|
-
|
|
11870
|
-
|
|
11871
|
-
|
|
11872
|
-
|
|
11800
|
+
async function chunkedFetchMultipleBinArrayBitmapExtensionAccount(program, pks, chunkSize = 100) {
|
|
11801
|
+
const accounts = (await Promise.all(
|
|
11802
|
+
chunks(pks, chunkSize).map(
|
|
11803
|
+
(chunk) => program.account.binArrayBitmapExtension.fetchMultiple(chunk)
|
|
11804
|
+
)
|
|
11805
|
+
)).flat();
|
|
11806
|
+
return accounts;
|
|
11873
11807
|
}
|
|
11874
|
-
function
|
|
11875
|
-
|
|
11876
|
-
return minDeltaId.gte(new BN11(0));
|
|
11877
|
-
}
|
|
11878
|
-
return minDeltaId.gt(new BN11(0));
|
|
11808
|
+
function getOutAmount(bin, inAmount, swapForY) {
|
|
11809
|
+
return swapForY ? mulShr(inAmount, bin.price, SCALE_OFFSET, 1 /* Down */) : shlDiv(inAmount, bin.price, SCALE_OFFSET, 1 /* Down */);
|
|
11879
11810
|
}
|
|
11880
|
-
function
|
|
11881
|
-
const
|
|
11882
|
-
|
|
11883
|
-
const maxBinId = activeId.add(maxDeltaId);
|
|
11884
|
-
for (let binId = minBinId.toNumber(); binId <= maxBinId.toNumber(); binId++) {
|
|
11885
|
-
const deltaBin = activeId.toNumber() - binId;
|
|
11886
|
-
const totalDeltaY = deltaY.mul(new BN11(deltaBin));
|
|
11887
|
-
const amountY = y0.add(totalDeltaY);
|
|
11888
|
-
amountInBins.push({
|
|
11889
|
-
binId: new BN11(binId),
|
|
11890
|
-
amountX: new BN11(0),
|
|
11891
|
-
amountY
|
|
11892
|
-
});
|
|
11893
|
-
}
|
|
11894
|
-
return amountInBins;
|
|
11811
|
+
async function getTokenDecimals(conn, mint) {
|
|
11812
|
+
const token = await getMint(conn, mint);
|
|
11813
|
+
return await token.decimals;
|
|
11895
11814
|
}
|
|
11896
|
-
|
|
11897
|
-
|
|
11898
|
-
const
|
|
11899
|
-
|
|
11900
|
-
|
|
11901
|
-
|
|
11902
|
-
|
|
11903
|
-
|
|
11904
|
-
|
|
11905
|
-
|
|
11906
|
-
|
|
11907
|
-
|
|
11908
|
-
|
|
11909
|
-
|
|
11910
|
-
|
|
11911
|
-
|
|
11912
|
-
|
|
11913
|
-
|
|
11815
|
+
var getOrCreateATAInstruction = async (connection, tokenMint, owner, programId, payer = owner, allowOwnerOffCurve = true) => {
|
|
11816
|
+
programId = programId ?? TOKEN_PROGRAM_ID3;
|
|
11817
|
+
const toAccount = getAssociatedTokenAddressSync(
|
|
11818
|
+
tokenMint,
|
|
11819
|
+
owner,
|
|
11820
|
+
allowOwnerOffCurve,
|
|
11821
|
+
programId,
|
|
11822
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
11823
|
+
);
|
|
11824
|
+
try {
|
|
11825
|
+
await getAccount(connection, toAccount, connection.commitment, programId);
|
|
11826
|
+
return { ataPubKey: toAccount, ix: void 0 };
|
|
11827
|
+
} catch (e) {
|
|
11828
|
+
if (e instanceof TokenAccountNotFoundError || e instanceof TokenInvalidAccountOwnerError) {
|
|
11829
|
+
const ix = createAssociatedTokenAccountIdempotentInstruction(
|
|
11830
|
+
payer,
|
|
11831
|
+
toAccount,
|
|
11832
|
+
owner,
|
|
11833
|
+
tokenMint,
|
|
11834
|
+
programId,
|
|
11835
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
11836
|
+
);
|
|
11837
|
+
return { ataPubKey: toAccount, ix };
|
|
11838
|
+
} else {
|
|
11839
|
+
console.error("Error::getOrCreateATAInstruction", e);
|
|
11840
|
+
throw e;
|
|
11841
|
+
}
|
|
11914
11842
|
}
|
|
11915
|
-
|
|
11843
|
+
};
|
|
11844
|
+
async function getTokenBalance(conn, tokenAccount) {
|
|
11845
|
+
const acc = await getAccount(conn, tokenAccount);
|
|
11846
|
+
return acc.amount;
|
|
11916
11847
|
}
|
|
11917
|
-
|
|
11918
|
-
if (
|
|
11919
|
-
|
|
11920
|
-
|
|
11921
|
-
|
|
11922
|
-
return getAmountInBinsAskSide(
|
|
11923
|
-
activeId,
|
|
11924
|
-
binStep,
|
|
11925
|
-
minDeltaId,
|
|
11926
|
-
maxDeltaId,
|
|
11927
|
-
deltaX,
|
|
11928
|
-
x0
|
|
11929
|
-
);
|
|
11848
|
+
var parseLogs = (eventParser, logs) => {
|
|
11849
|
+
if (!logs.length)
|
|
11850
|
+
throw new Error("No logs found");
|
|
11851
|
+
for (const event of eventParser?.parseLogs(logs)) {
|
|
11852
|
+
return event.data;
|
|
11930
11853
|
}
|
|
11931
|
-
|
|
11932
|
-
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11854
|
+
throw new Error("No events found");
|
|
11855
|
+
};
|
|
11856
|
+
var wrapSOLInstruction = (from, to, amount) => {
|
|
11857
|
+
return [
|
|
11858
|
+
SystemProgram.transfer({
|
|
11859
|
+
fromPubkey: from,
|
|
11860
|
+
toPubkey: to,
|
|
11861
|
+
lamports: amount
|
|
11862
|
+
}),
|
|
11863
|
+
new TransactionInstruction3({
|
|
11864
|
+
keys: [
|
|
11865
|
+
{
|
|
11866
|
+
pubkey: to,
|
|
11867
|
+
isSigner: false,
|
|
11868
|
+
isWritable: true
|
|
11869
|
+
}
|
|
11870
|
+
],
|
|
11871
|
+
data: Buffer.from(new Uint8Array([17])),
|
|
11872
|
+
programId: TOKEN_PROGRAM_ID3
|
|
11873
|
+
})
|
|
11874
|
+
];
|
|
11875
|
+
};
|
|
11876
|
+
var unwrapSOLInstruction = async (owner, allowOwnerOffCurve = true) => {
|
|
11877
|
+
const wSolATAAccount = getAssociatedTokenAddressSync(
|
|
11878
|
+
NATIVE_MINT,
|
|
11879
|
+
owner,
|
|
11880
|
+
allowOwnerOffCurve
|
|
11946
11881
|
);
|
|
11947
|
-
|
|
11948
|
-
|
|
11949
|
-
|
|
11950
|
-
|
|
11951
|
-
|
|
11952
|
-
|
|
11953
|
-
|
|
11954
|
-
function computeCompositionFee(binStep, sParameters3, vParameters3, outAmountX, inAmountX, outAmountY, inAmountY) {
|
|
11955
|
-
if (outAmountX.gt(inAmountX)) {
|
|
11956
|
-
const delta = inAmountY.sub(outAmountY);
|
|
11957
|
-
const totalFeeRate = getTotalFee(
|
|
11958
|
-
binStep.toNumber(),
|
|
11959
|
-
sParameters3,
|
|
11960
|
-
vParameters3
|
|
11882
|
+
if (wSolATAAccount) {
|
|
11883
|
+
const closedWrappedSolInstruction = createCloseAccountInstruction(
|
|
11884
|
+
wSolATAAccount,
|
|
11885
|
+
owner,
|
|
11886
|
+
owner,
|
|
11887
|
+
[],
|
|
11888
|
+
TOKEN_PROGRAM_ID3
|
|
11961
11889
|
);
|
|
11962
|
-
|
|
11963
|
-
return feeAmount.mul(FEE_PRECISION.add(totalFeeRate)).div(FEE_PRECISION.pow(new BN11(2)));
|
|
11964
|
-
}
|
|
11965
|
-
return new BN11(0);
|
|
11966
|
-
}
|
|
11967
|
-
function simulateDepositBin(binId, binStep, amountX, amountY, bin) {
|
|
11968
|
-
if (!bin) {
|
|
11969
|
-
return {
|
|
11970
|
-
amountXIntoBin: amountX,
|
|
11971
|
-
amountYIntoBin: amountY
|
|
11972
|
-
};
|
|
11890
|
+
return closedWrappedSolInstruction;
|
|
11973
11891
|
}
|
|
11974
|
-
|
|
11975
|
-
|
|
11976
|
-
|
|
11977
|
-
|
|
11978
|
-
|
|
11979
|
-
|
|
11980
|
-
|
|
11981
|
-
|
|
11892
|
+
return null;
|
|
11893
|
+
};
|
|
11894
|
+
async function chunkedGetMultipleAccountInfos(connection, pks, chunkSize = 100) {
|
|
11895
|
+
const accountInfos = (await Promise.all(
|
|
11896
|
+
chunks(pks, chunkSize).map(
|
|
11897
|
+
(chunk) => connection.getMultipleAccountsInfo(chunk)
|
|
11898
|
+
)
|
|
11899
|
+
)).flat();
|
|
11900
|
+
return accountInfos;
|
|
11901
|
+
}
|
|
11902
|
+
var getEstimatedComputeUnitUsageWithBuffer = async (connection, instructions, feePayer, buffer) => {
|
|
11903
|
+
if (!buffer) {
|
|
11904
|
+
buffer = 0.1;
|
|
11982
11905
|
}
|
|
11983
|
-
|
|
11984
|
-
|
|
11985
|
-
const
|
|
11986
|
-
|
|
11987
|
-
|
|
11988
|
-
|
|
11906
|
+
buffer = Math.max(0, buffer);
|
|
11907
|
+
buffer = Math.min(1, buffer);
|
|
11908
|
+
const estimatedComputeUnitUsage = await getSimulationComputeUnits(
|
|
11909
|
+
connection,
|
|
11910
|
+
instructions,
|
|
11911
|
+
feePayer,
|
|
11912
|
+
[]
|
|
11989
11913
|
);
|
|
11990
|
-
let
|
|
11991
|
-
|
|
11914
|
+
let extraComputeUnitBuffer = estimatedComputeUnitUsage * buffer;
|
|
11915
|
+
if (extraComputeUnitBuffer > MAX_CU_BUFFER) {
|
|
11916
|
+
extraComputeUnitBuffer = MAX_CU_BUFFER;
|
|
11917
|
+
} else if (extraComputeUnitBuffer < MIN_CU_BUFFER) {
|
|
11918
|
+
extraComputeUnitBuffer = MIN_CU_BUFFER;
|
|
11919
|
+
}
|
|
11920
|
+
return estimatedComputeUnitUsage + extraComputeUnitBuffer;
|
|
11921
|
+
};
|
|
11922
|
+
var getEstimatedComputeUnitIxWithBuffer = async (connection, instructions, feePayer, buffer) => {
|
|
11923
|
+
const units = await getEstimatedComputeUnitUsageWithBuffer(
|
|
11924
|
+
connection,
|
|
11925
|
+
instructions,
|
|
11926
|
+
feePayer,
|
|
11927
|
+
buffer
|
|
11928
|
+
).catch((error) => {
|
|
11929
|
+
console.error("Error::getEstimatedComputeUnitUsageWithBuffer", error);
|
|
11930
|
+
return 14e5;
|
|
11931
|
+
});
|
|
11932
|
+
return ComputeBudgetProgram2.setComputeUnitLimit({ units });
|
|
11933
|
+
};
|
|
11934
|
+
function createProgram(connection, opt) {
|
|
11935
|
+
const cluster = opt?.cluster || "mainnet-beta";
|
|
11936
|
+
const provider = new AnchorProvider(
|
|
11937
|
+
connection,
|
|
11938
|
+
{},
|
|
11939
|
+
AnchorProvider.defaultOptions()
|
|
11992
11940
|
);
|
|
11993
|
-
|
|
11941
|
+
return new Program2(
|
|
11942
|
+
{ ...dlmm_default, address: LBCLMM_PROGRAM_IDS[cluster] },
|
|
11943
|
+
provider
|
|
11944
|
+
);
|
|
11945
|
+
}
|
|
11946
|
+
function decodeAccount(program, accountName, buffer) {
|
|
11947
|
+
return program.coder.accounts.decode(accountName, buffer);
|
|
11948
|
+
}
|
|
11949
|
+
function getAccountDiscriminator(accountName) {
|
|
11950
|
+
return dlmm_default.accounts.find(
|
|
11951
|
+
(acc) => acc.name.toLowerCase() === accountName.toLowerCase()
|
|
11952
|
+
)?.discriminator;
|
|
11953
|
+
}
|
|
11954
|
+
function capSlippagePercentage(slippage) {
|
|
11955
|
+
if (slippage > 100) {
|
|
11956
|
+
slippage = 100;
|
|
11957
|
+
}
|
|
11958
|
+
if (slippage < 0) {
|
|
11959
|
+
slippage = 0;
|
|
11994
11960
|
}
|
|
11961
|
+
return slippage;
|
|
11962
|
+
}
|
|
11963
|
+
|
|
11964
|
+
// src/dlmm/helpers/accountFilters.ts
|
|
11965
|
+
import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes";
|
|
11966
|
+
var presetParameter2BinStepFilter = (binStep) => {
|
|
11995
11967
|
return {
|
|
11996
|
-
|
|
11997
|
-
|
|
11968
|
+
memcmp: {
|
|
11969
|
+
bytes: bs58.encode(binStep.toArrayLike(Buffer, "le", 2)),
|
|
11970
|
+
offset: 8
|
|
11971
|
+
}
|
|
11998
11972
|
};
|
|
11999
|
-
}
|
|
12000
|
-
var
|
|
12001
|
-
|
|
12002
|
-
|
|
12003
|
-
|
|
12004
|
-
|
|
12005
|
-
|
|
12006
|
-
|
|
12007
|
-
|
|
12008
|
-
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
|
|
12012
|
-
|
|
12013
|
-
|
|
12014
|
-
|
|
12015
|
-
|
|
12016
|
-
|
|
12017
|
-
|
|
12018
|
-
|
|
12019
|
-
|
|
12020
|
-
|
|
12021
|
-
|
|
11973
|
+
};
|
|
11974
|
+
var presetParameter2BaseFactorFilter = (baseFactor) => {
|
|
11975
|
+
return {
|
|
11976
|
+
memcmp: {
|
|
11977
|
+
bytes: bs58.encode(baseFactor.toArrayLike(Buffer, "le", 2)),
|
|
11978
|
+
offset: 8 + 2
|
|
11979
|
+
}
|
|
11980
|
+
};
|
|
11981
|
+
};
|
|
11982
|
+
var presetParameter2BaseFeePowerFactor = (baseFeePowerFactor) => {
|
|
11983
|
+
return {
|
|
11984
|
+
memcmp: {
|
|
11985
|
+
bytes: bs58.encode(baseFeePowerFactor.toArrayLike(Buffer, "le", 1)),
|
|
11986
|
+
offset: 8 + 22
|
|
11987
|
+
}
|
|
11988
|
+
};
|
|
11989
|
+
};
|
|
11990
|
+
var binArrayLbPairFilter = (lbPair) => {
|
|
11991
|
+
return {
|
|
11992
|
+
memcmp: {
|
|
11993
|
+
bytes: lbPair.toBase58(),
|
|
11994
|
+
offset: 8 + 16
|
|
11995
|
+
}
|
|
11996
|
+
};
|
|
11997
|
+
};
|
|
11998
|
+
var positionOwnerFilter = (owner) => {
|
|
11999
|
+
return {
|
|
12000
|
+
memcmp: {
|
|
12001
|
+
bytes: owner.toBase58(),
|
|
12002
|
+
offset: 8 + 32
|
|
12003
|
+
}
|
|
12004
|
+
};
|
|
12005
|
+
};
|
|
12006
|
+
var positionLbPairFilter = (lbPair) => {
|
|
12007
|
+
return {
|
|
12008
|
+
memcmp: {
|
|
12009
|
+
bytes: bs58.encode(lbPair.toBuffer()),
|
|
12010
|
+
offset: 8
|
|
12011
|
+
}
|
|
12012
|
+
};
|
|
12013
|
+
};
|
|
12014
|
+
var positionV2Filter = () => {
|
|
12015
|
+
return {
|
|
12016
|
+
memcmp: {
|
|
12017
|
+
bytes: bs58.encode(Buffer.from(getAccountDiscriminator("positionV2"))),
|
|
12018
|
+
offset: 0
|
|
12019
|
+
}
|
|
12020
|
+
};
|
|
12021
|
+
};
|
|
12022
|
+
|
|
12023
|
+
// src/dlmm/helpers/positions/index.ts
|
|
12024
|
+
import BN13 from "bn.js";
|
|
12025
|
+
|
|
12026
|
+
// src/dlmm/helpers/positions/wrapper.ts
|
|
12027
|
+
import BN12 from "bn.js";
|
|
12028
|
+
function combineBaseAndExtendedPositionBinData(base, extended) {
|
|
12029
|
+
const combinedLiquidityShares = base.liquidityShares;
|
|
12030
|
+
const combinedRewardInfos = base.rewardInfos;
|
|
12031
|
+
const combinedFeeInfos = base.feeInfos;
|
|
12032
|
+
for (const binData of extended) {
|
|
12033
|
+
combinedLiquidityShares.push(binData.liquidityShare);
|
|
12034
|
+
combinedRewardInfos.push(binData.rewardInfo);
|
|
12035
|
+
combinedFeeInfos.push(binData.feeInfo);
|
|
12022
12036
|
}
|
|
12023
|
-
|
|
12024
|
-
|
|
12037
|
+
return {
|
|
12038
|
+
liquidityShares: combinedLiquidityShares,
|
|
12039
|
+
rewardInfos: combinedRewardInfos,
|
|
12040
|
+
feeInfos: combinedFeeInfos
|
|
12041
|
+
};
|
|
12042
|
+
}
|
|
12043
|
+
function wrapPosition(program, key, account) {
|
|
12044
|
+
const disc = account.data.subarray(0, 8);
|
|
12045
|
+
if (disc.equals(Buffer.from(getAccountDiscriminator("positionV2")))) {
|
|
12046
|
+
const state = decodeAccount(
|
|
12025
12047
|
program,
|
|
12026
|
-
|
|
12027
|
-
|
|
12028
|
-
positionData,
|
|
12029
|
-
shouldClaimFee,
|
|
12030
|
-
shouldClaimReward
|
|
12031
|
-
} = params;
|
|
12032
|
-
const [lbPairAccount, clockAccount] = await program.provider.connection.getMultipleAccountsInfo([
|
|
12033
|
-
pairAddress,
|
|
12034
|
-
SYSVAR_CLOCK_PUBKEY
|
|
12035
|
-
]);
|
|
12036
|
-
const lbPair = decodeAccount(program, "lbPair", lbPairAccount.data);
|
|
12037
|
-
const clock = ClockLayout.decode(clockAccount.data);
|
|
12038
|
-
const activeBinArrayIdx = binIdToBinArrayIndex(new BN11(lbPair.activeId));
|
|
12039
|
-
const [activeBinArrayPubkey] = deriveBinArray(
|
|
12040
|
-
pairAddress,
|
|
12041
|
-
activeBinArrayIdx,
|
|
12042
|
-
program.programId
|
|
12043
|
-
);
|
|
12044
|
-
const activeBinArrayState = await program.account.binArray.fetch(
|
|
12045
|
-
activeBinArrayPubkey
|
|
12048
|
+
"positionV2",
|
|
12049
|
+
account.data
|
|
12046
12050
|
);
|
|
12047
|
-
const
|
|
12048
|
-
|
|
12049
|
-
|
|
12050
|
-
|
|
12051
|
-
upperBinId
|
|
12051
|
+
const extended = decodeExtendedPosition(
|
|
12052
|
+
state,
|
|
12053
|
+
program,
|
|
12054
|
+
account.data.subarray(8 + POSITION_MIN_SIZE)
|
|
12052
12055
|
);
|
|
12053
|
-
const
|
|
12054
|
-
|
|
12055
|
-
|
|
12056
|
-
positionData,
|
|
12057
|
-
lbPair,
|
|
12058
|
-
activeBin,
|
|
12059
|
-
shouldClaimFee,
|
|
12060
|
-
shouldClaimReward,
|
|
12061
|
-
clock.unixTimestamp
|
|
12056
|
+
const combinedPositionBinData = combineBaseAndExtendedPositionBinData(
|
|
12057
|
+
state,
|
|
12058
|
+
extended
|
|
12062
12059
|
);
|
|
12060
|
+
return new PositionV2Wrapper(key, state, extended, combinedPositionBinData);
|
|
12061
|
+
} else {
|
|
12062
|
+
throw new Error("Unknown position account");
|
|
12063
12063
|
}
|
|
12064
|
-
|
|
12065
|
-
|
|
12066
|
-
|
|
12067
|
-
|
|
12068
|
-
|
|
12069
|
-
|
|
12070
|
-
|
|
12071
|
-
this._simulateResize(
|
|
12072
|
-
new BN11(depositMinBinId),
|
|
12073
|
-
new BN11(depositMaxBinId),
|
|
12074
|
-
binStep,
|
|
12075
|
-
tokenXDecimal,
|
|
12076
|
-
tokenYDecimal
|
|
12077
|
-
);
|
|
12078
|
-
}
|
|
12079
|
-
let totalAmountXDeposited = new BN11(0);
|
|
12080
|
-
let totalAmountYDeposited = new BN11(0);
|
|
12081
|
-
const addLiquidityParam = [];
|
|
12082
|
-
for (const {
|
|
12083
|
-
x0,
|
|
12084
|
-
y0,
|
|
12085
|
-
favorXInActiveBin,
|
|
12086
|
-
deltaX,
|
|
12087
|
-
deltaY,
|
|
12088
|
-
minDeltaId,
|
|
12089
|
-
maxDeltaId
|
|
12090
|
-
} of deposits) {
|
|
12091
|
-
const params = buildBitFlagAndNegateStrategyParameters(
|
|
12092
|
-
x0,
|
|
12093
|
-
y0,
|
|
12094
|
-
deltaX,
|
|
12095
|
-
deltaY
|
|
12096
|
-
);
|
|
12097
|
-
addLiquidityParam.push({
|
|
12098
|
-
minDeltaId: minDeltaId.toNumber(),
|
|
12099
|
-
maxDeltaId: maxDeltaId.toNumber(),
|
|
12100
|
-
x0: params.x0,
|
|
12101
|
-
y0: params.y0,
|
|
12102
|
-
deltaX: params.deltaX,
|
|
12103
|
-
deltaY: params.deltaY,
|
|
12104
|
-
bitFlag: params.bitFlag,
|
|
12105
|
-
padding: Array(16).fill(0),
|
|
12106
|
-
favorXInActiveId: favorXInActiveBin
|
|
12107
|
-
});
|
|
12108
|
-
const amountIntoBins = toAmountIntoBins(
|
|
12109
|
-
activeId,
|
|
12110
|
-
minDeltaId,
|
|
12111
|
-
maxDeltaId,
|
|
12112
|
-
deltaX,
|
|
12113
|
-
deltaY,
|
|
12114
|
-
x0,
|
|
12115
|
-
y0,
|
|
12116
|
-
binStep,
|
|
12117
|
-
favorXInActiveBin
|
|
12118
|
-
);
|
|
12119
|
-
for (const { binId, amountX, amountY } of amountIntoBins) {
|
|
12120
|
-
totalAmountXDeposited = totalAmountXDeposited.add(amountX);
|
|
12121
|
-
totalAmountYDeposited = totalAmountYDeposited.add(amountY);
|
|
12122
|
-
const idx = this.rebalancePositionBinData.findIndex(
|
|
12123
|
-
(data) => data.binId == binId.toNumber()
|
|
12124
|
-
);
|
|
12125
|
-
if (binId.eq(activeId)) {
|
|
12126
|
-
const vParameters3 = Object.assign({}, this.lbPair.vParameters);
|
|
12127
|
-
const sParameters3 = Object.assign({}, this.lbPair.parameters);
|
|
12128
|
-
DLMM.updateReference(
|
|
12129
|
-
activeId.toNumber(),
|
|
12130
|
-
vParameters3,
|
|
12131
|
-
sParameters3,
|
|
12132
|
-
this.currentTimestamp.toNumber()
|
|
12133
|
-
);
|
|
12134
|
-
DLMM.updateVolatilityAccumulator(
|
|
12135
|
-
vParameters3,
|
|
12136
|
-
sParameters3,
|
|
12137
|
-
activeId.toNumber()
|
|
12138
|
-
);
|
|
12139
|
-
const { amountXIntoBin, amountYIntoBin } = simulateDepositBin(
|
|
12140
|
-
binId,
|
|
12141
|
-
binStep,
|
|
12142
|
-
amountX,
|
|
12143
|
-
amountY,
|
|
12144
|
-
this.activeBin
|
|
12145
|
-
);
|
|
12146
|
-
const feeY = computeCompositionFee(
|
|
12147
|
-
binStep,
|
|
12148
|
-
sParameters3,
|
|
12149
|
-
vParameters3,
|
|
12150
|
-
amountXIntoBin,
|
|
12151
|
-
amountX,
|
|
12152
|
-
amountYIntoBin,
|
|
12153
|
-
amountY
|
|
12154
|
-
);
|
|
12155
|
-
const feeX = computeCompositionFee(
|
|
12156
|
-
binStep,
|
|
12157
|
-
sParameters3,
|
|
12158
|
-
vParameters3,
|
|
12159
|
-
amountYIntoBin,
|
|
12160
|
-
amountY,
|
|
12161
|
-
amountXIntoBin,
|
|
12162
|
-
amountX
|
|
12163
|
-
);
|
|
12164
|
-
const amountXIntoBinExcludeFee = amountXIntoBin.sub(feeX);
|
|
12165
|
-
const amountYIntoBinExcludeFee = amountYIntoBin.sub(feeY);
|
|
12166
|
-
this.rebalancePositionBinData[idx].amountX = this.rebalancePositionBinData[idx].amountX.add(
|
|
12167
|
-
amountXIntoBinExcludeFee
|
|
12168
|
-
);
|
|
12169
|
-
this.rebalancePositionBinData[idx].amountY = this.rebalancePositionBinData[idx].amountY.add(
|
|
12170
|
-
amountYIntoBinExcludeFee
|
|
12171
|
-
);
|
|
12172
|
-
} else {
|
|
12173
|
-
this.rebalancePositionBinData[idx].amountX = this.rebalancePositionBinData[idx].amountX.add(amountX);
|
|
12174
|
-
this.rebalancePositionBinData[idx].amountY = this.rebalancePositionBinData[idx].amountY.add(amountY);
|
|
12175
|
-
}
|
|
12176
|
-
}
|
|
12177
|
-
}
|
|
12178
|
-
let actualTotalAmountXDeposited = totalAmountXDeposited;
|
|
12179
|
-
let actualTotalAmountYDeposited = totalAmountYDeposited;
|
|
12180
|
-
let actualLiquidityAndFeeXWithdrawn = liquidityAndFeeXWithdrawn;
|
|
12181
|
-
let actualLiquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn;
|
|
12182
|
-
if (actualTotalAmountXDeposited.gt(actualLiquidityAndFeeXWithdrawn)) {
|
|
12183
|
-
actualTotalAmountXDeposited = actualTotalAmountXDeposited.sub(
|
|
12184
|
-
actualLiquidityAndFeeXWithdrawn
|
|
12185
|
-
);
|
|
12186
|
-
actualLiquidityAndFeeXWithdrawn = new BN11(0);
|
|
12187
|
-
} else {
|
|
12188
|
-
actualLiquidityAndFeeXWithdrawn = actualLiquidityAndFeeXWithdrawn.sub(
|
|
12189
|
-
actualTotalAmountXDeposited
|
|
12190
|
-
);
|
|
12191
|
-
actualTotalAmountXDeposited = new BN11(0);
|
|
12192
|
-
}
|
|
12193
|
-
if (actualTotalAmountYDeposited.gt(actualLiquidityAndFeeYWithdrawn)) {
|
|
12194
|
-
actualTotalAmountYDeposited = actualTotalAmountYDeposited.sub(
|
|
12195
|
-
actualLiquidityAndFeeYWithdrawn
|
|
12196
|
-
);
|
|
12197
|
-
actualLiquidityAndFeeYWithdrawn = new BN11(0);
|
|
12198
|
-
} else {
|
|
12199
|
-
actualLiquidityAndFeeYWithdrawn = actualLiquidityAndFeeYWithdrawn.sub(
|
|
12200
|
-
actualTotalAmountYDeposited
|
|
12201
|
-
);
|
|
12202
|
-
actualTotalAmountYDeposited = new BN11(0);
|
|
12203
|
-
}
|
|
12204
|
-
return {
|
|
12205
|
-
result: {
|
|
12206
|
-
totalAmountXDeposited,
|
|
12207
|
-
totalAmountYDeposited,
|
|
12208
|
-
actualLiquidityAndFeeXWithdrawn,
|
|
12209
|
-
actualLiquidityAndFeeYWithdrawn,
|
|
12210
|
-
actualTotalAmountXDeposited,
|
|
12211
|
-
actualTotalAmountYDeposited
|
|
12212
|
-
},
|
|
12213
|
-
depositParams: addLiquidityParam
|
|
12214
|
-
};
|
|
12064
|
+
}
|
|
12065
|
+
var PositionV2Wrapper = class {
|
|
12066
|
+
constructor(positionAddress, inner, extended, combinedPositionBinData) {
|
|
12067
|
+
this.positionAddress = positionAddress;
|
|
12068
|
+
this.inner = inner;
|
|
12069
|
+
this.extended = extended;
|
|
12070
|
+
this.combinedPositionBinData = combinedPositionBinData;
|
|
12215
12071
|
}
|
|
12216
|
-
|
|
12217
|
-
|
|
12218
|
-
const tokenYMultiplier = new Decimal6(10 ** tokenYDecimal.toNumber());
|
|
12219
|
-
const [minBinId, maxBinId] = findMinMaxBinIdWithLiquidity(
|
|
12220
|
-
this.rebalancePositionBinData
|
|
12221
|
-
);
|
|
12222
|
-
const newMinBinId = new BN11(
|
|
12223
|
-
Math.min(depositMinBinId.toNumber(), minBinId ?? Number.MAX_SAFE_INTEGER)
|
|
12224
|
-
);
|
|
12225
|
-
const newMaxBinId = new BN11(
|
|
12226
|
-
Math.max(depositMaxBinId.toNumber(), maxBinId ?? Number.MIN_SAFE_INTEGER)
|
|
12227
|
-
);
|
|
12228
|
-
if (newMinBinId.lt(this.lowerBinId)) {
|
|
12229
|
-
const binCountToExpand = this.lowerBinId.sub(depositMinBinId);
|
|
12230
|
-
for (let i = 1; i <= binCountToExpand.toNumber(); i++) {
|
|
12231
|
-
const binId = this.lowerBinId.subn(i);
|
|
12232
|
-
const price = getPriceOfBinByBinId(
|
|
12233
|
-
binId.toNumber(),
|
|
12234
|
-
binStep.toNumber()
|
|
12235
|
-
);
|
|
12236
|
-
const adjustedPrice = price.mul(tokenXMultiplier).div(tokenYMultiplier);
|
|
12237
|
-
this.rebalancePositionBinData.unshift({
|
|
12238
|
-
binId: binId.toNumber(),
|
|
12239
|
-
price: adjustedPrice.toString(),
|
|
12240
|
-
pricePerToken: adjustedPrice.toString(),
|
|
12241
|
-
amountX: new BN11(0),
|
|
12242
|
-
amountY: new BN11(0),
|
|
12243
|
-
claimableRewardAmount: [new BN11(0), new BN11(0)],
|
|
12244
|
-
claimableFeeXAmount: new BN11(0),
|
|
12245
|
-
claimableFeeYAmount: new BN11(0)
|
|
12246
|
-
});
|
|
12247
|
-
}
|
|
12248
|
-
} else {
|
|
12249
|
-
const binCountToShrink = newMinBinId.sub(this.lowerBinId);
|
|
12250
|
-
for (let i = 1; i <= binCountToShrink.toNumber(); i++) {
|
|
12251
|
-
this.rebalancePositionBinData.shift();
|
|
12252
|
-
}
|
|
12253
|
-
}
|
|
12254
|
-
if (newMaxBinId.gt(this.upperBinId)) {
|
|
12255
|
-
const binCountToExpand = newMaxBinId.sub(this.upperBinId);
|
|
12256
|
-
for (let i = 1; i <= binCountToExpand.toNumber(); i++) {
|
|
12257
|
-
const binId = this.upperBinId.addn(i);
|
|
12258
|
-
const price = getPriceOfBinByBinId(
|
|
12259
|
-
binId.toNumber(),
|
|
12260
|
-
binStep.toNumber()
|
|
12261
|
-
);
|
|
12262
|
-
const adjustedPrice = price.mul(tokenXMultiplier).div(tokenYMultiplier);
|
|
12263
|
-
this.rebalancePositionBinData.push({
|
|
12264
|
-
binId: binId.toNumber(),
|
|
12265
|
-
price: adjustedPrice.toString(),
|
|
12266
|
-
pricePerToken: adjustedPrice.toString(),
|
|
12267
|
-
amountX: new BN11(0),
|
|
12268
|
-
amountY: new BN11(0),
|
|
12269
|
-
claimableRewardAmount: [new BN11(0), new BN11(0)],
|
|
12270
|
-
claimableFeeXAmount: new BN11(0),
|
|
12271
|
-
claimableFeeYAmount: new BN11(0)
|
|
12272
|
-
});
|
|
12273
|
-
}
|
|
12274
|
-
} else {
|
|
12275
|
-
const binCountToShrink = this.upperBinId.sub(newMaxBinId);
|
|
12276
|
-
for (let i = 1; i <= binCountToShrink.toNumber(); i++) {
|
|
12277
|
-
this.rebalancePositionBinData.pop();
|
|
12278
|
-
}
|
|
12279
|
-
}
|
|
12280
|
-
this.lowerBinId = newMinBinId;
|
|
12281
|
-
this.upperBinId = newMaxBinId;
|
|
12072
|
+
address() {
|
|
12073
|
+
return this.positionAddress;
|
|
12282
12074
|
}
|
|
12283
|
-
|
|
12284
|
-
|
|
12285
|
-
let liquidityAndFeeYWithdrawn = new BN11(0);
|
|
12286
|
-
let rewardsAmountClaimed = [new BN11(0), new BN11(0)];
|
|
12287
|
-
const activeId = new BN11(this.lbPair.activeId);
|
|
12288
|
-
for (const { minBinId, maxBinId, bps } of withdraws) {
|
|
12289
|
-
const fromBinId = minBinId ?? activeId;
|
|
12290
|
-
const toBinId = maxBinId ?? activeId;
|
|
12291
|
-
const binIds = binRangeToBinIdArray(fromBinId, toBinId).filter(
|
|
12292
|
-
(binId) => binId.gte(this.lowerBinId) && binId.lte(this.upperBinId)
|
|
12293
|
-
);
|
|
12294
|
-
for (const binId of binIds) {
|
|
12295
|
-
const idx = this.rebalancePositionBinData.findIndex(
|
|
12296
|
-
(b) => b.binId === binId.toNumber()
|
|
12297
|
-
);
|
|
12298
|
-
const binData = this.rebalancePositionBinData[idx];
|
|
12299
|
-
const amountXWithdrawn = binData.amountX.mul(bps).divn(BASIS_POINT_MAX);
|
|
12300
|
-
const amountYWithdrawn = binData.amountY.mul(bps).divn(BASIS_POINT_MAX);
|
|
12301
|
-
liquidityAndFeeXWithdrawn = liquidityAndFeeXWithdrawn.add(amountXWithdrawn);
|
|
12302
|
-
liquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn.add(amountYWithdrawn);
|
|
12303
|
-
binData.amountX = binData.amountX.sub(amountXWithdrawn);
|
|
12304
|
-
binData.amountY = binData.amountY.sub(amountYWithdrawn);
|
|
12305
|
-
if (this.shouldClaimFee) {
|
|
12306
|
-
liquidityAndFeeXWithdrawn = liquidityAndFeeXWithdrawn.add(
|
|
12307
|
-
binData.claimableFeeXAmount
|
|
12308
|
-
);
|
|
12309
|
-
liquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn.add(
|
|
12310
|
-
binData.claimableFeeYAmount
|
|
12311
|
-
);
|
|
12312
|
-
binData.claimableFeeXAmount = new BN11(0);
|
|
12313
|
-
binData.claimableFeeYAmount = new BN11(0);
|
|
12314
|
-
}
|
|
12315
|
-
if (this.shouldClaimReward) {
|
|
12316
|
-
for (const [idx2, amount] of binData.claimableRewardAmount.entries()) {
|
|
12317
|
-
rewardsAmountClaimed[idx2] = rewardsAmountClaimed[idx2].add(amount);
|
|
12318
|
-
binData.claimableRewardAmount[idx2] = new BN11(0);
|
|
12319
|
-
}
|
|
12320
|
-
}
|
|
12321
|
-
this.rebalancePositionBinData[idx] = binData;
|
|
12322
|
-
}
|
|
12323
|
-
}
|
|
12324
|
-
const withdrawParams = withdraws.map(
|
|
12325
|
-
({ minBinId, maxBinId, bps }) => {
|
|
12326
|
-
return {
|
|
12327
|
-
minBinId: minBinId ? minBinId.toNumber() : null,
|
|
12328
|
-
maxBinId: maxBinId ? maxBinId.toNumber() : null,
|
|
12329
|
-
bps: bps.toNumber(),
|
|
12330
|
-
padding: Array(16).fill(0)
|
|
12331
|
-
};
|
|
12332
|
-
}
|
|
12333
|
-
);
|
|
12334
|
-
return {
|
|
12335
|
-
result: {
|
|
12336
|
-
liquidityAndFeeXWithdrawn,
|
|
12337
|
-
liquidityAndFeeYWithdrawn,
|
|
12338
|
-
rewardsAmountClaimed
|
|
12339
|
-
},
|
|
12340
|
-
withdrawParams
|
|
12341
|
-
};
|
|
12075
|
+
totalClaimedRewards() {
|
|
12076
|
+
return this.inner.totalClaimedRewards;
|
|
12342
12077
|
}
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12352
|
-
|
|
12353
|
-
|
|
12354
|
-
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
tokenXDecimal,
|
|
12358
|
-
tokenYDecimal,
|
|
12359
|
-
deposits,
|
|
12360
|
-
withdrawResult
|
|
12361
|
-
);
|
|
12362
|
-
const afterWidth = getPositionWidthWithMinWidth(
|
|
12363
|
-
this.lowerBinId.toNumber(),
|
|
12364
|
-
this.upperBinId.toNumber()
|
|
12365
|
-
);
|
|
12366
|
-
const widthDelta = afterWidth - beforeWidth;
|
|
12367
|
-
let rentalCostLamports = new BN11(0);
|
|
12368
|
-
if (widthDelta != 0) {
|
|
12369
|
-
const sizeChanges = Math.abs(widthDelta) * POSITION_BIN_DATA_SIZE;
|
|
12370
|
-
const [minimumLamports, rentExemptionLamports] = await Promise.all([
|
|
12371
|
-
connection.getMinimumBalanceForRentExemption(0),
|
|
12372
|
-
connection.getMinimumBalanceForRentExemption(sizeChanges)
|
|
12373
|
-
]);
|
|
12374
|
-
const lamportChanges = new BN11(rentExemptionLamports).sub(
|
|
12375
|
-
new BN11(minimumLamports)
|
|
12376
|
-
);
|
|
12377
|
-
if (widthDelta > 0) {
|
|
12378
|
-
rentalCostLamports = rentalCostLamports.add(lamportChanges);
|
|
12379
|
-
} else {
|
|
12380
|
-
rentalCostLamports = rentalCostLamports.sub(lamportChanges);
|
|
12381
|
-
}
|
|
12382
|
-
}
|
|
12383
|
-
return {
|
|
12384
|
-
amountXDeposited: depositResult.totalAmountXDeposited,
|
|
12385
|
-
amountYDeposited: depositResult.totalAmountYDeposited,
|
|
12386
|
-
actualAmountXDeposited: depositResult.actualTotalAmountXDeposited,
|
|
12387
|
-
actualAmountYDeposited: depositResult.actualTotalAmountYDeposited,
|
|
12388
|
-
actualAmountXWithdrawn: depositResult.actualLiquidityAndFeeXWithdrawn,
|
|
12389
|
-
actualAmountYWithdrawn: depositResult.actualLiquidityAndFeeYWithdrawn,
|
|
12390
|
-
rewardAmountsClaimed: withdrawResult.rewardsAmountClaimed,
|
|
12391
|
-
withdrawParams,
|
|
12392
|
-
depositParams,
|
|
12393
|
-
rentalCostLamports
|
|
12394
|
-
};
|
|
12078
|
+
feeOwner() {
|
|
12079
|
+
return this.inner.feeOwner;
|
|
12080
|
+
}
|
|
12081
|
+
lockReleasePoint() {
|
|
12082
|
+
return this.inner.lockReleasePoint;
|
|
12083
|
+
}
|
|
12084
|
+
operator() {
|
|
12085
|
+
return this.inner.operator;
|
|
12086
|
+
}
|
|
12087
|
+
totalClaimedFeeYAmount() {
|
|
12088
|
+
return this.inner.totalClaimedFeeYAmount;
|
|
12089
|
+
}
|
|
12090
|
+
totalClaimedFeeXAmount() {
|
|
12091
|
+
return this.inner.totalClaimedFeeXAmount;
|
|
12395
12092
|
}
|
|
12396
|
-
|
|
12397
|
-
|
|
12398
|
-
let totalAmountY = new BN11(0);
|
|
12399
|
-
for (const binData of this.rebalancePositionBinData) {
|
|
12400
|
-
totalAmountX = totalAmountX.add(binData.amountX);
|
|
12401
|
-
totalAmountY = totalAmountY.add(binData.amountY);
|
|
12402
|
-
}
|
|
12403
|
-
return [totalAmountX, totalAmountY];
|
|
12093
|
+
lbPair() {
|
|
12094
|
+
return this.inner.lbPair;
|
|
12404
12095
|
}
|
|
12405
|
-
|
|
12406
|
-
|
|
12407
|
-
let totalFeeYAmount = new BN11(0);
|
|
12408
|
-
for (const binData of this.rebalancePositionBinData) {
|
|
12409
|
-
totalFeeXAmount = totalFeeXAmount.add(binData.claimableFeeXAmount);
|
|
12410
|
-
totalFeeYAmount = totalFeeYAmount.add(binData.claimableFeeYAmount);
|
|
12411
|
-
}
|
|
12412
|
-
return [totalFeeXAmount, totalFeeYAmount];
|
|
12096
|
+
lowerBinId() {
|
|
12097
|
+
return new BN12(this.inner.lowerBinId);
|
|
12413
12098
|
}
|
|
12414
|
-
|
|
12415
|
-
|
|
12416
|
-
for (const binData of this.rebalancePositionBinData) {
|
|
12417
|
-
totalRewardAmounts[0] = totalRewardAmounts[0].add(
|
|
12418
|
-
binData.claimableRewardAmount[0]
|
|
12419
|
-
);
|
|
12420
|
-
totalRewardAmounts[1] = totalRewardAmounts[1].add(
|
|
12421
|
-
binData.claimableRewardAmount[1]
|
|
12422
|
-
);
|
|
12423
|
-
}
|
|
12424
|
-
return totalRewardAmounts;
|
|
12099
|
+
upperBinId() {
|
|
12100
|
+
return new BN12(this.inner.upperBinId);
|
|
12425
12101
|
}
|
|
12426
|
-
|
|
12427
|
-
|
|
12428
|
-
const width = upperBinId - lowerBinId + 1;
|
|
12429
|
-
return Math.max(width, DEFAULT_BIN_PER_POSITION.toNumber());
|
|
12430
|
-
}
|
|
12431
|
-
function validateAndSortRebalanceDeposit(deposits) {
|
|
12432
|
-
const sortedDeposits = deposits.sort(
|
|
12433
|
-
(a, b) => a.minDeltaId.sub(b.minDeltaId).toNumber()
|
|
12434
|
-
);
|
|
12435
|
-
for (const deposit of deposits) {
|
|
12436
|
-
if (deposit.minDeltaId.gte(deposit.maxDeltaId)) {
|
|
12437
|
-
throw "Invalid minDeltaId or maxDeltaId";
|
|
12438
|
-
}
|
|
12102
|
+
liquidityShares() {
|
|
12103
|
+
return this.combinedPositionBinData.liquidityShares;
|
|
12439
12104
|
}
|
|
12440
|
-
|
|
12441
|
-
|
|
12442
|
-
const currDeposit = sortedDeposits[i];
|
|
12443
|
-
if (prevDeposit.maxDeltaId.gte(currDeposit.minDeltaId)) {
|
|
12444
|
-
throw "Overlap deposit bin range";
|
|
12445
|
-
}
|
|
12105
|
+
rewardInfos() {
|
|
12106
|
+
return this.combinedPositionBinData.rewardInfos;
|
|
12446
12107
|
}
|
|
12447
|
-
|
|
12448
|
-
|
|
12449
|
-
function validateAndSortRebalanceWithdraw(withdraws, activeId) {
|
|
12450
|
-
const filledWithdraws = [];
|
|
12451
|
-
for (const { minBinId, maxBinId, bps } of withdraws) {
|
|
12452
|
-
if (bps.toNumber() < 0 || bps.toNumber() > BASIS_POINT_MAX) {
|
|
12453
|
-
throw "Invalid bps";
|
|
12454
|
-
}
|
|
12455
|
-
const filledMinBinId = minBinId ?? activeId;
|
|
12456
|
-
const filledMaxBinId = maxBinId ?? activeId;
|
|
12457
|
-
if (filledMinBinId.gt(filledMaxBinId)) {
|
|
12458
|
-
throw "Invalid minBinId or maxBinId";
|
|
12459
|
-
}
|
|
12460
|
-
filledWithdraws.push({
|
|
12461
|
-
minBinId: filledMinBinId,
|
|
12462
|
-
maxBinId: filledMaxBinId,
|
|
12463
|
-
bps
|
|
12464
|
-
});
|
|
12108
|
+
feeInfos() {
|
|
12109
|
+
return this.combinedPositionBinData.feeInfos;
|
|
12465
12110
|
}
|
|
12466
|
-
|
|
12467
|
-
return
|
|
12468
|
-
}
|
|
12469
|
-
|
|
12470
|
-
const
|
|
12471
|
-
|
|
12472
|
-
|
|
12473
|
-
|
|
12111
|
+
lastUpdatedAt() {
|
|
12112
|
+
return this.inner.lastUpdatedAt;
|
|
12113
|
+
}
|
|
12114
|
+
getBinArrayIndexesCoverage() {
|
|
12115
|
+
const isExtended = this.extended.length > 0;
|
|
12116
|
+
if (isExtended) {
|
|
12117
|
+
return getBinArrayIndexesCoverage(this.lowerBinId(), this.upperBinId());
|
|
12118
|
+
} else {
|
|
12119
|
+
const lowerBinArrayIndex = binIdToBinArrayIndex(this.lowerBinId());
|
|
12120
|
+
const upperBinArrayIndex = lowerBinArrayIndex.add(new BN12(1));
|
|
12121
|
+
return [lowerBinArrayIndex, upperBinArrayIndex];
|
|
12474
12122
|
}
|
|
12475
12123
|
}
|
|
12476
|
-
|
|
12477
|
-
|
|
12478
|
-
|
|
12479
|
-
|
|
12480
|
-
const fromBinId = minBinId.toNumber();
|
|
12481
|
-
const toBinId = maxBinId.toNumber();
|
|
12482
|
-
for (let binId = fromBinId; binId <= toBinId; binId++) {
|
|
12483
|
-
binIdArray.push(new BN11(binId));
|
|
12124
|
+
getBinArrayKeysCoverage(programId) {
|
|
12125
|
+
return this.getBinArrayIndexesCoverage().map(
|
|
12126
|
+
(index) => deriveBinArray(this.lbPair(), index, programId)[0]
|
|
12127
|
+
);
|
|
12484
12128
|
}
|
|
12485
|
-
|
|
12129
|
+
version() {
|
|
12130
|
+
return 1 /* V2 */;
|
|
12131
|
+
}
|
|
12132
|
+
owner() {
|
|
12133
|
+
return this.inner.owner;
|
|
12134
|
+
}
|
|
12135
|
+
width() {
|
|
12136
|
+
return this.upperBinId().sub(this.lowerBinId()).add(new BN12(1));
|
|
12137
|
+
}
|
|
12138
|
+
};
|
|
12139
|
+
|
|
12140
|
+
// src/dlmm/helpers/positions/index.ts
|
|
12141
|
+
function getBinArrayIndexesCoverage(lowerBinId, upperBinId) {
|
|
12142
|
+
const lowerBinArrayIndex = binIdToBinArrayIndex(lowerBinId);
|
|
12143
|
+
const upperBinArrayIndex = binIdToBinArrayIndex(upperBinId);
|
|
12144
|
+
const binArrayIndexes = [];
|
|
12145
|
+
for (let i = lowerBinArrayIndex.toNumber(); i <= upperBinArrayIndex.toNumber(); i++) {
|
|
12146
|
+
binArrayIndexes.push(new BN13(i));
|
|
12147
|
+
}
|
|
12148
|
+
return binArrayIndexes;
|
|
12486
12149
|
}
|
|
12487
|
-
function
|
|
12488
|
-
|
|
12489
|
-
|
|
12490
|
-
|
|
12491
|
-
if (minBinId == null) {
|
|
12492
|
-
minBinId = activeId;
|
|
12493
|
-
}
|
|
12494
|
-
let maxBinId = value.maxBinId;
|
|
12495
|
-
if (maxBinId == null) {
|
|
12496
|
-
maxBinId = activeId;
|
|
12497
|
-
}
|
|
12498
|
-
let binArrayIndex = binIdToBinArrayIndex(new BN11(minBinId));
|
|
12499
|
-
const upperBinId = new BN11(maxBinId);
|
|
12500
|
-
while (true) {
|
|
12501
|
-
indexMap.set(binArrayIndex.toNumber(), true);
|
|
12502
|
-
const [binArrayLowerBinId, binArrayUpperBinId] = getBinArrayLowerUpperBinId(binArrayIndex);
|
|
12503
|
-
if (upperBinId.gte(binArrayLowerBinId) && upperBinId.lte(binArrayUpperBinId)) {
|
|
12504
|
-
break;
|
|
12505
|
-
} else {
|
|
12506
|
-
binArrayIndex = binArrayIndex.add(new BN11(1));
|
|
12507
|
-
}
|
|
12508
|
-
}
|
|
12150
|
+
function getBinArrayKeysCoverage2(lowerBinId, upperBinId, lbPair, programId) {
|
|
12151
|
+
const binArrayIndexes = getBinArrayIndexesCoverage(lowerBinId, upperBinId);
|
|
12152
|
+
return binArrayIndexes.map((index) => {
|
|
12153
|
+
return deriveBinArray(lbPair, index, programId)[0];
|
|
12509
12154
|
});
|
|
12510
|
-
|
|
12511
|
-
|
|
12512
|
-
|
|
12513
|
-
|
|
12514
|
-
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
break;
|
|
12520
|
-
} else {
|
|
12521
|
-
binArrayIndex = binArrayIndex.add(new BN11(1));
|
|
12522
|
-
}
|
|
12155
|
+
}
|
|
12156
|
+
function getBinArrayAccountMetasCoverage(lowerBinId, upperBinId, lbPair, programId) {
|
|
12157
|
+
return getBinArrayKeysCoverage2(lowerBinId, upperBinId, lbPair, programId).map(
|
|
12158
|
+
(key) => {
|
|
12159
|
+
return {
|
|
12160
|
+
pubkey: key,
|
|
12161
|
+
isSigner: false,
|
|
12162
|
+
isWritable: true
|
|
12163
|
+
};
|
|
12523
12164
|
}
|
|
12524
|
-
});
|
|
12525
|
-
const binArrayIndexes = Array.from(indexMap.keys()).map((idx) => new BN11(idx));
|
|
12526
|
-
const requireBitmapExtension = binArrayIndexes.some(
|
|
12527
|
-
(index) => isOverflowDefaultBinArrayBitmap(new BN11(index))
|
|
12528
12165
|
);
|
|
12529
|
-
return {
|
|
12530
|
-
binArrayIndexes,
|
|
12531
|
-
binArrayBitmap: requireBitmapExtension ? deriveBinArrayBitmapExtension(pairAddress, programId)[0] : programId
|
|
12532
|
-
};
|
|
12533
12166
|
}
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12539
|
-
|
|
12540
|
-
|
|
12541
|
-
|
|
12542
|
-
return new BN12(0);
|
|
12543
|
-
}
|
|
12544
|
-
if (minDeltaId.eq(maxDeltaId)) {
|
|
12545
|
-
return amountY;
|
|
12546
|
-
}
|
|
12547
|
-
const m1 = minDeltaId.neg().subn(1);
|
|
12548
|
-
const m2 = maxDeltaId.neg();
|
|
12549
|
-
const b = m2.neg().mul(m1.sub(m2).addn(1));
|
|
12550
|
-
const c = m1.mul(m1.addn(1)).divn(2);
|
|
12551
|
-
const d = m2.mul(m2.subn(1)).divn(2);
|
|
12552
|
-
const a = b.add(c.sub(d));
|
|
12553
|
-
return amountY.div(a);
|
|
12167
|
+
function getPositionLowerUpperBinIdWithLiquidity(position) {
|
|
12168
|
+
const binWithLiquidity = position.positionBinData.filter(
|
|
12169
|
+
(b) => !new BN13(b.binLiquidity).isZero() || !new BN13(b.positionFeeXAmount.toString()).isZero() || !new BN13(b.positionFeeYAmount.toString()).isZero() || !new BN13(b.positionRewardAmount[0].toString()).isZero() || !new BN13(b.positionRewardAmount[1].toString()).isZero()
|
|
12170
|
+
);
|
|
12171
|
+
return binWithLiquidity.length > 0 ? {
|
|
12172
|
+
lowerBinId: new BN13(binWithLiquidity[0].binId),
|
|
12173
|
+
upperBinId: new BN13(binWithLiquidity[binWithLiquidity.length - 1].binId)
|
|
12174
|
+
} : null;
|
|
12554
12175
|
}
|
|
12555
|
-
function
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12176
|
+
function isPositionNoFee(position) {
|
|
12177
|
+
return position.feeX.isZero() && position.feeY.isZero();
|
|
12178
|
+
}
|
|
12179
|
+
function isPositionNoReward(position) {
|
|
12180
|
+
return position.rewardOne.isZero() && position.rewardTwo.isZero();
|
|
12181
|
+
}
|
|
12182
|
+
function chunkBinRange(minBinId, maxBinId) {
|
|
12183
|
+
const chunkedBinRange = [];
|
|
12184
|
+
let startBinId = minBinId;
|
|
12185
|
+
while (startBinId <= maxBinId) {
|
|
12186
|
+
const endBinId = Math.min(
|
|
12187
|
+
startBinId + DEFAULT_BIN_PER_POSITION.toNumber() - 1,
|
|
12188
|
+
maxBinId
|
|
12189
|
+
);
|
|
12190
|
+
chunkedBinRange.push({
|
|
12191
|
+
lowerBinId: startBinId,
|
|
12192
|
+
upperBinId: endBinId
|
|
12193
|
+
});
|
|
12194
|
+
startBinId += DEFAULT_BIN_PER_POSITION.toNumber();
|
|
12561
12195
|
}
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
|
|
12570
|
-
|
|
12196
|
+
return chunkedBinRange;
|
|
12197
|
+
}
|
|
12198
|
+
async function getPositionExpandRentExemption(currentMinBinId, currentMaxBinId, connection, binCountToExpand) {
|
|
12199
|
+
const currentPositionWidth = currentMaxBinId.sub(currentMinBinId).addn(1);
|
|
12200
|
+
const positionWidthAfterExpand = currentPositionWidth.add(binCountToExpand);
|
|
12201
|
+
if (positionWidthAfterExpand.lte(DEFAULT_BIN_PER_POSITION)) {
|
|
12202
|
+
return 0;
|
|
12203
|
+
} else {
|
|
12204
|
+
const binCountInExpandedBytes = positionWidthAfterExpand.sub(
|
|
12205
|
+
DEFAULT_BIN_PER_POSITION
|
|
12571
12206
|
);
|
|
12572
|
-
const
|
|
12573
|
-
|
|
12574
|
-
|
|
12575
|
-
|
|
12576
|
-
|
|
12577
|
-
|
|
12578
|
-
|
|
12579
|
-
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12207
|
+
const expandSize = binCountInExpandedBytes.toNumber() * POSITION_BIN_DATA_SIZE;
|
|
12208
|
+
const [minimumLamports, rentExemptionLamports] = await Promise.all([
|
|
12209
|
+
connection.getMinimumBalanceForRentExemption(0),
|
|
12210
|
+
connection.getMinimumBalanceForRentExemption(expandSize)
|
|
12211
|
+
]);
|
|
12212
|
+
return rentExemptionLamports - minimumLamports;
|
|
12213
|
+
}
|
|
12214
|
+
}
|
|
12215
|
+
function getExtendedPositionBinCount(minBinId, maxBinId) {
|
|
12216
|
+
const width = maxBinId.sub(minBinId).addn(1);
|
|
12217
|
+
const extended = width.sub(DEFAULT_BIN_PER_POSITION);
|
|
12218
|
+
return extended.lte(new BN13(0)) ? new BN13(0) : extended;
|
|
12219
|
+
}
|
|
12220
|
+
function decodeExtendedPosition(base, program, bytes) {
|
|
12221
|
+
const width = base.upperBinId - base.lowerBinId + 1;
|
|
12222
|
+
const extendedWidth = width - DEFAULT_BIN_PER_POSITION.toNumber();
|
|
12223
|
+
const extendedPosition = [];
|
|
12224
|
+
for (let i = 0; i < extendedWidth; i++) {
|
|
12225
|
+
const offset = i * POSITION_BIN_DATA_SIZE;
|
|
12226
|
+
const data = bytes.subarray(offset, offset + POSITION_BIN_DATA_SIZE);
|
|
12227
|
+
const decodedPositionBinData = program.coder.types.decode(
|
|
12228
|
+
// TODO: Find a type safe way
|
|
12229
|
+
"positionBinData",
|
|
12230
|
+
data
|
|
12231
|
+
);
|
|
12232
|
+
extendedPosition.push(decodedPositionBinData);
|
|
12583
12233
|
}
|
|
12234
|
+
return extendedPosition;
|
|
12584
12235
|
}
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
|
|
12236
|
+
|
|
12237
|
+
// src/dlmm/helpers/rebalance/rebalancePosition.ts
|
|
12238
|
+
import { SYSVAR_CLOCK_PUBKEY } from "@solana/web3.js";
|
|
12239
|
+
import BN14 from "bn.js";
|
|
12240
|
+
import Decimal6 from "decimal.js";
|
|
12241
|
+
function buildBitFlagAndNegateStrategyParameters(x0, y0, deltaX, deltaY) {
|
|
12242
|
+
let bitFlag = 0;
|
|
12243
|
+
if (x0.isNeg()) {
|
|
12244
|
+
bitFlag |= 1;
|
|
12245
|
+
x0 = x0.neg();
|
|
12588
12246
|
}
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
let m2 = maxDeltaId.addn(1);
|
|
12593
|
-
for (let m = m1.toNumber(); m <= m2.toNumber(); m++) {
|
|
12594
|
-
const binId = activeId.addn(m);
|
|
12595
|
-
const pm = getQPriceFromId(binId.neg(), binStep);
|
|
12596
|
-
const bDelta = m1.mul(pm);
|
|
12597
|
-
b = b.add(bDelta);
|
|
12598
|
-
const cDelta = new BN12(m).mul(pm);
|
|
12599
|
-
c = c.add(cDelta);
|
|
12247
|
+
if (y0.isNeg()) {
|
|
12248
|
+
bitFlag |= 2;
|
|
12249
|
+
y0 = y0.neg();
|
|
12600
12250
|
}
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN12(0)) || amountX.isZero()) {
|
|
12605
|
-
return {
|
|
12606
|
-
base: new BN12(0),
|
|
12607
|
-
delta: new BN12(0)
|
|
12608
|
-
};
|
|
12251
|
+
if (deltaX.isNeg()) {
|
|
12252
|
+
bitFlag |= 4;
|
|
12253
|
+
deltaX = deltaX.neg();
|
|
12609
12254
|
}
|
|
12610
|
-
|
|
12611
|
-
|
|
12612
|
-
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
|
|
12617
|
-
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12621
|
-
|
|
12622
|
-
|
|
12623
|
-
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12632
|
-
|
|
12255
|
+
if (deltaY.isNeg()) {
|
|
12256
|
+
bitFlag |= 8;
|
|
12257
|
+
deltaY = deltaY.neg();
|
|
12258
|
+
}
|
|
12259
|
+
return {
|
|
12260
|
+
bitFlag,
|
|
12261
|
+
x0,
|
|
12262
|
+
y0,
|
|
12263
|
+
deltaX,
|
|
12264
|
+
deltaY
|
|
12265
|
+
};
|
|
12266
|
+
}
|
|
12267
|
+
function toRebalancePositionBinData(positionData) {
|
|
12268
|
+
return positionData.positionBinData.map(
|
|
12269
|
+
({
|
|
12270
|
+
binId,
|
|
12271
|
+
price,
|
|
12272
|
+
pricePerToken,
|
|
12273
|
+
positionXAmount,
|
|
12274
|
+
positionYAmount,
|
|
12275
|
+
positionFeeXAmount,
|
|
12276
|
+
positionFeeYAmount,
|
|
12277
|
+
positionRewardAmount
|
|
12278
|
+
}) => {
|
|
12633
12279
|
return {
|
|
12634
|
-
|
|
12635
|
-
|
|
12280
|
+
binId,
|
|
12281
|
+
price,
|
|
12282
|
+
pricePerToken,
|
|
12283
|
+
amountX: new BN14(positionXAmount),
|
|
12284
|
+
amountY: new BN14(positionYAmount),
|
|
12285
|
+
claimableRewardAmount: positionRewardAmount.map(
|
|
12286
|
+
(amount) => new BN14(amount)
|
|
12287
|
+
),
|
|
12288
|
+
claimableFeeXAmount: new BN14(positionFeeXAmount),
|
|
12289
|
+
claimableFeeYAmount: new BN14(positionFeeYAmount)
|
|
12636
12290
|
};
|
|
12637
12291
|
}
|
|
12292
|
+
);
|
|
12293
|
+
}
|
|
12294
|
+
function getDepositBinIds(activeId, deposits) {
|
|
12295
|
+
const uniqueBinId = /* @__PURE__ */ new Set();
|
|
12296
|
+
for (const { minDeltaId, maxDeltaId } of deposits) {
|
|
12297
|
+
const minBinId = activeId.add(minDeltaId);
|
|
12298
|
+
const maxBinId = activeId.add(maxDeltaId);
|
|
12299
|
+
for (let binId = minBinId.toNumber(); binId <= maxBinId.toNumber(); binId++) {
|
|
12300
|
+
uniqueBinId.add(binId);
|
|
12301
|
+
}
|
|
12638
12302
|
}
|
|
12303
|
+
const binIds = Array.from(uniqueBinId);
|
|
12304
|
+
binIds.sort((a, b) => a - b);
|
|
12305
|
+
return binIds;
|
|
12639
12306
|
}
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
|
|
12307
|
+
function findMinMaxBinIdWithLiquidity(rebalancePositionBinData) {
|
|
12308
|
+
let minBinId = null;
|
|
12309
|
+
let maxBinId = null;
|
|
12310
|
+
for (const binData of rebalancePositionBinData) {
|
|
12311
|
+
if (binData.amountX.isZero() && binData.amountY.isZero() && binData.claimableFeeXAmount.isZero() && binData.claimableFeeYAmount.isZero() && binData.claimableRewardAmount.every((amount) => amount.isZero())) {
|
|
12312
|
+
continue;
|
|
12313
|
+
}
|
|
12314
|
+
if (minBinId == null || binData.binId < minBinId) {
|
|
12315
|
+
minBinId = binData.binId;
|
|
12316
|
+
}
|
|
12317
|
+
if (maxBinId == null || binData.binId > maxBinId) {
|
|
12318
|
+
maxBinId = binData.binId;
|
|
12319
|
+
}
|
|
12643
12320
|
}
|
|
12644
|
-
|
|
12645
|
-
|
|
12321
|
+
return [minBinId, maxBinId];
|
|
12322
|
+
}
|
|
12323
|
+
function onlyDepositToBidSide(maxDeltaId, favorXInActiveBin) {
|
|
12324
|
+
if (favorXInActiveBin) {
|
|
12325
|
+
return maxDeltaId.lt(new BN14(0));
|
|
12646
12326
|
}
|
|
12647
|
-
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
const totalAmountX = toAmountIntoBins(
|
|
12653
|
-
activeId,
|
|
12654
|
-
minDeltaId,
|
|
12655
|
-
maxDeltaId,
|
|
12656
|
-
deltaX,
|
|
12657
|
-
new BN12(0),
|
|
12658
|
-
x0,
|
|
12659
|
-
new BN12(0),
|
|
12660
|
-
binStep,
|
|
12661
|
-
favorXInActiveBin
|
|
12662
|
-
).reduce((acc, bin) => {
|
|
12663
|
-
return acc.add(bin.amountX);
|
|
12664
|
-
}, new BN12(0));
|
|
12665
|
-
return {
|
|
12666
|
-
base: x0,
|
|
12667
|
-
delta: deltaX,
|
|
12668
|
-
amountX: totalAmountX
|
|
12669
|
-
};
|
|
12327
|
+
return maxDeltaId.lte(new BN14(0));
|
|
12328
|
+
}
|
|
12329
|
+
function onlyDepositToAskSide(minDeltaId, favorXInActiveBin) {
|
|
12330
|
+
if (favorXInActiveBin) {
|
|
12331
|
+
return minDeltaId.gte(new BN14(0));
|
|
12670
12332
|
}
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
const
|
|
12679
|
-
const
|
|
12680
|
-
const amountY =
|
|
12681
|
-
|
|
12682
|
-
|
|
12683
|
-
|
|
12684
|
-
new BN12(0),
|
|
12685
|
-
deltaY,
|
|
12686
|
-
new BN12(0),
|
|
12687
|
-
y0,
|
|
12688
|
-
binStep,
|
|
12689
|
-
favorXInActiveBin
|
|
12690
|
-
).reduce((acc, bin) => {
|
|
12691
|
-
return acc.add(bin.amountY);
|
|
12692
|
-
}, new BN12(0));
|
|
12693
|
-
return {
|
|
12694
|
-
base: y0,
|
|
12695
|
-
delta: deltaY,
|
|
12333
|
+
return minDeltaId.gt(new BN14(0));
|
|
12334
|
+
}
|
|
12335
|
+
function getAmountInBinsBidSide(activeId, minDeltaId, maxDeltaId, deltaY, y0) {
|
|
12336
|
+
const amountInBins = [];
|
|
12337
|
+
const minBinId = activeId.add(minDeltaId);
|
|
12338
|
+
const maxBinId = activeId.add(maxDeltaId);
|
|
12339
|
+
for (let binId = minBinId.toNumber(); binId <= maxBinId.toNumber(); binId++) {
|
|
12340
|
+
const deltaBin = activeId.toNumber() - binId;
|
|
12341
|
+
const totalDeltaY = deltaY.mul(new BN14(deltaBin));
|
|
12342
|
+
const amountY = y0.add(totalDeltaY);
|
|
12343
|
+
amountInBins.push({
|
|
12344
|
+
binId: new BN14(binId),
|
|
12345
|
+
amountX: new BN14(0),
|
|
12696
12346
|
amountY
|
|
12697
|
-
};
|
|
12698
|
-
}
|
|
12699
|
-
};
|
|
12700
|
-
|
|
12701
|
-
// src/dlmm/helpers/rebalance/liquidity_strategy/curve.ts
|
|
12702
|
-
import BN13 from "bn.js";
|
|
12703
|
-
function findBaseY0(amountY, minDeltaId, maxDeltaId) {
|
|
12704
|
-
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new BN13(0))) {
|
|
12705
|
-
return new BN13(0);
|
|
12706
|
-
}
|
|
12707
|
-
if (minDeltaId.eq(maxDeltaId)) {
|
|
12708
|
-
return amountY;
|
|
12347
|
+
});
|
|
12709
12348
|
}
|
|
12710
|
-
|
|
12711
|
-
const m2 = maxDeltaId.neg();
|
|
12712
|
-
const b = m1.sub(m2).addn(1);
|
|
12713
|
-
const c = m1.mul(m1.addn(1)).divn(2);
|
|
12714
|
-
const d = m2.mul(m2.subn(1)).divn(2);
|
|
12715
|
-
const a = b.sub(c.sub(d).div(m1.addn(1)));
|
|
12716
|
-
return amountY.div(a);
|
|
12349
|
+
return amountInBins;
|
|
12717
12350
|
}
|
|
12718
|
-
function
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12351
|
+
function getAmountInBinsAskSide(activeId, binStep, minDeltaId, maxDeltaId, deltaX, x0) {
|
|
12352
|
+
const binCount = maxDeltaId.sub(minDeltaId).add(new BN14(1));
|
|
12353
|
+
const minBinId = activeId.add(minDeltaId);
|
|
12354
|
+
const maxBinId = activeId.add(maxDeltaId);
|
|
12355
|
+
const amountInBins = new Array(binCount.toNumber());
|
|
12356
|
+
const base = getQPriceBaseFactor(binStep);
|
|
12357
|
+
let inverseBasePrice = pow(base, maxBinId.neg());
|
|
12358
|
+
for (let binId = maxBinId.toNumber(); binId >= minBinId.toNumber(); binId--) {
|
|
12359
|
+
const delta = binId - activeId.toNumber();
|
|
12360
|
+
const totalDeltaX = deltaX.mul(new BN14(delta));
|
|
12361
|
+
const amountX = x0.add(totalDeltaX).mul(inverseBasePrice).shrn(SCALE_OFFSET);
|
|
12362
|
+
const idx = binId - minBinId.toNumber();
|
|
12363
|
+
amountInBins[idx] = {
|
|
12364
|
+
binId: new BN14(binId),
|
|
12365
|
+
amountX,
|
|
12366
|
+
amountY: new BN14(0)
|
|
12723
12367
|
};
|
|
12368
|
+
inverseBasePrice = inverseBasePrice.mul(base).shrn(SCALE_OFFSET);
|
|
12724
12369
|
}
|
|
12725
|
-
|
|
12726
|
-
while (true) {
|
|
12727
|
-
const deltaY = baseY0.neg().div(minDeltaId.neg().addn(1));
|
|
12728
|
-
const amountInBins = getAmountInBinsBidSide(
|
|
12729
|
-
activeId,
|
|
12730
|
-
minDeltaId,
|
|
12731
|
-
maxDeltaId,
|
|
12732
|
-
deltaY,
|
|
12733
|
-
baseY0
|
|
12734
|
-
);
|
|
12735
|
-
const totalAmountY = amountInBins.reduce((acc, { amountY: amountY2 }) => {
|
|
12736
|
-
return acc.add(amountY2);
|
|
12737
|
-
}, new BN13(0));
|
|
12738
|
-
if (totalAmountY.gt(amountY)) {
|
|
12739
|
-
baseY0 = baseY0.sub(new BN13(1));
|
|
12740
|
-
} else {
|
|
12741
|
-
return {
|
|
12742
|
-
base: baseY0,
|
|
12743
|
-
delta: deltaY
|
|
12744
|
-
};
|
|
12745
|
-
}
|
|
12746
|
-
}
|
|
12747
|
-
}
|
|
12748
|
-
function findBaseX0(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12749
|
-
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN13(0))) {
|
|
12750
|
-
return new BN13(0);
|
|
12751
|
-
}
|
|
12752
|
-
let b = new BN13(0);
|
|
12753
|
-
let c = new BN13(0);
|
|
12754
|
-
let m1 = minDeltaId;
|
|
12755
|
-
let m2 = maxDeltaId;
|
|
12756
|
-
for (let m = m1.toNumber(); m <= m2.toNumber(); m++) {
|
|
12757
|
-
const binId = activeId.addn(m);
|
|
12758
|
-
const pm = getQPriceFromId(binId.neg(), binStep);
|
|
12759
|
-
b = b.add(pm);
|
|
12760
|
-
const cDelta = new BN13(m).mul(pm).div(m2);
|
|
12761
|
-
c = c.add(cDelta);
|
|
12762
|
-
}
|
|
12763
|
-
return amountX.shln(SCALE_OFFSET).div(b.sub(c));
|
|
12370
|
+
return amountInBins;
|
|
12764
12371
|
}
|
|
12765
|
-
function
|
|
12766
|
-
if (
|
|
12767
|
-
return
|
|
12768
|
-
base: new BN13(0),
|
|
12769
|
-
delta: new BN13(0)
|
|
12770
|
-
};
|
|
12372
|
+
function toAmountIntoBins(activeId, minDeltaId, maxDeltaId, deltaX, deltaY, x0, y0, binStep, favorXInActiveBin) {
|
|
12373
|
+
if (onlyDepositToBidSide(maxDeltaId, favorXInActiveBin)) {
|
|
12374
|
+
return getAmountInBinsBidSide(activeId, minDeltaId, maxDeltaId, deltaY, y0);
|
|
12771
12375
|
}
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
while (true) {
|
|
12775
|
-
const amountInBins = getAmountInBinsAskSide(
|
|
12376
|
+
if (onlyDepositToAskSide(minDeltaId, favorXInActiveBin)) {
|
|
12377
|
+
return getAmountInBinsAskSide(
|
|
12776
12378
|
activeId,
|
|
12777
12379
|
binStep,
|
|
12778
12380
|
minDeltaId,
|
|
12779
12381
|
maxDeltaId,
|
|
12780
12382
|
deltaX,
|
|
12781
|
-
|
|
12383
|
+
x0
|
|
12384
|
+
);
|
|
12385
|
+
}
|
|
12386
|
+
const [bidSideEndDeltaId, askSideStartDeltaId] = favorXInActiveBin ? [-1, 0] : [0, 1];
|
|
12387
|
+
const amountInBinsBidSide = getAmountInBinsBidSide(
|
|
12388
|
+
activeId,
|
|
12389
|
+
minDeltaId,
|
|
12390
|
+
new BN14(bidSideEndDeltaId),
|
|
12391
|
+
deltaY,
|
|
12392
|
+
y0
|
|
12393
|
+
);
|
|
12394
|
+
const amountInBinsAskSide = getAmountInBinsAskSide(
|
|
12395
|
+
activeId,
|
|
12396
|
+
binStep,
|
|
12397
|
+
new BN14(askSideStartDeltaId),
|
|
12398
|
+
maxDeltaId,
|
|
12399
|
+
deltaX,
|
|
12400
|
+
x0
|
|
12401
|
+
);
|
|
12402
|
+
return amountInBinsBidSide.concat(amountInBinsAskSide);
|
|
12403
|
+
}
|
|
12404
|
+
function getLiquidity(x, y, price) {
|
|
12405
|
+
const px = price.mul(x);
|
|
12406
|
+
const shly = y.shln(SCALE_OFFSET);
|
|
12407
|
+
return px.add(shly);
|
|
12408
|
+
}
|
|
12409
|
+
function computeCompositionFee(binStep, sParameters3, vParameters3, outAmountX, inAmountX, outAmountY, inAmountY) {
|
|
12410
|
+
if (outAmountX.gt(inAmountX)) {
|
|
12411
|
+
const delta = inAmountY.sub(outAmountY);
|
|
12412
|
+
const totalFeeRate = getTotalFee(
|
|
12413
|
+
binStep.toNumber(),
|
|
12414
|
+
sParameters3,
|
|
12415
|
+
vParameters3
|
|
12782
12416
|
);
|
|
12783
|
-
const
|
|
12784
|
-
|
|
12785
|
-
}, new BN13(0));
|
|
12786
|
-
if (totalAmountX.gt(amountX)) {
|
|
12787
|
-
baseX0 = baseX0.sub(new BN13(1));
|
|
12788
|
-
} else {
|
|
12789
|
-
return {
|
|
12790
|
-
base: baseX0,
|
|
12791
|
-
delta: deltaX
|
|
12792
|
-
};
|
|
12793
|
-
}
|
|
12417
|
+
const feeAmount = delta.mul(totalFeeRate);
|
|
12418
|
+
return feeAmount.mul(FEE_PRECISION.add(totalFeeRate)).div(FEE_PRECISION.pow(new BN14(2)));
|
|
12794
12419
|
}
|
|
12420
|
+
return new BN14(0);
|
|
12795
12421
|
}
|
|
12796
|
-
|
|
12797
|
-
|
|
12798
|
-
return findX0AndDeltaX2(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
12799
|
-
}
|
|
12800
|
-
findYParameters(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
12801
|
-
return findY0AndDeltaY2(amountY, minDeltaId, maxDeltaId, activeId);
|
|
12802
|
-
}
|
|
12803
|
-
suggestBalancedXParametersFromY(activeId, binStep, favorXInActiveBin, minDeltaId, maxDeltaId, amountY) {
|
|
12804
|
-
const x0 = amountY.muln(2).div(maxDeltaId.addn(1));
|
|
12805
|
-
const deltaX = x0.neg().div(maxDeltaId);
|
|
12806
|
-
const totalAmountX = toAmountIntoBins(
|
|
12807
|
-
activeId,
|
|
12808
|
-
minDeltaId,
|
|
12809
|
-
maxDeltaId,
|
|
12810
|
-
deltaX,
|
|
12811
|
-
new BN13(0),
|
|
12812
|
-
x0,
|
|
12813
|
-
new BN13(0),
|
|
12814
|
-
binStep,
|
|
12815
|
-
favorXInActiveBin
|
|
12816
|
-
).reduce((acc, bin) => {
|
|
12817
|
-
return acc.add(bin.amountX);
|
|
12818
|
-
}, new BN13(0));
|
|
12422
|
+
function simulateDepositBin(binId, binStep, amountX, amountY, bin) {
|
|
12423
|
+
if (!bin) {
|
|
12819
12424
|
return {
|
|
12820
|
-
|
|
12821
|
-
|
|
12822
|
-
amountX: totalAmountX
|
|
12425
|
+
amountXIntoBin: amountX,
|
|
12426
|
+
amountYIntoBin: amountY
|
|
12823
12427
|
};
|
|
12824
12428
|
}
|
|
12825
|
-
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
|
|
12829
|
-
const a2 = m1.mul(m1.addn(1)).divn(2);
|
|
12830
|
-
const a3 = m2.mul(m2.subn(1)).divn(2);
|
|
12831
|
-
const a = m1.sub(a3.sub(a2)).div(m1);
|
|
12832
|
-
const y0 = amountXInQuoteValue.div(a);
|
|
12833
|
-
const deltaY = y0.neg().div(m1);
|
|
12834
|
-
const amountY = toAmountIntoBins(
|
|
12835
|
-
activeId,
|
|
12836
|
-
minDeltaId,
|
|
12837
|
-
maxDeltaId,
|
|
12838
|
-
new BN13(0),
|
|
12839
|
-
deltaY,
|
|
12840
|
-
new BN13(0),
|
|
12841
|
-
y0,
|
|
12842
|
-
binStep,
|
|
12843
|
-
favorXInActiveBin
|
|
12844
|
-
).reduce((acc, bin) => {
|
|
12845
|
-
return acc.add(bin.amountY);
|
|
12846
|
-
}, new BN13(0));
|
|
12429
|
+
const price = getQPriceFromId(binId, binStep);
|
|
12430
|
+
const inLiquidity = getLiquidity(amountX, amountY, price);
|
|
12431
|
+
const binLiquidity = getLiquidity(bin.amountX, bin.amountY, price);
|
|
12432
|
+
if (bin.liquiditySupply.isZero()) {
|
|
12847
12433
|
return {
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
amountY
|
|
12434
|
+
amountXIntoBin: amountX,
|
|
12435
|
+
amountYIntoBin: amountY
|
|
12851
12436
|
};
|
|
12852
12437
|
}
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
|
|
12438
|
+
const liquidityShare = inLiquidity.mul(bin.liquiditySupply).div(binLiquidity);
|
|
12439
|
+
const updatedBinXAmount = bin.amountX.add(amountX);
|
|
12440
|
+
const updatedBinYAmount = bin.amountY.add(amountY);
|
|
12441
|
+
const updatedBinSupply = bin.liquiditySupply.add(liquidityShare);
|
|
12442
|
+
let amountXIntoBin = liquidityShare.mul(
|
|
12443
|
+
updatedBinXAmount.div(updatedBinSupply)
|
|
12444
|
+
);
|
|
12445
|
+
let amountYIntoBin = liquidityShare.mul(
|
|
12446
|
+
updatedBinYAmount.div(updatedBinSupply)
|
|
12447
|
+
);
|
|
12448
|
+
if (amountXIntoBin.gt(amountX)) {
|
|
12860
12449
|
}
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
|
|
12450
|
+
return {
|
|
12451
|
+
amountXIntoBin,
|
|
12452
|
+
amountYIntoBin
|
|
12453
|
+
};
|
|
12865
12454
|
}
|
|
12866
|
-
|
|
12867
|
-
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
|
|
12455
|
+
var RebalancePosition = class {
|
|
12456
|
+
address;
|
|
12457
|
+
lowerBinId;
|
|
12458
|
+
upperBinId;
|
|
12459
|
+
lbPair;
|
|
12460
|
+
owner;
|
|
12461
|
+
shouldClaimFee;
|
|
12462
|
+
shouldClaimReward;
|
|
12463
|
+
rebalancePositionBinData;
|
|
12464
|
+
activeBin;
|
|
12465
|
+
currentTimestamp;
|
|
12466
|
+
constructor(positionAddress, positionData, lbPair, activeBin, shouldClaimFee, shouldClaimReward, currentTimestamp) {
|
|
12467
|
+
this.address = positionAddress;
|
|
12468
|
+
this.rebalancePositionBinData = toRebalancePositionBinData(positionData);
|
|
12469
|
+
this.lowerBinId = new BN14(positionData.lowerBinId);
|
|
12470
|
+
this.upperBinId = new BN14(positionData.upperBinId);
|
|
12471
|
+
this.lbPair = lbPair;
|
|
12472
|
+
this.shouldClaimFee = shouldClaimFee;
|
|
12473
|
+
this.shouldClaimReward = shouldClaimReward;
|
|
12474
|
+
this.owner = positionData.owner;
|
|
12475
|
+
this.activeBin = activeBin;
|
|
12476
|
+
this.currentTimestamp = currentTimestamp;
|
|
12875
12477
|
}
|
|
12876
|
-
|
|
12877
|
-
|
|
12878
|
-
|
|
12879
|
-
|
|
12880
|
-
|
|
12478
|
+
static async create(params) {
|
|
12479
|
+
const {
|
|
12480
|
+
program,
|
|
12481
|
+
positionAddress,
|
|
12482
|
+
pairAddress,
|
|
12483
|
+
positionData,
|
|
12484
|
+
shouldClaimFee,
|
|
12485
|
+
shouldClaimReward
|
|
12486
|
+
} = params;
|
|
12487
|
+
const [lbPairAccount, clockAccount] = await program.provider.connection.getMultipleAccountsInfo([
|
|
12488
|
+
pairAddress,
|
|
12489
|
+
SYSVAR_CLOCK_PUBKEY
|
|
12490
|
+
]);
|
|
12491
|
+
const lbPair = decodeAccount(program, "lbPair", lbPairAccount.data);
|
|
12492
|
+
const clock = ClockLayout.decode(clockAccount.data);
|
|
12493
|
+
const activeBinArrayIdx = binIdToBinArrayIndex(new BN14(lbPair.activeId));
|
|
12494
|
+
const [activeBinArrayPubkey] = deriveBinArray(
|
|
12495
|
+
pairAddress,
|
|
12496
|
+
activeBinArrayIdx,
|
|
12497
|
+
program.programId
|
|
12498
|
+
);
|
|
12499
|
+
const activeBinArrayState = await program.account.binArray.fetch(
|
|
12500
|
+
activeBinArrayPubkey
|
|
12501
|
+
);
|
|
12502
|
+
const [lowerBinId, upperBinId] = getBinArrayLowerUpperBinId(activeBinArrayIdx);
|
|
12503
|
+
const idx = getBinIdIndexInBinArray(
|
|
12504
|
+
new BN14(lbPair.activeId),
|
|
12505
|
+
lowerBinId,
|
|
12506
|
+
upperBinId
|
|
12507
|
+
);
|
|
12508
|
+
const activeBin = activeBinArrayState[idx.toNumber()];
|
|
12509
|
+
return new RebalancePosition(
|
|
12510
|
+
positionAddress,
|
|
12511
|
+
positionData,
|
|
12512
|
+
lbPair,
|
|
12513
|
+
activeBin,
|
|
12514
|
+
shouldClaimFee,
|
|
12515
|
+
shouldClaimReward,
|
|
12516
|
+
clock.unixTimestamp
|
|
12517
|
+
);
|
|
12881
12518
|
}
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
const
|
|
12885
|
-
|
|
12886
|
-
|
|
12519
|
+
_simulateDeposit(binStep, tokenXDecimal, tokenYDecimal, deposits, simulatedWithdrawResult) {
|
|
12520
|
+
const { liquidityAndFeeXWithdrawn, liquidityAndFeeYWithdrawn } = simulatedWithdrawResult;
|
|
12521
|
+
const activeId = new BN14(this.lbPair.activeId);
|
|
12522
|
+
const depositBinIds = getDepositBinIds(activeId, deposits);
|
|
12523
|
+
if (depositBinIds.length > 0) {
|
|
12524
|
+
const depositMinBinId = depositBinIds[0];
|
|
12525
|
+
const depositMaxBinId = depositBinIds[depositBinIds.length - 1];
|
|
12526
|
+
this._simulateResize(
|
|
12527
|
+
new BN14(depositMinBinId),
|
|
12528
|
+
new BN14(depositMaxBinId),
|
|
12529
|
+
binStep,
|
|
12530
|
+
tokenXDecimal,
|
|
12531
|
+
tokenYDecimal
|
|
12532
|
+
);
|
|
12533
|
+
}
|
|
12534
|
+
let totalAmountXDeposited = new BN14(0);
|
|
12535
|
+
let totalAmountYDeposited = new BN14(0);
|
|
12536
|
+
const addLiquidityParam = [];
|
|
12537
|
+
for (const {
|
|
12538
|
+
x0,
|
|
12539
|
+
y0,
|
|
12540
|
+
favorXInActiveBin,
|
|
12541
|
+
deltaX,
|
|
12542
|
+
deltaY,
|
|
12887
12543
|
minDeltaId,
|
|
12888
|
-
maxDeltaId
|
|
12889
|
-
|
|
12890
|
-
|
|
12891
|
-
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
|
|
12896
|
-
|
|
12544
|
+
maxDeltaId
|
|
12545
|
+
} of deposits) {
|
|
12546
|
+
const params = buildBitFlagAndNegateStrategyParameters(
|
|
12547
|
+
x0,
|
|
12548
|
+
y0,
|
|
12549
|
+
deltaX,
|
|
12550
|
+
deltaY
|
|
12551
|
+
);
|
|
12552
|
+
addLiquidityParam.push({
|
|
12553
|
+
minDeltaId: minDeltaId.toNumber(),
|
|
12554
|
+
maxDeltaId: maxDeltaId.toNumber(),
|
|
12555
|
+
x0: params.x0,
|
|
12556
|
+
y0: params.y0,
|
|
12557
|
+
deltaX: params.deltaX,
|
|
12558
|
+
deltaY: params.deltaY,
|
|
12559
|
+
bitFlag: params.bitFlag,
|
|
12560
|
+
padding: Array(16).fill(0),
|
|
12561
|
+
favorXInActiveId: favorXInActiveBin
|
|
12562
|
+
});
|
|
12563
|
+
const amountIntoBins = toAmountIntoBins(
|
|
12564
|
+
activeId,
|
|
12565
|
+
minDeltaId,
|
|
12566
|
+
maxDeltaId,
|
|
12567
|
+
deltaX,
|
|
12568
|
+
deltaY,
|
|
12569
|
+
x0,
|
|
12570
|
+
y0,
|
|
12571
|
+
binStep,
|
|
12572
|
+
favorXInActiveBin
|
|
12573
|
+
);
|
|
12574
|
+
for (const { binId, amountX, amountY } of amountIntoBins) {
|
|
12575
|
+
totalAmountXDeposited = totalAmountXDeposited.add(amountX);
|
|
12576
|
+
totalAmountYDeposited = totalAmountYDeposited.add(amountY);
|
|
12577
|
+
const idx = this.rebalancePositionBinData.findIndex(
|
|
12578
|
+
(data) => data.binId == binId.toNumber()
|
|
12579
|
+
);
|
|
12580
|
+
if (binId.eq(activeId)) {
|
|
12581
|
+
const vParameters3 = Object.assign({}, this.lbPair.vParameters);
|
|
12582
|
+
const sParameters3 = Object.assign({}, this.lbPair.parameters);
|
|
12583
|
+
DLMM.updateReference(
|
|
12584
|
+
activeId.toNumber(),
|
|
12585
|
+
vParameters3,
|
|
12586
|
+
sParameters3,
|
|
12587
|
+
this.currentTimestamp.toNumber()
|
|
12588
|
+
);
|
|
12589
|
+
DLMM.updateVolatilityAccumulator(
|
|
12590
|
+
vParameters3,
|
|
12591
|
+
sParameters3,
|
|
12592
|
+
activeId.toNumber()
|
|
12593
|
+
);
|
|
12594
|
+
const { amountXIntoBin, amountYIntoBin } = simulateDepositBin(
|
|
12595
|
+
binId,
|
|
12596
|
+
binStep,
|
|
12597
|
+
amountX,
|
|
12598
|
+
amountY,
|
|
12599
|
+
this.activeBin
|
|
12600
|
+
);
|
|
12601
|
+
const feeY = computeCompositionFee(
|
|
12602
|
+
binStep,
|
|
12603
|
+
sParameters3,
|
|
12604
|
+
vParameters3,
|
|
12605
|
+
amountXIntoBin,
|
|
12606
|
+
amountX,
|
|
12607
|
+
amountYIntoBin,
|
|
12608
|
+
amountY
|
|
12609
|
+
);
|
|
12610
|
+
const feeX = computeCompositionFee(
|
|
12611
|
+
binStep,
|
|
12612
|
+
sParameters3,
|
|
12613
|
+
vParameters3,
|
|
12614
|
+
amountYIntoBin,
|
|
12615
|
+
amountY,
|
|
12616
|
+
amountXIntoBin,
|
|
12617
|
+
amountX
|
|
12618
|
+
);
|
|
12619
|
+
const amountXIntoBinExcludeFee = amountXIntoBin.sub(feeX);
|
|
12620
|
+
const amountYIntoBinExcludeFee = amountYIntoBin.sub(feeY);
|
|
12621
|
+
this.rebalancePositionBinData[idx].amountX = this.rebalancePositionBinData[idx].amountX.add(
|
|
12622
|
+
amountXIntoBinExcludeFee
|
|
12623
|
+
);
|
|
12624
|
+
this.rebalancePositionBinData[idx].amountY = this.rebalancePositionBinData[idx].amountY.add(
|
|
12625
|
+
amountYIntoBinExcludeFee
|
|
12626
|
+
);
|
|
12627
|
+
} else {
|
|
12628
|
+
this.rebalancePositionBinData[idx].amountX = this.rebalancePositionBinData[idx].amountX.add(amountX);
|
|
12629
|
+
this.rebalancePositionBinData[idx].amountY = this.rebalancePositionBinData[idx].amountY.add(amountY);
|
|
12630
|
+
}
|
|
12631
|
+
}
|
|
12632
|
+
}
|
|
12633
|
+
let actualTotalAmountXDeposited = totalAmountXDeposited;
|
|
12634
|
+
let actualTotalAmountYDeposited = totalAmountYDeposited;
|
|
12635
|
+
let actualLiquidityAndFeeXWithdrawn = liquidityAndFeeXWithdrawn;
|
|
12636
|
+
let actualLiquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn;
|
|
12637
|
+
if (actualTotalAmountXDeposited.gt(actualLiquidityAndFeeXWithdrawn)) {
|
|
12638
|
+
actualTotalAmountXDeposited = actualTotalAmountXDeposited.sub(
|
|
12639
|
+
actualLiquidityAndFeeXWithdrawn
|
|
12640
|
+
);
|
|
12641
|
+
actualLiquidityAndFeeXWithdrawn = new BN14(0);
|
|
12897
12642
|
} else {
|
|
12898
|
-
|
|
12899
|
-
|
|
12643
|
+
actualLiquidityAndFeeXWithdrawn = actualLiquidityAndFeeXWithdrawn.sub(
|
|
12644
|
+
actualTotalAmountXDeposited
|
|
12645
|
+
);
|
|
12646
|
+
actualTotalAmountXDeposited = new BN14(0);
|
|
12647
|
+
}
|
|
12648
|
+
if (actualTotalAmountYDeposited.gt(actualLiquidityAndFeeYWithdrawn)) {
|
|
12649
|
+
actualTotalAmountYDeposited = actualTotalAmountYDeposited.sub(
|
|
12650
|
+
actualLiquidityAndFeeYWithdrawn
|
|
12651
|
+
);
|
|
12652
|
+
actualLiquidityAndFeeYWithdrawn = new BN14(0);
|
|
12653
|
+
} else {
|
|
12654
|
+
actualLiquidityAndFeeYWithdrawn = actualLiquidityAndFeeYWithdrawn.sub(
|
|
12655
|
+
actualTotalAmountYDeposited
|
|
12656
|
+
);
|
|
12657
|
+
actualTotalAmountYDeposited = new BN14(0);
|
|
12900
12658
|
}
|
|
12901
|
-
}
|
|
12902
|
-
}
|
|
12903
|
-
var SpotStrategyParameterBuilder = class {
|
|
12904
|
-
findXParameters(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12905
|
-
return {
|
|
12906
|
-
base: findX0(amountX, minDeltaId, maxDeltaId, binStep, activeId),
|
|
12907
|
-
delta: new BN14(0)
|
|
12908
|
-
};
|
|
12909
|
-
}
|
|
12910
|
-
findYParameters(amountY, minDeltaId, maxDeltaId, _activeId) {
|
|
12911
|
-
return {
|
|
12912
|
-
base: findY0(amountY, minDeltaId, maxDeltaId),
|
|
12913
|
-
delta: new BN14(0)
|
|
12914
|
-
};
|
|
12915
|
-
}
|
|
12916
|
-
suggestBalancedXParametersFromY(activeId, binStep, favorXInActiveBin, minDeltaId, maxDeltaId, amountY) {
|
|
12917
|
-
const x0 = amountY.div(maxDeltaId.addn(1));
|
|
12918
|
-
const totalAmountX = toAmountIntoBins(
|
|
12919
|
-
activeId,
|
|
12920
|
-
minDeltaId,
|
|
12921
|
-
maxDeltaId,
|
|
12922
|
-
new BN14(0),
|
|
12923
|
-
new BN14(0),
|
|
12924
|
-
x0,
|
|
12925
|
-
new BN14(0),
|
|
12926
|
-
binStep,
|
|
12927
|
-
favorXInActiveBin
|
|
12928
|
-
).reduce((acc, bin) => {
|
|
12929
|
-
return acc.add(bin.amountX);
|
|
12930
|
-
}, new BN14(0));
|
|
12931
|
-
return {
|
|
12932
|
-
base: new BN14(x0.toString()),
|
|
12933
|
-
delta: new BN14(0),
|
|
12934
|
-
amountX: totalAmountX
|
|
12935
|
-
};
|
|
12936
|
-
}
|
|
12937
|
-
suggestBalancedYParametersFromX(activeId, binStep, favorXInActiveBin, minDeltaId, maxDeltaId, amountXInQuoteValue) {
|
|
12938
|
-
const y0 = amountXInQuoteValue.div(maxDeltaId.sub(minDeltaId).addn(1));
|
|
12939
|
-
const amountY = toAmountIntoBins(
|
|
12940
|
-
activeId,
|
|
12941
|
-
minDeltaId,
|
|
12942
|
-
maxDeltaId,
|
|
12943
|
-
new BN14(0),
|
|
12944
|
-
new BN14(0),
|
|
12945
|
-
new BN14(0),
|
|
12946
|
-
y0,
|
|
12947
|
-
binStep,
|
|
12948
|
-
favorXInActiveBin
|
|
12949
|
-
).reduce((acc, bin) => {
|
|
12950
|
-
return acc.add(bin.amountY);
|
|
12951
|
-
}, new BN14(0));
|
|
12952
|
-
return {
|
|
12953
|
-
base: y0,
|
|
12954
|
-
delta: new BN14(0),
|
|
12955
|
-
amountY
|
|
12956
|
-
};
|
|
12957
|
-
}
|
|
12958
|
-
};
|
|
12959
|
-
|
|
12960
|
-
// src/dlmm/helpers/rebalance/liquidity_strategy/index.ts
|
|
12961
|
-
import Decimal7 from "decimal.js";
|
|
12962
|
-
function getLiquidityStrategyParameterBuilder(strategyType) {
|
|
12963
|
-
switch (strategyType) {
|
|
12964
|
-
case 0 /* Spot */:
|
|
12965
|
-
return new SpotStrategyParameterBuilder();
|
|
12966
|
-
case 1 /* Curve */:
|
|
12967
|
-
return new CurveStrategyParameterBuilder();
|
|
12968
|
-
case 2 /* BidAsk */:
|
|
12969
|
-
return new BidAskStrategyParameterBuilder();
|
|
12970
|
-
default:
|
|
12971
|
-
throw new Error("Strategy not supported");
|
|
12972
|
-
}
|
|
12973
|
-
}
|
|
12974
|
-
function suggestBalancedXParametersFromY(y0, deltaY, minDeltaId, maxDeltaId, activeId, binStep, favorXInActiveBin, builder) {
|
|
12975
|
-
const endDeltaIdBidSide = favorXInActiveBin ? new BN15(-1) : new BN15(0);
|
|
12976
|
-
if (maxDeltaId.lte(endDeltaIdBidSide)) {
|
|
12977
12659
|
return {
|
|
12978
|
-
|
|
12979
|
-
|
|
12980
|
-
|
|
12660
|
+
result: {
|
|
12661
|
+
totalAmountXDeposited,
|
|
12662
|
+
totalAmountYDeposited,
|
|
12663
|
+
actualLiquidityAndFeeXWithdrawn,
|
|
12664
|
+
actualLiquidityAndFeeYWithdrawn,
|
|
12665
|
+
actualTotalAmountXDeposited,
|
|
12666
|
+
actualTotalAmountYDeposited
|
|
12667
|
+
},
|
|
12668
|
+
depositParams: addLiquidityParam
|
|
12981
12669
|
};
|
|
12982
12670
|
}
|
|
12983
|
-
|
|
12984
|
-
|
|
12985
|
-
|
|
12986
|
-
|
|
12987
|
-
|
|
12988
|
-
|
|
12989
|
-
new
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
|
|
12996
|
-
|
|
12997
|
-
|
|
12998
|
-
|
|
12999
|
-
|
|
13000
|
-
|
|
13001
|
-
|
|
13002
|
-
|
|
13003
|
-
|
|
13004
|
-
|
|
13005
|
-
|
|
13006
|
-
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
|
|
13014
|
-
|
|
13015
|
-
let activeIdIndex = -1;
|
|
13016
|
-
for (const [
|
|
13017
|
-
idx,
|
|
13018
|
-
binData
|
|
13019
|
-
] of rebalancePosition.rebalancePositionBinData.entries()) {
|
|
13020
|
-
const liquidityBid = binData.amountY;
|
|
13021
|
-
const liquidityAsk = new Decimal7(binData.price).mul(new Decimal7(binData.amountX.toString())).floor().toString();
|
|
13022
|
-
liquidityInBidSide = liquidityInBidSide.add(liquidityBid);
|
|
13023
|
-
liquidityInAskSide = liquidityInAskSide.add(new BN15(liquidityAsk));
|
|
13024
|
-
if (binData.binId == lbPair.activeId) {
|
|
13025
|
-
favorXInActiveBin = binData.amountX.gt(binData.amountY);
|
|
13026
|
-
activeIdIndex = idx;
|
|
13027
|
-
}
|
|
13028
|
-
}
|
|
13029
|
-
if (liquidityInAskSide.gt(liquidityInBidSide)) {
|
|
13030
|
-
const minBinId = rebalancePosition.rebalancePositionBinData[0].binId;
|
|
13031
|
-
let maxBinId;
|
|
13032
|
-
if (activeIdIndex == -1) {
|
|
13033
|
-
maxBinId = rebalancePosition.rebalancePositionBinData[rebalancePosition.rebalancePositionBinData.length - 1].binId;
|
|
12671
|
+
_simulateResize(depositMinBinId, depositMaxBinId, binStep, tokenXDecimal, tokenYDecimal) {
|
|
12672
|
+
const tokenXMultiplier = new Decimal6(10 ** tokenXDecimal.toNumber());
|
|
12673
|
+
const tokenYMultiplier = new Decimal6(10 ** tokenYDecimal.toNumber());
|
|
12674
|
+
const [minBinId, maxBinId] = findMinMaxBinIdWithLiquidity(
|
|
12675
|
+
this.rebalancePositionBinData
|
|
12676
|
+
);
|
|
12677
|
+
const newMinBinId = new BN14(
|
|
12678
|
+
Math.min(depositMinBinId.toNumber(), minBinId ?? Number.MAX_SAFE_INTEGER)
|
|
12679
|
+
);
|
|
12680
|
+
const newMaxBinId = new BN14(
|
|
12681
|
+
Math.max(depositMaxBinId.toNumber(), maxBinId ?? Number.MIN_SAFE_INTEGER)
|
|
12682
|
+
);
|
|
12683
|
+
if (newMinBinId.lt(this.lowerBinId)) {
|
|
12684
|
+
const binCountToExpand = this.lowerBinId.sub(depositMinBinId);
|
|
12685
|
+
for (let i = 1; i <= binCountToExpand.toNumber(); i++) {
|
|
12686
|
+
const binId = this.lowerBinId.subn(i);
|
|
12687
|
+
const price = getPriceOfBinByBinId(
|
|
12688
|
+
binId.toNumber(),
|
|
12689
|
+
binStep.toNumber()
|
|
12690
|
+
);
|
|
12691
|
+
const adjustedPrice = price.mul(tokenXMultiplier).div(tokenYMultiplier);
|
|
12692
|
+
this.rebalancePositionBinData.unshift({
|
|
12693
|
+
binId: binId.toNumber(),
|
|
12694
|
+
price: adjustedPrice.toString(),
|
|
12695
|
+
pricePerToken: adjustedPrice.toString(),
|
|
12696
|
+
amountX: new BN14(0),
|
|
12697
|
+
amountY: new BN14(0),
|
|
12698
|
+
claimableRewardAmount: [new BN14(0), new BN14(0)],
|
|
12699
|
+
claimableFeeXAmount: new BN14(0),
|
|
12700
|
+
claimableFeeYAmount: new BN14(0)
|
|
12701
|
+
});
|
|
12702
|
+
}
|
|
13034
12703
|
} else {
|
|
13035
|
-
|
|
12704
|
+
const binCountToShrink = newMinBinId.sub(this.lowerBinId);
|
|
12705
|
+
for (let i = 1; i <= binCountToShrink.toNumber(); i++) {
|
|
12706
|
+
this.rebalancePositionBinData.shift();
|
|
12707
|
+
}
|
|
13036
12708
|
}
|
|
13037
|
-
|
|
13038
|
-
|
|
13039
|
-
|
|
13040
|
-
|
|
13041
|
-
|
|
13042
|
-
|
|
13043
|
-
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
|
|
13047
|
-
|
|
13048
|
-
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
13052
|
-
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
12709
|
+
if (newMaxBinId.gt(this.upperBinId)) {
|
|
12710
|
+
const binCountToExpand = newMaxBinId.sub(this.upperBinId);
|
|
12711
|
+
for (let i = 1; i <= binCountToExpand.toNumber(); i++) {
|
|
12712
|
+
const binId = this.upperBinId.addn(i);
|
|
12713
|
+
const price = getPriceOfBinByBinId(
|
|
12714
|
+
binId.toNumber(),
|
|
12715
|
+
binStep.toNumber()
|
|
12716
|
+
);
|
|
12717
|
+
const adjustedPrice = price.mul(tokenXMultiplier).div(tokenYMultiplier);
|
|
12718
|
+
this.rebalancePositionBinData.push({
|
|
12719
|
+
binId: binId.toNumber(),
|
|
12720
|
+
price: adjustedPrice.toString(),
|
|
12721
|
+
pricePerToken: adjustedPrice.toString(),
|
|
12722
|
+
amountX: new BN14(0),
|
|
12723
|
+
amountY: new BN14(0),
|
|
12724
|
+
claimableRewardAmount: [new BN14(0), new BN14(0)],
|
|
12725
|
+
claimableFeeXAmount: new BN14(0),
|
|
12726
|
+
claimableFeeYAmount: new BN14(0)
|
|
12727
|
+
});
|
|
12728
|
+
}
|
|
13057
12729
|
} else {
|
|
13058
|
-
|
|
12730
|
+
const binCountToShrink = this.upperBinId.sub(newMaxBinId);
|
|
12731
|
+
for (let i = 1; i <= binCountToShrink.toNumber(); i++) {
|
|
12732
|
+
this.rebalancePositionBinData.pop();
|
|
12733
|
+
}
|
|
13059
12734
|
}
|
|
13060
|
-
|
|
13061
|
-
|
|
13062
|
-
const { amountX } = builder.suggestBalancedXParametersFromY(
|
|
13063
|
-
new BN15(lbPair.activeId),
|
|
13064
|
-
new BN15(lbPair.binStep),
|
|
13065
|
-
favorXInActiveBin,
|
|
13066
|
-
new BN15(minDeltaId),
|
|
13067
|
-
new BN15(maxDeltaId),
|
|
13068
|
-
liquidityInBidSide
|
|
13069
|
-
);
|
|
13070
|
-
const [positionAmountX] = rebalancePosition.totalAmounts();
|
|
13071
|
-
return {
|
|
13072
|
-
amount: BN15.max(amountX.sub(positionAmountX), new BN15(0)),
|
|
13073
|
-
isBidSide: false
|
|
13074
|
-
};
|
|
13075
|
-
} else {
|
|
13076
|
-
return {
|
|
13077
|
-
amount: new BN15(0),
|
|
13078
|
-
isBidSide: false
|
|
13079
|
-
};
|
|
13080
|
-
}
|
|
13081
|
-
}
|
|
13082
|
-
function suggestBalancedYParametersFromX(x0, deltaX, minDeltaId, maxDeltaId, activeId, binStep, favorXInActiveBin, builder) {
|
|
13083
|
-
const startDeltaIdAskSide = favorXInActiveBin ? new BN15(0) : new BN15(1);
|
|
13084
|
-
if (minDeltaId.gte(startDeltaIdAskSide)) {
|
|
13085
|
-
return {
|
|
13086
|
-
base: new BN15(0),
|
|
13087
|
-
delta: new BN15(0),
|
|
13088
|
-
amountY: new BN15(0)
|
|
13089
|
-
};
|
|
12735
|
+
this.lowerBinId = newMinBinId;
|
|
12736
|
+
this.upperBinId = newMaxBinId;
|
|
13090
12737
|
}
|
|
13091
|
-
|
|
13092
|
-
|
|
13093
|
-
|
|
13094
|
-
|
|
13095
|
-
|
|
13096
|
-
|
|
13097
|
-
|
|
13098
|
-
|
|
13099
|
-
|
|
13100
|
-
|
|
13101
|
-
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
|
|
13107
|
-
|
|
12738
|
+
_simulateWithdraw(withdraws) {
|
|
12739
|
+
let liquidityAndFeeXWithdrawn = new BN14(0);
|
|
12740
|
+
let liquidityAndFeeYWithdrawn = new BN14(0);
|
|
12741
|
+
let rewardsAmountClaimed = [new BN14(0), new BN14(0)];
|
|
12742
|
+
const activeId = new BN14(this.lbPair.activeId);
|
|
12743
|
+
for (const { minBinId, maxBinId, bps } of withdraws) {
|
|
12744
|
+
const fromBinId = minBinId ?? activeId;
|
|
12745
|
+
const toBinId = maxBinId ?? activeId;
|
|
12746
|
+
const binIds = binRangeToBinIdArray(fromBinId, toBinId).filter(
|
|
12747
|
+
(binId) => binId.gte(this.lowerBinId) && binId.lte(this.upperBinId)
|
|
12748
|
+
);
|
|
12749
|
+
for (const binId of binIds) {
|
|
12750
|
+
const idx = this.rebalancePositionBinData.findIndex(
|
|
12751
|
+
(b) => b.binId === binId.toNumber()
|
|
12752
|
+
);
|
|
12753
|
+
const binData = this.rebalancePositionBinData[idx];
|
|
12754
|
+
const amountXWithdrawn = binData.amountX.mul(bps).divn(BASIS_POINT_MAX);
|
|
12755
|
+
const amountYWithdrawn = binData.amountY.mul(bps).divn(BASIS_POINT_MAX);
|
|
12756
|
+
liquidityAndFeeXWithdrawn = liquidityAndFeeXWithdrawn.add(amountXWithdrawn);
|
|
12757
|
+
liquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn.add(amountYWithdrawn);
|
|
12758
|
+
binData.amountX = binData.amountX.sub(amountXWithdrawn);
|
|
12759
|
+
binData.amountY = binData.amountY.sub(amountYWithdrawn);
|
|
12760
|
+
if (this.shouldClaimFee) {
|
|
12761
|
+
liquidityAndFeeXWithdrawn = liquidityAndFeeXWithdrawn.add(
|
|
12762
|
+
binData.claimableFeeXAmount
|
|
12763
|
+
);
|
|
12764
|
+
liquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn.add(
|
|
12765
|
+
binData.claimableFeeYAmount
|
|
12766
|
+
);
|
|
12767
|
+
binData.claimableFeeXAmount = new BN14(0);
|
|
12768
|
+
binData.claimableFeeYAmount = new BN14(0);
|
|
12769
|
+
}
|
|
12770
|
+
if (this.shouldClaimReward) {
|
|
12771
|
+
for (const [idx2, amount] of binData.claimableRewardAmount.entries()) {
|
|
12772
|
+
rewardsAmountClaimed[idx2] = rewardsAmountClaimed[idx2].add(amount);
|
|
12773
|
+
binData.claimableRewardAmount[idx2] = new BN14(0);
|
|
12774
|
+
}
|
|
12775
|
+
}
|
|
12776
|
+
this.rebalancePositionBinData[idx] = binData;
|
|
12777
|
+
}
|
|
12778
|
+
}
|
|
12779
|
+
const withdrawParams = withdraws.map(
|
|
12780
|
+
({ minBinId, maxBinId, bps }) => {
|
|
12781
|
+
return {
|
|
12782
|
+
minBinId: minBinId ? minBinId.toNumber() : null,
|
|
12783
|
+
maxBinId: maxBinId ? maxBinId.toNumber() : null,
|
|
12784
|
+
bps: bps.toNumber(),
|
|
12785
|
+
padding: Array(16).fill(0)
|
|
12786
|
+
};
|
|
12787
|
+
}
|
|
13108
12788
|
);
|
|
13109
|
-
return acc.add(price.mul(new Decimal7(bin.amountX.toString())));
|
|
13110
|
-
}, new Decimal7(0));
|
|
13111
|
-
const totalAmountXInQuoteBN = new BN15(totalAmountXInQuote.floor().toString());
|
|
13112
|
-
const minYDeltaId = minDeltaId;
|
|
13113
|
-
const maxYDeltaId = startDeltaIdAskSide.subn(1);
|
|
13114
|
-
return builder.suggestBalancedYParametersFromX(
|
|
13115
|
-
activeId,
|
|
13116
|
-
binStep,
|
|
13117
|
-
favorXInActiveBin,
|
|
13118
|
-
minYDeltaId,
|
|
13119
|
-
maxYDeltaId,
|
|
13120
|
-
totalAmountXInQuoteBN
|
|
13121
|
-
);
|
|
13122
|
-
}
|
|
13123
|
-
function buildLiquidityStrategyParameters(amountX, amountY, minDeltaId, maxDeltaId, binStep, favorXInActiveId, activeId, strategyParameterBuilder) {
|
|
13124
|
-
if (minDeltaId.gt(maxDeltaId)) {
|
|
13125
12789
|
return {
|
|
13126
|
-
|
|
13127
|
-
|
|
13128
|
-
|
|
13129
|
-
|
|
12790
|
+
result: {
|
|
12791
|
+
liquidityAndFeeXWithdrawn,
|
|
12792
|
+
liquidityAndFeeYWithdrawn,
|
|
12793
|
+
rewardsAmountClaimed
|
|
12794
|
+
},
|
|
12795
|
+
withdrawParams
|
|
13130
12796
|
};
|
|
13131
12797
|
}
|
|
13132
|
-
|
|
13133
|
-
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
|
|
13137
|
-
|
|
13138
|
-
|
|
13139
|
-
|
|
12798
|
+
async simulateRebalance(connection, binStep, tokenXDecimal, tokenYDecimal, withdraws, deposits) {
|
|
12799
|
+
if (withdraws.length == 0 && deposits.length == 0) {
|
|
12800
|
+
throw "No rebalance action";
|
|
12801
|
+
}
|
|
12802
|
+
const activeId = new BN14(this.lbPair.activeId);
|
|
12803
|
+
withdraws = validateAndSortRebalanceWithdraw(withdraws, activeId);
|
|
12804
|
+
deposits = validateAndSortRebalanceDeposit(deposits);
|
|
12805
|
+
const beforeWidth = getPositionWidthWithMinWidth(
|
|
12806
|
+
this.lowerBinId.toNumber(),
|
|
12807
|
+
this.upperBinId.toNumber()
|
|
12808
|
+
);
|
|
12809
|
+
const { withdrawParams, result: withdrawResult } = this._simulateWithdraw(withdraws);
|
|
12810
|
+
const { depositParams, result: depositResult } = this._simulateDeposit(
|
|
12811
|
+
binStep,
|
|
12812
|
+
tokenXDecimal,
|
|
12813
|
+
tokenYDecimal,
|
|
12814
|
+
deposits,
|
|
12815
|
+
withdrawResult
|
|
12816
|
+
);
|
|
12817
|
+
const afterWidth = getPositionWidthWithMinWidth(
|
|
12818
|
+
this.lowerBinId.toNumber(),
|
|
12819
|
+
this.upperBinId.toNumber()
|
|
13140
12820
|
);
|
|
12821
|
+
const widthDelta = afterWidth - beforeWidth;
|
|
12822
|
+
let rentalCostLamports = new BN14(0);
|
|
12823
|
+
if (widthDelta != 0) {
|
|
12824
|
+
const sizeChanges = Math.abs(widthDelta) * POSITION_BIN_DATA_SIZE;
|
|
12825
|
+
const [minimumLamports, rentExemptionLamports] = await Promise.all([
|
|
12826
|
+
connection.getMinimumBalanceForRentExemption(0),
|
|
12827
|
+
connection.getMinimumBalanceForRentExemption(sizeChanges)
|
|
12828
|
+
]);
|
|
12829
|
+
const lamportChanges = new BN14(rentExemptionLamports).sub(
|
|
12830
|
+
new BN14(minimumLamports)
|
|
12831
|
+
);
|
|
12832
|
+
if (widthDelta > 0) {
|
|
12833
|
+
rentalCostLamports = rentalCostLamports.add(lamportChanges);
|
|
12834
|
+
} else {
|
|
12835
|
+
rentalCostLamports = rentalCostLamports.sub(lamportChanges);
|
|
12836
|
+
}
|
|
12837
|
+
}
|
|
13141
12838
|
return {
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
|
|
13145
|
-
|
|
12839
|
+
amountXDeposited: depositResult.totalAmountXDeposited,
|
|
12840
|
+
amountYDeposited: depositResult.totalAmountYDeposited,
|
|
12841
|
+
actualAmountXDeposited: depositResult.actualTotalAmountXDeposited,
|
|
12842
|
+
actualAmountYDeposited: depositResult.actualTotalAmountYDeposited,
|
|
12843
|
+
actualAmountXWithdrawn: depositResult.actualLiquidityAndFeeXWithdrawn,
|
|
12844
|
+
actualAmountYWithdrawn: depositResult.actualLiquidityAndFeeYWithdrawn,
|
|
12845
|
+
rewardAmountsClaimed: withdrawResult.rewardsAmountClaimed,
|
|
12846
|
+
withdrawParams,
|
|
12847
|
+
depositParams,
|
|
12848
|
+
rentalCostLamports
|
|
13146
12849
|
};
|
|
13147
12850
|
}
|
|
13148
|
-
|
|
13149
|
-
|
|
13150
|
-
|
|
13151
|
-
|
|
13152
|
-
|
|
13153
|
-
|
|
13154
|
-
|
|
13155
|
-
|
|
13156
|
-
return {
|
|
13157
|
-
x0: base,
|
|
13158
|
-
deltaX: delta,
|
|
13159
|
-
y0: new BN15(0),
|
|
13160
|
-
deltaY: new BN15(0)
|
|
13161
|
-
};
|
|
12851
|
+
totalAmounts() {
|
|
12852
|
+
let totalAmountX = new BN14(0);
|
|
12853
|
+
let totalAmountY = new BN14(0);
|
|
12854
|
+
for (const binData of this.rebalancePositionBinData) {
|
|
12855
|
+
totalAmountX = totalAmountX.add(binData.amountX);
|
|
12856
|
+
totalAmountY = totalAmountY.add(binData.amountY);
|
|
12857
|
+
}
|
|
12858
|
+
return [totalAmountX, totalAmountY];
|
|
13162
12859
|
}
|
|
13163
|
-
|
|
13164
|
-
|
|
13165
|
-
|
|
13166
|
-
|
|
13167
|
-
|
|
13168
|
-
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
|
|
13172
|
-
|
|
13173
|
-
|
|
13174
|
-
|
|
13175
|
-
|
|
13176
|
-
|
|
13177
|
-
|
|
13178
|
-
|
|
13179
|
-
|
|
13180
|
-
deltaX,
|
|
13181
|
-
y0,
|
|
13182
|
-
deltaY
|
|
13183
|
-
};
|
|
13184
|
-
}
|
|
13185
|
-
|
|
13186
|
-
// src/dlmm/helpers/index.ts
|
|
13187
|
-
function chunks(array, size) {
|
|
13188
|
-
return Array.apply(0, new Array(Math.ceil(array.length / size))).map(
|
|
13189
|
-
(_, index) => array.slice(index * size, (index + 1) * size)
|
|
13190
|
-
);
|
|
13191
|
-
}
|
|
13192
|
-
function range(min, max, mapfn) {
|
|
13193
|
-
const length = max - min + 1;
|
|
13194
|
-
return Array.from({ length }, (_, i) => mapfn(min + i));
|
|
13195
|
-
}
|
|
13196
|
-
async function chunkedFetchMultiplePoolAccount(program, pks, chunkSize = 100) {
|
|
13197
|
-
const accounts = (await Promise.all(
|
|
13198
|
-
chunks(pks, chunkSize).map(
|
|
13199
|
-
(chunk) => program.account.lbPair.fetchMultiple(chunk)
|
|
13200
|
-
)
|
|
13201
|
-
)).flat();
|
|
13202
|
-
return accounts.filter(Boolean);
|
|
13203
|
-
}
|
|
13204
|
-
async function chunkedFetchMultipleBinArrayBitmapExtensionAccount(program, pks, chunkSize = 100) {
|
|
13205
|
-
const accounts = (await Promise.all(
|
|
13206
|
-
chunks(pks, chunkSize).map(
|
|
13207
|
-
(chunk) => program.account.binArrayBitmapExtension.fetchMultiple(chunk)
|
|
13208
|
-
)
|
|
13209
|
-
)).flat();
|
|
13210
|
-
return accounts;
|
|
13211
|
-
}
|
|
13212
|
-
function getOutAmount(bin, inAmount, swapForY) {
|
|
13213
|
-
return swapForY ? mulShr(inAmount, bin.price, SCALE_OFFSET, 1 /* Down */) : shlDiv(inAmount, bin.price, SCALE_OFFSET, 1 /* Down */);
|
|
13214
|
-
}
|
|
13215
|
-
async function getTokenDecimals(conn, mint) {
|
|
13216
|
-
const token = await getMint(conn, mint);
|
|
13217
|
-
return await token.decimals;
|
|
13218
|
-
}
|
|
13219
|
-
var getOrCreateATAInstruction = async (connection, tokenMint, owner, programId, payer = owner, allowOwnerOffCurve = true) => {
|
|
13220
|
-
programId = programId ?? TOKEN_PROGRAM_ID3;
|
|
13221
|
-
const toAccount = getAssociatedTokenAddressSync(
|
|
13222
|
-
tokenMint,
|
|
13223
|
-
owner,
|
|
13224
|
-
allowOwnerOffCurve,
|
|
13225
|
-
programId,
|
|
13226
|
-
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
13227
|
-
);
|
|
13228
|
-
try {
|
|
13229
|
-
await getAccount(connection, toAccount, connection.commitment, programId);
|
|
13230
|
-
return { ataPubKey: toAccount, ix: void 0 };
|
|
13231
|
-
} catch (e) {
|
|
13232
|
-
if (e instanceof TokenAccountNotFoundError || e instanceof TokenInvalidAccountOwnerError) {
|
|
13233
|
-
const ix = createAssociatedTokenAccountIdempotentInstruction(
|
|
13234
|
-
payer,
|
|
13235
|
-
toAccount,
|
|
13236
|
-
owner,
|
|
13237
|
-
tokenMint,
|
|
13238
|
-
programId,
|
|
13239
|
-
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
12860
|
+
totalFeeAmounts() {
|
|
12861
|
+
let totalFeeXAmount = new BN14(0);
|
|
12862
|
+
let totalFeeYAmount = new BN14(0);
|
|
12863
|
+
for (const binData of this.rebalancePositionBinData) {
|
|
12864
|
+
totalFeeXAmount = totalFeeXAmount.add(binData.claimableFeeXAmount);
|
|
12865
|
+
totalFeeYAmount = totalFeeYAmount.add(binData.claimableFeeYAmount);
|
|
12866
|
+
}
|
|
12867
|
+
return [totalFeeXAmount, totalFeeYAmount];
|
|
12868
|
+
}
|
|
12869
|
+
totalRewardAmounts() {
|
|
12870
|
+
let totalRewardAmounts = [new BN14(0), new BN14(0)];
|
|
12871
|
+
for (const binData of this.rebalancePositionBinData) {
|
|
12872
|
+
totalRewardAmounts[0] = totalRewardAmounts[0].add(
|
|
12873
|
+
binData.claimableRewardAmount[0]
|
|
12874
|
+
);
|
|
12875
|
+
totalRewardAmounts[1] = totalRewardAmounts[1].add(
|
|
12876
|
+
binData.claimableRewardAmount[1]
|
|
13240
12877
|
);
|
|
13241
|
-
return { ataPubKey: toAccount, ix };
|
|
13242
|
-
} else {
|
|
13243
|
-
console.error("Error::getOrCreateATAInstruction", e);
|
|
13244
|
-
throw e;
|
|
13245
12878
|
}
|
|
12879
|
+
return totalRewardAmounts;
|
|
13246
12880
|
}
|
|
13247
12881
|
};
|
|
13248
|
-
|
|
13249
|
-
const
|
|
13250
|
-
return
|
|
12882
|
+
function getPositionWidthWithMinWidth(lowerBinId, upperBinId) {
|
|
12883
|
+
const width = upperBinId - lowerBinId + 1;
|
|
12884
|
+
return Math.max(width, DEFAULT_BIN_PER_POSITION.toNumber());
|
|
13251
12885
|
}
|
|
13252
|
-
|
|
13253
|
-
|
|
13254
|
-
|
|
13255
|
-
for (const event of eventParser?.parseLogs(logs)) {
|
|
13256
|
-
return event.data;
|
|
13257
|
-
}
|
|
13258
|
-
throw new Error("No events found");
|
|
13259
|
-
};
|
|
13260
|
-
var wrapSOLInstruction = (from, to, amount) => {
|
|
13261
|
-
return [
|
|
13262
|
-
SystemProgram.transfer({
|
|
13263
|
-
fromPubkey: from,
|
|
13264
|
-
toPubkey: to,
|
|
13265
|
-
lamports: amount
|
|
13266
|
-
}),
|
|
13267
|
-
new TransactionInstruction3({
|
|
13268
|
-
keys: [
|
|
13269
|
-
{
|
|
13270
|
-
pubkey: to,
|
|
13271
|
-
isSigner: false,
|
|
13272
|
-
isWritable: true
|
|
13273
|
-
}
|
|
13274
|
-
],
|
|
13275
|
-
data: Buffer.from(new Uint8Array([17])),
|
|
13276
|
-
programId: TOKEN_PROGRAM_ID3
|
|
13277
|
-
})
|
|
13278
|
-
];
|
|
13279
|
-
};
|
|
13280
|
-
var unwrapSOLInstruction = async (owner, allowOwnerOffCurve = true) => {
|
|
13281
|
-
const wSolATAAccount = getAssociatedTokenAddressSync(
|
|
13282
|
-
NATIVE_MINT,
|
|
13283
|
-
owner,
|
|
13284
|
-
allowOwnerOffCurve
|
|
12886
|
+
function validateAndSortRebalanceDeposit(deposits) {
|
|
12887
|
+
const sortedDeposits = deposits.sort(
|
|
12888
|
+
(a, b) => a.minDeltaId.sub(b.minDeltaId).toNumber()
|
|
13285
12889
|
);
|
|
13286
|
-
|
|
13287
|
-
|
|
13288
|
-
|
|
13289
|
-
|
|
13290
|
-
owner,
|
|
13291
|
-
[],
|
|
13292
|
-
TOKEN_PROGRAM_ID3
|
|
13293
|
-
);
|
|
13294
|
-
return closedWrappedSolInstruction;
|
|
13295
|
-
}
|
|
13296
|
-
return null;
|
|
13297
|
-
};
|
|
13298
|
-
async function chunkedGetMultipleAccountInfos(connection, pks, chunkSize = 100) {
|
|
13299
|
-
const accountInfos = (await Promise.all(
|
|
13300
|
-
chunks(pks, chunkSize).map(
|
|
13301
|
-
(chunk) => connection.getMultipleAccountsInfo(chunk)
|
|
13302
|
-
)
|
|
13303
|
-
)).flat();
|
|
13304
|
-
return accountInfos;
|
|
13305
|
-
}
|
|
13306
|
-
var getEstimatedComputeUnitUsageWithBuffer = async (connection, instructions, feePayer, buffer) => {
|
|
13307
|
-
if (!buffer) {
|
|
13308
|
-
buffer = 0.1;
|
|
12890
|
+
for (const deposit of deposits) {
|
|
12891
|
+
if (deposit.minDeltaId.gte(deposit.maxDeltaId)) {
|
|
12892
|
+
throw "Invalid minDeltaId or maxDeltaId";
|
|
12893
|
+
}
|
|
13309
12894
|
}
|
|
13310
|
-
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
[]
|
|
13317
|
-
);
|
|
13318
|
-
let extraComputeUnitBuffer = estimatedComputeUnitUsage * buffer;
|
|
13319
|
-
if (extraComputeUnitBuffer > MAX_CU_BUFFER) {
|
|
13320
|
-
extraComputeUnitBuffer = MAX_CU_BUFFER;
|
|
13321
|
-
} else if (extraComputeUnitBuffer < MIN_CU_BUFFER) {
|
|
13322
|
-
extraComputeUnitBuffer = MIN_CU_BUFFER;
|
|
12895
|
+
for (let i = 1; i < sortedDeposits.length; i++) {
|
|
12896
|
+
const prevDeposit = sortedDeposits[i - 1];
|
|
12897
|
+
const currDeposit = sortedDeposits[i];
|
|
12898
|
+
if (prevDeposit.maxDeltaId.gte(currDeposit.minDeltaId)) {
|
|
12899
|
+
throw "Overlap deposit bin range";
|
|
12900
|
+
}
|
|
13323
12901
|
}
|
|
13324
|
-
return
|
|
13325
|
-
};
|
|
13326
|
-
var getEstimatedComputeUnitIxWithBuffer = async (connection, instructions, feePayer, buffer) => {
|
|
13327
|
-
const units = await getEstimatedComputeUnitUsageWithBuffer(
|
|
13328
|
-
connection,
|
|
13329
|
-
instructions,
|
|
13330
|
-
feePayer,
|
|
13331
|
-
buffer
|
|
13332
|
-
).catch((error) => {
|
|
13333
|
-
console.error("Error::getEstimatedComputeUnitUsageWithBuffer", error);
|
|
13334
|
-
return 14e5;
|
|
13335
|
-
});
|
|
13336
|
-
return ComputeBudgetProgram2.setComputeUnitLimit({ units });
|
|
13337
|
-
};
|
|
13338
|
-
function createProgram(connection, opt) {
|
|
13339
|
-
const cluster = opt?.cluster || "mainnet-beta";
|
|
13340
|
-
const provider = new AnchorProvider(
|
|
13341
|
-
connection,
|
|
13342
|
-
{},
|
|
13343
|
-
AnchorProvider.defaultOptions()
|
|
13344
|
-
);
|
|
13345
|
-
return new Program2(
|
|
13346
|
-
{ ...dlmm_default, address: LBCLMM_PROGRAM_IDS[cluster] },
|
|
13347
|
-
provider
|
|
13348
|
-
);
|
|
13349
|
-
}
|
|
13350
|
-
function decodeAccount(program, accountName, buffer) {
|
|
13351
|
-
return program.coder.accounts.decode(accountName, buffer);
|
|
13352
|
-
}
|
|
13353
|
-
function getAccountDiscriminator(accountName) {
|
|
13354
|
-
return dlmm_default.accounts.find(
|
|
13355
|
-
(acc) => acc.name.toLowerCase() === accountName.toLowerCase()
|
|
13356
|
-
)?.discriminator;
|
|
12902
|
+
return sortedDeposits;
|
|
13357
12903
|
}
|
|
13358
|
-
function
|
|
13359
|
-
|
|
13360
|
-
|
|
12904
|
+
function validateAndSortRebalanceWithdraw(withdraws, activeId) {
|
|
12905
|
+
const filledWithdraws = [];
|
|
12906
|
+
for (const { minBinId, maxBinId, bps } of withdraws) {
|
|
12907
|
+
if (bps.toNumber() < 0 || bps.toNumber() > BASIS_POINT_MAX) {
|
|
12908
|
+
throw "Invalid bps";
|
|
12909
|
+
}
|
|
12910
|
+
const filledMinBinId = minBinId ?? activeId;
|
|
12911
|
+
const filledMaxBinId = maxBinId ?? activeId;
|
|
12912
|
+
if (filledMinBinId.gt(filledMaxBinId)) {
|
|
12913
|
+
throw "Invalid minBinId or maxBinId";
|
|
12914
|
+
}
|
|
12915
|
+
filledWithdraws.push({
|
|
12916
|
+
minBinId: filledMinBinId,
|
|
12917
|
+
maxBinId: filledMaxBinId,
|
|
12918
|
+
bps
|
|
12919
|
+
});
|
|
13361
12920
|
}
|
|
13362
|
-
|
|
13363
|
-
|
|
12921
|
+
filledWithdraws.sort((a, b) => {
|
|
12922
|
+
return a.minBinId.sub(b.minBinId).toNumber();
|
|
12923
|
+
});
|
|
12924
|
+
for (let i = 1; i < filledWithdraws.length; i++) {
|
|
12925
|
+
const prev = filledWithdraws[i - 1];
|
|
12926
|
+
const curr = filledWithdraws[i];
|
|
12927
|
+
if (curr.minBinId.lte(prev.maxBinId)) {
|
|
12928
|
+
throw "Overlap withdraw bin range";
|
|
12929
|
+
}
|
|
13364
12930
|
}
|
|
13365
|
-
return
|
|
12931
|
+
return filledWithdraws;
|
|
13366
12932
|
}
|
|
13367
|
-
|
|
13368
|
-
|
|
13369
|
-
|
|
13370
|
-
|
|
13371
|
-
|
|
13372
|
-
|
|
13373
|
-
|
|
13374
|
-
|
|
13375
|
-
|
|
13376
|
-
|
|
13377
|
-
|
|
13378
|
-
|
|
13379
|
-
|
|
13380
|
-
|
|
13381
|
-
|
|
13382
|
-
offset: 8 + 2
|
|
13383
|
-
}
|
|
13384
|
-
};
|
|
13385
|
-
};
|
|
13386
|
-
var presetParameter2BaseFeePowerFactor = (baseFeePowerFactor) => {
|
|
13387
|
-
return {
|
|
13388
|
-
memcmp: {
|
|
13389
|
-
bytes: bs58.encode(baseFeePowerFactor.toArrayLike(Buffer, "le", 1)),
|
|
13390
|
-
offset: 8 + 22
|
|
12933
|
+
function binRangeToBinIdArray(minBinId, maxBinId) {
|
|
12934
|
+
const binIdArray = [];
|
|
12935
|
+
const fromBinId = minBinId.toNumber();
|
|
12936
|
+
const toBinId = maxBinId.toNumber();
|
|
12937
|
+
for (let binId = fromBinId; binId <= toBinId; binId++) {
|
|
12938
|
+
binIdArray.push(new BN14(binId));
|
|
12939
|
+
}
|
|
12940
|
+
return binIdArray;
|
|
12941
|
+
}
|
|
12942
|
+
function getRebalanceBinArrayIndexesAndBitmapCoverage(adds, removes, activeId, pairAddress, programId) {
|
|
12943
|
+
let indexMap = /* @__PURE__ */ new Map();
|
|
12944
|
+
removes.forEach((value) => {
|
|
12945
|
+
let minBinId = value.minBinId;
|
|
12946
|
+
if (minBinId == null) {
|
|
12947
|
+
minBinId = activeId;
|
|
13391
12948
|
}
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
return {
|
|
13396
|
-
memcmp: {
|
|
13397
|
-
bytes: lbPair.toBase58(),
|
|
13398
|
-
offset: 8 + 16
|
|
12949
|
+
let maxBinId = value.maxBinId;
|
|
12950
|
+
if (maxBinId == null) {
|
|
12951
|
+
maxBinId = activeId;
|
|
13399
12952
|
}
|
|
13400
|
-
|
|
13401
|
-
|
|
13402
|
-
|
|
13403
|
-
|
|
13404
|
-
|
|
13405
|
-
|
|
13406
|
-
|
|
12953
|
+
let binArrayIndex = binIdToBinArrayIndex(new BN14(minBinId));
|
|
12954
|
+
const upperBinId = new BN14(maxBinId);
|
|
12955
|
+
while (true) {
|
|
12956
|
+
indexMap.set(binArrayIndex.toNumber(), true);
|
|
12957
|
+
const [binArrayLowerBinId, binArrayUpperBinId] = getBinArrayLowerUpperBinId(binArrayIndex);
|
|
12958
|
+
if (upperBinId.gte(binArrayLowerBinId) && upperBinId.lte(binArrayUpperBinId)) {
|
|
12959
|
+
break;
|
|
12960
|
+
} else {
|
|
12961
|
+
binArrayIndex = binArrayIndex.add(new BN14(1));
|
|
12962
|
+
}
|
|
13407
12963
|
}
|
|
13408
|
-
};
|
|
13409
|
-
|
|
13410
|
-
|
|
13411
|
-
|
|
13412
|
-
|
|
13413
|
-
|
|
13414
|
-
|
|
12964
|
+
});
|
|
12965
|
+
adds.forEach((value) => {
|
|
12966
|
+
const minBinId = activeId + value.minDeltaId;
|
|
12967
|
+
const maxBinId = activeId + value.maxDeltaId;
|
|
12968
|
+
let binArrayIndex = binIdToBinArrayIndex(new BN14(minBinId));
|
|
12969
|
+
const upperBinId = new BN14(maxBinId);
|
|
12970
|
+
while (true) {
|
|
12971
|
+
indexMap.set(binArrayIndex.toNumber(), true);
|
|
12972
|
+
const [binArrayLowerBinId, binArrayUpperBinId] = getBinArrayLowerUpperBinId(binArrayIndex);
|
|
12973
|
+
if (upperBinId.gte(binArrayLowerBinId) && upperBinId.lte(binArrayUpperBinId)) {
|
|
12974
|
+
break;
|
|
12975
|
+
} else {
|
|
12976
|
+
binArrayIndex = binArrayIndex.add(new BN14(1));
|
|
12977
|
+
}
|
|
13415
12978
|
}
|
|
13416
|
-
};
|
|
13417
|
-
|
|
13418
|
-
|
|
12979
|
+
});
|
|
12980
|
+
const binArrayIndexes = Array.from(indexMap.keys()).map((idx) => new BN14(idx));
|
|
12981
|
+
const requireBitmapExtension = binArrayIndexes.some(
|
|
12982
|
+
(index) => isOverflowDefaultBinArrayBitmap(new BN14(index))
|
|
12983
|
+
);
|
|
13419
12984
|
return {
|
|
13420
|
-
|
|
13421
|
-
|
|
13422
|
-
offset: 0
|
|
13423
|
-
}
|
|
12985
|
+
binArrayIndexes,
|
|
12986
|
+
binArrayBitmap: requireBitmapExtension ? deriveBinArrayBitmapExtension(pairAddress, programId)[0] : programId
|
|
13424
12987
|
};
|
|
13425
|
-
}
|
|
12988
|
+
}
|
|
13426
12989
|
|
|
13427
|
-
// src/dlmm/helpers/
|
|
12990
|
+
// src/dlmm/helpers/rebalance/liquidity_strategy/index.ts
|
|
13428
12991
|
import BN18 from "bn.js";
|
|
13429
12992
|
|
|
13430
|
-
// src/dlmm/helpers/
|
|
13431
|
-
import
|
|
13432
|
-
function
|
|
13433
|
-
const
|
|
13434
|
-
const
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
|
|
13439
|
-
|
|
12993
|
+
// src/dlmm/helpers/rebalance/liquidity_strategy/bidAsk.ts
|
|
12994
|
+
import BN15 from "bn.js";
|
|
12995
|
+
function findMinY0(amountY, minDeltaId, maxDeltaId) {
|
|
12996
|
+
const binCount = maxDeltaId.sub(minDeltaId).addn(1);
|
|
12997
|
+
const totalWeight = binCount.mul(binCount.addn(1)).divn(2);
|
|
12998
|
+
return amountY.div(totalWeight);
|
|
12999
|
+
}
|
|
13000
|
+
function findBaseDeltaY(amountY, minDeltaId, maxDeltaId, minY0) {
|
|
13001
|
+
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new BN15(0))) {
|
|
13002
|
+
return new BN15(0);
|
|
13440
13003
|
}
|
|
13441
|
-
|
|
13442
|
-
|
|
13443
|
-
|
|
13444
|
-
|
|
13445
|
-
|
|
13004
|
+
if (minDeltaId.eq(maxDeltaId)) {
|
|
13005
|
+
return amountY;
|
|
13006
|
+
}
|
|
13007
|
+
const m1 = minDeltaId.neg();
|
|
13008
|
+
const m2 = maxDeltaId.neg();
|
|
13009
|
+
const b = m2.neg().mul(m1.sub(m2).addn(1));
|
|
13010
|
+
const c = m1.mul(m1.addn(1)).divn(2);
|
|
13011
|
+
const d = m2.mul(m2.subn(1)).divn(2);
|
|
13012
|
+
const a = b.add(c.sub(d));
|
|
13013
|
+
const e = minY0;
|
|
13014
|
+
return amountY.sub(e).div(a);
|
|
13446
13015
|
}
|
|
13447
|
-
function
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13016
|
+
function findY0AndDeltaY(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
13017
|
+
if (minDeltaId.gt(maxDeltaId) || amountY.isZero()) {
|
|
13018
|
+
return {
|
|
13019
|
+
base: new BN15(0),
|
|
13020
|
+
delta: new BN15(0)
|
|
13021
|
+
};
|
|
13022
|
+
}
|
|
13023
|
+
const minY0 = findMinY0(amountY, minDeltaId, maxDeltaId);
|
|
13024
|
+
let baseDeltaY = findBaseDeltaY(amountY, minDeltaId, maxDeltaId, minY0);
|
|
13025
|
+
const y0 = baseDeltaY.neg().mul(maxDeltaId).add(minY0);
|
|
13026
|
+
while (true) {
|
|
13027
|
+
const amountInBins = getAmountInBinsBidSide(
|
|
13028
|
+
activeId,
|
|
13029
|
+
minDeltaId,
|
|
13030
|
+
maxDeltaId,
|
|
13031
|
+
baseDeltaY,
|
|
13032
|
+
y0
|
|
13463
13033
|
);
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
|
|
13034
|
+
const totalAmountY = amountInBins.reduce((acc, { amountY: amountY2 }) => {
|
|
13035
|
+
return acc.add(amountY2);
|
|
13036
|
+
}, new BN15(0));
|
|
13037
|
+
if (totalAmountY.gt(amountY)) {
|
|
13038
|
+
baseDeltaY = baseDeltaY.sub(new BN15(1));
|
|
13039
|
+
} else {
|
|
13040
|
+
return {
|
|
13041
|
+
base: y0,
|
|
13042
|
+
delta: baseDeltaY
|
|
13043
|
+
};
|
|
13044
|
+
}
|
|
13467
13045
|
}
|
|
13468
13046
|
}
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13047
|
+
function findMinX0(amountX, minDeltaId, maxDeltaId, activeId, binStep) {
|
|
13048
|
+
const minBinId = activeId.add(minDeltaId);
|
|
13049
|
+
const maxBinId = activeId.add(maxDeltaId);
|
|
13050
|
+
let totalWeight = new BN15(0);
|
|
13051
|
+
for (let binId = minBinId.toNumber(); binId <= maxBinId.toNumber(); binId++) {
|
|
13052
|
+
const binDelta = binId - minBinId.toNumber() + 1;
|
|
13053
|
+
const binPrice = getQPriceFromId(new BN15(binId), binStep);
|
|
13054
|
+
const weight = new BN15(binDelta).mul(binPrice);
|
|
13055
|
+
totalWeight = totalWeight.add(weight);
|
|
13478
13056
|
}
|
|
13479
|
-
|
|
13480
|
-
|
|
13057
|
+
return amountX.shln(SCALE_OFFSET).div(totalWeight);
|
|
13058
|
+
}
|
|
13059
|
+
function findBaseDeltaX(amountX, minDeltaId, maxDeltaId, binStep, activeId, minX0) {
|
|
13060
|
+
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN15(0))) {
|
|
13061
|
+
return new BN15(0);
|
|
13481
13062
|
}
|
|
13482
|
-
|
|
13483
|
-
|
|
13063
|
+
let b = new BN15(0);
|
|
13064
|
+
let c = new BN15(0);
|
|
13065
|
+
let m1 = minDeltaId;
|
|
13066
|
+
let m2 = maxDeltaId;
|
|
13067
|
+
for (let m = m1.toNumber(); m <= m2.toNumber(); m++) {
|
|
13068
|
+
const binId = activeId.addn(m);
|
|
13069
|
+
const pm = getQPriceFromId(binId.neg(), binStep);
|
|
13070
|
+
const bDelta = m1.mul(pm);
|
|
13071
|
+
b = b.add(bDelta);
|
|
13072
|
+
const cDelta = new BN15(m).mul(pm);
|
|
13073
|
+
c = c.add(cDelta);
|
|
13484
13074
|
}
|
|
13485
|
-
|
|
13486
|
-
|
|
13075
|
+
return amountX.sub(minX0).shln(SCALE_OFFSET).div(c.sub(b));
|
|
13076
|
+
}
|
|
13077
|
+
function findX0AndDeltaX(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13078
|
+
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN15(0)) || amountX.isZero()) {
|
|
13079
|
+
return {
|
|
13080
|
+
base: new BN15(0),
|
|
13081
|
+
delta: new BN15(0)
|
|
13082
|
+
};
|
|
13487
13083
|
}
|
|
13488
|
-
|
|
13489
|
-
|
|
13084
|
+
const minX0 = findMinX0(amountX, minDeltaId, maxDeltaId, activeId, binStep);
|
|
13085
|
+
let baseDeltaX = findBaseDeltaX(
|
|
13086
|
+
amountX,
|
|
13087
|
+
minDeltaId,
|
|
13088
|
+
maxDeltaId,
|
|
13089
|
+
binStep,
|
|
13090
|
+
activeId,
|
|
13091
|
+
minX0
|
|
13092
|
+
);
|
|
13093
|
+
const x0 = minDeltaId.neg().mul(baseDeltaX).add(minX0);
|
|
13094
|
+
while (true) {
|
|
13095
|
+
const amountInBins = getAmountInBinsAskSide(
|
|
13096
|
+
activeId,
|
|
13097
|
+
binStep,
|
|
13098
|
+
minDeltaId,
|
|
13099
|
+
maxDeltaId,
|
|
13100
|
+
baseDeltaX,
|
|
13101
|
+
x0
|
|
13102
|
+
);
|
|
13103
|
+
const totalAmountX = amountInBins.reduce((acc, { amountX: amountX2 }) => {
|
|
13104
|
+
return acc.add(amountX2);
|
|
13105
|
+
}, new BN15(0));
|
|
13106
|
+
if (totalAmountX.gt(amountX)) {
|
|
13107
|
+
baseDeltaX = baseDeltaX.sub(new BN15(1));
|
|
13108
|
+
} else {
|
|
13109
|
+
return {
|
|
13110
|
+
base: x0,
|
|
13111
|
+
delta: baseDeltaX
|
|
13112
|
+
};
|
|
13113
|
+
}
|
|
13490
13114
|
}
|
|
13491
|
-
|
|
13492
|
-
|
|
13115
|
+
}
|
|
13116
|
+
var BidAskStrategyParameterBuilder = class {
|
|
13117
|
+
findXParameters(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13118
|
+
return findX0AndDeltaX(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
13493
13119
|
}
|
|
13494
|
-
|
|
13495
|
-
return
|
|
13120
|
+
findYParameters(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
13121
|
+
return findY0AndDeltaY(amountY, minDeltaId, maxDeltaId, activeId);
|
|
13496
13122
|
}
|
|
13497
|
-
|
|
13498
|
-
|
|
13123
|
+
};
|
|
13124
|
+
|
|
13125
|
+
// src/dlmm/helpers/rebalance/liquidity_strategy/curve.ts
|
|
13126
|
+
import BN16 from "bn.js";
|
|
13127
|
+
function findBaseY0(amountY, minDeltaId, maxDeltaId) {
|
|
13128
|
+
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new BN16(0))) {
|
|
13129
|
+
return new BN16(0);
|
|
13499
13130
|
}
|
|
13500
|
-
|
|
13501
|
-
return
|
|
13131
|
+
if (minDeltaId.eq(maxDeltaId)) {
|
|
13132
|
+
return amountY;
|
|
13502
13133
|
}
|
|
13503
|
-
|
|
13504
|
-
|
|
13134
|
+
const m1 = minDeltaId.neg();
|
|
13135
|
+
const m2 = maxDeltaId.neg();
|
|
13136
|
+
const b = m1.sub(m2).addn(1);
|
|
13137
|
+
const c = m1.mul(m1.addn(1)).divn(2);
|
|
13138
|
+
const d = m2.mul(m2.subn(1)).divn(2);
|
|
13139
|
+
const a = b.sub(c.sub(d).div(m1.addn(1)));
|
|
13140
|
+
return amountY.div(a);
|
|
13141
|
+
}
|
|
13142
|
+
function findY0AndDeltaY2(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
13143
|
+
if (minDeltaId.gt(maxDeltaId) || amountY.isZero()) {
|
|
13144
|
+
return {
|
|
13145
|
+
base: new BN16(0),
|
|
13146
|
+
delta: new BN16(0)
|
|
13147
|
+
};
|
|
13505
13148
|
}
|
|
13506
|
-
|
|
13507
|
-
|
|
13149
|
+
let baseY0 = findBaseY0(amountY, minDeltaId, maxDeltaId);
|
|
13150
|
+
while (true) {
|
|
13151
|
+
const deltaY = baseY0.neg().div(minDeltaId.neg().addn(1));
|
|
13152
|
+
const amountInBins = getAmountInBinsBidSide(
|
|
13153
|
+
activeId,
|
|
13154
|
+
minDeltaId,
|
|
13155
|
+
maxDeltaId,
|
|
13156
|
+
deltaY,
|
|
13157
|
+
baseY0
|
|
13158
|
+
);
|
|
13159
|
+
const totalAmountY = amountInBins.reduce((acc, { amountY: amountY2 }) => {
|
|
13160
|
+
return acc.add(amountY2);
|
|
13161
|
+
}, new BN16(0));
|
|
13162
|
+
if (totalAmountY.gt(amountY)) {
|
|
13163
|
+
baseY0 = baseY0.sub(new BN16(1));
|
|
13164
|
+
} else {
|
|
13165
|
+
return {
|
|
13166
|
+
base: baseY0,
|
|
13167
|
+
delta: deltaY
|
|
13168
|
+
};
|
|
13169
|
+
}
|
|
13508
13170
|
}
|
|
13509
|
-
|
|
13510
|
-
|
|
13171
|
+
}
|
|
13172
|
+
function findBaseX0(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13173
|
+
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN16(0))) {
|
|
13174
|
+
return new BN16(0);
|
|
13511
13175
|
}
|
|
13512
|
-
|
|
13513
|
-
|
|
13176
|
+
let b = new BN16(0);
|
|
13177
|
+
let c = new BN16(0);
|
|
13178
|
+
let m1 = minDeltaId;
|
|
13179
|
+
let m2 = maxDeltaId;
|
|
13180
|
+
for (let m = m1.toNumber(); m <= m2.toNumber(); m++) {
|
|
13181
|
+
const binId = activeId.addn(m);
|
|
13182
|
+
const pm = getQPriceFromId(binId.neg(), binStep);
|
|
13183
|
+
b = b.add(pm);
|
|
13184
|
+
const cDelta = new BN16(m).mul(pm).div(m2);
|
|
13185
|
+
c = c.add(cDelta);
|
|
13514
13186
|
}
|
|
13515
|
-
|
|
13516
|
-
|
|
13187
|
+
return amountX.shln(SCALE_OFFSET).div(b.sub(c));
|
|
13188
|
+
}
|
|
13189
|
+
function findX0AndDeltaX2(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13190
|
+
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN16(0)) || amountX.isZero()) {
|
|
13191
|
+
return {
|
|
13192
|
+
base: new BN16(0),
|
|
13193
|
+
delta: new BN16(0)
|
|
13194
|
+
};
|
|
13517
13195
|
}
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
|
|
13196
|
+
let baseX0 = findBaseX0(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
13197
|
+
const deltaX = baseX0.neg().div(maxDeltaId);
|
|
13198
|
+
while (true) {
|
|
13199
|
+
const amountInBins = getAmountInBinsAskSide(
|
|
13200
|
+
activeId,
|
|
13201
|
+
binStep,
|
|
13202
|
+
minDeltaId,
|
|
13203
|
+
maxDeltaId,
|
|
13204
|
+
deltaX,
|
|
13205
|
+
baseX0
|
|
13206
|
+
);
|
|
13207
|
+
const totalAmountX = amountInBins.reduce((acc, { amountX: amountX2 }) => {
|
|
13208
|
+
return acc.add(amountX2);
|
|
13209
|
+
}, new BN16(0));
|
|
13210
|
+
if (totalAmountX.gt(amountX)) {
|
|
13211
|
+
baseX0 = baseX0.sub(new BN16(1));
|
|
13522
13212
|
} else {
|
|
13523
|
-
|
|
13524
|
-
|
|
13525
|
-
|
|
13213
|
+
return {
|
|
13214
|
+
base: baseX0,
|
|
13215
|
+
delta: deltaX
|
|
13216
|
+
};
|
|
13526
13217
|
}
|
|
13527
13218
|
}
|
|
13528
|
-
|
|
13529
|
-
|
|
13530
|
-
|
|
13531
|
-
);
|
|
13532
|
-
}
|
|
13533
|
-
version() {
|
|
13534
|
-
return 1 /* V2 */;
|
|
13535
|
-
}
|
|
13536
|
-
owner() {
|
|
13537
|
-
return this.inner.owner;
|
|
13219
|
+
}
|
|
13220
|
+
var CurveStrategyParameterBuilder = class {
|
|
13221
|
+
findXParameters(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13222
|
+
return findX0AndDeltaX2(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
13538
13223
|
}
|
|
13539
|
-
|
|
13540
|
-
return
|
|
13224
|
+
findYParameters(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
13225
|
+
return findY0AndDeltaY2(amountY, minDeltaId, maxDeltaId, activeId);
|
|
13541
13226
|
}
|
|
13542
13227
|
};
|
|
13543
13228
|
|
|
13544
|
-
// src/dlmm/helpers/
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
for (let i = lowerBinArrayIndex.toNumber(); i <= upperBinArrayIndex.toNumber(); i++) {
|
|
13550
|
-
binArrayIndexes.push(new BN18(i));
|
|
13229
|
+
// src/dlmm/helpers/rebalance/liquidity_strategy/spot.ts
|
|
13230
|
+
import BN17 from "bn.js";
|
|
13231
|
+
function findY0(amountY, minDeltaId, maxDeltaId) {
|
|
13232
|
+
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new BN17(0)) || amountY.isZero()) {
|
|
13233
|
+
return new BN17(0);
|
|
13551
13234
|
}
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13555
|
-
|
|
13556
|
-
return binArrayIndexes.map((index) => {
|
|
13557
|
-
return deriveBinArray(lbPair, index, programId)[0];
|
|
13558
|
-
});
|
|
13559
|
-
}
|
|
13560
|
-
function getBinArrayAccountMetasCoverage(lowerBinId, upperBinId, lbPair, programId) {
|
|
13561
|
-
return getBinArrayKeysCoverage2(lowerBinId, upperBinId, lbPair, programId).map(
|
|
13562
|
-
(key) => {
|
|
13563
|
-
return {
|
|
13564
|
-
pubkey: key,
|
|
13565
|
-
isSigner: false,
|
|
13566
|
-
isWritable: true
|
|
13567
|
-
};
|
|
13568
|
-
}
|
|
13569
|
-
);
|
|
13570
|
-
}
|
|
13571
|
-
function getPositionLowerUpperBinIdWithLiquidity(position) {
|
|
13572
|
-
const binWithLiquidity = position.positionBinData.filter(
|
|
13573
|
-
(b) => !new BN18(b.binLiquidity).isZero() || !new BN18(b.positionFeeXAmount.toString()).isZero() || !new BN18(b.positionFeeYAmount.toString()).isZero() || !new BN18(b.positionRewardAmount[0].toString()).isZero() || !new BN18(b.positionRewardAmount[1].toString()).isZero()
|
|
13574
|
-
);
|
|
13575
|
-
return binWithLiquidity.length > 0 ? {
|
|
13576
|
-
lowerBinId: new BN18(binWithLiquidity[0].binId),
|
|
13577
|
-
upperBinId: new BN18(binWithLiquidity[binWithLiquidity.length - 1].binId)
|
|
13578
|
-
} : null;
|
|
13579
|
-
}
|
|
13580
|
-
function isPositionNoFee(position) {
|
|
13581
|
-
return position.feeX.isZero() && position.feeY.isZero();
|
|
13582
|
-
}
|
|
13583
|
-
function isPositionNoReward(position) {
|
|
13584
|
-
return position.rewardOne.isZero() && position.rewardTwo.isZero();
|
|
13235
|
+
const m1 = minDeltaId.neg();
|
|
13236
|
+
const m2 = maxDeltaId.neg();
|
|
13237
|
+
const delta = m1.sub(m2).addn(1);
|
|
13238
|
+
return amountY.div(delta);
|
|
13585
13239
|
}
|
|
13586
|
-
function
|
|
13587
|
-
|
|
13588
|
-
|
|
13589
|
-
|
|
13590
|
-
|
|
13591
|
-
|
|
13592
|
-
|
|
13593
|
-
);
|
|
13594
|
-
|
|
13595
|
-
lowerBinId: startBinId,
|
|
13596
|
-
upperBinId: endBinId
|
|
13597
|
-
});
|
|
13598
|
-
startBinId += DEFAULT_BIN_PER_POSITION.toNumber();
|
|
13240
|
+
function findBaseX02(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13241
|
+
let totalWeight = new BN17(0);
|
|
13242
|
+
const minBinId = activeId.add(minDeltaId);
|
|
13243
|
+
const maxBinId = activeId.add(maxDeltaId);
|
|
13244
|
+
let baseFactor = getQPriceBaseFactor(binStep);
|
|
13245
|
+
let basePrice = getQPriceFromId(maxBinId.neg(), binStep);
|
|
13246
|
+
for (let binId = minBinId.toNumber(); binId <= maxBinId.toNumber(); binId++) {
|
|
13247
|
+
totalWeight = totalWeight.add(basePrice);
|
|
13248
|
+
basePrice = basePrice.mul(baseFactor).shrn(SCALE_OFFSET);
|
|
13599
13249
|
}
|
|
13600
|
-
return
|
|
13250
|
+
return amountX.shln(SCALE_OFFSET).div(totalWeight);
|
|
13601
13251
|
}
|
|
13602
|
-
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
|
|
13608
|
-
const
|
|
13609
|
-
|
|
13252
|
+
function findX0(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13253
|
+
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN17(0)) || amountX.isZero()) {
|
|
13254
|
+
return new BN17(0);
|
|
13255
|
+
}
|
|
13256
|
+
let x0 = findBaseX02(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
13257
|
+
while (true) {
|
|
13258
|
+
const amountInBins = getAmountInBinsAskSide(
|
|
13259
|
+
activeId,
|
|
13260
|
+
binStep,
|
|
13261
|
+
minDeltaId,
|
|
13262
|
+
maxDeltaId,
|
|
13263
|
+
new BN17(0),
|
|
13264
|
+
x0
|
|
13610
13265
|
);
|
|
13611
|
-
const
|
|
13612
|
-
|
|
13613
|
-
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13266
|
+
const totalAmountX = amountInBins.reduce((acc, bin) => {
|
|
13267
|
+
return acc.add(bin.amountX);
|
|
13268
|
+
}, new BN17(0));
|
|
13269
|
+
if (totalAmountX.lt(amountX)) {
|
|
13270
|
+
x0 = x0.add(new BN17(1));
|
|
13271
|
+
} else {
|
|
13272
|
+
x0 = x0.sub(new BN17(1));
|
|
13273
|
+
return x0;
|
|
13274
|
+
}
|
|
13617
13275
|
}
|
|
13618
13276
|
}
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13277
|
+
var SpotStrategyParameterBuilder = class {
|
|
13278
|
+
findXParameters(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13279
|
+
return {
|
|
13280
|
+
base: findX0(amountX, minDeltaId, maxDeltaId, binStep, activeId),
|
|
13281
|
+
delta: new BN17(0)
|
|
13282
|
+
};
|
|
13283
|
+
}
|
|
13284
|
+
findYParameters(amountY, minDeltaId, maxDeltaId, _activeId) {
|
|
13285
|
+
return {
|
|
13286
|
+
base: findY0(amountY, minDeltaId, maxDeltaId),
|
|
13287
|
+
delta: new BN17(0)
|
|
13288
|
+
};
|
|
13289
|
+
}
|
|
13290
|
+
};
|
|
13291
|
+
|
|
13292
|
+
// src/dlmm/helpers/rebalance/liquidity_strategy/index.ts
|
|
13293
|
+
function getLiquidityStrategyParameterBuilder(strategyType) {
|
|
13294
|
+
switch (strategyType) {
|
|
13295
|
+
case 0 /* Spot */:
|
|
13296
|
+
return new SpotStrategyParameterBuilder();
|
|
13297
|
+
case 1 /* Curve */:
|
|
13298
|
+
return new CurveStrategyParameterBuilder();
|
|
13299
|
+
case 2 /* BidAsk */:
|
|
13300
|
+
return new BidAskStrategyParameterBuilder();
|
|
13301
|
+
default:
|
|
13302
|
+
throw new Error("Strategy not supported");
|
|
13303
|
+
}
|
|
13623
13304
|
}
|
|
13624
|
-
function
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
|
|
13634
|
-
|
|
13305
|
+
function buildLiquidityStrategyParameters(amountX, amountY, minDeltaId, maxDeltaId, binStep, favorXInActiveId, activeId, strategyParameterBuilder) {
|
|
13306
|
+
if (minDeltaId.gt(maxDeltaId)) {
|
|
13307
|
+
return {
|
|
13308
|
+
x0: new BN18(0),
|
|
13309
|
+
y0: new BN18(0),
|
|
13310
|
+
deltaX: new BN18(0),
|
|
13311
|
+
deltaY: new BN18(0)
|
|
13312
|
+
};
|
|
13313
|
+
}
|
|
13314
|
+
const depositOnlyY = maxDeltaId.lt(new BN18(0)) || maxDeltaId.isZero() && !favorXInActiveId;
|
|
13315
|
+
const depositOnlyX = minDeltaId.gt(new BN18(0)) || minDeltaId.isZero() && favorXInActiveId;
|
|
13316
|
+
if (depositOnlyY) {
|
|
13317
|
+
const { base, delta } = strategyParameterBuilder.findYParameters(
|
|
13318
|
+
amountY,
|
|
13319
|
+
minDeltaId,
|
|
13320
|
+
maxDeltaId,
|
|
13321
|
+
activeId
|
|
13322
|
+
);
|
|
13323
|
+
return {
|
|
13324
|
+
x0: new BN18(0),
|
|
13325
|
+
deltaX: new BN18(0),
|
|
13326
|
+
y0: base,
|
|
13327
|
+
deltaY: delta
|
|
13328
|
+
};
|
|
13329
|
+
}
|
|
13330
|
+
if (depositOnlyX) {
|
|
13331
|
+
const { base, delta } = strategyParameterBuilder.findXParameters(
|
|
13332
|
+
amountX,
|
|
13333
|
+
minDeltaId,
|
|
13334
|
+
maxDeltaId,
|
|
13335
|
+
binStep,
|
|
13336
|
+
activeId
|
|
13635
13337
|
);
|
|
13636
|
-
|
|
13338
|
+
return {
|
|
13339
|
+
x0: base,
|
|
13340
|
+
deltaX: delta,
|
|
13341
|
+
y0: new BN18(0),
|
|
13342
|
+
deltaY: new BN18(0)
|
|
13343
|
+
};
|
|
13637
13344
|
}
|
|
13638
|
-
|
|
13345
|
+
const maxDeltaIdBidSide = favorXInActiveId ? new BN18(-1) : new BN18(0);
|
|
13346
|
+
const minDeltaIdAskSide = favorXInActiveId ? new BN18(0) : new BN18(1);
|
|
13347
|
+
const { base: y0, delta: deltaY } = strategyParameterBuilder.findYParameters(
|
|
13348
|
+
amountY,
|
|
13349
|
+
minDeltaId,
|
|
13350
|
+
maxDeltaIdBidSide,
|
|
13351
|
+
activeId
|
|
13352
|
+
);
|
|
13353
|
+
const { base: x0, delta: deltaX } = strategyParameterBuilder.findXParameters(
|
|
13354
|
+
amountX,
|
|
13355
|
+
minDeltaIdAskSide,
|
|
13356
|
+
maxDeltaId,
|
|
13357
|
+
binStep,
|
|
13358
|
+
activeId
|
|
13359
|
+
);
|
|
13360
|
+
return {
|
|
13361
|
+
x0,
|
|
13362
|
+
deltaX,
|
|
13363
|
+
y0,
|
|
13364
|
+
deltaY
|
|
13365
|
+
};
|
|
13639
13366
|
}
|
|
13640
13367
|
|
|
13641
13368
|
// src/dlmm/helpers/rebalance/strategy/balanced.ts
|
|
@@ -14429,11 +14156,11 @@ var DLMM = class {
|
|
|
14429
14156
|
return positionsMap;
|
|
14430
14157
|
}
|
|
14431
14158
|
static getPricePerLamport(tokenXDecimal, tokenYDecimal, price) {
|
|
14432
|
-
return new
|
|
14159
|
+
return new Decimal7(price).mul(new Decimal7(10 ** (tokenYDecimal - tokenXDecimal))).toString();
|
|
14433
14160
|
}
|
|
14434
14161
|
static getBinIdFromPrice(price, binStep, min) {
|
|
14435
|
-
const binStepNum = new
|
|
14436
|
-
const binId = new
|
|
14162
|
+
const binStepNum = new Decimal7(binStep).div(new Decimal7(BASIS_POINT_MAX));
|
|
14163
|
+
const binId = new Decimal7(price).log().dividedBy(new Decimal7(1).add(binStepNum).log());
|
|
14437
14164
|
return (min ? binId.floor() : binId.ceil()).toNumber();
|
|
14438
14165
|
}
|
|
14439
14166
|
/**
|
|
@@ -15045,8 +14772,8 @@ var DLMM = class {
|
|
|
15045
14772
|
*/
|
|
15046
14773
|
static calculateFeeInfo(baseFactor, binStep, baseFeePowerFactor) {
|
|
15047
14774
|
const baseFeeRate = new BN21(baseFactor).mul(new BN21(binStep)).mul(new BN21(10)).mul(new BN21(10).pow(new BN21(baseFeePowerFactor ?? 0)));
|
|
15048
|
-
const baseFeeRatePercentage = new
|
|
15049
|
-
const maxFeeRatePercentage = new
|
|
14775
|
+
const baseFeeRatePercentage = new Decimal7(baseFeeRate.toString()).mul(new Decimal7(100)).div(new Decimal7(FEE_PRECISION.toString()));
|
|
14776
|
+
const maxFeeRatePercentage = new Decimal7(MAX_FEE_RATE.toString()).mul(new Decimal7(100)).div(new Decimal7(FEE_PRECISION.toString()));
|
|
15050
14777
|
return {
|
|
15051
14778
|
baseFeeRatePercentage,
|
|
15052
14779
|
maxFeeRatePercentage
|
|
@@ -15064,7 +14791,7 @@ var DLMM = class {
|
|
|
15064
14791
|
this.lbPair.binStep,
|
|
15065
14792
|
this.lbPair.parameters.baseFeePowerFactor
|
|
15066
14793
|
);
|
|
15067
|
-
const protocolFeePercentage = new
|
|
14794
|
+
const protocolFeePercentage = new Decimal7(protocolShare.toString()).mul(new Decimal7(100)).div(new Decimal7(BASIS_POINT_MAX));
|
|
15068
14795
|
return {
|
|
15069
14796
|
baseFeeRatePercentage,
|
|
15070
14797
|
maxFeeRatePercentage,
|
|
@@ -15096,7 +14823,7 @@ var DLMM = class {
|
|
|
15096
14823
|
sParameters3,
|
|
15097
14824
|
vParameterClone
|
|
15098
14825
|
);
|
|
15099
|
-
return new
|
|
14826
|
+
return new Decimal7(totalFee.toString()).div(new Decimal7(FEE_PRECISION.toString())).mul(100);
|
|
15100
14827
|
}
|
|
15101
14828
|
/**
|
|
15102
14829
|
* The function `getEmissionRate` returns the emission rates for two rewards.
|
|
@@ -15109,8 +14836,8 @@ var DLMM = class {
|
|
|
15109
14836
|
({ rewardRate, rewardDurationEnd }) => now > rewardDurationEnd.toNumber() ? void 0 : rewardRate
|
|
15110
14837
|
);
|
|
15111
14838
|
return {
|
|
15112
|
-
rewardOne: rewardOneEmissionRate ? new
|
|
15113
|
-
rewardTwo: rewardTwoEmissionRate ? new
|
|
14839
|
+
rewardOne: rewardOneEmissionRate ? new Decimal7(rewardOneEmissionRate.toString()).div(PRECISION) : void 0,
|
|
14840
|
+
rewardTwo: rewardTwoEmissionRate ? new Decimal7(rewardTwoEmissionRate.toString()).div(PRECISION) : void 0
|
|
15114
14841
|
};
|
|
15115
14842
|
}
|
|
15116
14843
|
/**
|
|
@@ -15203,8 +14930,8 @@ var DLMM = class {
|
|
|
15203
14930
|
* @returns {string} real price of bin
|
|
15204
14931
|
*/
|
|
15205
14932
|
fromPricePerLamport(pricePerLamport) {
|
|
15206
|
-
return new
|
|
15207
|
-
new
|
|
14933
|
+
return new Decimal7(pricePerLamport).div(
|
|
14934
|
+
new Decimal7(
|
|
15208
14935
|
10 ** (this.tokenY.mint.decimals - this.tokenX.mint.decimals)
|
|
15209
14936
|
)
|
|
15210
14937
|
).toString();
|
|
@@ -15362,12 +15089,12 @@ var DLMM = class {
|
|
|
15362
15089
|
const lowerBinArrayIndex = binIdToBinArrayIndex(currentMinBinId);
|
|
15363
15090
|
const upperBinArrayIndex = binIdToBinArrayIndex(currentMaxBinId);
|
|
15364
15091
|
const binArraysCount = (await this.binArraysToBeCreate(lowerBinArrayIndex, upperBinArrayIndex)).length;
|
|
15365
|
-
const binArrayCost = new
|
|
15366
|
-
new
|
|
15092
|
+
const binArrayCost = new Decimal7(binArraysCount).mul(
|
|
15093
|
+
new Decimal7(BIN_ARRAY_FEE)
|
|
15367
15094
|
);
|
|
15368
15095
|
return {
|
|
15369
|
-
positionExtendCost: new
|
|
15370
|
-
new
|
|
15096
|
+
positionExtendCost: new Decimal7(positionExtendCost).div(
|
|
15097
|
+
new Decimal7(LAMPORTS_PER_SOL2)
|
|
15371
15098
|
),
|
|
15372
15099
|
binArrayCost
|
|
15373
15100
|
};
|
|
@@ -15380,14 +15107,16 @@ var DLMM = class {
|
|
|
15380
15107
|
lowerBinArrayIndex.add(new BN21(1))
|
|
15381
15108
|
);
|
|
15382
15109
|
const binArraysCount = (await this.binArraysToBeCreate(lowerBinArrayIndex, upperBinArrayIndex)).length;
|
|
15383
|
-
const
|
|
15384
|
-
(maxBinId - minBinId + 1) /
|
|
15110
|
+
const positionCount = Math.ceil(
|
|
15111
|
+
(maxBinId - minBinId + 1) / Number(MAX_BINS_PER_POSITION)
|
|
15385
15112
|
);
|
|
15386
15113
|
const binArrayCost = binArraysCount * BIN_ARRAY_FEE;
|
|
15114
|
+
const positionCost = positionCount * POSITION_FEE;
|
|
15387
15115
|
return {
|
|
15388
15116
|
binArraysCount,
|
|
15389
15117
|
binArrayCost,
|
|
15390
|
-
|
|
15118
|
+
positionCount,
|
|
15119
|
+
positionCost
|
|
15391
15120
|
};
|
|
15392
15121
|
}
|
|
15393
15122
|
/**
|
|
@@ -16636,7 +16365,7 @@ var DLMM = class {
|
|
|
16636
16365
|
activeId.toNumber(),
|
|
16637
16366
|
this.lbPair.binStep
|
|
16638
16367
|
);
|
|
16639
|
-
const priceImpact = startPrice.sub(endPrice).abs().div(startPrice).mul(new
|
|
16368
|
+
const priceImpact = startPrice.sub(endPrice).abs().div(startPrice).mul(new Decimal7(100));
|
|
16640
16369
|
actualInAmount = calculateTransferFeeIncludedAmount(
|
|
16641
16370
|
actualInAmount.add(feeAmount),
|
|
16642
16371
|
inMint,
|
|
@@ -16823,7 +16552,7 @@ var DLMM = class {
|
|
|
16823
16552
|
),
|
|
16824
16553
|
swapForY
|
|
16825
16554
|
);
|
|
16826
|
-
const priceImpact = new
|
|
16555
|
+
const priceImpact = new Decimal7(totalOutAmount.toString()).sub(new Decimal7(outAmountWithoutSlippage.toString())).div(new Decimal7(outAmountWithoutSlippage.toString())).mul(new Decimal7(100)).abs();
|
|
16827
16556
|
const endPrice = getPriceOfBinByBinId(
|
|
16828
16557
|
lastFilledActiveBinId.toNumber(),
|
|
16829
16558
|
this.lbPair.binStep
|
|
@@ -17432,11 +17161,11 @@ var DLMM = class {
|
|
|
17432
17161
|
let totalBinArraysCount = new BN21(0);
|
|
17433
17162
|
let totalBinArraysLamports = new BN21(0);
|
|
17434
17163
|
let binArrayBitmapLamports = new BN21(0);
|
|
17435
|
-
const toLamportMultiplier = new
|
|
17164
|
+
const toLamportMultiplier = new Decimal7(
|
|
17436
17165
|
10 ** (this.tokenY.mint.decimals - this.tokenX.mint.decimals)
|
|
17437
17166
|
);
|
|
17438
|
-
const minPricePerLamport = new
|
|
17439
|
-
const maxPricePerLamport = new
|
|
17167
|
+
const minPricePerLamport = new Decimal7(minPrice).mul(toLamportMultiplier);
|
|
17168
|
+
const maxPricePerLamport = new Decimal7(maxPrice).mul(toLamportMultiplier);
|
|
17440
17169
|
const minBinId = new BN21(
|
|
17441
17170
|
DLMM.getBinIdFromPrice(minPricePerLamport, this.lbPair.binStep, false)
|
|
17442
17171
|
);
|
|
@@ -18452,65 +18181,9 @@ var DLMM = class {
|
|
|
18452
18181
|
withdraws,
|
|
18453
18182
|
deposits
|
|
18454
18183
|
);
|
|
18455
|
-
const binArrayQuoteResult = await this.quoteBinArrayAccountsRentalCost(
|
|
18456
|
-
simulationResult.depositParams,
|
|
18457
|
-
simulationResult.withdrawParams,
|
|
18458
|
-
new BN21(rebalancePosition.lbPair.activeId)
|
|
18459
|
-
);
|
|
18460
18184
|
return {
|
|
18461
18185
|
rebalancePosition,
|
|
18462
|
-
simulationResult
|
|
18463
|
-
...binArrayQuoteResult
|
|
18464
|
-
};
|
|
18465
|
-
}
|
|
18466
|
-
async quoteBinArrayAccountsRentalCost(deposits, withdraws, activeId) {
|
|
18467
|
-
const { binArrayBitmap, binArrayIndexes } = getRebalanceBinArrayIndexesAndBitmapCoverage(
|
|
18468
|
-
deposits,
|
|
18469
|
-
withdraws,
|
|
18470
|
-
activeId.toNumber(),
|
|
18471
|
-
this.pubkey,
|
|
18472
|
-
this.program.programId
|
|
18473
|
-
);
|
|
18474
|
-
const binArrayPublicKeys = binArrayIndexes.map((index) => {
|
|
18475
|
-
const [binArrayPubkey] = deriveBinArray(
|
|
18476
|
-
this.pubkey,
|
|
18477
|
-
index,
|
|
18478
|
-
this.program.programId
|
|
18479
|
-
);
|
|
18480
|
-
return binArrayPubkey;
|
|
18481
|
-
});
|
|
18482
|
-
const accountPublicKeys = [...binArrayPublicKeys];
|
|
18483
|
-
if (!binArrayBitmap.equals(PublicKey10.default)) {
|
|
18484
|
-
accountPublicKeys.push(binArrayBitmap);
|
|
18485
|
-
}
|
|
18486
|
-
const accounts = await chunkedGetMultipleAccountInfos(
|
|
18487
|
-
this.program.provider.connection,
|
|
18488
|
-
binArrayPublicKeys
|
|
18489
|
-
);
|
|
18490
|
-
const binArrayAccounts = accounts.splice(0, binArrayPublicKeys.length);
|
|
18491
|
-
let binArrayCount = 0;
|
|
18492
|
-
let bitmapExtensionCost = 0;
|
|
18493
|
-
const binArraySet = /* @__PURE__ */ new Set();
|
|
18494
|
-
for (let i = 0; i < binArrayAccounts.length; i++) {
|
|
18495
|
-
const binArrayAccount = binArrayAccounts[i];
|
|
18496
|
-
const binArrayPubkey = binArrayPublicKeys[i];
|
|
18497
|
-
if (!binArrayAccount) {
|
|
18498
|
-
binArrayCount++;
|
|
18499
|
-
} else {
|
|
18500
|
-
binArraySet.add(binArrayPubkey.toBase58());
|
|
18501
|
-
}
|
|
18502
|
-
}
|
|
18503
|
-
if (!binArrayBitmap.equals(PublicKey10.default)) {
|
|
18504
|
-
const bitmapAccount = accounts.pop();
|
|
18505
|
-
if (!bitmapAccount) {
|
|
18506
|
-
bitmapExtensionCost = BIN_ARRAY_BITMAP_FEE;
|
|
18507
|
-
}
|
|
18508
|
-
}
|
|
18509
|
-
return {
|
|
18510
|
-
binArrayCost: binArrayCount * BIN_ARRAY_FEE,
|
|
18511
|
-
binArrayCount,
|
|
18512
|
-
binArrayExistence: binArraySet,
|
|
18513
|
-
bitmapExtensionCost
|
|
18186
|
+
simulationResult
|
|
18514
18187
|
};
|
|
18515
18188
|
}
|
|
18516
18189
|
/**
|
|
@@ -18540,15 +18213,9 @@ var DLMM = class {
|
|
|
18540
18213
|
withdraws,
|
|
18541
18214
|
deposits
|
|
18542
18215
|
);
|
|
18543
|
-
const binArrayQuoteResult = await this.quoteBinArrayAccountsRentalCost(
|
|
18544
|
-
simulationResult.depositParams,
|
|
18545
|
-
simulationResult.withdrawParams,
|
|
18546
|
-
new BN21(rebalancePosition.lbPair.activeId)
|
|
18547
|
-
);
|
|
18548
18216
|
return {
|
|
18549
18217
|
rebalancePosition,
|
|
18550
|
-
simulationResult
|
|
18551
|
-
...binArrayQuoteResult
|
|
18218
|
+
simulationResult
|
|
18552
18219
|
};
|
|
18553
18220
|
}
|
|
18554
18221
|
/**
|
|
@@ -18565,302 +18232,213 @@ var DLMM = class {
|
|
|
18565
18232
|
const { lbPair, shouldClaimFee, shouldClaimReward, owner, address } = rebalancePosition;
|
|
18566
18233
|
const { depositParams, withdrawParams } = simulationResult;
|
|
18567
18234
|
const activeId = new BN21(lbPair.activeId);
|
|
18568
|
-
|
|
18569
|
-
|
|
18570
|
-
|
|
18571
|
-
|
|
18572
|
-
const
|
|
18573
|
-
|
|
18574
|
-
|
|
18575
|
-
|
|
18576
|
-
|
|
18577
|
-
|
|
18578
|
-
|
|
18579
|
-
|
|
18580
|
-
|
|
18581
|
-
|
|
18582
|
-
|
|
18583
|
-
|
|
18584
|
-
|
|
18585
|
-
|
|
18586
|
-
|
|
18587
|
-
|
|
18588
|
-
|
|
18589
|
-
|
|
18590
|
-
|
|
18591
|
-
|
|
18592
|
-
|
|
18593
|
-
|
|
18594
|
-
continue;
|
|
18595
|
-
const newMin = Math.max(absMin, chunk.lowerBinId);
|
|
18596
|
-
const newMax = Math.min(absMax, chunk.upperBinId);
|
|
18597
|
-
res.push({
|
|
18598
|
-
...param,
|
|
18599
|
-
minDeltaId: newMin - activeId2.toNumber(),
|
|
18600
|
-
maxDeltaId: newMax - activeId2.toNumber()
|
|
18601
|
-
});
|
|
18602
|
-
}
|
|
18603
|
-
return res;
|
|
18604
|
-
}
|
|
18605
|
-
function splitWithdrawParamsForChunk(params, chunk) {
|
|
18606
|
-
const res = [];
|
|
18607
|
-
for (const param of params) {
|
|
18608
|
-
const absMin = param.minBinId !== null ? param.minBinId : activeId.toNumber();
|
|
18609
|
-
const absMax = param.maxBinId !== null ? param.maxBinId : activeId.toNumber();
|
|
18610
|
-
if (absMax < chunk.lowerBinId || absMin > chunk.upperBinId)
|
|
18611
|
-
continue;
|
|
18612
|
-
const newMin = Math.max(absMin, chunk.lowerBinId);
|
|
18613
|
-
const newMax = Math.min(absMax, chunk.upperBinId);
|
|
18614
|
-
res.push({
|
|
18615
|
-
...param,
|
|
18616
|
-
minBinId: newMin,
|
|
18617
|
-
maxBinId: newMax
|
|
18618
|
-
});
|
|
18619
|
-
}
|
|
18620
|
-
return res;
|
|
18621
|
-
}
|
|
18622
|
-
const allInstructions = [];
|
|
18623
|
-
for (const chunk of binChunks) {
|
|
18624
|
-
const chunkedDepositParams = splitDepositParamsForChunk(
|
|
18625
|
-
depositParams,
|
|
18626
|
-
chunk,
|
|
18627
|
-
activeId
|
|
18628
|
-
);
|
|
18629
|
-
const chunkedWithdrawParams = splitWithdrawParamsForChunk(
|
|
18630
|
-
withdrawParams,
|
|
18631
|
-
chunk
|
|
18632
|
-
);
|
|
18633
|
-
if (chunkedDepositParams.length === 0 && chunkedWithdrawParams.length === 0)
|
|
18634
|
-
continue;
|
|
18635
|
-
const { slices, accounts: transferHookAccounts } = this.getPotentialToken2022IxDataAndAccounts(0 /* Liquidity */);
|
|
18636
|
-
const preInstructions = [];
|
|
18637
|
-
const harvestRewardRemainingAccountMetas = [];
|
|
18638
|
-
if (shouldClaimReward) {
|
|
18639
|
-
for (const [idx, reward] of this.lbPair.rewardInfos.entries()) {
|
|
18640
|
-
if (!reward.mint.equals(PublicKey10.default)) {
|
|
18641
|
-
const rewardTokenInfo = this.rewards[idx];
|
|
18642
|
-
slices.push({
|
|
18643
|
-
accountsType: {
|
|
18644
|
-
transferHookMultiReward: {
|
|
18645
|
-
0: idx
|
|
18646
|
-
}
|
|
18647
|
-
},
|
|
18648
|
-
length: rewardTokenInfo.transferHookAccountMetas.length
|
|
18649
|
-
});
|
|
18650
|
-
transferHookAccounts.push(
|
|
18651
|
-
...rewardTokenInfo.transferHookAccountMetas
|
|
18652
|
-
);
|
|
18653
|
-
const userTokenRewardAddress = getAssociatedTokenAddressSync2(
|
|
18654
|
-
reward.mint,
|
|
18235
|
+
const { slices, accounts: transferHookAccounts } = this.getPotentialToken2022IxDataAndAccounts(0 /* Liquidity */);
|
|
18236
|
+
const preInstructions = [];
|
|
18237
|
+
const harvestRewardRemainingAccountMetas = [];
|
|
18238
|
+
if (shouldClaimReward) {
|
|
18239
|
+
for (const [idx, reward] of this.lbPair.rewardInfos.entries()) {
|
|
18240
|
+
if (!reward.mint.equals(PublicKey10.default)) {
|
|
18241
|
+
const rewardTokenInfo = this.rewards[idx];
|
|
18242
|
+
slices.push({
|
|
18243
|
+
accountsType: {
|
|
18244
|
+
transferHookMultiReward: {
|
|
18245
|
+
0: idx
|
|
18246
|
+
}
|
|
18247
|
+
},
|
|
18248
|
+
length: rewardTokenInfo.transferHookAccountMetas.length
|
|
18249
|
+
});
|
|
18250
|
+
transferHookAccounts.push(
|
|
18251
|
+
...rewardTokenInfo.transferHookAccountMetas
|
|
18252
|
+
);
|
|
18253
|
+
const userTokenRewardAddress = getAssociatedTokenAddressSync2(
|
|
18254
|
+
reward.mint,
|
|
18255
|
+
owner,
|
|
18256
|
+
true,
|
|
18257
|
+
rewardTokenInfo.owner
|
|
18258
|
+
);
|
|
18259
|
+
preInstructions.push(
|
|
18260
|
+
createAssociatedTokenAccountIdempotentInstruction2(
|
|
18655
18261
|
owner,
|
|
18656
|
-
|
|
18262
|
+
userTokenRewardAddress,
|
|
18263
|
+
owner,
|
|
18264
|
+
reward.mint,
|
|
18657
18265
|
rewardTokenInfo.owner
|
|
18658
|
-
)
|
|
18659
|
-
|
|
18660
|
-
|
|
18661
|
-
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
|
|
18665
|
-
|
|
18666
|
-
|
|
18667
|
-
|
|
18668
|
-
|
|
18669
|
-
|
|
18670
|
-
|
|
18671
|
-
|
|
18672
|
-
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
|
|
18676
|
-
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18680
|
-
|
|
18681
|
-
|
|
18682
|
-
|
|
18683
|
-
|
|
18684
|
-
|
|
18685
|
-
|
|
18686
|
-
isWritable: false
|
|
18687
|
-
};
|
|
18688
|
-
harvestRewardRemainingAccountMetas.push(
|
|
18689
|
-
rewardVault,
|
|
18690
|
-
userTokenReward,
|
|
18691
|
-
rewardMint,
|
|
18692
|
-
rewardTokenProgram
|
|
18693
|
-
);
|
|
18694
|
-
}
|
|
18266
|
+
)
|
|
18267
|
+
);
|
|
18268
|
+
const rewardVault = {
|
|
18269
|
+
pubkey: reward.vault,
|
|
18270
|
+
isSigner: false,
|
|
18271
|
+
isWritable: true
|
|
18272
|
+
};
|
|
18273
|
+
const userTokenReward = {
|
|
18274
|
+
pubkey: userTokenRewardAddress,
|
|
18275
|
+
isSigner: false,
|
|
18276
|
+
isWritable: true
|
|
18277
|
+
};
|
|
18278
|
+
const rewardMint = {
|
|
18279
|
+
pubkey: reward.mint,
|
|
18280
|
+
isSigner: false,
|
|
18281
|
+
isWritable: false
|
|
18282
|
+
};
|
|
18283
|
+
const rewardTokenProgram = {
|
|
18284
|
+
pubkey: rewardTokenInfo.owner,
|
|
18285
|
+
isSigner: false,
|
|
18286
|
+
isWritable: false
|
|
18287
|
+
};
|
|
18288
|
+
harvestRewardRemainingAccountMetas.push(
|
|
18289
|
+
rewardVault,
|
|
18290
|
+
userTokenReward,
|
|
18291
|
+
rewardMint,
|
|
18292
|
+
rewardTokenProgram
|
|
18293
|
+
);
|
|
18695
18294
|
}
|
|
18696
18295
|
}
|
|
18697
|
-
|
|
18698
|
-
|
|
18699
|
-
|
|
18700
|
-
|
|
18701
|
-
|
|
18296
|
+
}
|
|
18297
|
+
const initBinArrayInstructions = [];
|
|
18298
|
+
const { binArrayBitmap, binArrayIndexes } = getRebalanceBinArrayIndexesAndBitmapCoverage(
|
|
18299
|
+
depositParams,
|
|
18300
|
+
withdrawParams,
|
|
18301
|
+
activeId.toNumber(),
|
|
18302
|
+
this.pubkey,
|
|
18303
|
+
this.program.programId
|
|
18304
|
+
);
|
|
18305
|
+
const binArrayPublicKeys = binArrayIndexes.map((index) => {
|
|
18306
|
+
const [binArrayPubkey] = deriveBinArray(
|
|
18702
18307
|
this.pubkey,
|
|
18308
|
+
index,
|
|
18703
18309
|
this.program.programId
|
|
18704
18310
|
);
|
|
18705
|
-
|
|
18706
|
-
|
|
18707
|
-
|
|
18708
|
-
|
|
18709
|
-
|
|
18710
|
-
|
|
18711
|
-
|
|
18712
|
-
|
|
18713
|
-
|
|
18714
|
-
|
|
18715
|
-
|
|
18716
|
-
|
|
18717
|
-
|
|
18718
|
-
|
|
18719
|
-
|
|
18720
|
-
|
|
18721
|
-
|
|
18722
|
-
const initBinArrayIx = await this.program.methods.initializeBinArray(binArrayIndex).accountsPartial({
|
|
18723
|
-
binArray: binArrayPubkey,
|
|
18724
|
-
funder: owner,
|
|
18725
|
-
lbPair: this.pubkey
|
|
18726
|
-
}).instruction();
|
|
18727
|
-
initBinArrayInstructions.push(initBinArrayIx);
|
|
18728
|
-
}
|
|
18729
|
-
}
|
|
18730
|
-
if (!binArrayBitmap.equals(PublicKey10.default)) {
|
|
18731
|
-
const bitmapAccount = await this.program.provider.connection.getAccountInfo(binArrayBitmap);
|
|
18732
|
-
if (!bitmapAccount) {
|
|
18733
|
-
const initBitmapExtensionIx = await this.program.methods.initializeBinArrayBitmapExtension().accountsPartial({
|
|
18734
|
-
binArrayBitmapExtension: binArrayBitmap,
|
|
18735
|
-
funder: owner,
|
|
18736
|
-
lbPair: this.pubkey
|
|
18737
|
-
}).preInstructions([
|
|
18738
|
-
ComputeBudgetProgram3.setComputeUnitLimit({
|
|
18739
|
-
units: DEFAULT_INIT_BIN_ARRAY_CU
|
|
18740
|
-
})
|
|
18741
|
-
]).instruction();
|
|
18742
|
-
preInstructions.push(initBitmapExtensionIx);
|
|
18743
|
-
}
|
|
18744
|
-
}
|
|
18745
|
-
const [
|
|
18746
|
-
{ ataPubKey: userTokenX, ix: createUserTokenXIx },
|
|
18747
|
-
{ ataPubKey: userTokenY, ix: createUserTokenYIx }
|
|
18748
|
-
] = await Promise.all([
|
|
18749
|
-
getOrCreateATAInstruction(
|
|
18750
|
-
this.program.provider.connection,
|
|
18751
|
-
this.tokenX.publicKey,
|
|
18752
|
-
owner,
|
|
18753
|
-
this.tokenX.owner
|
|
18754
|
-
),
|
|
18755
|
-
getOrCreateATAInstruction(
|
|
18756
|
-
this.program.provider.connection,
|
|
18757
|
-
this.tokenY.publicKey,
|
|
18758
|
-
owner,
|
|
18759
|
-
this.tokenY.owner
|
|
18760
|
-
)
|
|
18761
|
-
]);
|
|
18762
|
-
createUserTokenXIx && preInstructions.push(createUserTokenXIx);
|
|
18763
|
-
createUserTokenYIx && preInstructions.push(createUserTokenYIx);
|
|
18764
|
-
slippage = capSlippagePercentage(slippage);
|
|
18765
|
-
const applySlippageMaxAmount = (amount, slippage2) => {
|
|
18766
|
-
return slippage2 == 100 ? U64_MAX : amount.muln(100 + slippage2).divn(100);
|
|
18767
|
-
};
|
|
18768
|
-
const applySlippageMinAmount = (amount, slippage2) => {
|
|
18769
|
-
return amount.muln(100 - slippage2).divn(100);
|
|
18770
|
-
};
|
|
18771
|
-
const maxDepositXAmount = applySlippageMaxAmount(
|
|
18772
|
-
simulationResult.actualAmountXDeposited,
|
|
18773
|
-
slippage
|
|
18774
|
-
);
|
|
18775
|
-
const maxDepositYAmount = applySlippageMaxAmount(
|
|
18776
|
-
simulationResult.actualAmountYDeposited,
|
|
18777
|
-
slippage
|
|
18778
|
-
);
|
|
18779
|
-
const minWithdrawXAmount = applySlippageMinAmount(
|
|
18780
|
-
simulationResult.actualAmountXWithdrawn,
|
|
18781
|
-
slippage
|
|
18782
|
-
);
|
|
18783
|
-
const minWithdrawYAmount = applySlippageMinAmount(
|
|
18784
|
-
simulationResult.actualAmountYWithdrawn,
|
|
18785
|
-
slippage
|
|
18786
|
-
);
|
|
18787
|
-
const postInstructions = [];
|
|
18788
|
-
if (this.tokenX.publicKey.equals(NATIVE_MINT2) && simulationResult.actualAmountXDeposited.gtn(0)) {
|
|
18789
|
-
const wrapSOLIx = wrapSOLInstruction(
|
|
18790
|
-
owner,
|
|
18791
|
-
userTokenX,
|
|
18792
|
-
BigInt(simulationResult.actualAmountXDeposited.toString())
|
|
18793
|
-
);
|
|
18794
|
-
preInstructions.push(...wrapSOLIx);
|
|
18795
|
-
}
|
|
18796
|
-
if (this.tokenY.publicKey.equals(NATIVE_MINT2) && simulationResult.actualAmountYDeposited.gtn(0)) {
|
|
18797
|
-
const wrapSOLIx = wrapSOLInstruction(
|
|
18798
|
-
owner,
|
|
18799
|
-
userTokenY,
|
|
18800
|
-
BigInt(simulationResult.actualAmountYDeposited.toString())
|
|
18801
|
-
);
|
|
18802
|
-
preInstructions.push(...wrapSOLIx);
|
|
18311
|
+
return binArrayPubkey;
|
|
18312
|
+
});
|
|
18313
|
+
const binArrayAccounts = await chunkedGetMultipleAccountInfos(
|
|
18314
|
+
this.program.provider.connection,
|
|
18315
|
+
binArrayPublicKeys
|
|
18316
|
+
);
|
|
18317
|
+
for (let i = 0; i < binArrayAccounts.length; i++) {
|
|
18318
|
+
const binArrayAccount = binArrayAccounts[i];
|
|
18319
|
+
if (!binArrayAccount) {
|
|
18320
|
+
const binArrayPubkey = binArrayPublicKeys[i];
|
|
18321
|
+
const binArrayIndex = binArrayIndexes[i];
|
|
18322
|
+
const initBinArrayIx = await this.program.methods.initializeBinArray(binArrayIndex).accountsPartial({
|
|
18323
|
+
binArray: binArrayPubkey,
|
|
18324
|
+
funder: owner,
|
|
18325
|
+
lbPair: this.pubkey
|
|
18326
|
+
}).instruction();
|
|
18327
|
+
initBinArrayInstructions.push(initBinArrayIx);
|
|
18803
18328
|
}
|
|
18804
|
-
|
|
18805
|
-
|
|
18806
|
-
|
|
18329
|
+
}
|
|
18330
|
+
if (!binArrayBitmap.equals(PublicKey10.default)) {
|
|
18331
|
+
const bitmapAccount = await this.program.provider.connection.getAccountInfo(binArrayBitmap);
|
|
18332
|
+
if (!bitmapAccount) {
|
|
18333
|
+
const initBitmapExtensionIx = await this.program.methods.initializeBinArrayBitmapExtension().accountsPartial({
|
|
18334
|
+
binArrayBitmapExtension: binArrayBitmap,
|
|
18335
|
+
funder: owner,
|
|
18336
|
+
lbPair: this.pubkey
|
|
18337
|
+
}).preInstructions([
|
|
18338
|
+
ComputeBudgetProgram3.setComputeUnitLimit({
|
|
18339
|
+
units: DEFAULT_INIT_BIN_ARRAY_CU
|
|
18340
|
+
})
|
|
18341
|
+
]).instruction();
|
|
18342
|
+
preInstructions.push(initBitmapExtensionIx);
|
|
18807
18343
|
}
|
|
18808
|
-
|
|
18809
|
-
|
|
18810
|
-
|
|
18811
|
-
|
|
18812
|
-
|
|
18813
|
-
|
|
18814
|
-
|
|
18815
|
-
|
|
18816
|
-
maxDepositXAmount,
|
|
18817
|
-
maxDepositYAmount,
|
|
18818
|
-
minWithdrawXAmount,
|
|
18819
|
-
minWithdrawYAmount,
|
|
18820
|
-
padding: Array(32).fill(0)
|
|
18821
|
-
},
|
|
18822
|
-
{
|
|
18823
|
-
slices
|
|
18824
|
-
}
|
|
18825
|
-
).accountsPartial({
|
|
18826
|
-
lbPair: this.pubkey,
|
|
18827
|
-
binArrayBitmapExtension: binArrayBitmap,
|
|
18828
|
-
position: address,
|
|
18344
|
+
}
|
|
18345
|
+
const [
|
|
18346
|
+
{ ataPubKey: userTokenX, ix: createUserTokenXIx },
|
|
18347
|
+
{ ataPubKey: userTokenY, ix: createUserTokenYIx }
|
|
18348
|
+
] = await Promise.all([
|
|
18349
|
+
getOrCreateATAInstruction(
|
|
18350
|
+
this.program.provider.connection,
|
|
18351
|
+
this.tokenX.publicKey,
|
|
18829
18352
|
owner,
|
|
18830
|
-
|
|
18831
|
-
|
|
18832
|
-
|
|
18833
|
-
reserveY: this.lbPair.reserveY,
|
|
18834
|
-
tokenXMint: this.tokenX.publicKey,
|
|
18835
|
-
tokenYMint: this.tokenY.publicKey,
|
|
18836
|
-
tokenXProgram: this.tokenX.owner,
|
|
18837
|
-
tokenYProgram: this.tokenY.owner,
|
|
18838
|
-
memoProgram: MEMO_PROGRAM_ID,
|
|
18839
|
-
rentPayer: rentPayer ?? owner
|
|
18840
|
-
}).remainingAccounts(transferHookAccounts).remainingAccounts(
|
|
18841
|
-
binArrayPublicKeys.map((pubkey) => {
|
|
18842
|
-
return {
|
|
18843
|
-
pubkey,
|
|
18844
|
-
isSigner: false,
|
|
18845
|
-
isWritable: true
|
|
18846
|
-
};
|
|
18847
|
-
})
|
|
18848
|
-
).instruction();
|
|
18849
|
-
const setCUIX = await getEstimatedComputeUnitIxWithBuffer(
|
|
18353
|
+
this.tokenX.owner
|
|
18354
|
+
),
|
|
18355
|
+
getOrCreateATAInstruction(
|
|
18850
18356
|
this.program.provider.connection,
|
|
18851
|
-
|
|
18852
|
-
owner
|
|
18853
|
-
|
|
18854
|
-
|
|
18855
|
-
|
|
18856
|
-
|
|
18857
|
-
|
|
18858
|
-
|
|
18859
|
-
|
|
18860
|
-
|
|
18861
|
-
|
|
18862
|
-
|
|
18863
|
-
|
|
18357
|
+
this.tokenY.publicKey,
|
|
18358
|
+
owner,
|
|
18359
|
+
this.tokenY.owner
|
|
18360
|
+
)
|
|
18361
|
+
]);
|
|
18362
|
+
createUserTokenXIx && preInstructions.push(createUserTokenXIx);
|
|
18363
|
+
createUserTokenYIx && preInstructions.push(createUserTokenYIx);
|
|
18364
|
+
slippage = capSlippagePercentage(slippage);
|
|
18365
|
+
const applySlippageMaxAmount = (amount, slippage2) => {
|
|
18366
|
+
return slippage2 == 100 ? U64_MAX : amount.muln(100 + slippage2).divn(100);
|
|
18367
|
+
};
|
|
18368
|
+
const applySlippageMinAmount = (amount, slippage2) => {
|
|
18369
|
+
return amount.muln(100 - slippage2).divn(100);
|
|
18370
|
+
};
|
|
18371
|
+
const maxDepositXAmount = applySlippageMaxAmount(
|
|
18372
|
+
simulationResult.actualAmountXDeposited,
|
|
18373
|
+
slippage
|
|
18374
|
+
);
|
|
18375
|
+
const maxDepositYAmount = applySlippageMaxAmount(
|
|
18376
|
+
simulationResult.actualAmountYDeposited,
|
|
18377
|
+
slippage
|
|
18378
|
+
);
|
|
18379
|
+
const minWithdrawXAmount = applySlippageMinAmount(
|
|
18380
|
+
simulationResult.actualAmountXWithdrawn,
|
|
18381
|
+
slippage
|
|
18382
|
+
);
|
|
18383
|
+
const minWithdrawYAmount = applySlippageMinAmount(
|
|
18384
|
+
simulationResult.actualAmountYWithdrawn,
|
|
18385
|
+
slippage
|
|
18386
|
+
);
|
|
18387
|
+
const instruction = await this.program.methods.rebalanceLiquidity(
|
|
18388
|
+
{
|
|
18389
|
+
adds: depositParams,
|
|
18390
|
+
removes: withdrawParams,
|
|
18391
|
+
activeId: activeId.toNumber(),
|
|
18392
|
+
shouldClaimFee,
|
|
18393
|
+
shouldClaimReward,
|
|
18394
|
+
maxActiveBinSlippage: maxActiveBinSlippage.toNumber(),
|
|
18395
|
+
maxDepositXAmount,
|
|
18396
|
+
maxDepositYAmount,
|
|
18397
|
+
minWithdrawXAmount,
|
|
18398
|
+
minWithdrawYAmount,
|
|
18399
|
+
padding: Array(32).fill(0)
|
|
18400
|
+
},
|
|
18401
|
+
{
|
|
18402
|
+
slices
|
|
18403
|
+
}
|
|
18404
|
+
).accountsPartial({
|
|
18405
|
+
lbPair: this.pubkey,
|
|
18406
|
+
binArrayBitmapExtension: binArrayBitmap,
|
|
18407
|
+
position: address,
|
|
18408
|
+
owner,
|
|
18409
|
+
userTokenX,
|
|
18410
|
+
userTokenY,
|
|
18411
|
+
reserveX: this.lbPair.reserveX,
|
|
18412
|
+
reserveY: this.lbPair.reserveY,
|
|
18413
|
+
tokenXMint: this.tokenX.publicKey,
|
|
18414
|
+
tokenYMint: this.tokenY.publicKey,
|
|
18415
|
+
tokenXProgram: this.tokenX.owner,
|
|
18416
|
+
tokenYProgram: this.tokenY.owner,
|
|
18417
|
+
memoProgram: MEMO_PROGRAM_ID,
|
|
18418
|
+
rentPayer: rentPayer ?? owner
|
|
18419
|
+
}).remainingAccounts(transferHookAccounts).remainingAccounts(
|
|
18420
|
+
binArrayPublicKeys.map((pubkey) => {
|
|
18421
|
+
return {
|
|
18422
|
+
pubkey,
|
|
18423
|
+
isSigner: false,
|
|
18424
|
+
isWritable: true
|
|
18425
|
+
};
|
|
18426
|
+
})
|
|
18427
|
+
).instruction();
|
|
18428
|
+
const setCUIX = await getEstimatedComputeUnitIxWithBuffer(
|
|
18429
|
+
this.program.provider.connection,
|
|
18430
|
+
[instruction],
|
|
18431
|
+
owner
|
|
18432
|
+
);
|
|
18433
|
+
const rebalancePositionInstruction = [
|
|
18434
|
+
setCUIX,
|
|
18435
|
+
...preInstructions,
|
|
18436
|
+
instruction
|
|
18437
|
+
];
|
|
18438
|
+
return {
|
|
18439
|
+
initBinArrayInstructions,
|
|
18440
|
+
rebalancePositionInstruction
|
|
18441
|
+
};
|
|
18864
18442
|
}
|
|
18865
18443
|
/**
|
|
18866
18444
|
* Create an extended empty position.
|
|
@@ -18886,8 +18464,7 @@ var DLMM = class {
|
|
|
18886
18464
|
);
|
|
18887
18465
|
const latestBlockhashInfo = await this.program.provider.connection.getLatestBlockhash();
|
|
18888
18466
|
const tx = new Transaction({
|
|
18889
|
-
...latestBlockhashInfo
|
|
18890
|
-
feePayer: owner
|
|
18467
|
+
...latestBlockhashInfo
|
|
18891
18468
|
}).add(...ixs);
|
|
18892
18469
|
return tx;
|
|
18893
18470
|
}
|
|
@@ -18995,8 +18572,8 @@ var DLMM = class {
|
|
|
18995
18572
|
if (!bins.length)
|
|
18996
18573
|
return null;
|
|
18997
18574
|
const positionData = [];
|
|
18998
|
-
let totalXAmount = new
|
|
18999
|
-
let totalYAmount = new
|
|
18575
|
+
let totalXAmount = new Decimal7(0);
|
|
18576
|
+
let totalYAmount = new Decimal7(0);
|
|
19000
18577
|
const ZERO = new BN21(0);
|
|
19001
18578
|
let feeX = ZERO;
|
|
19002
18579
|
let feeY = ZERO;
|
|
@@ -19007,8 +18584,8 @@ var DLMM = class {
|
|
|
19007
18584
|
const posBinRewardInfo = positionRewardInfos[idx];
|
|
19008
18585
|
const positionXAmount = binSupply.eq(ZERO) ? ZERO : posShare.mul(bin.xAmount).div(binSupply);
|
|
19009
18586
|
const positionYAmount = binSupply.eq(ZERO) ? ZERO : posShare.mul(bin.yAmount).div(binSupply);
|
|
19010
|
-
totalXAmount = totalXAmount.add(new
|
|
19011
|
-
totalYAmount = totalYAmount.add(new
|
|
18587
|
+
totalXAmount = totalXAmount.add(new Decimal7(positionXAmount.toString()));
|
|
18588
|
+
totalYAmount = totalYAmount.add(new Decimal7(positionYAmount.toString()));
|
|
19012
18589
|
const feeInfo = feeInfos[idx];
|
|
19013
18590
|
const newFeeX = mulShr(
|
|
19014
18591
|
posShares[idx].shrn(SCALE_OFFSET),
|
|
@@ -19172,7 +18749,7 @@ var DLMM = class {
|
|
|
19172
18749
|
rewardPerTokenStored: [ZERO, ZERO],
|
|
19173
18750
|
price: pricePerLamport,
|
|
19174
18751
|
version: 2,
|
|
19175
|
-
pricePerToken: new
|
|
18752
|
+
pricePerToken: new Decimal7(pricePerLamport).mul(new Decimal7(10 ** (baseTokenDecimal - quoteTokenDecimal))).toString()
|
|
19176
18753
|
});
|
|
19177
18754
|
} else {
|
|
19178
18755
|
const bin = binArray.bins[i];
|
|
@@ -19186,7 +18763,7 @@ var DLMM = class {
|
|
|
19186
18763
|
rewardPerTokenStored: bin.rewardPerTokenStored,
|
|
19187
18764
|
price: pricePerLamport,
|
|
19188
18765
|
version: binArray.version,
|
|
19189
|
-
pricePerToken: new
|
|
18766
|
+
pricePerToken: new Decimal7(pricePerLamport).mul(new Decimal7(10 ** (baseTokenDecimal - quoteTokenDecimal))).toString()
|
|
19190
18767
|
});
|
|
19191
18768
|
}
|
|
19192
18769
|
}
|
|
@@ -19545,7 +19122,6 @@ export {
|
|
|
19545
19122
|
PairStatus,
|
|
19546
19123
|
PairType,
|
|
19547
19124
|
PositionVersion,
|
|
19548
|
-
RebalancePosition,
|
|
19549
19125
|
ResizeSide,
|
|
19550
19126
|
SCALE,
|
|
19551
19127
|
SCALE_OFFSET,
|
|
@@ -19560,7 +19136,6 @@ export {
|
|
|
19560
19136
|
autoFillYByStrategy,
|
|
19561
19137
|
autoFillYByWeight,
|
|
19562
19138
|
binIdToBinArrayIndex,
|
|
19563
|
-
buildLiquidityStrategyParameters,
|
|
19564
19139
|
calculateBidAskDistribution,
|
|
19565
19140
|
calculateNormalDistribution,
|
|
19566
19141
|
calculateSpotDistribution,
|
|
@@ -19597,9 +19172,6 @@ export {
|
|
|
19597
19172
|
fromWeightDistributionToAmount,
|
|
19598
19173
|
fromWeightDistributionToAmountOneSide,
|
|
19599
19174
|
getAccountDiscriminator,
|
|
19600
|
-
getAmountInBinsAskSide,
|
|
19601
|
-
getAmountInBinsBidSide,
|
|
19602
|
-
getAutoFillAmountByRebalancedPosition,
|
|
19603
19175
|
getBaseFee,
|
|
19604
19176
|
getBinArrayLowerUpperBinId,
|
|
19605
19177
|
getBinArraysRequiredByPositionRange,
|
|
@@ -19607,11 +19179,9 @@ export {
|
|
|
19607
19179
|
getBinIdIndexInBinArray,
|
|
19608
19180
|
getEstimatedComputeUnitIxWithBuffer,
|
|
19609
19181
|
getEstimatedComputeUnitUsageWithBuffer,
|
|
19610
|
-
getLiquidityStrategyParameterBuilder,
|
|
19611
19182
|
getOrCreateATAInstruction,
|
|
19612
19183
|
getOutAmount,
|
|
19613
19184
|
getPriceOfBinByBinId,
|
|
19614
|
-
getRebalanceBinArrayIndexesAndBitmapCoverage,
|
|
19615
19185
|
getTokenBalance,
|
|
19616
19186
|
getTokenDecimals,
|
|
19617
19187
|
getTokenProgramId,
|
|
@@ -19622,14 +19192,11 @@ export {
|
|
|
19622
19192
|
isOverflowDefaultBinArrayBitmap,
|
|
19623
19193
|
parseLogs,
|
|
19624
19194
|
range,
|
|
19625
|
-
suggestBalancedXParametersFromY,
|
|
19626
|
-
suggestBalancedYParametersFromX,
|
|
19627
19195
|
swapExactInQuoteAtBin,
|
|
19628
19196
|
swapExactOutQuoteAtBin,
|
|
19629
19197
|
toAmountAskSide,
|
|
19630
19198
|
toAmountBidSide,
|
|
19631
19199
|
toAmountBothSide,
|
|
19632
|
-
toAmountIntoBins,
|
|
19633
19200
|
toAmountsBothSideByStrategy,
|
|
19634
19201
|
toStrategyParameters,
|
|
19635
19202
|
toWeightDistribution,
|