@meteora-ag/dlmm 1.6.0-rc.18 → 1.6.0-rc.20
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 +46 -1
- package/dist/index.js +1729 -1570
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1244 -1085
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -11779,645 +11779,190 @@ function getTokenProgramId(lbPairState) {
|
|
|
11779
11779
|
};
|
|
11780
11780
|
}
|
|
11781
11781
|
|
|
11782
|
-
// src/dlmm/helpers/
|
|
11783
|
-
|
|
11784
|
-
|
|
11785
|
-
|
|
11782
|
+
// src/dlmm/helpers/rebalance/rebalancePosition.ts
|
|
11783
|
+
import { SYSVAR_CLOCK_PUBKEY } from "@solana/web3.js";
|
|
11784
|
+
import BN11 from "bn.js";
|
|
11785
|
+
import Decimal6 from "decimal.js";
|
|
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
|
+
}
|
|
11786
11837
|
);
|
|
11787
11838
|
}
|
|
11788
|
-
function
|
|
11789
|
-
const
|
|
11790
|
-
|
|
11839
|
+
function getDepositBinIds(activeId, deposits) {
|
|
11840
|
+
const uniqueBinId = /* @__PURE__ */ new Set();
|
|
11841
|
+
for (const { minDeltaId, maxDeltaId } of deposits) {
|
|
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;
|
|
11791
11851
|
}
|
|
11792
|
-
|
|
11793
|
-
|
|
11794
|
-
|
|
11795
|
-
|
|
11796
|
-
)
|
|
11797
|
-
|
|
11798
|
-
|
|
11852
|
+
function findMinMaxBinIdWithLiquidity(rebalancePositionBinData) {
|
|
11853
|
+
let minBinId = null;
|
|
11854
|
+
let maxBinId = null;
|
|
11855
|
+
for (const binData of rebalancePositionBinData) {
|
|
11856
|
+
if (binData.amountX.isZero() && binData.amountY.isZero() && binData.claimableFeeXAmount.isZero() && binData.claimableFeeYAmount.isZero() && binData.claimableRewardAmount.every((amount) => amount.isZero())) {
|
|
11857
|
+
continue;
|
|
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];
|
|
11799
11867
|
}
|
|
11800
|
-
|
|
11801
|
-
|
|
11802
|
-
|
|
11803
|
-
|
|
11804
|
-
|
|
11805
|
-
)).flat();
|
|
11806
|
-
return accounts;
|
|
11868
|
+
function onlyDepositToBidSide(maxDeltaId, favorXInActiveBin) {
|
|
11869
|
+
if (favorXInActiveBin) {
|
|
11870
|
+
return maxDeltaId.lt(new BN11(0));
|
|
11871
|
+
}
|
|
11872
|
+
return maxDeltaId.lte(new BN11(0));
|
|
11807
11873
|
}
|
|
11808
|
-
function
|
|
11809
|
-
|
|
11874
|
+
function onlyDepositToAskSide(minDeltaId, favorXInActiveBin) {
|
|
11875
|
+
if (favorXInActiveBin) {
|
|
11876
|
+
return minDeltaId.gte(new BN11(0));
|
|
11877
|
+
}
|
|
11878
|
+
return minDeltaId.gt(new BN11(0));
|
|
11810
11879
|
}
|
|
11811
|
-
|
|
11812
|
-
const
|
|
11813
|
-
|
|
11880
|
+
function getAmountInBinsBidSide(activeId, minDeltaId, maxDeltaId, deltaY, y0) {
|
|
11881
|
+
const amountInBins = [];
|
|
11882
|
+
const minBinId = activeId.add(minDeltaId);
|
|
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;
|
|
11814
11895
|
}
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
const
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
|
|
11825
|
-
|
|
11826
|
-
|
|
11827
|
-
|
|
11828
|
-
|
|
11829
|
-
|
|
11830
|
-
|
|
11831
|
-
|
|
11832
|
-
|
|
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
|
-
}
|
|
11896
|
+
function getAmountInBinsAskSide(activeId, binStep, minDeltaId, maxDeltaId, deltaX, x0) {
|
|
11897
|
+
const binCount = maxDeltaId.sub(minDeltaId).add(new BN11(1));
|
|
11898
|
+
const minBinId = activeId.add(minDeltaId);
|
|
11899
|
+
const maxBinId = activeId.add(maxDeltaId);
|
|
11900
|
+
const amountInBins = new Array(binCount.toNumber());
|
|
11901
|
+
const base = getQPriceBaseFactor(binStep);
|
|
11902
|
+
let inverseBasePrice = pow(base, maxBinId.neg());
|
|
11903
|
+
for (let binId = maxBinId.toNumber(); binId >= minBinId.toNumber(); binId--) {
|
|
11904
|
+
const delta = binId - activeId.toNumber();
|
|
11905
|
+
const totalDeltaX = deltaX.mul(new BN11(delta));
|
|
11906
|
+
const amountX = x0.add(totalDeltaX).mul(inverseBasePrice).shrn(SCALE_OFFSET);
|
|
11907
|
+
const idx = binId - minBinId.toNumber();
|
|
11908
|
+
amountInBins[idx] = {
|
|
11909
|
+
binId: new BN11(binId),
|
|
11910
|
+
amountX,
|
|
11911
|
+
amountY: new BN11(0)
|
|
11912
|
+
};
|
|
11913
|
+
inverseBasePrice = inverseBasePrice.mul(base).shrn(SCALE_OFFSET);
|
|
11842
11914
|
}
|
|
11843
|
-
|
|
11844
|
-
async function getTokenBalance(conn, tokenAccount) {
|
|
11845
|
-
const acc = await getAccount(conn, tokenAccount);
|
|
11846
|
-
return acc.amount;
|
|
11915
|
+
return amountInBins;
|
|
11847
11916
|
}
|
|
11848
|
-
|
|
11849
|
-
if (
|
|
11850
|
-
|
|
11851
|
-
for (const event of eventParser?.parseLogs(logs)) {
|
|
11852
|
-
return event.data;
|
|
11917
|
+
function toAmountIntoBins(activeId, minDeltaId, maxDeltaId, deltaX, deltaY, x0, y0, binStep, favorXInActiveBin) {
|
|
11918
|
+
if (onlyDepositToBidSide(maxDeltaId, favorXInActiveBin)) {
|
|
11919
|
+
return getAmountInBinsBidSide(activeId, minDeltaId, maxDeltaId, deltaY, y0);
|
|
11853
11920
|
}
|
|
11854
|
-
|
|
11855
|
-
|
|
11856
|
-
|
|
11857
|
-
|
|
11858
|
-
|
|
11859
|
-
|
|
11860
|
-
|
|
11861
|
-
|
|
11862
|
-
|
|
11863
|
-
|
|
11864
|
-
|
|
11865
|
-
|
|
11866
|
-
|
|
11867
|
-
|
|
11868
|
-
|
|
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
|
|
11921
|
+
if (onlyDepositToAskSide(minDeltaId, favorXInActiveBin)) {
|
|
11922
|
+
return getAmountInBinsAskSide(
|
|
11923
|
+
activeId,
|
|
11924
|
+
binStep,
|
|
11925
|
+
minDeltaId,
|
|
11926
|
+
maxDeltaId,
|
|
11927
|
+
deltaX,
|
|
11928
|
+
x0
|
|
11929
|
+
);
|
|
11930
|
+
}
|
|
11931
|
+
const [bidSideEndDeltaId, askSideStartDeltaId] = favorXInActiveBin ? [-1, 0] : [0, 1];
|
|
11932
|
+
const amountInBinsBidSide = getAmountInBinsBidSide(
|
|
11933
|
+
activeId,
|
|
11934
|
+
minDeltaId,
|
|
11935
|
+
new BN11(bidSideEndDeltaId),
|
|
11936
|
+
deltaY,
|
|
11937
|
+
y0
|
|
11881
11938
|
);
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11939
|
+
const amountInBinsAskSide = getAmountInBinsAskSide(
|
|
11940
|
+
activeId,
|
|
11941
|
+
binStep,
|
|
11942
|
+
new BN11(askSideStartDeltaId),
|
|
11943
|
+
maxDeltaId,
|
|
11944
|
+
deltaX,
|
|
11945
|
+
x0
|
|
11946
|
+
);
|
|
11947
|
+
return amountInBinsBidSide.concat(amountInBinsAskSide);
|
|
11948
|
+
}
|
|
11949
|
+
function getLiquidity(x, y, price) {
|
|
11950
|
+
const px = price.mul(x);
|
|
11951
|
+
const shly = y.shln(SCALE_OFFSET);
|
|
11952
|
+
return px.add(shly);
|
|
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
|
|
11889
11961
|
);
|
|
11890
|
-
|
|
11962
|
+
const feeAmount = delta.mul(totalFeeRate);
|
|
11963
|
+
return feeAmount.mul(FEE_PRECISION.add(totalFeeRate)).div(FEE_PRECISION.pow(new BN11(2)));
|
|
11891
11964
|
}
|
|
11892
|
-
return
|
|
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;
|
|
11905
|
-
}
|
|
11906
|
-
buffer = Math.max(0, buffer);
|
|
11907
|
-
buffer = Math.min(1, buffer);
|
|
11908
|
-
const estimatedComputeUnitUsage = await getSimulationComputeUnits(
|
|
11909
|
-
connection,
|
|
11910
|
-
instructions,
|
|
11911
|
-
feePayer,
|
|
11912
|
-
[]
|
|
11913
|
-
);
|
|
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()
|
|
11940
|
-
);
|
|
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;
|
|
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) => {
|
|
11967
|
-
return {
|
|
11968
|
-
memcmp: {
|
|
11969
|
-
bytes: bs58.encode(binStep.toArrayLike(Buffer, "le", 2)),
|
|
11970
|
-
offset: 8
|
|
11971
|
-
}
|
|
11972
|
-
};
|
|
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);
|
|
12036
|
-
}
|
|
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(
|
|
12047
|
-
program,
|
|
12048
|
-
"positionV2",
|
|
12049
|
-
account.data
|
|
12050
|
-
);
|
|
12051
|
-
const extended = decodeExtendedPosition(
|
|
12052
|
-
state,
|
|
12053
|
-
program,
|
|
12054
|
-
account.data.subarray(8 + POSITION_MIN_SIZE)
|
|
12055
|
-
);
|
|
12056
|
-
const combinedPositionBinData = combineBaseAndExtendedPositionBinData(
|
|
12057
|
-
state,
|
|
12058
|
-
extended
|
|
12059
|
-
);
|
|
12060
|
-
return new PositionV2Wrapper(key, state, extended, combinedPositionBinData);
|
|
12061
|
-
} else {
|
|
12062
|
-
throw new Error("Unknown position account");
|
|
12063
|
-
}
|
|
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;
|
|
12071
|
-
}
|
|
12072
|
-
address() {
|
|
12073
|
-
return this.positionAddress;
|
|
12074
|
-
}
|
|
12075
|
-
totalClaimedRewards() {
|
|
12076
|
-
return this.inner.totalClaimedRewards;
|
|
12077
|
-
}
|
|
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;
|
|
12092
|
-
}
|
|
12093
|
-
lbPair() {
|
|
12094
|
-
return this.inner.lbPair;
|
|
12095
|
-
}
|
|
12096
|
-
lowerBinId() {
|
|
12097
|
-
return new BN12(this.inner.lowerBinId);
|
|
12098
|
-
}
|
|
12099
|
-
upperBinId() {
|
|
12100
|
-
return new BN12(this.inner.upperBinId);
|
|
12101
|
-
}
|
|
12102
|
-
liquidityShares() {
|
|
12103
|
-
return this.combinedPositionBinData.liquidityShares;
|
|
12104
|
-
}
|
|
12105
|
-
rewardInfos() {
|
|
12106
|
-
return this.combinedPositionBinData.rewardInfos;
|
|
12107
|
-
}
|
|
12108
|
-
feeInfos() {
|
|
12109
|
-
return this.combinedPositionBinData.feeInfos;
|
|
12110
|
-
}
|
|
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];
|
|
12122
|
-
}
|
|
12123
|
-
}
|
|
12124
|
-
getBinArrayKeysCoverage(programId) {
|
|
12125
|
-
return this.getBinArrayIndexesCoverage().map(
|
|
12126
|
-
(index) => deriveBinArray(this.lbPair(), index, programId)[0]
|
|
12127
|
-
);
|
|
12128
|
-
}
|
|
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;
|
|
12149
|
-
}
|
|
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];
|
|
12154
|
-
});
|
|
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
|
-
};
|
|
12164
|
-
}
|
|
12165
|
-
);
|
|
12166
|
-
}
|
|
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;
|
|
12175
|
-
}
|
|
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();
|
|
12195
|
-
}
|
|
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
|
|
12206
|
-
);
|
|
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);
|
|
12233
|
-
}
|
|
12234
|
-
return extendedPosition;
|
|
12235
|
-
}
|
|
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();
|
|
12246
|
-
}
|
|
12247
|
-
if (y0.isNeg()) {
|
|
12248
|
-
bitFlag |= 2;
|
|
12249
|
-
y0 = y0.neg();
|
|
12250
|
-
}
|
|
12251
|
-
if (deltaX.isNeg()) {
|
|
12252
|
-
bitFlag |= 4;
|
|
12253
|
-
deltaX = deltaX.neg();
|
|
12254
|
-
}
|
|
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
|
-
}) => {
|
|
12279
|
-
return {
|
|
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)
|
|
12290
|
-
};
|
|
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
|
-
}
|
|
12302
|
-
}
|
|
12303
|
-
const binIds = Array.from(uniqueBinId);
|
|
12304
|
-
binIds.sort((a, b) => a - b);
|
|
12305
|
-
return binIds;
|
|
12306
|
-
}
|
|
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
|
-
}
|
|
12320
|
-
}
|
|
12321
|
-
return [minBinId, maxBinId];
|
|
12322
|
-
}
|
|
12323
|
-
function onlyDepositToBidSide(maxDeltaId, favorXInActiveBin) {
|
|
12324
|
-
if (favorXInActiveBin) {
|
|
12325
|
-
return maxDeltaId.lt(new BN14(0));
|
|
12326
|
-
}
|
|
12327
|
-
return maxDeltaId.lte(new BN14(0));
|
|
12328
|
-
}
|
|
12329
|
-
function onlyDepositToAskSide(minDeltaId, favorXInActiveBin) {
|
|
12330
|
-
if (favorXInActiveBin) {
|
|
12331
|
-
return minDeltaId.gte(new BN14(0));
|
|
12332
|
-
}
|
|
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),
|
|
12346
|
-
amountY
|
|
12347
|
-
});
|
|
12348
|
-
}
|
|
12349
|
-
return amountInBins;
|
|
12350
|
-
}
|
|
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)
|
|
12367
|
-
};
|
|
12368
|
-
inverseBasePrice = inverseBasePrice.mul(base).shrn(SCALE_OFFSET);
|
|
12369
|
-
}
|
|
12370
|
-
return amountInBins;
|
|
12371
|
-
}
|
|
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);
|
|
12375
|
-
}
|
|
12376
|
-
if (onlyDepositToAskSide(minDeltaId, favorXInActiveBin)) {
|
|
12377
|
-
return getAmountInBinsAskSide(
|
|
12378
|
-
activeId,
|
|
12379
|
-
binStep,
|
|
12380
|
-
minDeltaId,
|
|
12381
|
-
maxDeltaId,
|
|
12382
|
-
deltaX,
|
|
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
|
|
12416
|
-
);
|
|
12417
|
-
const feeAmount = delta.mul(totalFeeRate);
|
|
12418
|
-
return feeAmount.mul(FEE_PRECISION.add(totalFeeRate)).div(FEE_PRECISION.pow(new BN14(2)));
|
|
12419
|
-
}
|
|
12420
|
-
return new BN14(0);
|
|
11965
|
+
return new BN11(0);
|
|
12421
11966
|
}
|
|
12422
11967
|
function simulateDepositBin(binId, binStep, amountX, amountY, bin) {
|
|
12423
11968
|
if (!bin) {
|
|
@@ -12466,8 +12011,8 @@ var RebalancePosition = class {
|
|
|
12466
12011
|
constructor(positionAddress, positionData, lbPair, activeBin, shouldClaimFee, shouldClaimReward, currentTimestamp) {
|
|
12467
12012
|
this.address = positionAddress;
|
|
12468
12013
|
this.rebalancePositionBinData = toRebalancePositionBinData(positionData);
|
|
12469
|
-
this.lowerBinId = new
|
|
12470
|
-
this.upperBinId = new
|
|
12014
|
+
this.lowerBinId = new BN11(positionData.lowerBinId);
|
|
12015
|
+
this.upperBinId = new BN11(positionData.upperBinId);
|
|
12471
12016
|
this.lbPair = lbPair;
|
|
12472
12017
|
this.shouldClaimFee = shouldClaimFee;
|
|
12473
12018
|
this.shouldClaimReward = shouldClaimReward;
|
|
@@ -12490,7 +12035,7 @@ var RebalancePosition = class {
|
|
|
12490
12035
|
]);
|
|
12491
12036
|
const lbPair = decodeAccount(program, "lbPair", lbPairAccount.data);
|
|
12492
12037
|
const clock = ClockLayout.decode(clockAccount.data);
|
|
12493
|
-
const activeBinArrayIdx = binIdToBinArrayIndex(new
|
|
12038
|
+
const activeBinArrayIdx = binIdToBinArrayIndex(new BN11(lbPair.activeId));
|
|
12494
12039
|
const [activeBinArrayPubkey] = deriveBinArray(
|
|
12495
12040
|
pairAddress,
|
|
12496
12041
|
activeBinArrayIdx,
|
|
@@ -12501,7 +12046,7 @@ var RebalancePosition = class {
|
|
|
12501
12046
|
);
|
|
12502
12047
|
const [lowerBinId, upperBinId] = getBinArrayLowerUpperBinId(activeBinArrayIdx);
|
|
12503
12048
|
const idx = getBinIdIndexInBinArray(
|
|
12504
|
-
new
|
|
12049
|
+
new BN11(lbPair.activeId),
|
|
12505
12050
|
lowerBinId,
|
|
12506
12051
|
upperBinId
|
|
12507
12052
|
);
|
|
@@ -12518,21 +12063,21 @@ var RebalancePosition = class {
|
|
|
12518
12063
|
}
|
|
12519
12064
|
_simulateDeposit(binStep, tokenXDecimal, tokenYDecimal, deposits, simulatedWithdrawResult) {
|
|
12520
12065
|
const { liquidityAndFeeXWithdrawn, liquidityAndFeeYWithdrawn } = simulatedWithdrawResult;
|
|
12521
|
-
const activeId = new
|
|
12066
|
+
const activeId = new BN11(this.lbPair.activeId);
|
|
12522
12067
|
const depositBinIds = getDepositBinIds(activeId, deposits);
|
|
12523
12068
|
if (depositBinIds.length > 0) {
|
|
12524
12069
|
const depositMinBinId = depositBinIds[0];
|
|
12525
12070
|
const depositMaxBinId = depositBinIds[depositBinIds.length - 1];
|
|
12526
12071
|
this._simulateResize(
|
|
12527
|
-
new
|
|
12528
|
-
new
|
|
12072
|
+
new BN11(depositMinBinId),
|
|
12073
|
+
new BN11(depositMaxBinId),
|
|
12529
12074
|
binStep,
|
|
12530
12075
|
tokenXDecimal,
|
|
12531
12076
|
tokenYDecimal
|
|
12532
12077
|
);
|
|
12533
12078
|
}
|
|
12534
|
-
let totalAmountXDeposited = new
|
|
12535
|
-
let totalAmountYDeposited = new
|
|
12079
|
+
let totalAmountXDeposited = new BN11(0);
|
|
12080
|
+
let totalAmountYDeposited = new BN11(0);
|
|
12536
12081
|
const addLiquidityParam = [];
|
|
12537
12082
|
for (const {
|
|
12538
12083
|
x0,
|
|
@@ -12638,23 +12183,23 @@ var RebalancePosition = class {
|
|
|
12638
12183
|
actualTotalAmountXDeposited = actualTotalAmountXDeposited.sub(
|
|
12639
12184
|
actualLiquidityAndFeeXWithdrawn
|
|
12640
12185
|
);
|
|
12641
|
-
actualLiquidityAndFeeXWithdrawn = new
|
|
12186
|
+
actualLiquidityAndFeeXWithdrawn = new BN11(0);
|
|
12642
12187
|
} else {
|
|
12643
12188
|
actualLiquidityAndFeeXWithdrawn = actualLiquidityAndFeeXWithdrawn.sub(
|
|
12644
12189
|
actualTotalAmountXDeposited
|
|
12645
12190
|
);
|
|
12646
|
-
actualTotalAmountXDeposited = new
|
|
12191
|
+
actualTotalAmountXDeposited = new BN11(0);
|
|
12647
12192
|
}
|
|
12648
12193
|
if (actualTotalAmountYDeposited.gt(actualLiquidityAndFeeYWithdrawn)) {
|
|
12649
12194
|
actualTotalAmountYDeposited = actualTotalAmountYDeposited.sub(
|
|
12650
12195
|
actualLiquidityAndFeeYWithdrawn
|
|
12651
12196
|
);
|
|
12652
|
-
actualLiquidityAndFeeYWithdrawn = new
|
|
12197
|
+
actualLiquidityAndFeeYWithdrawn = new BN11(0);
|
|
12653
12198
|
} else {
|
|
12654
12199
|
actualLiquidityAndFeeYWithdrawn = actualLiquidityAndFeeYWithdrawn.sub(
|
|
12655
12200
|
actualTotalAmountYDeposited
|
|
12656
12201
|
);
|
|
12657
|
-
actualTotalAmountYDeposited = new
|
|
12202
|
+
actualTotalAmountYDeposited = new BN11(0);
|
|
12658
12203
|
}
|
|
12659
12204
|
return {
|
|
12660
12205
|
result: {
|
|
@@ -12674,10 +12219,10 @@ var RebalancePosition = class {
|
|
|
12674
12219
|
const [minBinId, maxBinId] = findMinMaxBinIdWithLiquidity(
|
|
12675
12220
|
this.rebalancePositionBinData
|
|
12676
12221
|
);
|
|
12677
|
-
const newMinBinId = new
|
|
12222
|
+
const newMinBinId = new BN11(
|
|
12678
12223
|
Math.min(depositMinBinId.toNumber(), minBinId ?? Number.MAX_SAFE_INTEGER)
|
|
12679
12224
|
);
|
|
12680
|
-
const newMaxBinId = new
|
|
12225
|
+
const newMaxBinId = new BN11(
|
|
12681
12226
|
Math.max(depositMaxBinId.toNumber(), maxBinId ?? Number.MIN_SAFE_INTEGER)
|
|
12682
12227
|
);
|
|
12683
12228
|
if (newMinBinId.lt(this.lowerBinId)) {
|
|
@@ -12693,11 +12238,11 @@ var RebalancePosition = class {
|
|
|
12693
12238
|
binId: binId.toNumber(),
|
|
12694
12239
|
price: adjustedPrice.toString(),
|
|
12695
12240
|
pricePerToken: adjustedPrice.toString(),
|
|
12696
|
-
amountX: new
|
|
12697
|
-
amountY: new
|
|
12698
|
-
claimableRewardAmount: [new
|
|
12699
|
-
claimableFeeXAmount: new
|
|
12700
|
-
claimableFeeYAmount: new
|
|
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)
|
|
12701
12246
|
});
|
|
12702
12247
|
}
|
|
12703
12248
|
} else {
|
|
@@ -12719,11 +12264,11 @@ var RebalancePosition = class {
|
|
|
12719
12264
|
binId: binId.toNumber(),
|
|
12720
12265
|
price: adjustedPrice.toString(),
|
|
12721
12266
|
pricePerToken: adjustedPrice.toString(),
|
|
12722
|
-
amountX: new
|
|
12723
|
-
amountY: new
|
|
12724
|
-
claimableRewardAmount: [new
|
|
12725
|
-
claimableFeeXAmount: new
|
|
12726
|
-
claimableFeeYAmount: new
|
|
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)
|
|
12727
12272
|
});
|
|
12728
12273
|
}
|
|
12729
12274
|
} else {
|
|
@@ -12736,10 +12281,10 @@ var RebalancePosition = class {
|
|
|
12736
12281
|
this.upperBinId = newMaxBinId;
|
|
12737
12282
|
}
|
|
12738
12283
|
_simulateWithdraw(withdraws) {
|
|
12739
|
-
let liquidityAndFeeXWithdrawn = new
|
|
12740
|
-
let liquidityAndFeeYWithdrawn = new
|
|
12741
|
-
let rewardsAmountClaimed = [new
|
|
12742
|
-
const activeId = new
|
|
12284
|
+
let liquidityAndFeeXWithdrawn = new BN11(0);
|
|
12285
|
+
let liquidityAndFeeYWithdrawn = new BN11(0);
|
|
12286
|
+
let rewardsAmountClaimed = [new BN11(0), new BN11(0)];
|
|
12287
|
+
const activeId = new BN11(this.lbPair.activeId);
|
|
12743
12288
|
for (const { minBinId, maxBinId, bps } of withdraws) {
|
|
12744
12289
|
const fromBinId = minBinId ?? activeId;
|
|
12745
12290
|
const toBinId = maxBinId ?? activeId;
|
|
@@ -12764,13 +12309,13 @@ var RebalancePosition = class {
|
|
|
12764
12309
|
liquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn.add(
|
|
12765
12310
|
binData.claimableFeeYAmount
|
|
12766
12311
|
);
|
|
12767
|
-
binData.claimableFeeXAmount = new
|
|
12768
|
-
binData.claimableFeeYAmount = new
|
|
12312
|
+
binData.claimableFeeXAmount = new BN11(0);
|
|
12313
|
+
binData.claimableFeeYAmount = new BN11(0);
|
|
12769
12314
|
}
|
|
12770
12315
|
if (this.shouldClaimReward) {
|
|
12771
12316
|
for (const [idx2, amount] of binData.claimableRewardAmount.entries()) {
|
|
12772
12317
|
rewardsAmountClaimed[idx2] = rewardsAmountClaimed[idx2].add(amount);
|
|
12773
|
-
binData.claimableRewardAmount[idx2] = new
|
|
12318
|
+
binData.claimableRewardAmount[idx2] = new BN11(0);
|
|
12774
12319
|
}
|
|
12775
12320
|
}
|
|
12776
12321
|
this.rebalancePositionBinData[idx] = binData;
|
|
@@ -12799,7 +12344,7 @@ var RebalancePosition = class {
|
|
|
12799
12344
|
if (withdraws.length == 0 && deposits.length == 0) {
|
|
12800
12345
|
throw "No rebalance action";
|
|
12801
12346
|
}
|
|
12802
|
-
const activeId = new
|
|
12347
|
+
const activeId = new BN11(this.lbPair.activeId);
|
|
12803
12348
|
withdraws = validateAndSortRebalanceWithdraw(withdraws, activeId);
|
|
12804
12349
|
deposits = validateAndSortRebalanceDeposit(deposits);
|
|
12805
12350
|
const beforeWidth = getPositionWidthWithMinWidth(
|
|
@@ -12819,15 +12364,15 @@ var RebalancePosition = class {
|
|
|
12819
12364
|
this.upperBinId.toNumber()
|
|
12820
12365
|
);
|
|
12821
12366
|
const widthDelta = afterWidth - beforeWidth;
|
|
12822
|
-
let rentalCostLamports = new
|
|
12367
|
+
let rentalCostLamports = new BN11(0);
|
|
12823
12368
|
if (widthDelta != 0) {
|
|
12824
12369
|
const sizeChanges = Math.abs(widthDelta) * POSITION_BIN_DATA_SIZE;
|
|
12825
12370
|
const [minimumLamports, rentExemptionLamports] = await Promise.all([
|
|
12826
12371
|
connection.getMinimumBalanceForRentExemption(0),
|
|
12827
12372
|
connection.getMinimumBalanceForRentExemption(sizeChanges)
|
|
12828
12373
|
]);
|
|
12829
|
-
const lamportChanges = new
|
|
12830
|
-
new
|
|
12374
|
+
const lamportChanges = new BN11(rentExemptionLamports).sub(
|
|
12375
|
+
new BN11(minimumLamports)
|
|
12831
12376
|
);
|
|
12832
12377
|
if (widthDelta > 0) {
|
|
12833
12378
|
rentalCostLamports = rentalCostLamports.add(lamportChanges);
|
|
@@ -12849,8 +12394,8 @@ var RebalancePosition = class {
|
|
|
12849
12394
|
};
|
|
12850
12395
|
}
|
|
12851
12396
|
totalAmounts() {
|
|
12852
|
-
let totalAmountX = new
|
|
12853
|
-
let totalAmountY = new
|
|
12397
|
+
let totalAmountX = new BN11(0);
|
|
12398
|
+
let totalAmountY = new BN11(0);
|
|
12854
12399
|
for (const binData of this.rebalancePositionBinData) {
|
|
12855
12400
|
totalAmountX = totalAmountX.add(binData.amountX);
|
|
12856
12401
|
totalAmountY = totalAmountY.add(binData.amountY);
|
|
@@ -12858,8 +12403,8 @@ var RebalancePosition = class {
|
|
|
12858
12403
|
return [totalAmountX, totalAmountY];
|
|
12859
12404
|
}
|
|
12860
12405
|
totalFeeAmounts() {
|
|
12861
|
-
let totalFeeXAmount = new
|
|
12862
|
-
let totalFeeYAmount = new
|
|
12406
|
+
let totalFeeXAmount = new BN11(0);
|
|
12407
|
+
let totalFeeYAmount = new BN11(0);
|
|
12863
12408
|
for (const binData of this.rebalancePositionBinData) {
|
|
12864
12409
|
totalFeeXAmount = totalFeeXAmount.add(binData.claimableFeeXAmount);
|
|
12865
12410
|
totalFeeYAmount = totalFeeYAmount.add(binData.claimableFeeYAmount);
|
|
@@ -12867,7 +12412,7 @@ var RebalancePosition = class {
|
|
|
12867
12412
|
return [totalFeeXAmount, totalFeeYAmount];
|
|
12868
12413
|
}
|
|
12869
12414
|
totalRewardAmounts() {
|
|
12870
|
-
let totalRewardAmounts = [new
|
|
12415
|
+
let totalRewardAmounts = [new BN11(0), new BN11(0)];
|
|
12871
12416
|
for (const binData of this.rebalancePositionBinData) {
|
|
12872
12417
|
totalRewardAmounts[0] = totalRewardAmounts[0].add(
|
|
12873
12418
|
binData.claimableRewardAmount[0]
|
|
@@ -12935,7 +12480,7 @@ function binRangeToBinIdArray(minBinId, maxBinId) {
|
|
|
12935
12480
|
const fromBinId = minBinId.toNumber();
|
|
12936
12481
|
const toBinId = maxBinId.toNumber();
|
|
12937
12482
|
for (let binId = fromBinId; binId <= toBinId; binId++) {
|
|
12938
|
-
binIdArray.push(new
|
|
12483
|
+
binIdArray.push(new BN11(binId));
|
|
12939
12484
|
}
|
|
12940
12485
|
return binIdArray;
|
|
12941
12486
|
}
|
|
@@ -12950,36 +12495,36 @@ function getRebalanceBinArrayIndexesAndBitmapCoverage(adds, removes, activeId, p
|
|
|
12950
12495
|
if (maxBinId == null) {
|
|
12951
12496
|
maxBinId = activeId;
|
|
12952
12497
|
}
|
|
12953
|
-
let binArrayIndex = binIdToBinArrayIndex(new
|
|
12954
|
-
const upperBinId = new
|
|
12498
|
+
let binArrayIndex = binIdToBinArrayIndex(new BN11(minBinId));
|
|
12499
|
+
const upperBinId = new BN11(maxBinId);
|
|
12955
12500
|
while (true) {
|
|
12956
12501
|
indexMap.set(binArrayIndex.toNumber(), true);
|
|
12957
12502
|
const [binArrayLowerBinId, binArrayUpperBinId] = getBinArrayLowerUpperBinId(binArrayIndex);
|
|
12958
12503
|
if (upperBinId.gte(binArrayLowerBinId) && upperBinId.lte(binArrayUpperBinId)) {
|
|
12959
12504
|
break;
|
|
12960
12505
|
} else {
|
|
12961
|
-
binArrayIndex = binArrayIndex.add(new
|
|
12506
|
+
binArrayIndex = binArrayIndex.add(new BN11(1));
|
|
12962
12507
|
}
|
|
12963
12508
|
}
|
|
12964
12509
|
});
|
|
12965
12510
|
adds.forEach((value) => {
|
|
12966
12511
|
const minBinId = activeId + value.minDeltaId;
|
|
12967
12512
|
const maxBinId = activeId + value.maxDeltaId;
|
|
12968
|
-
let binArrayIndex = binIdToBinArrayIndex(new
|
|
12969
|
-
const upperBinId = new
|
|
12513
|
+
let binArrayIndex = binIdToBinArrayIndex(new BN11(minBinId));
|
|
12514
|
+
const upperBinId = new BN11(maxBinId);
|
|
12970
12515
|
while (true) {
|
|
12971
12516
|
indexMap.set(binArrayIndex.toNumber(), true);
|
|
12972
12517
|
const [binArrayLowerBinId, binArrayUpperBinId] = getBinArrayLowerUpperBinId(binArrayIndex);
|
|
12973
12518
|
if (upperBinId.gte(binArrayLowerBinId) && upperBinId.lte(binArrayUpperBinId)) {
|
|
12974
12519
|
break;
|
|
12975
12520
|
} else {
|
|
12976
|
-
binArrayIndex = binArrayIndex.add(new
|
|
12521
|
+
binArrayIndex = binArrayIndex.add(new BN11(1));
|
|
12977
12522
|
}
|
|
12978
12523
|
}
|
|
12979
12524
|
});
|
|
12980
|
-
const binArrayIndexes = Array.from(indexMap.keys()).map((idx) => new
|
|
12525
|
+
const binArrayIndexes = Array.from(indexMap.keys()).map((idx) => new BN11(idx));
|
|
12981
12526
|
const requireBitmapExtension = binArrayIndexes.some(
|
|
12982
|
-
(index) => isOverflowDefaultBinArrayBitmap(new
|
|
12527
|
+
(index) => isOverflowDefaultBinArrayBitmap(new BN11(index))
|
|
12983
12528
|
);
|
|
12984
12529
|
return {
|
|
12985
12530
|
binArrayIndexes,
|
|
@@ -12988,505 +12533,1109 @@ function getRebalanceBinArrayIndexesAndBitmapCoverage(adds, removes, activeId, p
|
|
|
12988
12533
|
}
|
|
12989
12534
|
|
|
12990
12535
|
// src/dlmm/helpers/rebalance/liquidity_strategy/index.ts
|
|
12991
|
-
import
|
|
12536
|
+
import BN15 from "bn.js";
|
|
12537
|
+
|
|
12538
|
+
// src/dlmm/helpers/rebalance/liquidity_strategy/bidAsk.ts
|
|
12539
|
+
import BN12 from "bn.js";
|
|
12540
|
+
function findBaseDeltaY(amountY, minDeltaId, maxDeltaId) {
|
|
12541
|
+
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new BN12(0))) {
|
|
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);
|
|
12554
|
+
}
|
|
12555
|
+
function findY0AndDeltaY(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
12556
|
+
if (minDeltaId.gt(maxDeltaId) || amountY.isZero()) {
|
|
12557
|
+
return {
|
|
12558
|
+
base: new BN12(0),
|
|
12559
|
+
delta: new BN12(0)
|
|
12560
|
+
};
|
|
12561
|
+
}
|
|
12562
|
+
let baseDeltaY = findBaseDeltaY(amountY, minDeltaId, maxDeltaId);
|
|
12563
|
+
const y0 = baseDeltaY.neg().mul(maxDeltaId).add(baseDeltaY);
|
|
12564
|
+
while (true) {
|
|
12565
|
+
const amountInBins = getAmountInBinsBidSide(
|
|
12566
|
+
activeId,
|
|
12567
|
+
minDeltaId,
|
|
12568
|
+
maxDeltaId,
|
|
12569
|
+
baseDeltaY,
|
|
12570
|
+
y0
|
|
12571
|
+
);
|
|
12572
|
+
const totalAmountY = amountInBins.reduce((acc, { amountY: amountY2 }) => {
|
|
12573
|
+
return acc.add(amountY2);
|
|
12574
|
+
}, new BN12(0));
|
|
12575
|
+
if (totalAmountY.gt(amountY)) {
|
|
12576
|
+
baseDeltaY = baseDeltaY.sub(new BN12(1));
|
|
12577
|
+
} else {
|
|
12578
|
+
return {
|
|
12579
|
+
base: y0,
|
|
12580
|
+
delta: baseDeltaY
|
|
12581
|
+
};
|
|
12582
|
+
}
|
|
12583
|
+
}
|
|
12584
|
+
}
|
|
12585
|
+
function findBaseDeltaX(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12586
|
+
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN12(0))) {
|
|
12587
|
+
return new BN12(0);
|
|
12588
|
+
}
|
|
12589
|
+
let b = new BN12(0);
|
|
12590
|
+
let c = new BN12(0);
|
|
12591
|
+
let m1 = minDeltaId;
|
|
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);
|
|
12600
|
+
}
|
|
12601
|
+
return amountX.shln(SCALE_OFFSET).div(c.sub(b));
|
|
12602
|
+
}
|
|
12603
|
+
function findX0AndDeltaX(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
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
|
+
};
|
|
12609
|
+
}
|
|
12610
|
+
let baseDeltaX = findBaseDeltaX(
|
|
12611
|
+
amountX,
|
|
12612
|
+
minDeltaId,
|
|
12613
|
+
maxDeltaId,
|
|
12614
|
+
binStep,
|
|
12615
|
+
activeId
|
|
12616
|
+
);
|
|
12617
|
+
const x0 = minDeltaId.neg().mul(baseDeltaX).add(baseDeltaX);
|
|
12618
|
+
while (true) {
|
|
12619
|
+
const amountInBins = getAmountInBinsAskSide(
|
|
12620
|
+
activeId,
|
|
12621
|
+
binStep,
|
|
12622
|
+
minDeltaId,
|
|
12623
|
+
maxDeltaId,
|
|
12624
|
+
baseDeltaX,
|
|
12625
|
+
x0
|
|
12626
|
+
);
|
|
12627
|
+
const totalAmountX = amountInBins.reduce((acc, { amountX: amountX2 }) => {
|
|
12628
|
+
return acc.add(amountX2);
|
|
12629
|
+
}, new BN12(0));
|
|
12630
|
+
if (totalAmountX.gt(amountX)) {
|
|
12631
|
+
baseDeltaX = baseDeltaX.sub(new BN12(1));
|
|
12632
|
+
} else {
|
|
12633
|
+
return {
|
|
12634
|
+
base: x0,
|
|
12635
|
+
delta: baseDeltaX
|
|
12636
|
+
};
|
|
12637
|
+
}
|
|
12638
|
+
}
|
|
12639
|
+
}
|
|
12640
|
+
var BidAskStrategyParameterBuilder = class {
|
|
12641
|
+
findXParameters(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12642
|
+
return findX0AndDeltaX(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
12643
|
+
}
|
|
12644
|
+
findYParameters(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
12645
|
+
return findY0AndDeltaY(amountY, minDeltaId, maxDeltaId, activeId);
|
|
12646
|
+
}
|
|
12647
|
+
suggestBalancedXParametersFromY(activeId, binStep, favorXInActiveBin, minDeltaId, maxDeltaId, amountY) {
|
|
12648
|
+
const deltaX = amountY.div(
|
|
12649
|
+
maxDeltaId.addn(1).mul(maxDeltaId.addn(2)).divn(2)
|
|
12650
|
+
);
|
|
12651
|
+
const x0 = minDeltaId.neg().mul(deltaX).add(deltaX);
|
|
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
|
+
};
|
|
12670
|
+
}
|
|
12671
|
+
suggestBalancedYParametersFromX(activeId, binStep, favorXInActiveBin, minDeltaId, maxDeltaId, amountXInQuoteValue) {
|
|
12672
|
+
const m1 = minDeltaId.neg().subn(1);
|
|
12673
|
+
const m2 = maxDeltaId.neg();
|
|
12674
|
+
const a1 = m2.neg().mul(m1.sub(m2).addn(1));
|
|
12675
|
+
const a2 = m1.mul(m1.addn(1)).divn(2);
|
|
12676
|
+
const a3 = m2.mul(m2.subn(1)).divn(2);
|
|
12677
|
+
const a = a1.add(a2.sub(a3));
|
|
12678
|
+
const deltaY = amountXInQuoteValue.div(a);
|
|
12679
|
+
const y0 = deltaY.neg().mul(m2).add(deltaY);
|
|
12680
|
+
const amountY = toAmountIntoBins(
|
|
12681
|
+
activeId,
|
|
12682
|
+
minDeltaId,
|
|
12683
|
+
maxDeltaId,
|
|
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,
|
|
12696
|
+
amountY
|
|
12697
|
+
};
|
|
12698
|
+
}
|
|
12699
|
+
};
|
|
12992
12700
|
|
|
12993
|
-
// src/dlmm/helpers/rebalance/liquidity_strategy/
|
|
12994
|
-
import
|
|
12995
|
-
function
|
|
12996
|
-
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new
|
|
12997
|
-
return new
|
|
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);
|
|
12998
12706
|
}
|
|
12999
12707
|
if (minDeltaId.eq(maxDeltaId)) {
|
|
13000
12708
|
return amountY;
|
|
13001
12709
|
}
|
|
13002
|
-
const m1 = minDeltaId.neg()
|
|
12710
|
+
const m1 = minDeltaId.neg();
|
|
13003
12711
|
const m2 = maxDeltaId.neg();
|
|
13004
|
-
const b =
|
|
12712
|
+
const b = m1.sub(m2).addn(1);
|
|
13005
12713
|
const c = m1.mul(m1.addn(1)).divn(2);
|
|
13006
12714
|
const d = m2.mul(m2.subn(1)).divn(2);
|
|
13007
|
-
const a = b.
|
|
12715
|
+
const a = b.sub(c.sub(d).div(m1.addn(1)));
|
|
13008
12716
|
return amountY.div(a);
|
|
13009
12717
|
}
|
|
13010
|
-
function
|
|
12718
|
+
function findY0AndDeltaY2(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
13011
12719
|
if (minDeltaId.gt(maxDeltaId) || amountY.isZero()) {
|
|
13012
12720
|
return {
|
|
13013
|
-
base: new
|
|
13014
|
-
delta: new
|
|
12721
|
+
base: new BN13(0),
|
|
12722
|
+
delta: new BN13(0)
|
|
13015
12723
|
};
|
|
13016
12724
|
}
|
|
13017
|
-
let
|
|
13018
|
-
const y0 = baseDeltaY.neg().mul(maxDeltaId).add(baseDeltaY);
|
|
12725
|
+
let baseY0 = findBaseY0(amountY, minDeltaId, maxDeltaId);
|
|
13019
12726
|
while (true) {
|
|
12727
|
+
const deltaY = baseY0.neg().div(minDeltaId.neg().addn(1));
|
|
13020
12728
|
const amountInBins = getAmountInBinsBidSide(
|
|
13021
12729
|
activeId,
|
|
13022
12730
|
minDeltaId,
|
|
13023
12731
|
maxDeltaId,
|
|
13024
|
-
|
|
13025
|
-
|
|
12732
|
+
deltaY,
|
|
12733
|
+
baseY0
|
|
13026
12734
|
);
|
|
13027
12735
|
const totalAmountY = amountInBins.reduce((acc, { amountY: amountY2 }) => {
|
|
13028
12736
|
return acc.add(amountY2);
|
|
13029
|
-
}, new
|
|
12737
|
+
}, new BN13(0));
|
|
13030
12738
|
if (totalAmountY.gt(amountY)) {
|
|
13031
|
-
|
|
12739
|
+
baseY0 = baseY0.sub(new BN13(1));
|
|
13032
12740
|
} else {
|
|
13033
12741
|
return {
|
|
13034
|
-
base:
|
|
13035
|
-
delta:
|
|
12742
|
+
base: baseY0,
|
|
12743
|
+
delta: deltaY
|
|
13036
12744
|
};
|
|
13037
12745
|
}
|
|
13038
12746
|
}
|
|
13039
12747
|
}
|
|
13040
|
-
function
|
|
13041
|
-
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new
|
|
13042
|
-
return new
|
|
12748
|
+
function findBaseX0(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12749
|
+
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN13(0))) {
|
|
12750
|
+
return new BN13(0);
|
|
13043
12751
|
}
|
|
13044
|
-
let b = new
|
|
13045
|
-
let c = new
|
|
12752
|
+
let b = new BN13(0);
|
|
12753
|
+
let c = new BN13(0);
|
|
13046
12754
|
let m1 = minDeltaId;
|
|
13047
|
-
let m2 = maxDeltaId
|
|
12755
|
+
let m2 = maxDeltaId;
|
|
13048
12756
|
for (let m = m1.toNumber(); m <= m2.toNumber(); m++) {
|
|
13049
12757
|
const binId = activeId.addn(m);
|
|
13050
12758
|
const pm = getQPriceFromId(binId.neg(), binStep);
|
|
13051
|
-
|
|
13052
|
-
|
|
13053
|
-
const cDelta = new BN15(m).mul(pm);
|
|
12759
|
+
b = b.add(pm);
|
|
12760
|
+
const cDelta = new BN13(m).mul(pm).div(m2);
|
|
13054
12761
|
c = c.add(cDelta);
|
|
13055
12762
|
}
|
|
13056
|
-
return amountX.shln(SCALE_OFFSET).div(
|
|
12763
|
+
return amountX.shln(SCALE_OFFSET).div(b.sub(c));
|
|
12764
|
+
}
|
|
12765
|
+
function findX0AndDeltaX2(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12766
|
+
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN13(0)) || amountX.isZero()) {
|
|
12767
|
+
return {
|
|
12768
|
+
base: new BN13(0),
|
|
12769
|
+
delta: new BN13(0)
|
|
12770
|
+
};
|
|
12771
|
+
}
|
|
12772
|
+
let baseX0 = findBaseX0(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
12773
|
+
const deltaX = baseX0.neg().div(maxDeltaId);
|
|
12774
|
+
while (true) {
|
|
12775
|
+
const amountInBins = getAmountInBinsAskSide(
|
|
12776
|
+
activeId,
|
|
12777
|
+
binStep,
|
|
12778
|
+
minDeltaId,
|
|
12779
|
+
maxDeltaId,
|
|
12780
|
+
deltaX,
|
|
12781
|
+
baseX0
|
|
12782
|
+
);
|
|
12783
|
+
const totalAmountX = amountInBins.reduce((acc, { amountX: amountX2 }) => {
|
|
12784
|
+
return acc.add(amountX2);
|
|
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
|
+
}
|
|
12794
|
+
}
|
|
12795
|
+
}
|
|
12796
|
+
var CurveStrategyParameterBuilder = class {
|
|
12797
|
+
findXParameters(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
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));
|
|
12819
|
+
return {
|
|
12820
|
+
base: x0,
|
|
12821
|
+
delta: deltaX,
|
|
12822
|
+
amountX: totalAmountX
|
|
12823
|
+
};
|
|
12824
|
+
}
|
|
12825
|
+
suggestBalancedYParametersFromX(activeId, binStep, favorXInActiveBin, minDeltaId, maxDeltaId, amountXInQuoteValue) {
|
|
12826
|
+
const m1 = minDeltaId.neg();
|
|
12827
|
+
const m2 = maxDeltaId.neg();
|
|
12828
|
+
const a1 = m1.sub(m2).addn(1);
|
|
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));
|
|
12847
|
+
return {
|
|
12848
|
+
base: y0,
|
|
12849
|
+
delta: deltaY,
|
|
12850
|
+
amountY
|
|
12851
|
+
};
|
|
12852
|
+
}
|
|
12853
|
+
};
|
|
12854
|
+
|
|
12855
|
+
// src/dlmm/helpers/rebalance/liquidity_strategy/spot.ts
|
|
12856
|
+
import BN14 from "bn.js";
|
|
12857
|
+
function findY0(amountY, minDeltaId, maxDeltaId) {
|
|
12858
|
+
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new BN14(0)) || amountY.isZero()) {
|
|
12859
|
+
return new BN14(0);
|
|
12860
|
+
}
|
|
12861
|
+
const m1 = minDeltaId.neg();
|
|
12862
|
+
const m2 = maxDeltaId.neg();
|
|
12863
|
+
const delta = m1.sub(m2).addn(1);
|
|
12864
|
+
return amountY.div(delta);
|
|
12865
|
+
}
|
|
12866
|
+
function findBaseX02(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12867
|
+
let totalWeight = new BN14(0);
|
|
12868
|
+
const minBinId = activeId.add(minDeltaId);
|
|
12869
|
+
const maxBinId = activeId.add(maxDeltaId);
|
|
12870
|
+
let baseFactor = getQPriceBaseFactor(binStep);
|
|
12871
|
+
let basePrice = getQPriceFromId(maxBinId.neg(), binStep);
|
|
12872
|
+
for (let binId = minBinId.toNumber(); binId <= maxBinId.toNumber(); binId++) {
|
|
12873
|
+
totalWeight = totalWeight.add(basePrice);
|
|
12874
|
+
basePrice = basePrice.mul(baseFactor).shrn(SCALE_OFFSET);
|
|
12875
|
+
}
|
|
12876
|
+
return amountX.shln(SCALE_OFFSET).div(totalWeight);
|
|
12877
|
+
}
|
|
12878
|
+
function findX0(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12879
|
+
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN14(0)) || amountX.isZero()) {
|
|
12880
|
+
return new BN14(0);
|
|
12881
|
+
}
|
|
12882
|
+
let x0 = findBaseX02(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
12883
|
+
while (true) {
|
|
12884
|
+
const amountInBins = getAmountInBinsAskSide(
|
|
12885
|
+
activeId,
|
|
12886
|
+
binStep,
|
|
12887
|
+
minDeltaId,
|
|
12888
|
+
maxDeltaId,
|
|
12889
|
+
new BN14(0),
|
|
12890
|
+
x0
|
|
12891
|
+
);
|
|
12892
|
+
const totalAmountX = amountInBins.reduce((acc, bin) => {
|
|
12893
|
+
return acc.add(bin.amountX);
|
|
12894
|
+
}, new BN14(0));
|
|
12895
|
+
if (totalAmountX.lt(amountX)) {
|
|
12896
|
+
x0 = x0.add(new BN14(1));
|
|
12897
|
+
} else {
|
|
12898
|
+
x0 = x0.sub(new BN14(1));
|
|
12899
|
+
return x0;
|
|
12900
|
+
}
|
|
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
|
+
return {
|
|
12978
|
+
base: new BN15(0),
|
|
12979
|
+
delta: new BN15(0),
|
|
12980
|
+
amountX: new BN15(0)
|
|
12981
|
+
};
|
|
12982
|
+
}
|
|
12983
|
+
const minYDeltaId = minDeltaId;
|
|
12984
|
+
const maxYDeltaId = endDeltaIdBidSide;
|
|
12985
|
+
const totalAmountY = toAmountIntoBins(
|
|
12986
|
+
activeId,
|
|
12987
|
+
minYDeltaId,
|
|
12988
|
+
maxYDeltaId,
|
|
12989
|
+
new BN15(0),
|
|
12990
|
+
deltaY,
|
|
12991
|
+
new BN15(0),
|
|
12992
|
+
y0,
|
|
12993
|
+
binStep,
|
|
12994
|
+
favorXInActiveBin
|
|
12995
|
+
).reduce((acc, bin) => {
|
|
12996
|
+
return acc.add(bin.amountY);
|
|
12997
|
+
}, new BN15(0));
|
|
12998
|
+
const minXDeltaId = maxYDeltaId.addn(1);
|
|
12999
|
+
const maxXDeltaId = maxDeltaId;
|
|
13000
|
+
return builder.suggestBalancedXParametersFromY(
|
|
13001
|
+
activeId,
|
|
13002
|
+
binStep,
|
|
13003
|
+
favorXInActiveBin,
|
|
13004
|
+
minXDeltaId,
|
|
13005
|
+
maxXDeltaId,
|
|
13006
|
+
totalAmountY
|
|
13007
|
+
);
|
|
13008
|
+
}
|
|
13009
|
+
function getAutoFillAmountByRebalancedPosition(rebalancePosition, strategyType) {
|
|
13010
|
+
let liquidityInBidSide = new BN15(0);
|
|
13011
|
+
let liquidityInAskSide = new BN15(0);
|
|
13012
|
+
const builder = getLiquidityStrategyParameterBuilder(strategyType);
|
|
13013
|
+
const { lbPair } = rebalancePosition;
|
|
13014
|
+
let favorXInActiveBin = false;
|
|
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;
|
|
13034
|
+
} else {
|
|
13035
|
+
maxBinId = rebalancePosition.rebalancePositionBinData[favorXInActiveBin ? activeIdIndex - 1 : activeIdIndex].binId;
|
|
13036
|
+
}
|
|
13037
|
+
const minDeltaId = minBinId - lbPair.activeId;
|
|
13038
|
+
const maxDeltaId = maxBinId - lbPair.activeId;
|
|
13039
|
+
const { amountY } = builder.suggestBalancedYParametersFromX(
|
|
13040
|
+
new BN15(lbPair.activeId),
|
|
13041
|
+
new BN15(lbPair.binStep),
|
|
13042
|
+
favorXInActiveBin,
|
|
13043
|
+
new BN15(minDeltaId),
|
|
13044
|
+
new BN15(maxDeltaId),
|
|
13045
|
+
liquidityInAskSide
|
|
13046
|
+
);
|
|
13047
|
+
const [_, positionAmountY] = rebalancePosition.totalAmounts();
|
|
13048
|
+
return {
|
|
13049
|
+
amount: BN15.max(amountY.sub(positionAmountY), new BN15(0)),
|
|
13050
|
+
isBidSide: true
|
|
13051
|
+
};
|
|
13052
|
+
} else if (liquidityInAskSide.lt(liquidityInBidSide)) {
|
|
13053
|
+
const maxBinId = rebalancePosition.rebalancePositionBinData[rebalancePosition.rebalancePositionBinData.length - 1].binId;
|
|
13054
|
+
let minBinId;
|
|
13055
|
+
if (activeIdIndex == -1) {
|
|
13056
|
+
minBinId = rebalancePosition.rebalancePositionBinData[0].binId;
|
|
13057
|
+
} else {
|
|
13058
|
+
minBinId = rebalancePosition.rebalancePositionBinData[favorXInActiveBin ? activeIdIndex - 1 : activeIdIndex].binId;
|
|
13059
|
+
}
|
|
13060
|
+
const minDeltaId = lbPair.activeId - minBinId;
|
|
13061
|
+
const maxDeltaId = lbPair.activeId - maxBinId;
|
|
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
|
+
}
|
|
13057
13081
|
}
|
|
13058
|
-
function
|
|
13059
|
-
|
|
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)) {
|
|
13060
13085
|
return {
|
|
13061
13086
|
base: new BN15(0),
|
|
13062
|
-
delta: new BN15(0)
|
|
13087
|
+
delta: new BN15(0),
|
|
13088
|
+
amountY: new BN15(0)
|
|
13063
13089
|
};
|
|
13064
13090
|
}
|
|
13065
|
-
|
|
13066
|
-
|
|
13067
|
-
|
|
13068
|
-
|
|
13091
|
+
const minXDeltaId = startDeltaIdAskSide;
|
|
13092
|
+
const maxXDeltaId = maxDeltaId;
|
|
13093
|
+
const amountXInBins = toAmountIntoBins(
|
|
13094
|
+
activeId,
|
|
13095
|
+
minXDeltaId,
|
|
13096
|
+
maxXDeltaId,
|
|
13097
|
+
deltaX,
|
|
13098
|
+
new BN15(0),
|
|
13099
|
+
x0,
|
|
13100
|
+
new BN15(0),
|
|
13069
13101
|
binStep,
|
|
13070
|
-
|
|
13102
|
+
favorXInActiveBin
|
|
13071
13103
|
);
|
|
13072
|
-
const
|
|
13073
|
-
|
|
13074
|
-
|
|
13075
|
-
|
|
13076
|
-
binStep,
|
|
13077
|
-
minDeltaId,
|
|
13078
|
-
maxDeltaId,
|
|
13079
|
-
baseDeltaX,
|
|
13080
|
-
x0
|
|
13104
|
+
const totalAmountXInQuote = amountXInBins.reduce((acc, bin) => {
|
|
13105
|
+
const price = getPriceOfBinByBinId(
|
|
13106
|
+
bin.binId.toNumber(),
|
|
13107
|
+
binStep.toNumber()
|
|
13081
13108
|
);
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13085
|
-
|
|
13086
|
-
|
|
13087
|
-
|
|
13088
|
-
|
|
13089
|
-
|
|
13090
|
-
|
|
13091
|
-
|
|
13092
|
-
|
|
13093
|
-
|
|
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
|
+
);
|
|
13094
13122
|
}
|
|
13095
|
-
|
|
13096
|
-
|
|
13097
|
-
return
|
|
13098
|
-
|
|
13099
|
-
|
|
13100
|
-
|
|
13123
|
+
function buildLiquidityStrategyParameters(amountX, amountY, minDeltaId, maxDeltaId, binStep, favorXInActiveId, activeId, strategyParameterBuilder) {
|
|
13124
|
+
if (minDeltaId.gt(maxDeltaId)) {
|
|
13125
|
+
return {
|
|
13126
|
+
x0: new BN15(0),
|
|
13127
|
+
y0: new BN15(0),
|
|
13128
|
+
deltaX: new BN15(0),
|
|
13129
|
+
deltaY: new BN15(0)
|
|
13130
|
+
};
|
|
13101
13131
|
}
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
|
|
13107
|
-
const totalAmountX = toAmountIntoBins(
|
|
13108
|
-
activeId,
|
|
13132
|
+
const depositOnlyY = maxDeltaId.lt(new BN15(0)) || maxDeltaId.isZero() && !favorXInActiveId;
|
|
13133
|
+
const depositOnlyX = minDeltaId.gt(new BN15(0)) || minDeltaId.isZero() && favorXInActiveId;
|
|
13134
|
+
if (depositOnlyY) {
|
|
13135
|
+
const { base, delta } = strategyParameterBuilder.findYParameters(
|
|
13136
|
+
amountY,
|
|
13109
13137
|
minDeltaId,
|
|
13110
13138
|
maxDeltaId,
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
x0,
|
|
13114
|
-
new BN15(0),
|
|
13115
|
-
binStep,
|
|
13116
|
-
favorXInActiveBin
|
|
13117
|
-
).reduce((acc, bin) => {
|
|
13118
|
-
return acc.add(bin.amountX);
|
|
13119
|
-
}, new BN15(0));
|
|
13139
|
+
activeId
|
|
13140
|
+
);
|
|
13120
13141
|
return {
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
|
|
13142
|
+
x0: new BN15(0),
|
|
13143
|
+
deltaX: new BN15(0),
|
|
13144
|
+
y0: base,
|
|
13145
|
+
deltaY: delta
|
|
13124
13146
|
};
|
|
13125
13147
|
}
|
|
13126
|
-
|
|
13127
|
-
const
|
|
13128
|
-
|
|
13129
|
-
const a1 = m2.neg().mul(m1.sub(m2).addn(1));
|
|
13130
|
-
const a2 = m1.mul(m1.addn(1)).divn(2);
|
|
13131
|
-
const a3 = m2.mul(m2.subn(1)).divn(2);
|
|
13132
|
-
const a = a1.add(a2.sub(a3));
|
|
13133
|
-
const deltaY = amountXInQuoteValue.div(a);
|
|
13134
|
-
const y0 = deltaY.neg().mul(m2).add(deltaY);
|
|
13135
|
-
const amountY = toAmountIntoBins(
|
|
13136
|
-
activeId,
|
|
13148
|
+
if (depositOnlyX) {
|
|
13149
|
+
const { base, delta } = strategyParameterBuilder.findXParameters(
|
|
13150
|
+
amountX,
|
|
13137
13151
|
minDeltaId,
|
|
13138
13152
|
maxDeltaId,
|
|
13139
|
-
new BN15(0),
|
|
13140
|
-
deltaY,
|
|
13141
|
-
new BN15(0),
|
|
13142
|
-
y0,
|
|
13143
13153
|
binStep,
|
|
13144
|
-
|
|
13145
|
-
)
|
|
13146
|
-
return acc.add(bin.amountY);
|
|
13147
|
-
}, new BN15(0));
|
|
13154
|
+
activeId
|
|
13155
|
+
);
|
|
13148
13156
|
return {
|
|
13149
|
-
|
|
13150
|
-
|
|
13151
|
-
|
|
13157
|
+
x0: base,
|
|
13158
|
+
deltaX: delta,
|
|
13159
|
+
y0: new BN15(0),
|
|
13160
|
+
deltaY: new BN15(0)
|
|
13152
13161
|
};
|
|
13153
13162
|
}
|
|
13163
|
+
const maxDeltaIdBidSide = favorXInActiveId ? new BN15(-1) : new BN15(0);
|
|
13164
|
+
const minDeltaIdAskSide = favorXInActiveId ? new BN15(0) : new BN15(1);
|
|
13165
|
+
const { base: y0, delta: deltaY } = strategyParameterBuilder.findYParameters(
|
|
13166
|
+
amountY,
|
|
13167
|
+
minDeltaId,
|
|
13168
|
+
maxDeltaIdBidSide,
|
|
13169
|
+
activeId
|
|
13170
|
+
);
|
|
13171
|
+
const { base: x0, delta: deltaX } = strategyParameterBuilder.findXParameters(
|
|
13172
|
+
amountX,
|
|
13173
|
+
minDeltaIdAskSide,
|
|
13174
|
+
maxDeltaId,
|
|
13175
|
+
binStep,
|
|
13176
|
+
activeId
|
|
13177
|
+
);
|
|
13178
|
+
return {
|
|
13179
|
+
x0,
|
|
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
|
|
13240
|
+
);
|
|
13241
|
+
return { ataPubKey: toAccount, ix };
|
|
13242
|
+
} else {
|
|
13243
|
+
console.error("Error::getOrCreateATAInstruction", e);
|
|
13244
|
+
throw e;
|
|
13245
|
+
}
|
|
13246
|
+
}
|
|
13247
|
+
};
|
|
13248
|
+
async function getTokenBalance(conn, tokenAccount) {
|
|
13249
|
+
const acc = await getAccount(conn, tokenAccount);
|
|
13250
|
+
return acc.amount;
|
|
13251
|
+
}
|
|
13252
|
+
var parseLogs = (eventParser, logs) => {
|
|
13253
|
+
if (!logs.length)
|
|
13254
|
+
throw new Error("No logs found");
|
|
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
|
|
13285
|
+
);
|
|
13286
|
+
if (wSolATAAccount) {
|
|
13287
|
+
const closedWrappedSolInstruction = createCloseAccountInstruction(
|
|
13288
|
+
wSolATAAccount,
|
|
13289
|
+
owner,
|
|
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;
|
|
13309
|
+
}
|
|
13310
|
+
buffer = Math.max(0, buffer);
|
|
13311
|
+
buffer = Math.min(1, buffer);
|
|
13312
|
+
const estimatedComputeUnitUsage = await getSimulationComputeUnits(
|
|
13313
|
+
connection,
|
|
13314
|
+
instructions,
|
|
13315
|
+
feePayer,
|
|
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;
|
|
13323
|
+
}
|
|
13324
|
+
return estimatedComputeUnitUsage + extraComputeUnitBuffer;
|
|
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 });
|
|
13154
13337
|
};
|
|
13155
|
-
|
|
13156
|
-
|
|
13157
|
-
|
|
13158
|
-
|
|
13159
|
-
|
|
13160
|
-
|
|
13161
|
-
|
|
13162
|
-
|
|
13163
|
-
|
|
13164
|
-
|
|
13165
|
-
|
|
13166
|
-
const m2 = maxDeltaId.neg();
|
|
13167
|
-
const b = m1.sub(m2).addn(1);
|
|
13168
|
-
const c = m1.mul(m1.addn(1)).divn(2);
|
|
13169
|
-
const d = m2.mul(m2.subn(1)).divn(2);
|
|
13170
|
-
const a = b.sub(c.sub(d).div(m1.addn(1)));
|
|
13171
|
-
return amountY.div(a);
|
|
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
|
+
);
|
|
13172
13349
|
}
|
|
13173
|
-
function
|
|
13174
|
-
|
|
13175
|
-
return {
|
|
13176
|
-
base: new BN16(0),
|
|
13177
|
-
delta: new BN16(0)
|
|
13178
|
-
};
|
|
13179
|
-
}
|
|
13180
|
-
let baseY0 = findBaseY0(amountY, minDeltaId, maxDeltaId);
|
|
13181
|
-
while (true) {
|
|
13182
|
-
const deltaY = baseY0.neg().div(minDeltaId.neg().addn(1));
|
|
13183
|
-
const amountInBins = getAmountInBinsBidSide(
|
|
13184
|
-
activeId,
|
|
13185
|
-
minDeltaId,
|
|
13186
|
-
maxDeltaId,
|
|
13187
|
-
deltaY,
|
|
13188
|
-
baseY0
|
|
13189
|
-
);
|
|
13190
|
-
const totalAmountY = amountInBins.reduce((acc, { amountY: amountY2 }) => {
|
|
13191
|
-
return acc.add(amountY2);
|
|
13192
|
-
}, new BN16(0));
|
|
13193
|
-
if (totalAmountY.gt(amountY)) {
|
|
13194
|
-
baseY0 = baseY0.sub(new BN16(1));
|
|
13195
|
-
} else {
|
|
13196
|
-
return {
|
|
13197
|
-
base: baseY0,
|
|
13198
|
-
delta: deltaY
|
|
13199
|
-
};
|
|
13200
|
-
}
|
|
13201
|
-
}
|
|
13350
|
+
function decodeAccount(program, accountName, buffer) {
|
|
13351
|
+
return program.coder.accounts.decode(accountName, buffer);
|
|
13202
13352
|
}
|
|
13203
|
-
function
|
|
13204
|
-
|
|
13205
|
-
|
|
13353
|
+
function getAccountDiscriminator(accountName) {
|
|
13354
|
+
return dlmm_default.accounts.find(
|
|
13355
|
+
(acc) => acc.name.toLowerCase() === accountName.toLowerCase()
|
|
13356
|
+
)?.discriminator;
|
|
13357
|
+
}
|
|
13358
|
+
function capSlippagePercentage(slippage) {
|
|
13359
|
+
if (slippage > 100) {
|
|
13360
|
+
slippage = 100;
|
|
13206
13361
|
}
|
|
13207
|
-
|
|
13208
|
-
|
|
13209
|
-
let m1 = minDeltaId;
|
|
13210
|
-
let m2 = maxDeltaId;
|
|
13211
|
-
for (let m = m1.toNumber(); m <= m2.toNumber(); m++) {
|
|
13212
|
-
const binId = activeId.addn(m);
|
|
13213
|
-
const pm = getQPriceFromId(binId.neg(), binStep);
|
|
13214
|
-
b = b.add(pm);
|
|
13215
|
-
const cDelta = new BN16(m).mul(pm).div(m2);
|
|
13216
|
-
c = c.add(cDelta);
|
|
13362
|
+
if (slippage < 0) {
|
|
13363
|
+
slippage = 0;
|
|
13217
13364
|
}
|
|
13218
|
-
return
|
|
13365
|
+
return slippage;
|
|
13219
13366
|
}
|
|
13220
|
-
|
|
13221
|
-
|
|
13222
|
-
|
|
13223
|
-
|
|
13224
|
-
|
|
13225
|
-
|
|
13367
|
+
|
|
13368
|
+
// src/dlmm/helpers/accountFilters.ts
|
|
13369
|
+
import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes";
|
|
13370
|
+
var presetParameter2BinStepFilter = (binStep) => {
|
|
13371
|
+
return {
|
|
13372
|
+
memcmp: {
|
|
13373
|
+
bytes: bs58.encode(binStep.toArrayLike(Buffer, "le", 2)),
|
|
13374
|
+
offset: 8
|
|
13375
|
+
}
|
|
13376
|
+
};
|
|
13377
|
+
};
|
|
13378
|
+
var presetParameter2BaseFactorFilter = (baseFactor) => {
|
|
13379
|
+
return {
|
|
13380
|
+
memcmp: {
|
|
13381
|
+
bytes: bs58.encode(baseFactor.toArrayLike(Buffer, "le", 2)),
|
|
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
|
|
13391
|
+
}
|
|
13392
|
+
};
|
|
13393
|
+
};
|
|
13394
|
+
var binArrayLbPairFilter = (lbPair) => {
|
|
13395
|
+
return {
|
|
13396
|
+
memcmp: {
|
|
13397
|
+
bytes: lbPair.toBase58(),
|
|
13398
|
+
offset: 8 + 16
|
|
13399
|
+
}
|
|
13400
|
+
};
|
|
13401
|
+
};
|
|
13402
|
+
var positionOwnerFilter = (owner) => {
|
|
13403
|
+
return {
|
|
13404
|
+
memcmp: {
|
|
13405
|
+
bytes: owner.toBase58(),
|
|
13406
|
+
offset: 8 + 32
|
|
13407
|
+
}
|
|
13408
|
+
};
|
|
13409
|
+
};
|
|
13410
|
+
var positionLbPairFilter = (lbPair) => {
|
|
13411
|
+
return {
|
|
13412
|
+
memcmp: {
|
|
13413
|
+
bytes: bs58.encode(lbPair.toBuffer()),
|
|
13414
|
+
offset: 8
|
|
13415
|
+
}
|
|
13416
|
+
};
|
|
13417
|
+
};
|
|
13418
|
+
var positionV2Filter = () => {
|
|
13419
|
+
return {
|
|
13420
|
+
memcmp: {
|
|
13421
|
+
bytes: bs58.encode(Buffer.from(getAccountDiscriminator("positionV2"))),
|
|
13422
|
+
offset: 0
|
|
13423
|
+
}
|
|
13424
|
+
};
|
|
13425
|
+
};
|
|
13426
|
+
|
|
13427
|
+
// src/dlmm/helpers/positions/index.ts
|
|
13428
|
+
import BN18 from "bn.js";
|
|
13429
|
+
|
|
13430
|
+
// src/dlmm/helpers/positions/wrapper.ts
|
|
13431
|
+
import BN17 from "bn.js";
|
|
13432
|
+
function combineBaseAndExtendedPositionBinData(base, extended) {
|
|
13433
|
+
const combinedLiquidityShares = base.liquidityShares;
|
|
13434
|
+
const combinedRewardInfos = base.rewardInfos;
|
|
13435
|
+
const combinedFeeInfos = base.feeInfos;
|
|
13436
|
+
for (const binData of extended) {
|
|
13437
|
+
combinedLiquidityShares.push(binData.liquidityShare);
|
|
13438
|
+
combinedRewardInfos.push(binData.rewardInfo);
|
|
13439
|
+
combinedFeeInfos.push(binData.feeInfo);
|
|
13226
13440
|
}
|
|
13227
|
-
|
|
13228
|
-
|
|
13229
|
-
|
|
13230
|
-
|
|
13231
|
-
|
|
13232
|
-
|
|
13233
|
-
|
|
13234
|
-
|
|
13235
|
-
|
|
13236
|
-
|
|
13441
|
+
return {
|
|
13442
|
+
liquidityShares: combinedLiquidityShares,
|
|
13443
|
+
rewardInfos: combinedRewardInfos,
|
|
13444
|
+
feeInfos: combinedFeeInfos
|
|
13445
|
+
};
|
|
13446
|
+
}
|
|
13447
|
+
function wrapPosition(program, key, account) {
|
|
13448
|
+
const disc = account.data.subarray(0, 8);
|
|
13449
|
+
if (disc.equals(Buffer.from(getAccountDiscriminator("positionV2")))) {
|
|
13450
|
+
const state = decodeAccount(
|
|
13451
|
+
program,
|
|
13452
|
+
"positionV2",
|
|
13453
|
+
account.data
|
|
13237
13454
|
);
|
|
13238
|
-
const
|
|
13239
|
-
|
|
13240
|
-
|
|
13241
|
-
|
|
13242
|
-
|
|
13243
|
-
|
|
13244
|
-
|
|
13245
|
-
|
|
13246
|
-
|
|
13247
|
-
|
|
13248
|
-
|
|
13455
|
+
const extended = decodeExtendedPosition(
|
|
13456
|
+
state,
|
|
13457
|
+
program,
|
|
13458
|
+
account.data.subarray(8 + POSITION_MIN_SIZE)
|
|
13459
|
+
);
|
|
13460
|
+
const combinedPositionBinData = combineBaseAndExtendedPositionBinData(
|
|
13461
|
+
state,
|
|
13462
|
+
extended
|
|
13463
|
+
);
|
|
13464
|
+
return new PositionV2Wrapper(key, state, extended, combinedPositionBinData);
|
|
13465
|
+
} else {
|
|
13466
|
+
throw new Error("Unknown position account");
|
|
13249
13467
|
}
|
|
13250
13468
|
}
|
|
13251
|
-
var
|
|
13252
|
-
|
|
13253
|
-
|
|
13469
|
+
var PositionV2Wrapper = class {
|
|
13470
|
+
constructor(positionAddress, inner, extended, combinedPositionBinData) {
|
|
13471
|
+
this.positionAddress = positionAddress;
|
|
13472
|
+
this.inner = inner;
|
|
13473
|
+
this.extended = extended;
|
|
13474
|
+
this.combinedPositionBinData = combinedPositionBinData;
|
|
13254
13475
|
}
|
|
13255
|
-
|
|
13256
|
-
return
|
|
13476
|
+
address() {
|
|
13477
|
+
return this.positionAddress;
|
|
13257
13478
|
}
|
|
13258
|
-
|
|
13259
|
-
|
|
13260
|
-
const deltaX = x0.neg().div(maxDeltaId);
|
|
13261
|
-
const totalAmountX = toAmountIntoBins(
|
|
13262
|
-
activeId,
|
|
13263
|
-
minDeltaId,
|
|
13264
|
-
maxDeltaId,
|
|
13265
|
-
deltaX,
|
|
13266
|
-
new BN16(0),
|
|
13267
|
-
x0,
|
|
13268
|
-
new BN16(0),
|
|
13269
|
-
binStep,
|
|
13270
|
-
favorXInActiveBin
|
|
13271
|
-
).reduce((acc, bin) => {
|
|
13272
|
-
return acc.add(bin.amountX);
|
|
13273
|
-
}, new BN16(0));
|
|
13274
|
-
return {
|
|
13275
|
-
base: x0,
|
|
13276
|
-
delta: deltaX,
|
|
13277
|
-
amountX: totalAmountX
|
|
13278
|
-
};
|
|
13479
|
+
totalClaimedRewards() {
|
|
13480
|
+
return this.inner.totalClaimedRewards;
|
|
13279
13481
|
}
|
|
13280
|
-
|
|
13281
|
-
|
|
13282
|
-
const m2 = maxDeltaId.neg();
|
|
13283
|
-
const a1 = m1.sub(m2).addn(1);
|
|
13284
|
-
const a2 = m1.mul(m1.addn(1)).divn(2);
|
|
13285
|
-
const a3 = m2.mul(m2.subn(1)).divn(2);
|
|
13286
|
-
const a = m1.sub(a3.sub(a2)).div(m1);
|
|
13287
|
-
const y0 = amountXInQuoteValue.div(a);
|
|
13288
|
-
const deltaY = y0.neg().div(m1);
|
|
13289
|
-
const amountY = toAmountIntoBins(
|
|
13290
|
-
activeId,
|
|
13291
|
-
minDeltaId,
|
|
13292
|
-
maxDeltaId,
|
|
13293
|
-
new BN16(0),
|
|
13294
|
-
deltaY,
|
|
13295
|
-
new BN16(0),
|
|
13296
|
-
y0,
|
|
13297
|
-
binStep,
|
|
13298
|
-
favorXInActiveBin
|
|
13299
|
-
).reduce((acc, bin) => {
|
|
13300
|
-
return acc.add(bin.amountY);
|
|
13301
|
-
}, new BN16(0));
|
|
13302
|
-
return {
|
|
13303
|
-
base: y0,
|
|
13304
|
-
delta: deltaY,
|
|
13305
|
-
amountY
|
|
13306
|
-
};
|
|
13482
|
+
feeOwner() {
|
|
13483
|
+
return this.inner.feeOwner;
|
|
13307
13484
|
}
|
|
13308
|
-
|
|
13309
|
-
|
|
13310
|
-
// src/dlmm/helpers/rebalance/liquidity_strategy/spot.ts
|
|
13311
|
-
import BN17 from "bn.js";
|
|
13312
|
-
function findY0(amountY, minDeltaId, maxDeltaId) {
|
|
13313
|
-
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new BN17(0)) || amountY.isZero()) {
|
|
13314
|
-
return new BN17(0);
|
|
13485
|
+
lockReleasePoint() {
|
|
13486
|
+
return this.inner.lockReleasePoint;
|
|
13315
13487
|
}
|
|
13316
|
-
|
|
13317
|
-
|
|
13318
|
-
const delta = m1.sub(m2).addn(1);
|
|
13319
|
-
return amountY.div(delta);
|
|
13320
|
-
}
|
|
13321
|
-
function findBaseX02(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13322
|
-
let totalWeight = new BN17(0);
|
|
13323
|
-
const minBinId = activeId.add(minDeltaId);
|
|
13324
|
-
const maxBinId = activeId.add(maxDeltaId);
|
|
13325
|
-
let baseFactor = getQPriceBaseFactor(binStep);
|
|
13326
|
-
let basePrice = getQPriceFromId(maxBinId.neg(), binStep);
|
|
13327
|
-
for (let binId = minBinId.toNumber(); binId <= maxBinId.toNumber(); binId++) {
|
|
13328
|
-
totalWeight = totalWeight.add(basePrice);
|
|
13329
|
-
basePrice = basePrice.mul(baseFactor).shrn(SCALE_OFFSET);
|
|
13488
|
+
operator() {
|
|
13489
|
+
return this.inner.operator;
|
|
13330
13490
|
}
|
|
13331
|
-
|
|
13332
|
-
|
|
13333
|
-
function findX0(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13334
|
-
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN17(0)) || amountX.isZero()) {
|
|
13335
|
-
return new BN17(0);
|
|
13491
|
+
totalClaimedFeeYAmount() {
|
|
13492
|
+
return this.inner.totalClaimedFeeYAmount;
|
|
13336
13493
|
}
|
|
13337
|
-
|
|
13338
|
-
|
|
13339
|
-
|
|
13340
|
-
|
|
13341
|
-
|
|
13342
|
-
|
|
13343
|
-
|
|
13344
|
-
|
|
13345
|
-
|
|
13346
|
-
|
|
13347
|
-
|
|
13348
|
-
|
|
13349
|
-
|
|
13350
|
-
|
|
13351
|
-
|
|
13494
|
+
totalClaimedFeeXAmount() {
|
|
13495
|
+
return this.inner.totalClaimedFeeXAmount;
|
|
13496
|
+
}
|
|
13497
|
+
lbPair() {
|
|
13498
|
+
return this.inner.lbPair;
|
|
13499
|
+
}
|
|
13500
|
+
lowerBinId() {
|
|
13501
|
+
return new BN17(this.inner.lowerBinId);
|
|
13502
|
+
}
|
|
13503
|
+
upperBinId() {
|
|
13504
|
+
return new BN17(this.inner.upperBinId);
|
|
13505
|
+
}
|
|
13506
|
+
liquidityShares() {
|
|
13507
|
+
return this.combinedPositionBinData.liquidityShares;
|
|
13508
|
+
}
|
|
13509
|
+
rewardInfos() {
|
|
13510
|
+
return this.combinedPositionBinData.rewardInfos;
|
|
13511
|
+
}
|
|
13512
|
+
feeInfos() {
|
|
13513
|
+
return this.combinedPositionBinData.feeInfos;
|
|
13514
|
+
}
|
|
13515
|
+
lastUpdatedAt() {
|
|
13516
|
+
return this.inner.lastUpdatedAt;
|
|
13517
|
+
}
|
|
13518
|
+
getBinArrayIndexesCoverage() {
|
|
13519
|
+
const isExtended = this.extended.length > 0;
|
|
13520
|
+
if (isExtended) {
|
|
13521
|
+
return getBinArrayIndexesCoverage(this.lowerBinId(), this.upperBinId());
|
|
13352
13522
|
} else {
|
|
13353
|
-
|
|
13354
|
-
|
|
13523
|
+
const lowerBinArrayIndex = binIdToBinArrayIndex(this.lowerBinId());
|
|
13524
|
+
const upperBinArrayIndex = lowerBinArrayIndex.add(new BN17(1));
|
|
13525
|
+
return [lowerBinArrayIndex, upperBinArrayIndex];
|
|
13355
13526
|
}
|
|
13356
13527
|
}
|
|
13357
|
-
|
|
13358
|
-
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
base: findX0(amountX, minDeltaId, maxDeltaId, binStep, activeId),
|
|
13362
|
-
delta: new BN17(0)
|
|
13363
|
-
};
|
|
13528
|
+
getBinArrayKeysCoverage(programId) {
|
|
13529
|
+
return this.getBinArrayIndexesCoverage().map(
|
|
13530
|
+
(index) => deriveBinArray(this.lbPair(), index, programId)[0]
|
|
13531
|
+
);
|
|
13364
13532
|
}
|
|
13365
|
-
|
|
13366
|
-
return
|
|
13367
|
-
base: findY0(amountY, minDeltaId, maxDeltaId),
|
|
13368
|
-
delta: new BN17(0)
|
|
13369
|
-
};
|
|
13533
|
+
version() {
|
|
13534
|
+
return 1 /* V2 */;
|
|
13370
13535
|
}
|
|
13371
|
-
|
|
13372
|
-
|
|
13373
|
-
const totalAmountX = toAmountIntoBins(
|
|
13374
|
-
activeId,
|
|
13375
|
-
minDeltaId,
|
|
13376
|
-
maxDeltaId,
|
|
13377
|
-
new BN17(0),
|
|
13378
|
-
new BN17(0),
|
|
13379
|
-
x0,
|
|
13380
|
-
new BN17(0),
|
|
13381
|
-
binStep,
|
|
13382
|
-
favorXInActiveBin
|
|
13383
|
-
).reduce((acc, bin) => {
|
|
13384
|
-
return acc.add(bin.amountX);
|
|
13385
|
-
}, new BN17(0));
|
|
13386
|
-
return {
|
|
13387
|
-
base: new BN17(x0.toString()),
|
|
13388
|
-
delta: new BN17(0),
|
|
13389
|
-
amountX: totalAmountX
|
|
13390
|
-
};
|
|
13536
|
+
owner() {
|
|
13537
|
+
return this.inner.owner;
|
|
13391
13538
|
}
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
const amountY = toAmountIntoBins(
|
|
13395
|
-
activeId,
|
|
13396
|
-
minDeltaId,
|
|
13397
|
-
maxDeltaId,
|
|
13398
|
-
new BN17(0),
|
|
13399
|
-
new BN17(0),
|
|
13400
|
-
new BN17(0),
|
|
13401
|
-
y0,
|
|
13402
|
-
binStep,
|
|
13403
|
-
favorXInActiveBin
|
|
13404
|
-
).reduce((acc, bin) => {
|
|
13405
|
-
return acc.add(bin.amountY);
|
|
13406
|
-
}, new BN17(0));
|
|
13407
|
-
return {
|
|
13408
|
-
base: y0,
|
|
13409
|
-
delta: new BN17(0),
|
|
13410
|
-
amountY
|
|
13411
|
-
};
|
|
13539
|
+
width() {
|
|
13540
|
+
return this.upperBinId().sub(this.lowerBinId()).add(new BN17(1));
|
|
13412
13541
|
}
|
|
13413
13542
|
};
|
|
13414
13543
|
|
|
13415
|
-
// src/dlmm/helpers/
|
|
13416
|
-
|
|
13417
|
-
|
|
13418
|
-
|
|
13419
|
-
|
|
13420
|
-
|
|
13421
|
-
|
|
13422
|
-
return new CurveStrategyParameterBuilder();
|
|
13423
|
-
case 2 /* BidAsk */:
|
|
13424
|
-
return new BidAskStrategyParameterBuilder();
|
|
13425
|
-
default:
|
|
13426
|
-
throw new Error("Strategy not supported");
|
|
13544
|
+
// src/dlmm/helpers/positions/index.ts
|
|
13545
|
+
function getBinArrayIndexesCoverage(lowerBinId, upperBinId) {
|
|
13546
|
+
const lowerBinArrayIndex = binIdToBinArrayIndex(lowerBinId);
|
|
13547
|
+
const upperBinArrayIndex = binIdToBinArrayIndex(upperBinId);
|
|
13548
|
+
const binArrayIndexes = [];
|
|
13549
|
+
for (let i = lowerBinArrayIndex.toNumber(); i <= upperBinArrayIndex.toNumber(); i++) {
|
|
13550
|
+
binArrayIndexes.push(new BN18(i));
|
|
13427
13551
|
}
|
|
13552
|
+
return binArrayIndexes;
|
|
13428
13553
|
}
|
|
13429
|
-
function
|
|
13430
|
-
|
|
13431
|
-
|
|
13432
|
-
|
|
13433
|
-
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
|
|
13554
|
+
function getBinArrayKeysCoverage2(lowerBinId, upperBinId, lbPair, programId) {
|
|
13555
|
+
const binArrayIndexes = getBinArrayIndexesCoverage(lowerBinId, upperBinId);
|
|
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();
|
|
13585
|
+
}
|
|
13586
|
+
function chunkBinRange(minBinId, maxBinId) {
|
|
13587
|
+
const chunkedBinRange = [];
|
|
13588
|
+
let startBinId = minBinId;
|
|
13589
|
+
while (startBinId <= maxBinId) {
|
|
13590
|
+
const endBinId = Math.min(
|
|
13591
|
+
startBinId + DEFAULT_BIN_PER_POSITION.toNumber() - 1,
|
|
13592
|
+
maxBinId
|
|
13593
|
+
);
|
|
13594
|
+
chunkedBinRange.push({
|
|
13595
|
+
lowerBinId: startBinId,
|
|
13596
|
+
upperBinId: endBinId
|
|
13597
|
+
});
|
|
13598
|
+
startBinId += DEFAULT_BIN_PER_POSITION.toNumber();
|
|
13437
13599
|
}
|
|
13438
|
-
|
|
13439
|
-
|
|
13440
|
-
|
|
13441
|
-
|
|
13442
|
-
|
|
13443
|
-
|
|
13444
|
-
|
|
13445
|
-
|
|
13600
|
+
return chunkedBinRange;
|
|
13601
|
+
}
|
|
13602
|
+
async function getPositionExpandRentExemption(currentMinBinId, currentMaxBinId, connection, binCountToExpand) {
|
|
13603
|
+
const currentPositionWidth = currentMaxBinId.sub(currentMinBinId).addn(1);
|
|
13604
|
+
const positionWidthAfterExpand = currentPositionWidth.add(binCountToExpand);
|
|
13605
|
+
if (positionWidthAfterExpand.lte(DEFAULT_BIN_PER_POSITION)) {
|
|
13606
|
+
return 0;
|
|
13607
|
+
} else {
|
|
13608
|
+
const binCountInExpandedBytes = positionWidthAfterExpand.sub(
|
|
13609
|
+
DEFAULT_BIN_PER_POSITION
|
|
13446
13610
|
);
|
|
13447
|
-
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13611
|
+
const expandSize = binCountInExpandedBytes.toNumber() * POSITION_BIN_DATA_SIZE;
|
|
13612
|
+
const [minimumLamports, rentExemptionLamports] = await Promise.all([
|
|
13613
|
+
connection.getMinimumBalanceForRentExemption(0),
|
|
13614
|
+
connection.getMinimumBalanceForRentExemption(expandSize)
|
|
13615
|
+
]);
|
|
13616
|
+
return rentExemptionLamports - minimumLamports;
|
|
13453
13617
|
}
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13618
|
+
}
|
|
13619
|
+
function getExtendedPositionBinCount(minBinId, maxBinId) {
|
|
13620
|
+
const width = maxBinId.sub(minBinId).addn(1);
|
|
13621
|
+
const extended = width.sub(DEFAULT_BIN_PER_POSITION);
|
|
13622
|
+
return extended.lte(new BN18(0)) ? new BN18(0) : extended;
|
|
13623
|
+
}
|
|
13624
|
+
function decodeExtendedPosition(base, program, bytes) {
|
|
13625
|
+
const width = base.upperBinId - base.lowerBinId + 1;
|
|
13626
|
+
const extendedWidth = width - DEFAULT_BIN_PER_POSITION.toNumber();
|
|
13627
|
+
const extendedPosition = [];
|
|
13628
|
+
for (let i = 0; i < extendedWidth; i++) {
|
|
13629
|
+
const offset = i * POSITION_BIN_DATA_SIZE;
|
|
13630
|
+
const data = bytes.subarray(offset, offset + POSITION_BIN_DATA_SIZE);
|
|
13631
|
+
const decodedPositionBinData = program.coder.types.decode(
|
|
13632
|
+
// TODO: Find a type safe way
|
|
13633
|
+
"positionBinData",
|
|
13634
|
+
data
|
|
13461
13635
|
);
|
|
13462
|
-
|
|
13463
|
-
x0: base,
|
|
13464
|
-
deltaX: delta,
|
|
13465
|
-
y0: new BN18(0),
|
|
13466
|
-
deltaY: new BN18(0)
|
|
13467
|
-
};
|
|
13636
|
+
extendedPosition.push(decodedPositionBinData);
|
|
13468
13637
|
}
|
|
13469
|
-
|
|
13470
|
-
const minDeltaIdAskSide = favorXInActiveId ? new BN18(0) : new BN18(1);
|
|
13471
|
-
const { base: y0, delta: deltaY } = strategyParameterBuilder.findYParameters(
|
|
13472
|
-
amountY,
|
|
13473
|
-
minDeltaId,
|
|
13474
|
-
maxDeltaIdBidSide,
|
|
13475
|
-
activeId
|
|
13476
|
-
);
|
|
13477
|
-
const { base: x0, delta: deltaX } = strategyParameterBuilder.findXParameters(
|
|
13478
|
-
amountX,
|
|
13479
|
-
minDeltaIdAskSide,
|
|
13480
|
-
maxDeltaId,
|
|
13481
|
-
binStep,
|
|
13482
|
-
activeId
|
|
13483
|
-
);
|
|
13484
|
-
return {
|
|
13485
|
-
x0,
|
|
13486
|
-
deltaX,
|
|
13487
|
-
y0,
|
|
13488
|
-
deltaY
|
|
13489
|
-
};
|
|
13638
|
+
return extendedPosition;
|
|
13490
13639
|
}
|
|
13491
13640
|
|
|
13492
13641
|
// src/dlmm/helpers/rebalance/strategy/balanced.ts
|
|
@@ -19396,6 +19545,7 @@ export {
|
|
|
19396
19545
|
PairStatus,
|
|
19397
19546
|
PairType,
|
|
19398
19547
|
PositionVersion,
|
|
19548
|
+
RebalancePosition,
|
|
19399
19549
|
ResizeSide,
|
|
19400
19550
|
SCALE,
|
|
19401
19551
|
SCALE_OFFSET,
|
|
@@ -19410,6 +19560,7 @@ export {
|
|
|
19410
19560
|
autoFillYByStrategy,
|
|
19411
19561
|
autoFillYByWeight,
|
|
19412
19562
|
binIdToBinArrayIndex,
|
|
19563
|
+
buildLiquidityStrategyParameters,
|
|
19413
19564
|
calculateBidAskDistribution,
|
|
19414
19565
|
calculateNormalDistribution,
|
|
19415
19566
|
calculateSpotDistribution,
|
|
@@ -19446,6 +19597,9 @@ export {
|
|
|
19446
19597
|
fromWeightDistributionToAmount,
|
|
19447
19598
|
fromWeightDistributionToAmountOneSide,
|
|
19448
19599
|
getAccountDiscriminator,
|
|
19600
|
+
getAmountInBinsAskSide,
|
|
19601
|
+
getAmountInBinsBidSide,
|
|
19602
|
+
getAutoFillAmountByRebalancedPosition,
|
|
19449
19603
|
getBaseFee,
|
|
19450
19604
|
getBinArrayLowerUpperBinId,
|
|
19451
19605
|
getBinArraysRequiredByPositionRange,
|
|
@@ -19453,9 +19607,11 @@ export {
|
|
|
19453
19607
|
getBinIdIndexInBinArray,
|
|
19454
19608
|
getEstimatedComputeUnitIxWithBuffer,
|
|
19455
19609
|
getEstimatedComputeUnitUsageWithBuffer,
|
|
19610
|
+
getLiquidityStrategyParameterBuilder,
|
|
19456
19611
|
getOrCreateATAInstruction,
|
|
19457
19612
|
getOutAmount,
|
|
19458
19613
|
getPriceOfBinByBinId,
|
|
19614
|
+
getRebalanceBinArrayIndexesAndBitmapCoverage,
|
|
19459
19615
|
getTokenBalance,
|
|
19460
19616
|
getTokenDecimals,
|
|
19461
19617
|
getTokenProgramId,
|
|
@@ -19466,11 +19622,14 @@ export {
|
|
|
19466
19622
|
isOverflowDefaultBinArrayBitmap,
|
|
19467
19623
|
parseLogs,
|
|
19468
19624
|
range,
|
|
19625
|
+
suggestBalancedXParametersFromY,
|
|
19626
|
+
suggestBalancedYParametersFromX,
|
|
19469
19627
|
swapExactInQuoteAtBin,
|
|
19470
19628
|
swapExactOutQuoteAtBin,
|
|
19471
19629
|
toAmountAskSide,
|
|
19472
19630
|
toAmountBidSide,
|
|
19473
19631
|
toAmountBothSide,
|
|
19632
|
+
toAmountIntoBins,
|
|
19474
19633
|
toAmountsBothSideByStrategy,
|
|
19475
19634
|
toStrategyParameters,
|
|
19476
19635
|
toWeightDistribution,
|