@meteora-ag/dlmm 1.6.0-rc.17 → 1.6.0-rc.19
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 +55 -3
- package/dist/index.js +1774 -1439
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1793 -1458
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
SystemProgram as SystemProgram2,
|
|
20
20
|
Transaction
|
|
21
21
|
} from "@solana/web3.js";
|
|
22
|
-
import
|
|
22
|
+
import Decimal8 from "decimal.js";
|
|
23
23
|
|
|
24
24
|
// src/dlmm/constants/index.ts
|
|
25
25
|
import { LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js";
|
|
@@ -11779,1594 +11779,1861 @@ 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
|
-
new TransactionInstruction3({
|
|
11864
|
-
keys: [
|
|
11865
|
-
{
|
|
11866
|
-
pubkey: to,
|
|
11867
|
-
isSigner: false,
|
|
11868
|
-
isWritable: true
|
|
11869
|
-
}
|
|
11870
|
-
],
|
|
11871
|
-
data: Buffer.from(new Uint8Array([17])),
|
|
11872
|
-
programId: TOKEN_PROGRAM_ID3
|
|
11873
|
-
})
|
|
11874
|
-
];
|
|
11875
|
-
};
|
|
11876
|
-
var unwrapSOLInstruction = async (owner, allowOwnerOffCurve = true) => {
|
|
11877
|
-
const wSolATAAccount = getAssociatedTokenAddressSync(
|
|
11878
|
-
NATIVE_MINT,
|
|
11879
|
-
owner,
|
|
11880
|
-
allowOwnerOffCurve
|
|
11881
|
-
);
|
|
11882
|
-
if (wSolATAAccount) {
|
|
11883
|
-
const closedWrappedSolInstruction = createCloseAccountInstruction(
|
|
11884
|
-
wSolATAAccount,
|
|
11885
|
-
owner,
|
|
11886
|
-
owner,
|
|
11887
|
-
[],
|
|
11888
|
-
TOKEN_PROGRAM_ID3
|
|
11921
|
+
if (onlyDepositToAskSide(minDeltaId, favorXInActiveBin)) {
|
|
11922
|
+
return getAmountInBinsAskSide(
|
|
11923
|
+
activeId,
|
|
11924
|
+
binStep,
|
|
11925
|
+
minDeltaId,
|
|
11926
|
+
maxDeltaId,
|
|
11927
|
+
deltaX,
|
|
11928
|
+
x0
|
|
11889
11929
|
);
|
|
11890
|
-
return closedWrappedSolInstruction;
|
|
11891
|
-
}
|
|
11892
|
-
return null;
|
|
11893
|
-
};
|
|
11894
|
-
async function chunkedGetMultipleAccountInfos(connection, pks, chunkSize = 100) {
|
|
11895
|
-
const accountInfos = (await Promise.all(
|
|
11896
|
-
chunks(pks, chunkSize).map(
|
|
11897
|
-
(chunk) => connection.getMultipleAccountsInfo(chunk)
|
|
11898
|
-
)
|
|
11899
|
-
)).flat();
|
|
11900
|
-
return accountInfos;
|
|
11901
|
-
}
|
|
11902
|
-
var getEstimatedComputeUnitUsageWithBuffer = async (connection, instructions, feePayer, buffer) => {
|
|
11903
|
-
if (!buffer) {
|
|
11904
|
-
buffer = 0.1;
|
|
11905
11930
|
}
|
|
11906
|
-
|
|
11907
|
-
|
|
11908
|
-
|
|
11909
|
-
|
|
11910
|
-
|
|
11911
|
-
|
|
11912
|
-
|
|
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
|
|
11913
11938
|
);
|
|
11914
|
-
|
|
11915
|
-
|
|
11916
|
-
|
|
11917
|
-
|
|
11918
|
-
|
|
11919
|
-
|
|
11920
|
-
|
|
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
|
|
11939
|
+
const amountInBinsAskSide = getAmountInBinsAskSide(
|
|
11940
|
+
activeId,
|
|
11941
|
+
binStep,
|
|
11942
|
+
new BN11(askSideStartDeltaId),
|
|
11943
|
+
maxDeltaId,
|
|
11944
|
+
deltaX,
|
|
11945
|
+
x0
|
|
11944
11946
|
);
|
|
11947
|
+
return amountInBinsBidSide.concat(amountInBinsAskSide);
|
|
11945
11948
|
}
|
|
11946
|
-
function
|
|
11947
|
-
|
|
11949
|
+
function getLiquidity(x, y, price) {
|
|
11950
|
+
const px = price.mul(x);
|
|
11951
|
+
const shly = y.shln(SCALE_OFFSET);
|
|
11952
|
+
return px.add(shly);
|
|
11948
11953
|
}
|
|
11949
|
-
function
|
|
11950
|
-
|
|
11951
|
-
|
|
11952
|
-
|
|
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
|
|
11961
|
+
);
|
|
11962
|
+
const feeAmount = delta.mul(totalFeeRate);
|
|
11963
|
+
return feeAmount.mul(FEE_PRECISION.add(totalFeeRate)).div(FEE_PRECISION.pow(new BN11(2)));
|
|
11964
|
+
}
|
|
11965
|
+
return new BN11(0);
|
|
11953
11966
|
}
|
|
11954
|
-
function
|
|
11955
|
-
if (
|
|
11956
|
-
|
|
11967
|
+
function simulateDepositBin(binId, binStep, amountX, amountY, bin) {
|
|
11968
|
+
if (!bin) {
|
|
11969
|
+
return {
|
|
11970
|
+
amountXIntoBin: amountX,
|
|
11971
|
+
amountYIntoBin: amountY
|
|
11972
|
+
};
|
|
11957
11973
|
}
|
|
11958
|
-
|
|
11959
|
-
|
|
11974
|
+
const price = getQPriceFromId(binId, binStep);
|
|
11975
|
+
const inLiquidity = getLiquidity(amountX, amountY, price);
|
|
11976
|
+
const binLiquidity = getLiquidity(bin.amountX, bin.amountY, price);
|
|
11977
|
+
if (bin.liquiditySupply.isZero()) {
|
|
11978
|
+
return {
|
|
11979
|
+
amountXIntoBin: amountX,
|
|
11980
|
+
amountYIntoBin: amountY
|
|
11981
|
+
};
|
|
11960
11982
|
}
|
|
11961
|
-
|
|
11962
|
-
|
|
11963
|
-
|
|
11964
|
-
|
|
11965
|
-
|
|
11966
|
-
|
|
11967
|
-
|
|
11968
|
-
|
|
11969
|
-
|
|
11970
|
-
|
|
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);
|
|
11983
|
+
const liquidityShare = inLiquidity.mul(bin.liquiditySupply).div(binLiquidity);
|
|
11984
|
+
const updatedBinXAmount = bin.amountX.add(amountX);
|
|
11985
|
+
const updatedBinYAmount = bin.amountY.add(amountY);
|
|
11986
|
+
const updatedBinSupply = bin.liquiditySupply.add(liquidityShare);
|
|
11987
|
+
let amountXIntoBin = liquidityShare.mul(
|
|
11988
|
+
updatedBinXAmount.div(updatedBinSupply)
|
|
11989
|
+
);
|
|
11990
|
+
let amountYIntoBin = liquidityShare.mul(
|
|
11991
|
+
updatedBinYAmount.div(updatedBinSupply)
|
|
11992
|
+
);
|
|
11993
|
+
if (amountXIntoBin.gt(amountX)) {
|
|
12036
11994
|
}
|
|
12037
11995
|
return {
|
|
12038
|
-
|
|
12039
|
-
|
|
12040
|
-
feeInfos: combinedFeeInfos
|
|
11996
|
+
amountXIntoBin,
|
|
11997
|
+
amountYIntoBin
|
|
12041
11998
|
};
|
|
12042
11999
|
}
|
|
12043
|
-
|
|
12044
|
-
|
|
12045
|
-
|
|
12046
|
-
|
|
12000
|
+
var RebalancePosition = class {
|
|
12001
|
+
address;
|
|
12002
|
+
lowerBinId;
|
|
12003
|
+
upperBinId;
|
|
12004
|
+
lbPair;
|
|
12005
|
+
owner;
|
|
12006
|
+
shouldClaimFee;
|
|
12007
|
+
shouldClaimReward;
|
|
12008
|
+
rebalancePositionBinData;
|
|
12009
|
+
activeBin;
|
|
12010
|
+
currentTimestamp;
|
|
12011
|
+
constructor(positionAddress, positionData, lbPair, activeBin, shouldClaimFee, shouldClaimReward, currentTimestamp) {
|
|
12012
|
+
this.address = positionAddress;
|
|
12013
|
+
this.rebalancePositionBinData = toRebalancePositionBinData(positionData);
|
|
12014
|
+
this.lowerBinId = new BN11(positionData.lowerBinId);
|
|
12015
|
+
this.upperBinId = new BN11(positionData.upperBinId);
|
|
12016
|
+
this.lbPair = lbPair;
|
|
12017
|
+
this.shouldClaimFee = shouldClaimFee;
|
|
12018
|
+
this.shouldClaimReward = shouldClaimReward;
|
|
12019
|
+
this.owner = positionData.owner;
|
|
12020
|
+
this.activeBin = activeBin;
|
|
12021
|
+
this.currentTimestamp = currentTimestamp;
|
|
12022
|
+
}
|
|
12023
|
+
static async create(params) {
|
|
12024
|
+
const {
|
|
12047
12025
|
program,
|
|
12048
|
-
|
|
12049
|
-
|
|
12026
|
+
positionAddress,
|
|
12027
|
+
pairAddress,
|
|
12028
|
+
positionData,
|
|
12029
|
+
shouldClaimFee,
|
|
12030
|
+
shouldClaimReward
|
|
12031
|
+
} = params;
|
|
12032
|
+
const [lbPairAccount, clockAccount] = await program.provider.connection.getMultipleAccountsInfo([
|
|
12033
|
+
pairAddress,
|
|
12034
|
+
SYSVAR_CLOCK_PUBKEY
|
|
12035
|
+
]);
|
|
12036
|
+
const lbPair = decodeAccount(program, "lbPair", lbPairAccount.data);
|
|
12037
|
+
const clock = ClockLayout.decode(clockAccount.data);
|
|
12038
|
+
const activeBinArrayIdx = binIdToBinArrayIndex(new BN11(lbPair.activeId));
|
|
12039
|
+
const [activeBinArrayPubkey] = deriveBinArray(
|
|
12040
|
+
pairAddress,
|
|
12041
|
+
activeBinArrayIdx,
|
|
12042
|
+
program.programId
|
|
12050
12043
|
);
|
|
12051
|
-
const
|
|
12052
|
-
|
|
12053
|
-
program,
|
|
12054
|
-
account.data.subarray(8 + POSITION_MIN_SIZE)
|
|
12044
|
+
const activeBinArrayState = await program.account.binArray.fetch(
|
|
12045
|
+
activeBinArrayPubkey
|
|
12055
12046
|
);
|
|
12056
|
-
const
|
|
12057
|
-
|
|
12058
|
-
|
|
12047
|
+
const [lowerBinId, upperBinId] = getBinArrayLowerUpperBinId(activeBinArrayIdx);
|
|
12048
|
+
const idx = getBinIdIndexInBinArray(
|
|
12049
|
+
new BN11(lbPair.activeId),
|
|
12050
|
+
lowerBinId,
|
|
12051
|
+
upperBinId
|
|
12052
|
+
);
|
|
12053
|
+
const activeBin = activeBinArrayState[idx.toNumber()];
|
|
12054
|
+
return new RebalancePosition(
|
|
12055
|
+
positionAddress,
|
|
12056
|
+
positionData,
|
|
12057
|
+
lbPair,
|
|
12058
|
+
activeBin,
|
|
12059
|
+
shouldClaimFee,
|
|
12060
|
+
shouldClaimReward,
|
|
12061
|
+
clock.unixTimestamp
|
|
12059
12062
|
);
|
|
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
12063
|
}
|
|
12090
|
-
|
|
12091
|
-
|
|
12092
|
-
|
|
12093
|
-
|
|
12094
|
-
|
|
12064
|
+
_simulateDeposit(binStep, tokenXDecimal, tokenYDecimal, deposits, simulatedWithdrawResult) {
|
|
12065
|
+
const { liquidityAndFeeXWithdrawn, liquidityAndFeeYWithdrawn } = simulatedWithdrawResult;
|
|
12066
|
+
const activeId = new BN11(this.lbPair.activeId);
|
|
12067
|
+
const depositBinIds = getDepositBinIds(activeId, deposits);
|
|
12068
|
+
if (depositBinIds.length > 0) {
|
|
12069
|
+
const depositMinBinId = depositBinIds[0];
|
|
12070
|
+
const depositMaxBinId = depositBinIds[depositBinIds.length - 1];
|
|
12071
|
+
this._simulateResize(
|
|
12072
|
+
new BN11(depositMinBinId),
|
|
12073
|
+
new BN11(depositMaxBinId),
|
|
12074
|
+
binStep,
|
|
12075
|
+
tokenXDecimal,
|
|
12076
|
+
tokenYDecimal
|
|
12077
|
+
);
|
|
12078
|
+
}
|
|
12079
|
+
let totalAmountXDeposited = new BN11(0);
|
|
12080
|
+
let totalAmountYDeposited = new BN11(0);
|
|
12081
|
+
const addLiquidityParam = [];
|
|
12082
|
+
for (const {
|
|
12083
|
+
x0,
|
|
12084
|
+
y0,
|
|
12085
|
+
favorXInActiveBin,
|
|
12086
|
+
deltaX,
|
|
12087
|
+
deltaY,
|
|
12088
|
+
minDeltaId,
|
|
12089
|
+
maxDeltaId
|
|
12090
|
+
} of deposits) {
|
|
12091
|
+
const params = buildBitFlagAndNegateStrategyParameters(
|
|
12092
|
+
x0,
|
|
12093
|
+
y0,
|
|
12094
|
+
deltaX,
|
|
12095
|
+
deltaY
|
|
12096
|
+
);
|
|
12097
|
+
addLiquidityParam.push({
|
|
12098
|
+
minDeltaId: minDeltaId.toNumber(),
|
|
12099
|
+
maxDeltaId: maxDeltaId.toNumber(),
|
|
12100
|
+
x0: params.x0,
|
|
12101
|
+
y0: params.y0,
|
|
12102
|
+
deltaX: params.deltaX,
|
|
12103
|
+
deltaY: params.deltaY,
|
|
12104
|
+
bitFlag: params.bitFlag,
|
|
12105
|
+
padding: Array(16).fill(0),
|
|
12106
|
+
favorXInActiveId: favorXInActiveBin
|
|
12107
|
+
});
|
|
12108
|
+
const amountIntoBins = toAmountIntoBins(
|
|
12109
|
+
activeId,
|
|
12110
|
+
minDeltaId,
|
|
12111
|
+
maxDeltaId,
|
|
12112
|
+
deltaX,
|
|
12113
|
+
deltaY,
|
|
12114
|
+
x0,
|
|
12115
|
+
y0,
|
|
12116
|
+
binStep,
|
|
12117
|
+
favorXInActiveBin
|
|
12118
|
+
);
|
|
12119
|
+
for (const { binId, amountX, amountY } of amountIntoBins) {
|
|
12120
|
+
totalAmountXDeposited = totalAmountXDeposited.add(amountX);
|
|
12121
|
+
totalAmountYDeposited = totalAmountYDeposited.add(amountY);
|
|
12122
|
+
const idx = this.rebalancePositionBinData.findIndex(
|
|
12123
|
+
(data) => data.binId == binId.toNumber()
|
|
12124
|
+
);
|
|
12125
|
+
if (binId.eq(activeId)) {
|
|
12126
|
+
const vParameters3 = Object.assign({}, this.lbPair.vParameters);
|
|
12127
|
+
const sParameters3 = Object.assign({}, this.lbPair.parameters);
|
|
12128
|
+
DLMM.updateReference(
|
|
12129
|
+
activeId.toNumber(),
|
|
12130
|
+
vParameters3,
|
|
12131
|
+
sParameters3,
|
|
12132
|
+
this.currentTimestamp.toNumber()
|
|
12133
|
+
);
|
|
12134
|
+
DLMM.updateVolatilityAccumulator(
|
|
12135
|
+
vParameters3,
|
|
12136
|
+
sParameters3,
|
|
12137
|
+
activeId.toNumber()
|
|
12138
|
+
);
|
|
12139
|
+
const { amountXIntoBin, amountYIntoBin } = simulateDepositBin(
|
|
12140
|
+
binId,
|
|
12141
|
+
binStep,
|
|
12142
|
+
amountX,
|
|
12143
|
+
amountY,
|
|
12144
|
+
this.activeBin
|
|
12145
|
+
);
|
|
12146
|
+
const feeY = computeCompositionFee(
|
|
12147
|
+
binStep,
|
|
12148
|
+
sParameters3,
|
|
12149
|
+
vParameters3,
|
|
12150
|
+
amountXIntoBin,
|
|
12151
|
+
amountX,
|
|
12152
|
+
amountYIntoBin,
|
|
12153
|
+
amountY
|
|
12154
|
+
);
|
|
12155
|
+
const feeX = computeCompositionFee(
|
|
12156
|
+
binStep,
|
|
12157
|
+
sParameters3,
|
|
12158
|
+
vParameters3,
|
|
12159
|
+
amountYIntoBin,
|
|
12160
|
+
amountY,
|
|
12161
|
+
amountXIntoBin,
|
|
12162
|
+
amountX
|
|
12163
|
+
);
|
|
12164
|
+
const amountXIntoBinExcludeFee = amountXIntoBin.sub(feeX);
|
|
12165
|
+
const amountYIntoBinExcludeFee = amountYIntoBin.sub(feeY);
|
|
12166
|
+
this.rebalancePositionBinData[idx].amountX = this.rebalancePositionBinData[idx].amountX.add(
|
|
12167
|
+
amountXIntoBinExcludeFee
|
|
12168
|
+
);
|
|
12169
|
+
this.rebalancePositionBinData[idx].amountY = this.rebalancePositionBinData[idx].amountY.add(
|
|
12170
|
+
amountYIntoBinExcludeFee
|
|
12171
|
+
);
|
|
12172
|
+
} else {
|
|
12173
|
+
this.rebalancePositionBinData[idx].amountX = this.rebalancePositionBinData[idx].amountX.add(amountX);
|
|
12174
|
+
this.rebalancePositionBinData[idx].amountY = this.rebalancePositionBinData[idx].amountY.add(amountY);
|
|
12175
|
+
}
|
|
12176
|
+
}
|
|
12177
|
+
}
|
|
12178
|
+
let actualTotalAmountXDeposited = totalAmountXDeposited;
|
|
12179
|
+
let actualTotalAmountYDeposited = totalAmountYDeposited;
|
|
12180
|
+
let actualLiquidityAndFeeXWithdrawn = liquidityAndFeeXWithdrawn;
|
|
12181
|
+
let actualLiquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn;
|
|
12182
|
+
if (actualTotalAmountXDeposited.gt(actualLiquidityAndFeeXWithdrawn)) {
|
|
12183
|
+
actualTotalAmountXDeposited = actualTotalAmountXDeposited.sub(
|
|
12184
|
+
actualLiquidityAndFeeXWithdrawn
|
|
12185
|
+
);
|
|
12186
|
+
actualLiquidityAndFeeXWithdrawn = new BN11(0);
|
|
12187
|
+
} else {
|
|
12188
|
+
actualLiquidityAndFeeXWithdrawn = actualLiquidityAndFeeXWithdrawn.sub(
|
|
12189
|
+
actualTotalAmountXDeposited
|
|
12190
|
+
);
|
|
12191
|
+
actualTotalAmountXDeposited = new BN11(0);
|
|
12192
|
+
}
|
|
12193
|
+
if (actualTotalAmountYDeposited.gt(actualLiquidityAndFeeYWithdrawn)) {
|
|
12194
|
+
actualTotalAmountYDeposited = actualTotalAmountYDeposited.sub(
|
|
12195
|
+
actualLiquidityAndFeeYWithdrawn
|
|
12196
|
+
);
|
|
12197
|
+
actualLiquidityAndFeeYWithdrawn = new BN11(0);
|
|
12198
|
+
} else {
|
|
12199
|
+
actualLiquidityAndFeeYWithdrawn = actualLiquidityAndFeeYWithdrawn.sub(
|
|
12200
|
+
actualTotalAmountYDeposited
|
|
12201
|
+
);
|
|
12202
|
+
actualTotalAmountYDeposited = new BN11(0);
|
|
12203
|
+
}
|
|
12204
|
+
return {
|
|
12205
|
+
result: {
|
|
12206
|
+
totalAmountXDeposited,
|
|
12207
|
+
totalAmountYDeposited,
|
|
12208
|
+
actualLiquidityAndFeeXWithdrawn,
|
|
12209
|
+
actualLiquidityAndFeeYWithdrawn,
|
|
12210
|
+
actualTotalAmountXDeposited,
|
|
12211
|
+
actualTotalAmountYDeposited
|
|
12212
|
+
},
|
|
12213
|
+
depositParams: addLiquidityParam
|
|
12214
|
+
};
|
|
12095
12215
|
}
|
|
12096
|
-
|
|
12097
|
-
|
|
12216
|
+
_simulateResize(depositMinBinId, depositMaxBinId, binStep, tokenXDecimal, tokenYDecimal) {
|
|
12217
|
+
const tokenXMultiplier = new Decimal6(10 ** tokenXDecimal.toNumber());
|
|
12218
|
+
const tokenYMultiplier = new Decimal6(10 ** tokenYDecimal.toNumber());
|
|
12219
|
+
const [minBinId, maxBinId] = findMinMaxBinIdWithLiquidity(
|
|
12220
|
+
this.rebalancePositionBinData
|
|
12221
|
+
);
|
|
12222
|
+
const newMinBinId = new BN11(
|
|
12223
|
+
Math.min(depositMinBinId.toNumber(), minBinId ?? Number.MAX_SAFE_INTEGER)
|
|
12224
|
+
);
|
|
12225
|
+
const newMaxBinId = new BN11(
|
|
12226
|
+
Math.max(depositMaxBinId.toNumber(), maxBinId ?? Number.MIN_SAFE_INTEGER)
|
|
12227
|
+
);
|
|
12228
|
+
if (newMinBinId.lt(this.lowerBinId)) {
|
|
12229
|
+
const binCountToExpand = this.lowerBinId.sub(depositMinBinId);
|
|
12230
|
+
for (let i = 1; i <= binCountToExpand.toNumber(); i++) {
|
|
12231
|
+
const binId = this.lowerBinId.subn(i);
|
|
12232
|
+
const price = getPriceOfBinByBinId(
|
|
12233
|
+
binId.toNumber(),
|
|
12234
|
+
binStep.toNumber()
|
|
12235
|
+
);
|
|
12236
|
+
const adjustedPrice = price.mul(tokenXMultiplier).div(tokenYMultiplier);
|
|
12237
|
+
this.rebalancePositionBinData.unshift({
|
|
12238
|
+
binId: binId.toNumber(),
|
|
12239
|
+
price: adjustedPrice.toString(),
|
|
12240
|
+
pricePerToken: adjustedPrice.toString(),
|
|
12241
|
+
amountX: new BN11(0),
|
|
12242
|
+
amountY: new BN11(0),
|
|
12243
|
+
claimableRewardAmount: [new BN11(0), new BN11(0)],
|
|
12244
|
+
claimableFeeXAmount: new BN11(0),
|
|
12245
|
+
claimableFeeYAmount: new BN11(0)
|
|
12246
|
+
});
|
|
12247
|
+
}
|
|
12248
|
+
} else {
|
|
12249
|
+
const binCountToShrink = newMinBinId.sub(this.lowerBinId);
|
|
12250
|
+
for (let i = 1; i <= binCountToShrink.toNumber(); i++) {
|
|
12251
|
+
this.rebalancePositionBinData.shift();
|
|
12252
|
+
}
|
|
12253
|
+
}
|
|
12254
|
+
if (newMaxBinId.gt(this.upperBinId)) {
|
|
12255
|
+
const binCountToExpand = newMaxBinId.sub(this.upperBinId);
|
|
12256
|
+
for (let i = 1; i <= binCountToExpand.toNumber(); i++) {
|
|
12257
|
+
const binId = this.upperBinId.addn(i);
|
|
12258
|
+
const price = getPriceOfBinByBinId(
|
|
12259
|
+
binId.toNumber(),
|
|
12260
|
+
binStep.toNumber()
|
|
12261
|
+
);
|
|
12262
|
+
const adjustedPrice = price.mul(tokenXMultiplier).div(tokenYMultiplier);
|
|
12263
|
+
this.rebalancePositionBinData.push({
|
|
12264
|
+
binId: binId.toNumber(),
|
|
12265
|
+
price: adjustedPrice.toString(),
|
|
12266
|
+
pricePerToken: adjustedPrice.toString(),
|
|
12267
|
+
amountX: new BN11(0),
|
|
12268
|
+
amountY: new BN11(0),
|
|
12269
|
+
claimableRewardAmount: [new BN11(0), new BN11(0)],
|
|
12270
|
+
claimableFeeXAmount: new BN11(0),
|
|
12271
|
+
claimableFeeYAmount: new BN11(0)
|
|
12272
|
+
});
|
|
12273
|
+
}
|
|
12274
|
+
} else {
|
|
12275
|
+
const binCountToShrink = this.upperBinId.sub(newMaxBinId);
|
|
12276
|
+
for (let i = 1; i <= binCountToShrink.toNumber(); i++) {
|
|
12277
|
+
this.rebalancePositionBinData.pop();
|
|
12278
|
+
}
|
|
12279
|
+
}
|
|
12280
|
+
this.lowerBinId = newMinBinId;
|
|
12281
|
+
this.upperBinId = newMaxBinId;
|
|
12098
12282
|
}
|
|
12099
|
-
|
|
12100
|
-
|
|
12283
|
+
_simulateWithdraw(withdraws) {
|
|
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);
|
|
12288
|
+
for (const { minBinId, maxBinId, bps } of withdraws) {
|
|
12289
|
+
const fromBinId = minBinId ?? activeId;
|
|
12290
|
+
const toBinId = maxBinId ?? activeId;
|
|
12291
|
+
const binIds = binRangeToBinIdArray(fromBinId, toBinId).filter(
|
|
12292
|
+
(binId) => binId.gte(this.lowerBinId) && binId.lte(this.upperBinId)
|
|
12293
|
+
);
|
|
12294
|
+
for (const binId of binIds) {
|
|
12295
|
+
const idx = this.rebalancePositionBinData.findIndex(
|
|
12296
|
+
(b) => b.binId === binId.toNumber()
|
|
12297
|
+
);
|
|
12298
|
+
const binData = this.rebalancePositionBinData[idx];
|
|
12299
|
+
const amountXWithdrawn = binData.amountX.mul(bps).divn(BASIS_POINT_MAX);
|
|
12300
|
+
const amountYWithdrawn = binData.amountY.mul(bps).divn(BASIS_POINT_MAX);
|
|
12301
|
+
liquidityAndFeeXWithdrawn = liquidityAndFeeXWithdrawn.add(amountXWithdrawn);
|
|
12302
|
+
liquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn.add(amountYWithdrawn);
|
|
12303
|
+
binData.amountX = binData.amountX.sub(amountXWithdrawn);
|
|
12304
|
+
binData.amountY = binData.amountY.sub(amountYWithdrawn);
|
|
12305
|
+
if (this.shouldClaimFee) {
|
|
12306
|
+
liquidityAndFeeXWithdrawn = liquidityAndFeeXWithdrawn.add(
|
|
12307
|
+
binData.claimableFeeXAmount
|
|
12308
|
+
);
|
|
12309
|
+
liquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn.add(
|
|
12310
|
+
binData.claimableFeeYAmount
|
|
12311
|
+
);
|
|
12312
|
+
binData.claimableFeeXAmount = new BN11(0);
|
|
12313
|
+
binData.claimableFeeYAmount = new BN11(0);
|
|
12314
|
+
}
|
|
12315
|
+
if (this.shouldClaimReward) {
|
|
12316
|
+
for (const [idx2, amount] of binData.claimableRewardAmount.entries()) {
|
|
12317
|
+
rewardsAmountClaimed[idx2] = rewardsAmountClaimed[idx2].add(amount);
|
|
12318
|
+
binData.claimableRewardAmount[idx2] = new BN11(0);
|
|
12319
|
+
}
|
|
12320
|
+
}
|
|
12321
|
+
this.rebalancePositionBinData[idx] = binData;
|
|
12322
|
+
}
|
|
12323
|
+
}
|
|
12324
|
+
const withdrawParams = withdraws.map(
|
|
12325
|
+
({ minBinId, maxBinId, bps }) => {
|
|
12326
|
+
return {
|
|
12327
|
+
minBinId: minBinId ? minBinId.toNumber() : null,
|
|
12328
|
+
maxBinId: maxBinId ? maxBinId.toNumber() : null,
|
|
12329
|
+
bps: bps.toNumber(),
|
|
12330
|
+
padding: Array(16).fill(0)
|
|
12331
|
+
};
|
|
12332
|
+
}
|
|
12333
|
+
);
|
|
12334
|
+
return {
|
|
12335
|
+
result: {
|
|
12336
|
+
liquidityAndFeeXWithdrawn,
|
|
12337
|
+
liquidityAndFeeYWithdrawn,
|
|
12338
|
+
rewardsAmountClaimed
|
|
12339
|
+
},
|
|
12340
|
+
withdrawParams
|
|
12341
|
+
};
|
|
12101
12342
|
}
|
|
12102
|
-
|
|
12103
|
-
|
|
12343
|
+
async simulateRebalance(connection, binStep, tokenXDecimal, tokenYDecimal, withdraws, deposits) {
|
|
12344
|
+
if (withdraws.length == 0 && deposits.length == 0) {
|
|
12345
|
+
throw "No rebalance action";
|
|
12346
|
+
}
|
|
12347
|
+
const activeId = new BN11(this.lbPair.activeId);
|
|
12348
|
+
withdraws = validateAndSortRebalanceWithdraw(withdraws, activeId);
|
|
12349
|
+
deposits = validateAndSortRebalanceDeposit(deposits);
|
|
12350
|
+
const beforeWidth = getPositionWidthWithMinWidth(
|
|
12351
|
+
this.lowerBinId.toNumber(),
|
|
12352
|
+
this.upperBinId.toNumber()
|
|
12353
|
+
);
|
|
12354
|
+
const { withdrawParams, result: withdrawResult } = this._simulateWithdraw(withdraws);
|
|
12355
|
+
const { depositParams, result: depositResult } = this._simulateDeposit(
|
|
12356
|
+
binStep,
|
|
12357
|
+
tokenXDecimal,
|
|
12358
|
+
tokenYDecimal,
|
|
12359
|
+
deposits,
|
|
12360
|
+
withdrawResult
|
|
12361
|
+
);
|
|
12362
|
+
const afterWidth = getPositionWidthWithMinWidth(
|
|
12363
|
+
this.lowerBinId.toNumber(),
|
|
12364
|
+
this.upperBinId.toNumber()
|
|
12365
|
+
);
|
|
12366
|
+
const widthDelta = afterWidth - beforeWidth;
|
|
12367
|
+
let rentalCostLamports = new BN11(0);
|
|
12368
|
+
if (widthDelta != 0) {
|
|
12369
|
+
const sizeChanges = Math.abs(widthDelta) * POSITION_BIN_DATA_SIZE;
|
|
12370
|
+
const [minimumLamports, rentExemptionLamports] = await Promise.all([
|
|
12371
|
+
connection.getMinimumBalanceForRentExemption(0),
|
|
12372
|
+
connection.getMinimumBalanceForRentExemption(sizeChanges)
|
|
12373
|
+
]);
|
|
12374
|
+
const lamportChanges = new BN11(rentExemptionLamports).sub(
|
|
12375
|
+
new BN11(minimumLamports)
|
|
12376
|
+
);
|
|
12377
|
+
if (widthDelta > 0) {
|
|
12378
|
+
rentalCostLamports = rentalCostLamports.add(lamportChanges);
|
|
12379
|
+
} else {
|
|
12380
|
+
rentalCostLamports = rentalCostLamports.sub(lamportChanges);
|
|
12381
|
+
}
|
|
12382
|
+
}
|
|
12383
|
+
return {
|
|
12384
|
+
amountXDeposited: depositResult.totalAmountXDeposited,
|
|
12385
|
+
amountYDeposited: depositResult.totalAmountYDeposited,
|
|
12386
|
+
actualAmountXDeposited: depositResult.actualTotalAmountXDeposited,
|
|
12387
|
+
actualAmountYDeposited: depositResult.actualTotalAmountYDeposited,
|
|
12388
|
+
actualAmountXWithdrawn: depositResult.actualLiquidityAndFeeXWithdrawn,
|
|
12389
|
+
actualAmountYWithdrawn: depositResult.actualLiquidityAndFeeYWithdrawn,
|
|
12390
|
+
rewardAmountsClaimed: withdrawResult.rewardsAmountClaimed,
|
|
12391
|
+
withdrawParams,
|
|
12392
|
+
depositParams,
|
|
12393
|
+
rentalCostLamports
|
|
12394
|
+
};
|
|
12104
12395
|
}
|
|
12105
|
-
|
|
12106
|
-
|
|
12396
|
+
totalAmounts() {
|
|
12397
|
+
let totalAmountX = new BN11(0);
|
|
12398
|
+
let totalAmountY = new BN11(0);
|
|
12399
|
+
for (const binData of this.rebalancePositionBinData) {
|
|
12400
|
+
totalAmountX = totalAmountX.add(binData.amountX);
|
|
12401
|
+
totalAmountY = totalAmountY.add(binData.amountY);
|
|
12402
|
+
}
|
|
12403
|
+
return [totalAmountX, totalAmountY];
|
|
12107
12404
|
}
|
|
12108
|
-
|
|
12109
|
-
|
|
12405
|
+
totalFeeAmounts() {
|
|
12406
|
+
let totalFeeXAmount = new BN11(0);
|
|
12407
|
+
let totalFeeYAmount = new BN11(0);
|
|
12408
|
+
for (const binData of this.rebalancePositionBinData) {
|
|
12409
|
+
totalFeeXAmount = totalFeeXAmount.add(binData.claimableFeeXAmount);
|
|
12410
|
+
totalFeeYAmount = totalFeeYAmount.add(binData.claimableFeeYAmount);
|
|
12411
|
+
}
|
|
12412
|
+
return [totalFeeXAmount, totalFeeYAmount];
|
|
12110
12413
|
}
|
|
12111
|
-
|
|
12112
|
-
|
|
12414
|
+
totalRewardAmounts() {
|
|
12415
|
+
let totalRewardAmounts = [new BN11(0), new BN11(0)];
|
|
12416
|
+
for (const binData of this.rebalancePositionBinData) {
|
|
12417
|
+
totalRewardAmounts[0] = totalRewardAmounts[0].add(
|
|
12418
|
+
binData.claimableRewardAmount[0]
|
|
12419
|
+
);
|
|
12420
|
+
totalRewardAmounts[1] = totalRewardAmounts[1].add(
|
|
12421
|
+
binData.claimableRewardAmount[1]
|
|
12422
|
+
);
|
|
12423
|
+
}
|
|
12424
|
+
return totalRewardAmounts;
|
|
12113
12425
|
}
|
|
12114
|
-
|
|
12115
|
-
|
|
12116
|
-
|
|
12117
|
-
|
|
12118
|
-
|
|
12119
|
-
|
|
12120
|
-
|
|
12121
|
-
|
|
12426
|
+
};
|
|
12427
|
+
function getPositionWidthWithMinWidth(lowerBinId, upperBinId) {
|
|
12428
|
+
const width = upperBinId - lowerBinId + 1;
|
|
12429
|
+
return Math.max(width, DEFAULT_BIN_PER_POSITION.toNumber());
|
|
12430
|
+
}
|
|
12431
|
+
function validateAndSortRebalanceDeposit(deposits) {
|
|
12432
|
+
const sortedDeposits = deposits.sort(
|
|
12433
|
+
(a, b) => a.minDeltaId.sub(b.minDeltaId).toNumber()
|
|
12434
|
+
);
|
|
12435
|
+
for (const deposit of deposits) {
|
|
12436
|
+
if (deposit.minDeltaId.gte(deposit.maxDeltaId)) {
|
|
12437
|
+
throw "Invalid minDeltaId or maxDeltaId";
|
|
12122
12438
|
}
|
|
12123
12439
|
}
|
|
12124
|
-
|
|
12125
|
-
|
|
12126
|
-
|
|
12127
|
-
)
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
return 1 /* V2 */;
|
|
12440
|
+
for (let i = 1; i < sortedDeposits.length; i++) {
|
|
12441
|
+
const prevDeposit = sortedDeposits[i - 1];
|
|
12442
|
+
const currDeposit = sortedDeposits[i];
|
|
12443
|
+
if (prevDeposit.maxDeltaId.gte(currDeposit.minDeltaId)) {
|
|
12444
|
+
throw "Overlap deposit bin range";
|
|
12445
|
+
}
|
|
12131
12446
|
}
|
|
12132
|
-
|
|
12133
|
-
|
|
12447
|
+
return sortedDeposits;
|
|
12448
|
+
}
|
|
12449
|
+
function validateAndSortRebalanceWithdraw(withdraws, activeId) {
|
|
12450
|
+
const filledWithdraws = [];
|
|
12451
|
+
for (const { minBinId, maxBinId, bps } of withdraws) {
|
|
12452
|
+
if (bps.toNumber() < 0 || bps.toNumber() > BASIS_POINT_MAX) {
|
|
12453
|
+
throw "Invalid bps";
|
|
12454
|
+
}
|
|
12455
|
+
const filledMinBinId = minBinId ?? activeId;
|
|
12456
|
+
const filledMaxBinId = maxBinId ?? activeId;
|
|
12457
|
+
if (filledMinBinId.gt(filledMaxBinId)) {
|
|
12458
|
+
throw "Invalid minBinId or maxBinId";
|
|
12459
|
+
}
|
|
12460
|
+
filledWithdraws.push({
|
|
12461
|
+
minBinId: filledMinBinId,
|
|
12462
|
+
maxBinId: filledMaxBinId,
|
|
12463
|
+
bps
|
|
12464
|
+
});
|
|
12134
12465
|
}
|
|
12135
|
-
|
|
12136
|
-
return
|
|
12466
|
+
filledWithdraws.sort((a, b) => {
|
|
12467
|
+
return a.minBinId.sub(b.minBinId).toNumber();
|
|
12468
|
+
});
|
|
12469
|
+
for (let i = 1; i < filledWithdraws.length; i++) {
|
|
12470
|
+
const prev = filledWithdraws[i - 1];
|
|
12471
|
+
const curr = filledWithdraws[i];
|
|
12472
|
+
if (curr.minBinId.lte(prev.maxBinId)) {
|
|
12473
|
+
throw "Overlap withdraw bin range";
|
|
12474
|
+
}
|
|
12137
12475
|
}
|
|
12138
|
-
|
|
12139
|
-
|
|
12140
|
-
|
|
12141
|
-
|
|
12142
|
-
const
|
|
12143
|
-
const
|
|
12144
|
-
|
|
12145
|
-
|
|
12146
|
-
binArrayIndexes.push(new BN13(i));
|
|
12476
|
+
return filledWithdraws;
|
|
12477
|
+
}
|
|
12478
|
+
function binRangeToBinIdArray(minBinId, maxBinId) {
|
|
12479
|
+
const binIdArray = [];
|
|
12480
|
+
const fromBinId = minBinId.toNumber();
|
|
12481
|
+
const toBinId = maxBinId.toNumber();
|
|
12482
|
+
for (let binId = fromBinId; binId <= toBinId; binId++) {
|
|
12483
|
+
binIdArray.push(new BN11(binId));
|
|
12147
12484
|
}
|
|
12148
|
-
return
|
|
12485
|
+
return binIdArray;
|
|
12149
12486
|
}
|
|
12150
|
-
function
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
|
|
12487
|
+
function getRebalanceBinArrayIndexesAndBitmapCoverage(adds, removes, activeId, pairAddress, programId) {
|
|
12488
|
+
let indexMap = /* @__PURE__ */ new Map();
|
|
12489
|
+
removes.forEach((value) => {
|
|
12490
|
+
let minBinId = value.minBinId;
|
|
12491
|
+
if (minBinId == null) {
|
|
12492
|
+
minBinId = activeId;
|
|
12493
|
+
}
|
|
12494
|
+
let maxBinId = value.maxBinId;
|
|
12495
|
+
if (maxBinId == null) {
|
|
12496
|
+
maxBinId = activeId;
|
|
12497
|
+
}
|
|
12498
|
+
let binArrayIndex = binIdToBinArrayIndex(new BN11(minBinId));
|
|
12499
|
+
const upperBinId = new BN11(maxBinId);
|
|
12500
|
+
while (true) {
|
|
12501
|
+
indexMap.set(binArrayIndex.toNumber(), true);
|
|
12502
|
+
const [binArrayLowerBinId, binArrayUpperBinId] = getBinArrayLowerUpperBinId(binArrayIndex);
|
|
12503
|
+
if (upperBinId.gte(binArrayLowerBinId) && upperBinId.lte(binArrayUpperBinId)) {
|
|
12504
|
+
break;
|
|
12505
|
+
} else {
|
|
12506
|
+
binArrayIndex = binArrayIndex.add(new BN11(1));
|
|
12507
|
+
}
|
|
12508
|
+
}
|
|
12154
12509
|
});
|
|
12155
|
-
|
|
12156
|
-
|
|
12157
|
-
|
|
12158
|
-
(
|
|
12159
|
-
|
|
12160
|
-
|
|
12161
|
-
|
|
12162
|
-
|
|
12163
|
-
|
|
12510
|
+
adds.forEach((value) => {
|
|
12511
|
+
const minBinId = activeId + value.minDeltaId;
|
|
12512
|
+
const maxBinId = activeId + value.maxDeltaId;
|
|
12513
|
+
let binArrayIndex = binIdToBinArrayIndex(new BN11(minBinId));
|
|
12514
|
+
const upperBinId = new BN11(maxBinId);
|
|
12515
|
+
while (true) {
|
|
12516
|
+
indexMap.set(binArrayIndex.toNumber(), true);
|
|
12517
|
+
const [binArrayLowerBinId, binArrayUpperBinId] = getBinArrayLowerUpperBinId(binArrayIndex);
|
|
12518
|
+
if (upperBinId.gte(binArrayLowerBinId) && upperBinId.lte(binArrayUpperBinId)) {
|
|
12519
|
+
break;
|
|
12520
|
+
} else {
|
|
12521
|
+
binArrayIndex = binArrayIndex.add(new BN11(1));
|
|
12522
|
+
}
|
|
12164
12523
|
}
|
|
12524
|
+
});
|
|
12525
|
+
const binArrayIndexes = Array.from(indexMap.keys()).map((idx) => new BN11(idx));
|
|
12526
|
+
const requireBitmapExtension = binArrayIndexes.some(
|
|
12527
|
+
(index) => isOverflowDefaultBinArrayBitmap(new BN11(index))
|
|
12165
12528
|
);
|
|
12529
|
+
return {
|
|
12530
|
+
binArrayIndexes,
|
|
12531
|
+
binArrayBitmap: requireBitmapExtension ? deriveBinArrayBitmapExtension(pairAddress, programId)[0] : programId
|
|
12532
|
+
};
|
|
12166
12533
|
}
|
|
12167
|
-
|
|
12168
|
-
|
|
12169
|
-
|
|
12170
|
-
|
|
12171
|
-
|
|
12172
|
-
|
|
12173
|
-
|
|
12174
|
-
|
|
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();
|
|
12534
|
+
|
|
12535
|
+
// src/dlmm/helpers/rebalance/liquidity_strategy/index.ts
|
|
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);
|
|
12195
12543
|
}
|
|
12196
|
-
|
|
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);
|
|
12197
12554
|
}
|
|
12198
|
-
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12202
|
-
|
|
12203
|
-
|
|
12204
|
-
|
|
12205
|
-
|
|
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
|
|
12206
12571
|
);
|
|
12207
|
-
const
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
|
|
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
|
+
}
|
|
12213
12583
|
}
|
|
12214
12584
|
}
|
|
12215
|
-
function
|
|
12216
|
-
|
|
12217
|
-
|
|
12218
|
-
|
|
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));
|
|
12219
12602
|
}
|
|
12220
|
-
function
|
|
12221
|
-
|
|
12222
|
-
|
|
12223
|
-
|
|
12224
|
-
|
|
12225
|
-
|
|
12226
|
-
|
|
12227
|
-
|
|
12228
|
-
|
|
12229
|
-
|
|
12230
|
-
|
|
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
|
|
12231
12626
|
);
|
|
12232
|
-
|
|
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
|
+
}
|
|
12233
12638
|
}
|
|
12234
|
-
return extendedPosition;
|
|
12235
12639
|
}
|
|
12236
|
-
|
|
12237
|
-
|
|
12238
|
-
|
|
12239
|
-
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
|
|
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
|
+
};
|
|
12246
12670
|
}
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
|
|
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
|
+
};
|
|
12250
12698
|
}
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12699
|
+
};
|
|
12700
|
+
|
|
12701
|
+
// src/dlmm/helpers/rebalance/liquidity_strategy/curve.ts
|
|
12702
|
+
import BN13 from "bn.js";
|
|
12703
|
+
function findBaseY0(amountY, minDeltaId, maxDeltaId) {
|
|
12704
|
+
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new BN13(0))) {
|
|
12705
|
+
return new BN13(0);
|
|
12254
12706
|
}
|
|
12255
|
-
if (
|
|
12256
|
-
|
|
12257
|
-
deltaY = deltaY.neg();
|
|
12707
|
+
if (minDeltaId.eq(maxDeltaId)) {
|
|
12708
|
+
return amountY;
|
|
12258
12709
|
}
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
|
|
12262
|
-
|
|
12263
|
-
|
|
12264
|
-
|
|
12265
|
-
|
|
12710
|
+
const m1 = minDeltaId.neg();
|
|
12711
|
+
const m2 = maxDeltaId.neg();
|
|
12712
|
+
const b = m1.sub(m2).addn(1);
|
|
12713
|
+
const c = m1.mul(m1.addn(1)).divn(2);
|
|
12714
|
+
const d = m2.mul(m2.subn(1)).divn(2);
|
|
12715
|
+
const a = b.sub(c.sub(d).div(m1.addn(1)));
|
|
12716
|
+
return amountY.div(a);
|
|
12266
12717
|
}
|
|
12267
|
-
function
|
|
12268
|
-
|
|
12269
|
-
|
|
12270
|
-
|
|
12271
|
-
|
|
12272
|
-
|
|
12273
|
-
|
|
12274
|
-
|
|
12275
|
-
|
|
12276
|
-
|
|
12277
|
-
|
|
12278
|
-
|
|
12718
|
+
function findY0AndDeltaY2(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
12719
|
+
if (minDeltaId.gt(maxDeltaId) || amountY.isZero()) {
|
|
12720
|
+
return {
|
|
12721
|
+
base: new BN13(0),
|
|
12722
|
+
delta: new BN13(0)
|
|
12723
|
+
};
|
|
12724
|
+
}
|
|
12725
|
+
let baseY0 = findBaseY0(amountY, minDeltaId, maxDeltaId);
|
|
12726
|
+
while (true) {
|
|
12727
|
+
const deltaY = baseY0.neg().div(minDeltaId.neg().addn(1));
|
|
12728
|
+
const amountInBins = getAmountInBinsBidSide(
|
|
12729
|
+
activeId,
|
|
12730
|
+
minDeltaId,
|
|
12731
|
+
maxDeltaId,
|
|
12732
|
+
deltaY,
|
|
12733
|
+
baseY0
|
|
12734
|
+
);
|
|
12735
|
+
const totalAmountY = amountInBins.reduce((acc, { amountY: amountY2 }) => {
|
|
12736
|
+
return acc.add(amountY2);
|
|
12737
|
+
}, new BN13(0));
|
|
12738
|
+
if (totalAmountY.gt(amountY)) {
|
|
12739
|
+
baseY0 = baseY0.sub(new BN13(1));
|
|
12740
|
+
} else {
|
|
12279
12741
|
return {
|
|
12280
|
-
|
|
12281
|
-
|
|
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)
|
|
12742
|
+
base: baseY0,
|
|
12743
|
+
delta: deltaY
|
|
12290
12744
|
};
|
|
12291
12745
|
}
|
|
12292
|
-
|
|
12746
|
+
}
|
|
12293
12747
|
}
|
|
12294
|
-
function
|
|
12295
|
-
|
|
12296
|
-
|
|
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
|
-
}
|
|
12748
|
+
function findBaseX0(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12749
|
+
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN13(0))) {
|
|
12750
|
+
return new BN13(0);
|
|
12302
12751
|
}
|
|
12303
|
-
|
|
12304
|
-
|
|
12305
|
-
|
|
12752
|
+
let b = new BN13(0);
|
|
12753
|
+
let c = new BN13(0);
|
|
12754
|
+
let m1 = minDeltaId;
|
|
12755
|
+
let m2 = maxDeltaId;
|
|
12756
|
+
for (let m = m1.toNumber(); m <= m2.toNumber(); m++) {
|
|
12757
|
+
const binId = activeId.addn(m);
|
|
12758
|
+
const pm = getQPriceFromId(binId.neg(), binStep);
|
|
12759
|
+
b = b.add(pm);
|
|
12760
|
+
const cDelta = new BN13(m).mul(pm).div(m2);
|
|
12761
|
+
c = c.add(cDelta);
|
|
12762
|
+
}
|
|
12763
|
+
return amountX.shln(SCALE_OFFSET).div(b.sub(c));
|
|
12306
12764
|
}
|
|
12307
|
-
function
|
|
12308
|
-
|
|
12309
|
-
|
|
12310
|
-
|
|
12311
|
-
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12318
|
-
|
|
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
|
+
};
|
|
12319
12793
|
}
|
|
12320
12794
|
}
|
|
12321
|
-
return [minBinId, maxBinId];
|
|
12322
12795
|
}
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
return
|
|
12796
|
+
var CurveStrategyParameterBuilder = class {
|
|
12797
|
+
findXParameters(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12798
|
+
return findX0AndDeltaX2(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
12326
12799
|
}
|
|
12327
|
-
|
|
12328
|
-
|
|
12329
|
-
function onlyDepositToAskSide(minDeltaId, favorXInActiveBin) {
|
|
12330
|
-
if (favorXInActiveBin) {
|
|
12331
|
-
return minDeltaId.gte(new BN14(0));
|
|
12800
|
+
findYParameters(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
12801
|
+
return findY0AndDeltaY2(amountY, minDeltaId, maxDeltaId, activeId);
|
|
12332
12802
|
}
|
|
12333
|
-
|
|
12334
|
-
|
|
12335
|
-
|
|
12336
|
-
|
|
12337
|
-
|
|
12338
|
-
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
|
|
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,
|
|
12346
12850
|
amountY
|
|
12347
|
-
}
|
|
12851
|
+
};
|
|
12348
12852
|
}
|
|
12349
|
-
|
|
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);
|
|
12350
12865
|
}
|
|
12351
|
-
function
|
|
12352
|
-
|
|
12866
|
+
function findBaseX02(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12867
|
+
let totalWeight = new BN14(0);
|
|
12353
12868
|
const minBinId = activeId.add(minDeltaId);
|
|
12354
12869
|
const maxBinId = activeId.add(maxDeltaId);
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
let
|
|
12358
|
-
|
|
12359
|
-
|
|
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);
|
|
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);
|
|
12369
12875
|
}
|
|
12370
|
-
return
|
|
12876
|
+
return amountX.shln(SCALE_OFFSET).div(totalWeight);
|
|
12371
12877
|
}
|
|
12372
|
-
function
|
|
12373
|
-
if (
|
|
12374
|
-
return
|
|
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);
|
|
12375
12881
|
}
|
|
12376
|
-
|
|
12377
|
-
|
|
12882
|
+
let x0 = findBaseX02(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
12883
|
+
while (true) {
|
|
12884
|
+
const amountInBins = getAmountInBinsAskSide(
|
|
12378
12885
|
activeId,
|
|
12379
12886
|
binStep,
|
|
12380
12887
|
minDeltaId,
|
|
12381
|
-
maxDeltaId,
|
|
12382
|
-
|
|
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
|
|
12888
|
+
maxDeltaId,
|
|
12889
|
+
new BN14(0),
|
|
12890
|
+
x0
|
|
12416
12891
|
);
|
|
12417
|
-
const
|
|
12418
|
-
|
|
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
|
+
}
|
|
12419
12901
|
}
|
|
12420
|
-
return new BN14(0);
|
|
12421
12902
|
}
|
|
12422
|
-
|
|
12423
|
-
|
|
12903
|
+
var SpotStrategyParameterBuilder = class {
|
|
12904
|
+
findXParameters(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
12424
12905
|
return {
|
|
12425
|
-
|
|
12426
|
-
|
|
12906
|
+
base: findX0(amountX, minDeltaId, maxDeltaId, binStep, activeId),
|
|
12907
|
+
delta: new BN14(0)
|
|
12427
12908
|
};
|
|
12428
12909
|
}
|
|
12429
|
-
|
|
12430
|
-
const inLiquidity = getLiquidity(amountX, amountY, price);
|
|
12431
|
-
const binLiquidity = getLiquidity(bin.amountX, bin.amountY, price);
|
|
12432
|
-
if (bin.liquiditySupply.isZero()) {
|
|
12910
|
+
findYParameters(amountY, minDeltaId, maxDeltaId, _activeId) {
|
|
12433
12911
|
return {
|
|
12434
|
-
|
|
12435
|
-
|
|
12912
|
+
base: findY0(amountY, minDeltaId, maxDeltaId),
|
|
12913
|
+
delta: new BN14(0)
|
|
12436
12914
|
};
|
|
12437
12915
|
}
|
|
12438
|
-
|
|
12439
|
-
|
|
12440
|
-
|
|
12441
|
-
|
|
12442
|
-
|
|
12443
|
-
|
|
12444
|
-
|
|
12445
|
-
|
|
12446
|
-
updatedBinYAmount.div(updatedBinSupply)
|
|
12447
|
-
);
|
|
12448
|
-
if (amountXIntoBin.gt(amountX)) {
|
|
12449
|
-
}
|
|
12450
|
-
return {
|
|
12451
|
-
amountXIntoBin,
|
|
12452
|
-
amountYIntoBin
|
|
12453
|
-
};
|
|
12454
|
-
}
|
|
12455
|
-
var RebalancePosition = class {
|
|
12456
|
-
address;
|
|
12457
|
-
lowerBinId;
|
|
12458
|
-
upperBinId;
|
|
12459
|
-
lbPair;
|
|
12460
|
-
owner;
|
|
12461
|
-
shouldClaimFee;
|
|
12462
|
-
shouldClaimReward;
|
|
12463
|
-
rebalancePositionBinData;
|
|
12464
|
-
activeBin;
|
|
12465
|
-
currentTimestamp;
|
|
12466
|
-
constructor(positionAddress, positionData, lbPair, activeBin, shouldClaimFee, shouldClaimReward, currentTimestamp) {
|
|
12467
|
-
this.address = positionAddress;
|
|
12468
|
-
this.rebalancePositionBinData = toRebalancePositionBinData(positionData);
|
|
12469
|
-
this.lowerBinId = new BN14(positionData.lowerBinId);
|
|
12470
|
-
this.upperBinId = new BN14(positionData.upperBinId);
|
|
12471
|
-
this.lbPair = lbPair;
|
|
12472
|
-
this.shouldClaimFee = shouldClaimFee;
|
|
12473
|
-
this.shouldClaimReward = shouldClaimReward;
|
|
12474
|
-
this.owner = positionData.owner;
|
|
12475
|
-
this.activeBin = activeBin;
|
|
12476
|
-
this.currentTimestamp = currentTimestamp;
|
|
12477
|
-
}
|
|
12478
|
-
static async create(params) {
|
|
12479
|
-
const {
|
|
12480
|
-
program,
|
|
12481
|
-
positionAddress,
|
|
12482
|
-
pairAddress,
|
|
12483
|
-
positionData,
|
|
12484
|
-
shouldClaimFee,
|
|
12485
|
-
shouldClaimReward
|
|
12486
|
-
} = params;
|
|
12487
|
-
const [lbPairAccount, clockAccount] = await program.provider.connection.getMultipleAccountsInfo([
|
|
12488
|
-
pairAddress,
|
|
12489
|
-
SYSVAR_CLOCK_PUBKEY
|
|
12490
|
-
]);
|
|
12491
|
-
const lbPair = decodeAccount(program, "lbPair", lbPairAccount.data);
|
|
12492
|
-
const clock = ClockLayout.decode(clockAccount.data);
|
|
12493
|
-
const activeBinArrayIdx = binIdToBinArrayIndex(new BN14(lbPair.activeId));
|
|
12494
|
-
const [activeBinArrayPubkey] = deriveBinArray(
|
|
12495
|
-
pairAddress,
|
|
12496
|
-
activeBinArrayIdx,
|
|
12497
|
-
program.programId
|
|
12498
|
-
);
|
|
12499
|
-
const activeBinArrayState = await program.account.binArray.fetch(
|
|
12500
|
-
activeBinArrayPubkey
|
|
12501
|
-
);
|
|
12502
|
-
const [lowerBinId, upperBinId] = getBinArrayLowerUpperBinId(activeBinArrayIdx);
|
|
12503
|
-
const idx = getBinIdIndexInBinArray(
|
|
12504
|
-
new BN14(lbPair.activeId),
|
|
12505
|
-
lowerBinId,
|
|
12506
|
-
upperBinId
|
|
12507
|
-
);
|
|
12508
|
-
const activeBin = activeBinArrayState[idx.toNumber()];
|
|
12509
|
-
return new RebalancePosition(
|
|
12510
|
-
positionAddress,
|
|
12511
|
-
positionData,
|
|
12512
|
-
lbPair,
|
|
12513
|
-
activeBin,
|
|
12514
|
-
shouldClaimFee,
|
|
12515
|
-
shouldClaimReward,
|
|
12516
|
-
clock.unixTimestamp
|
|
12517
|
-
);
|
|
12518
|
-
}
|
|
12519
|
-
_simulateDeposit(binStep, tokenXDecimal, tokenYDecimal, deposits, simulatedWithdrawResult) {
|
|
12520
|
-
const { liquidityAndFeeXWithdrawn, liquidityAndFeeYWithdrawn } = simulatedWithdrawResult;
|
|
12521
|
-
const activeId = new BN14(this.lbPair.activeId);
|
|
12522
|
-
const depositBinIds = getDepositBinIds(activeId, deposits);
|
|
12523
|
-
if (depositBinIds.length > 0) {
|
|
12524
|
-
const depositMinBinId = depositBinIds[0];
|
|
12525
|
-
const depositMaxBinId = depositBinIds[depositBinIds.length - 1];
|
|
12526
|
-
this._simulateResize(
|
|
12527
|
-
new BN14(depositMinBinId),
|
|
12528
|
-
new BN14(depositMaxBinId),
|
|
12529
|
-
binStep,
|
|
12530
|
-
tokenXDecimal,
|
|
12531
|
-
tokenYDecimal
|
|
12532
|
-
);
|
|
12533
|
-
}
|
|
12534
|
-
let totalAmountXDeposited = new BN14(0);
|
|
12535
|
-
let totalAmountYDeposited = new BN14(0);
|
|
12536
|
-
const addLiquidityParam = [];
|
|
12537
|
-
for (const {
|
|
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),
|
|
12538
12924
|
x0,
|
|
12539
|
-
|
|
12540
|
-
|
|
12541
|
-
|
|
12542
|
-
|
|
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,
|
|
12543
12941
|
minDeltaId,
|
|
12544
|
-
maxDeltaId
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
|
|
12570
|
-
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
);
|
|
12574
|
-
|
|
12575
|
-
|
|
12576
|
-
|
|
12577
|
-
|
|
12578
|
-
|
|
12579
|
-
);
|
|
12580
|
-
if (binId.eq(activeId)) {
|
|
12581
|
-
const vParameters3 = Object.assign({}, this.lbPair.vParameters);
|
|
12582
|
-
const sParameters3 = Object.assign({}, this.lbPair.parameters);
|
|
12583
|
-
DLMM.updateReference(
|
|
12584
|
-
activeId.toNumber(),
|
|
12585
|
-
vParameters3,
|
|
12586
|
-
sParameters3,
|
|
12587
|
-
this.currentTimestamp.toNumber()
|
|
12588
|
-
);
|
|
12589
|
-
DLMM.updateVolatilityAccumulator(
|
|
12590
|
-
vParameters3,
|
|
12591
|
-
sParameters3,
|
|
12592
|
-
activeId.toNumber()
|
|
12593
|
-
);
|
|
12594
|
-
const { amountXIntoBin, amountYIntoBin } = simulateDepositBin(
|
|
12595
|
-
binId,
|
|
12596
|
-
binStep,
|
|
12597
|
-
amountX,
|
|
12598
|
-
amountY,
|
|
12599
|
-
this.activeBin
|
|
12600
|
-
);
|
|
12601
|
-
const feeY = computeCompositionFee(
|
|
12602
|
-
binStep,
|
|
12603
|
-
sParameters3,
|
|
12604
|
-
vParameters3,
|
|
12605
|
-
amountXIntoBin,
|
|
12606
|
-
amountX,
|
|
12607
|
-
amountYIntoBin,
|
|
12608
|
-
amountY
|
|
12609
|
-
);
|
|
12610
|
-
const feeX = computeCompositionFee(
|
|
12611
|
-
binStep,
|
|
12612
|
-
sParameters3,
|
|
12613
|
-
vParameters3,
|
|
12614
|
-
amountYIntoBin,
|
|
12615
|
-
amountY,
|
|
12616
|
-
amountXIntoBin,
|
|
12617
|
-
amountX
|
|
12618
|
-
);
|
|
12619
|
-
const amountXIntoBinExcludeFee = amountXIntoBin.sub(feeX);
|
|
12620
|
-
const amountYIntoBinExcludeFee = amountYIntoBin.sub(feeY);
|
|
12621
|
-
this.rebalancePositionBinData[idx].amountX = this.rebalancePositionBinData[idx].amountX.add(
|
|
12622
|
-
amountXIntoBinExcludeFee
|
|
12623
|
-
);
|
|
12624
|
-
this.rebalancePositionBinData[idx].amountY = this.rebalancePositionBinData[idx].amountY.add(
|
|
12625
|
-
amountYIntoBinExcludeFee
|
|
12626
|
-
);
|
|
12627
|
-
} else {
|
|
12628
|
-
this.rebalancePositionBinData[idx].amountX = this.rebalancePositionBinData[idx].amountX.add(amountX);
|
|
12629
|
-
this.rebalancePositionBinData[idx].amountY = this.rebalancePositionBinData[idx].amountY.add(amountY);
|
|
12630
|
-
}
|
|
12631
|
-
}
|
|
12632
|
-
}
|
|
12633
|
-
let actualTotalAmountXDeposited = totalAmountXDeposited;
|
|
12634
|
-
let actualTotalAmountYDeposited = totalAmountYDeposited;
|
|
12635
|
-
let actualLiquidityAndFeeXWithdrawn = liquidityAndFeeXWithdrawn;
|
|
12636
|
-
let actualLiquidityAndFeeYWithdrawn = liquidityAndFeeYWithdrawn;
|
|
12637
|
-
if (actualTotalAmountXDeposited.gt(actualLiquidityAndFeeXWithdrawn)) {
|
|
12638
|
-
actualTotalAmountXDeposited = actualTotalAmountXDeposited.sub(
|
|
12639
|
-
actualLiquidityAndFeeXWithdrawn
|
|
12640
|
-
);
|
|
12641
|
-
actualLiquidityAndFeeXWithdrawn = new BN14(0);
|
|
12642
|
-
} else {
|
|
12643
|
-
actualLiquidityAndFeeXWithdrawn = actualLiquidityAndFeeXWithdrawn.sub(
|
|
12644
|
-
actualTotalAmountXDeposited
|
|
12645
|
-
);
|
|
12646
|
-
actualTotalAmountXDeposited = new BN14(0);
|
|
12647
|
-
}
|
|
12648
|
-
if (actualTotalAmountYDeposited.gt(actualLiquidityAndFeeYWithdrawn)) {
|
|
12649
|
-
actualTotalAmountYDeposited = actualTotalAmountYDeposited.sub(
|
|
12650
|
-
actualLiquidityAndFeeYWithdrawn
|
|
12651
|
-
);
|
|
12652
|
-
actualLiquidityAndFeeYWithdrawn = new BN14(0);
|
|
12653
|
-
} else {
|
|
12654
|
-
actualLiquidityAndFeeYWithdrawn = actualLiquidityAndFeeYWithdrawn.sub(
|
|
12655
|
-
actualTotalAmountYDeposited
|
|
12656
|
-
);
|
|
12657
|
-
actualTotalAmountYDeposited = new BN14(0);
|
|
12658
|
-
}
|
|
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)) {
|
|
12659
12977
|
return {
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
actualLiquidityAndFeeXWithdrawn,
|
|
12664
|
-
actualLiquidityAndFeeYWithdrawn,
|
|
12665
|
-
actualTotalAmountXDeposited,
|
|
12666
|
-
actualTotalAmountYDeposited
|
|
12667
|
-
},
|
|
12668
|
-
depositParams: addLiquidityParam
|
|
12978
|
+
base: new BN15(0),
|
|
12979
|
+
delta: new BN15(0),
|
|
12980
|
+
amountX: new BN15(0)
|
|
12669
12981
|
};
|
|
12670
12982
|
}
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
)
|
|
12680
|
-
|
|
12681
|
-
|
|
12682
|
-
|
|
12683
|
-
|
|
12684
|
-
|
|
12685
|
-
|
|
12686
|
-
|
|
12687
|
-
|
|
12688
|
-
|
|
12689
|
-
|
|
12690
|
-
|
|
12691
|
-
|
|
12692
|
-
|
|
12693
|
-
|
|
12694
|
-
|
|
12695
|
-
|
|
12696
|
-
|
|
12697
|
-
|
|
12698
|
-
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
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;
|
|
12703
13034
|
} else {
|
|
12704
|
-
|
|
12705
|
-
for (let i = 1; i <= binCountToShrink.toNumber(); i++) {
|
|
12706
|
-
this.rebalancePositionBinData.shift();
|
|
12707
|
-
}
|
|
13035
|
+
maxBinId = rebalancePosition.rebalancePositionBinData[favorXInActiveBin ? activeIdIndex - 1 : activeIdIndex].binId;
|
|
12708
13036
|
}
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
|
|
12716
|
-
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
}
|
|
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
|
+
return {
|
|
13048
|
+
amount: amountY,
|
|
13049
|
+
isBidSide: true
|
|
13050
|
+
};
|
|
13051
|
+
} else if (liquidityInAskSide.lt(liquidityInBidSide)) {
|
|
13052
|
+
const maxBinId = rebalancePosition.rebalancePositionBinData[rebalancePosition.rebalancePositionBinData.length - 1].binId;
|
|
13053
|
+
let minBinId;
|
|
13054
|
+
if (activeIdIndex == -1) {
|
|
13055
|
+
minBinId = rebalancePosition.rebalancePositionBinData[0].binId;
|
|
12729
13056
|
} else {
|
|
12730
|
-
|
|
12731
|
-
for (let i = 1; i <= binCountToShrink.toNumber(); i++) {
|
|
12732
|
-
this.rebalancePositionBinData.pop();
|
|
12733
|
-
}
|
|
13057
|
+
minBinId = rebalancePosition.rebalancePositionBinData[favorXInActiveBin ? activeIdIndex - 1 : activeIdIndex].binId;
|
|
12734
13058
|
}
|
|
12735
|
-
|
|
12736
|
-
|
|
13059
|
+
const minDeltaId = lbPair.activeId - minBinId;
|
|
13060
|
+
const maxDeltaId = lbPair.activeId - maxBinId;
|
|
13061
|
+
const { amountX } = builder.suggestBalancedXParametersFromY(
|
|
13062
|
+
new BN15(lbPair.activeId),
|
|
13063
|
+
new BN15(lbPair.binStep),
|
|
13064
|
+
favorXInActiveBin,
|
|
13065
|
+
new BN15(minDeltaId),
|
|
13066
|
+
new BN15(maxDeltaId),
|
|
13067
|
+
liquidityInBidSide
|
|
13068
|
+
);
|
|
13069
|
+
return {
|
|
13070
|
+
amount: amountX,
|
|
13071
|
+
isBidSide: false
|
|
13072
|
+
};
|
|
13073
|
+
} else {
|
|
13074
|
+
return {
|
|
13075
|
+
amount: new BN15(0),
|
|
13076
|
+
isBidSide: false
|
|
13077
|
+
};
|
|
12737
13078
|
}
|
|
12738
|
-
|
|
12739
|
-
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
12745
|
-
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12750
|
-
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
binData.claimableFeeYAmount
|
|
12766
|
-
);
|
|
12767
|
-
binData.claimableFeeXAmount = new BN14(0);
|
|
12768
|
-
binData.claimableFeeYAmount = new BN14(0);
|
|
12769
|
-
}
|
|
12770
|
-
if (this.shouldClaimReward) {
|
|
12771
|
-
for (const [idx2, amount] of binData.claimableRewardAmount.entries()) {
|
|
12772
|
-
rewardsAmountClaimed[idx2] = rewardsAmountClaimed[idx2].add(amount);
|
|
12773
|
-
binData.claimableRewardAmount[idx2] = new BN14(0);
|
|
12774
|
-
}
|
|
12775
|
-
}
|
|
12776
|
-
this.rebalancePositionBinData[idx] = binData;
|
|
12777
|
-
}
|
|
12778
|
-
}
|
|
12779
|
-
const withdrawParams = withdraws.map(
|
|
12780
|
-
({ minBinId, maxBinId, bps }) => {
|
|
12781
|
-
return {
|
|
12782
|
-
minBinId: minBinId ? minBinId.toNumber() : null,
|
|
12783
|
-
maxBinId: maxBinId ? maxBinId.toNumber() : null,
|
|
12784
|
-
bps: bps.toNumber(),
|
|
12785
|
-
padding: Array(16).fill(0)
|
|
12786
|
-
};
|
|
12787
|
-
}
|
|
13079
|
+
}
|
|
13080
|
+
function suggestBalancedYParametersFromX(x0, deltaX, minDeltaId, maxDeltaId, activeId, binStep, favorXInActiveBin, builder) {
|
|
13081
|
+
const startDeltaIdAskSide = favorXInActiveBin ? new BN15(0) : new BN15(1);
|
|
13082
|
+
if (minDeltaId.gte(startDeltaIdAskSide)) {
|
|
13083
|
+
return {
|
|
13084
|
+
base: new BN15(0),
|
|
13085
|
+
delta: new BN15(0),
|
|
13086
|
+
amountY: new BN15(0)
|
|
13087
|
+
};
|
|
13088
|
+
}
|
|
13089
|
+
const minXDeltaId = startDeltaIdAskSide;
|
|
13090
|
+
const maxXDeltaId = maxDeltaId;
|
|
13091
|
+
const amountXInBins = toAmountIntoBins(
|
|
13092
|
+
activeId,
|
|
13093
|
+
minXDeltaId,
|
|
13094
|
+
maxXDeltaId,
|
|
13095
|
+
deltaX,
|
|
13096
|
+
new BN15(0),
|
|
13097
|
+
x0,
|
|
13098
|
+
new BN15(0),
|
|
13099
|
+
binStep,
|
|
13100
|
+
favorXInActiveBin
|
|
13101
|
+
);
|
|
13102
|
+
const totalAmountXInQuote = amountXInBins.reduce((acc, bin) => {
|
|
13103
|
+
const price = getPriceOfBinByBinId(
|
|
13104
|
+
bin.binId.toNumber(),
|
|
13105
|
+
binStep.toNumber()
|
|
12788
13106
|
);
|
|
13107
|
+
return acc.add(price.mul(new Decimal7(bin.amountX.toString())));
|
|
13108
|
+
}, new Decimal7(0));
|
|
13109
|
+
const totalAmountXInQuoteBN = new BN15(totalAmountXInQuote.floor().toString());
|
|
13110
|
+
const minYDeltaId = minDeltaId;
|
|
13111
|
+
const maxYDeltaId = startDeltaIdAskSide.subn(1);
|
|
13112
|
+
return builder.suggestBalancedYParametersFromX(
|
|
13113
|
+
activeId,
|
|
13114
|
+
binStep,
|
|
13115
|
+
favorXInActiveBin,
|
|
13116
|
+
minYDeltaId,
|
|
13117
|
+
maxYDeltaId,
|
|
13118
|
+
totalAmountXInQuoteBN
|
|
13119
|
+
);
|
|
13120
|
+
}
|
|
13121
|
+
function buildLiquidityStrategyParameters(amountX, amountY, minDeltaId, maxDeltaId, binStep, favorXInActiveId, activeId, strategyParameterBuilder) {
|
|
13122
|
+
if (minDeltaId.gt(maxDeltaId)) {
|
|
12789
13123
|
return {
|
|
12790
|
-
|
|
12791
|
-
|
|
12792
|
-
|
|
12793
|
-
|
|
12794
|
-
},
|
|
12795
|
-
withdrawParams
|
|
13124
|
+
x0: new BN15(0),
|
|
13125
|
+
y0: new BN15(0),
|
|
13126
|
+
deltaX: new BN15(0),
|
|
13127
|
+
deltaY: new BN15(0)
|
|
12796
13128
|
};
|
|
12797
13129
|
}
|
|
12798
|
-
|
|
12799
|
-
|
|
12800
|
-
|
|
12801
|
-
}
|
|
12802
|
-
|
|
12803
|
-
|
|
12804
|
-
|
|
12805
|
-
|
|
12806
|
-
this.lowerBinId.toNumber(),
|
|
12807
|
-
this.upperBinId.toNumber()
|
|
13130
|
+
const depositOnlyY = maxDeltaId.lt(new BN15(0)) || maxDeltaId.isZero() && !favorXInActiveId;
|
|
13131
|
+
const depositOnlyX = minDeltaId.gt(new BN15(0)) || minDeltaId.isZero() && favorXInActiveId;
|
|
13132
|
+
if (depositOnlyY) {
|
|
13133
|
+
const { base, delta } = strategyParameterBuilder.findYParameters(
|
|
13134
|
+
amountY,
|
|
13135
|
+
minDeltaId,
|
|
13136
|
+
maxDeltaId,
|
|
13137
|
+
activeId
|
|
12808
13138
|
);
|
|
12809
|
-
|
|
12810
|
-
|
|
13139
|
+
return {
|
|
13140
|
+
x0: new BN15(0),
|
|
13141
|
+
deltaX: new BN15(0),
|
|
13142
|
+
y0: base,
|
|
13143
|
+
deltaY: delta
|
|
13144
|
+
};
|
|
13145
|
+
}
|
|
13146
|
+
if (depositOnlyX) {
|
|
13147
|
+
const { base, delta } = strategyParameterBuilder.findXParameters(
|
|
13148
|
+
amountX,
|
|
13149
|
+
minDeltaId,
|
|
13150
|
+
maxDeltaId,
|
|
12811
13151
|
binStep,
|
|
12812
|
-
|
|
12813
|
-
tokenYDecimal,
|
|
12814
|
-
deposits,
|
|
12815
|
-
withdrawResult
|
|
12816
|
-
);
|
|
12817
|
-
const afterWidth = getPositionWidthWithMinWidth(
|
|
12818
|
-
this.lowerBinId.toNumber(),
|
|
12819
|
-
this.upperBinId.toNumber()
|
|
13152
|
+
activeId
|
|
12820
13153
|
);
|
|
12821
|
-
const widthDelta = afterWidth - beforeWidth;
|
|
12822
|
-
let rentalCostLamports = new BN14(0);
|
|
12823
|
-
if (widthDelta != 0) {
|
|
12824
|
-
const sizeChanges = Math.abs(widthDelta) * POSITION_BIN_DATA_SIZE;
|
|
12825
|
-
const [minimumLamports, rentExemptionLamports] = await Promise.all([
|
|
12826
|
-
connection.getMinimumBalanceForRentExemption(0),
|
|
12827
|
-
connection.getMinimumBalanceForRentExemption(sizeChanges)
|
|
12828
|
-
]);
|
|
12829
|
-
const lamportChanges = new BN14(rentExemptionLamports).sub(
|
|
12830
|
-
new BN14(minimumLamports)
|
|
12831
|
-
);
|
|
12832
|
-
if (widthDelta > 0) {
|
|
12833
|
-
rentalCostLamports = rentalCostLamports.add(lamportChanges);
|
|
12834
|
-
} else {
|
|
12835
|
-
rentalCostLamports = rentalCostLamports.sub(lamportChanges);
|
|
12836
|
-
}
|
|
12837
|
-
}
|
|
12838
13154
|
return {
|
|
12839
|
-
|
|
12840
|
-
|
|
12841
|
-
|
|
12842
|
-
|
|
12843
|
-
actualAmountXWithdrawn: depositResult.actualLiquidityAndFeeXWithdrawn,
|
|
12844
|
-
actualAmountYWithdrawn: depositResult.actualLiquidityAndFeeYWithdrawn,
|
|
12845
|
-
rewardAmountsClaimed: withdrawResult.rewardsAmountClaimed,
|
|
12846
|
-
withdrawParams,
|
|
12847
|
-
depositParams,
|
|
12848
|
-
rentalCostLamports
|
|
13155
|
+
x0: base,
|
|
13156
|
+
deltaX: delta,
|
|
13157
|
+
y0: new BN15(0),
|
|
13158
|
+
deltaY: new BN15(0)
|
|
12849
13159
|
};
|
|
12850
13160
|
}
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
}
|
|
12860
|
-
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
|
|
12865
|
-
|
|
12866
|
-
|
|
12867
|
-
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
|
|
12876
|
-
|
|
13161
|
+
const maxDeltaIdBidSide = favorXInActiveId ? new BN15(-1) : new BN15(0);
|
|
13162
|
+
const minDeltaIdAskSide = favorXInActiveId ? new BN15(0) : new BN15(1);
|
|
13163
|
+
const { base: y0, delta: deltaY } = strategyParameterBuilder.findYParameters(
|
|
13164
|
+
amountY,
|
|
13165
|
+
minDeltaId,
|
|
13166
|
+
maxDeltaIdBidSide,
|
|
13167
|
+
activeId
|
|
13168
|
+
);
|
|
13169
|
+
const { base: x0, delta: deltaX } = strategyParameterBuilder.findXParameters(
|
|
13170
|
+
amountX,
|
|
13171
|
+
minDeltaIdAskSide,
|
|
13172
|
+
maxDeltaId,
|
|
13173
|
+
binStep,
|
|
13174
|
+
activeId
|
|
13175
|
+
);
|
|
13176
|
+
return {
|
|
13177
|
+
x0,
|
|
13178
|
+
deltaX,
|
|
13179
|
+
y0,
|
|
13180
|
+
deltaY
|
|
13181
|
+
};
|
|
13182
|
+
}
|
|
13183
|
+
|
|
13184
|
+
// src/dlmm/helpers/index.ts
|
|
13185
|
+
function chunks(array, size) {
|
|
13186
|
+
return Array.apply(0, new Array(Math.ceil(array.length / size))).map(
|
|
13187
|
+
(_, index) => array.slice(index * size, (index + 1) * size)
|
|
13188
|
+
);
|
|
13189
|
+
}
|
|
13190
|
+
function range(min, max, mapfn) {
|
|
13191
|
+
const length = max - min + 1;
|
|
13192
|
+
return Array.from({ length }, (_, i) => mapfn(min + i));
|
|
13193
|
+
}
|
|
13194
|
+
async function chunkedFetchMultiplePoolAccount(program, pks, chunkSize = 100) {
|
|
13195
|
+
const accounts = (await Promise.all(
|
|
13196
|
+
chunks(pks, chunkSize).map(
|
|
13197
|
+
(chunk) => program.account.lbPair.fetchMultiple(chunk)
|
|
13198
|
+
)
|
|
13199
|
+
)).flat();
|
|
13200
|
+
return accounts.filter(Boolean);
|
|
13201
|
+
}
|
|
13202
|
+
async function chunkedFetchMultipleBinArrayBitmapExtensionAccount(program, pks, chunkSize = 100) {
|
|
13203
|
+
const accounts = (await Promise.all(
|
|
13204
|
+
chunks(pks, chunkSize).map(
|
|
13205
|
+
(chunk) => program.account.binArrayBitmapExtension.fetchMultiple(chunk)
|
|
13206
|
+
)
|
|
13207
|
+
)).flat();
|
|
13208
|
+
return accounts;
|
|
13209
|
+
}
|
|
13210
|
+
function getOutAmount(bin, inAmount, swapForY) {
|
|
13211
|
+
return swapForY ? mulShr(inAmount, bin.price, SCALE_OFFSET, 1 /* Down */) : shlDiv(inAmount, bin.price, SCALE_OFFSET, 1 /* Down */);
|
|
13212
|
+
}
|
|
13213
|
+
async function getTokenDecimals(conn, mint) {
|
|
13214
|
+
const token = await getMint(conn, mint);
|
|
13215
|
+
return await token.decimals;
|
|
13216
|
+
}
|
|
13217
|
+
var getOrCreateATAInstruction = async (connection, tokenMint, owner, programId, payer = owner, allowOwnerOffCurve = true) => {
|
|
13218
|
+
programId = programId ?? TOKEN_PROGRAM_ID3;
|
|
13219
|
+
const toAccount = getAssociatedTokenAddressSync(
|
|
13220
|
+
tokenMint,
|
|
13221
|
+
owner,
|
|
13222
|
+
allowOwnerOffCurve,
|
|
13223
|
+
programId,
|
|
13224
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
13225
|
+
);
|
|
13226
|
+
try {
|
|
13227
|
+
await getAccount(connection, toAccount, connection.commitment, programId);
|
|
13228
|
+
return { ataPubKey: toAccount, ix: void 0 };
|
|
13229
|
+
} catch (e) {
|
|
13230
|
+
if (e instanceof TokenAccountNotFoundError || e instanceof TokenInvalidAccountOwnerError) {
|
|
13231
|
+
const ix = createAssociatedTokenAccountIdempotentInstruction(
|
|
13232
|
+
payer,
|
|
13233
|
+
toAccount,
|
|
13234
|
+
owner,
|
|
13235
|
+
tokenMint,
|
|
13236
|
+
programId,
|
|
13237
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
12877
13238
|
);
|
|
13239
|
+
return { ataPubKey: toAccount, ix };
|
|
13240
|
+
} else {
|
|
13241
|
+
console.error("Error::getOrCreateATAInstruction", e);
|
|
13242
|
+
throw e;
|
|
12878
13243
|
}
|
|
12879
|
-
return totalRewardAmounts;
|
|
12880
13244
|
}
|
|
12881
13245
|
};
|
|
12882
|
-
function
|
|
12883
|
-
const
|
|
12884
|
-
return
|
|
13246
|
+
async function getTokenBalance(conn, tokenAccount) {
|
|
13247
|
+
const acc = await getAccount(conn, tokenAccount);
|
|
13248
|
+
return acc.amount;
|
|
12885
13249
|
}
|
|
12886
|
-
|
|
12887
|
-
|
|
12888
|
-
(
|
|
12889
|
-
)
|
|
12890
|
-
|
|
12891
|
-
if (deposit.minDeltaId.gte(deposit.maxDeltaId)) {
|
|
12892
|
-
throw "Invalid minDeltaId or maxDeltaId";
|
|
12893
|
-
}
|
|
13250
|
+
var parseLogs = (eventParser, logs) => {
|
|
13251
|
+
if (!logs.length)
|
|
13252
|
+
throw new Error("No logs found");
|
|
13253
|
+
for (const event of eventParser?.parseLogs(logs)) {
|
|
13254
|
+
return event.data;
|
|
12894
13255
|
}
|
|
12895
|
-
|
|
12896
|
-
|
|
12897
|
-
|
|
12898
|
-
|
|
12899
|
-
|
|
12900
|
-
|
|
13256
|
+
throw new Error("No events found");
|
|
13257
|
+
};
|
|
13258
|
+
var wrapSOLInstruction = (from, to, amount) => {
|
|
13259
|
+
return [
|
|
13260
|
+
SystemProgram.transfer({
|
|
13261
|
+
fromPubkey: from,
|
|
13262
|
+
toPubkey: to,
|
|
13263
|
+
lamports: amount
|
|
13264
|
+
}),
|
|
13265
|
+
new TransactionInstruction3({
|
|
13266
|
+
keys: [
|
|
13267
|
+
{
|
|
13268
|
+
pubkey: to,
|
|
13269
|
+
isSigner: false,
|
|
13270
|
+
isWritable: true
|
|
13271
|
+
}
|
|
13272
|
+
],
|
|
13273
|
+
data: Buffer.from(new Uint8Array([17])),
|
|
13274
|
+
programId: TOKEN_PROGRAM_ID3
|
|
13275
|
+
})
|
|
13276
|
+
];
|
|
13277
|
+
};
|
|
13278
|
+
var unwrapSOLInstruction = async (owner, allowOwnerOffCurve = true) => {
|
|
13279
|
+
const wSolATAAccount = getAssociatedTokenAddressSync(
|
|
13280
|
+
NATIVE_MINT,
|
|
13281
|
+
owner,
|
|
13282
|
+
allowOwnerOffCurve
|
|
13283
|
+
);
|
|
13284
|
+
if (wSolATAAccount) {
|
|
13285
|
+
const closedWrappedSolInstruction = createCloseAccountInstruction(
|
|
13286
|
+
wSolATAAccount,
|
|
13287
|
+
owner,
|
|
13288
|
+
owner,
|
|
13289
|
+
[],
|
|
13290
|
+
TOKEN_PROGRAM_ID3
|
|
13291
|
+
);
|
|
13292
|
+
return closedWrappedSolInstruction;
|
|
12901
13293
|
}
|
|
12902
|
-
return
|
|
13294
|
+
return null;
|
|
13295
|
+
};
|
|
13296
|
+
async function chunkedGetMultipleAccountInfos(connection, pks, chunkSize = 100) {
|
|
13297
|
+
const accountInfos = (await Promise.all(
|
|
13298
|
+
chunks(pks, chunkSize).map(
|
|
13299
|
+
(chunk) => connection.getMultipleAccountsInfo(chunk)
|
|
13300
|
+
)
|
|
13301
|
+
)).flat();
|
|
13302
|
+
return accountInfos;
|
|
12903
13303
|
}
|
|
12904
|
-
|
|
12905
|
-
|
|
12906
|
-
|
|
12907
|
-
if (bps.toNumber() < 0 || bps.toNumber() > BASIS_POINT_MAX) {
|
|
12908
|
-
throw "Invalid bps";
|
|
12909
|
-
}
|
|
12910
|
-
const filledMinBinId = minBinId ?? activeId;
|
|
12911
|
-
const filledMaxBinId = maxBinId ?? activeId;
|
|
12912
|
-
if (filledMinBinId.gt(filledMaxBinId)) {
|
|
12913
|
-
throw "Invalid minBinId or maxBinId";
|
|
12914
|
-
}
|
|
12915
|
-
filledWithdraws.push({
|
|
12916
|
-
minBinId: filledMinBinId,
|
|
12917
|
-
maxBinId: filledMaxBinId,
|
|
12918
|
-
bps
|
|
12919
|
-
});
|
|
13304
|
+
var getEstimatedComputeUnitUsageWithBuffer = async (connection, instructions, feePayer, buffer) => {
|
|
13305
|
+
if (!buffer) {
|
|
13306
|
+
buffer = 0.1;
|
|
12920
13307
|
}
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
13308
|
+
buffer = Math.max(0, buffer);
|
|
13309
|
+
buffer = Math.min(1, buffer);
|
|
13310
|
+
const estimatedComputeUnitUsage = await getSimulationComputeUnits(
|
|
13311
|
+
connection,
|
|
13312
|
+
instructions,
|
|
13313
|
+
feePayer,
|
|
13314
|
+
[]
|
|
13315
|
+
);
|
|
13316
|
+
let extraComputeUnitBuffer = estimatedComputeUnitUsage * buffer;
|
|
13317
|
+
if (extraComputeUnitBuffer > MAX_CU_BUFFER) {
|
|
13318
|
+
extraComputeUnitBuffer = MAX_CU_BUFFER;
|
|
13319
|
+
} else if (extraComputeUnitBuffer < MIN_CU_BUFFER) {
|
|
13320
|
+
extraComputeUnitBuffer = MIN_CU_BUFFER;
|
|
12930
13321
|
}
|
|
12931
|
-
return
|
|
13322
|
+
return estimatedComputeUnitUsage + extraComputeUnitBuffer;
|
|
13323
|
+
};
|
|
13324
|
+
var getEstimatedComputeUnitIxWithBuffer = async (connection, instructions, feePayer, buffer) => {
|
|
13325
|
+
const units = await getEstimatedComputeUnitUsageWithBuffer(
|
|
13326
|
+
connection,
|
|
13327
|
+
instructions,
|
|
13328
|
+
feePayer,
|
|
13329
|
+
buffer
|
|
13330
|
+
).catch((error) => {
|
|
13331
|
+
console.error("Error::getEstimatedComputeUnitUsageWithBuffer", error);
|
|
13332
|
+
return 14e5;
|
|
13333
|
+
});
|
|
13334
|
+
return ComputeBudgetProgram2.setComputeUnitLimit({ units });
|
|
13335
|
+
};
|
|
13336
|
+
function createProgram(connection, opt) {
|
|
13337
|
+
const cluster = opt?.cluster || "mainnet-beta";
|
|
13338
|
+
const provider = new AnchorProvider(
|
|
13339
|
+
connection,
|
|
13340
|
+
{},
|
|
13341
|
+
AnchorProvider.defaultOptions()
|
|
13342
|
+
);
|
|
13343
|
+
return new Program2(
|
|
13344
|
+
{ ...dlmm_default, address: LBCLMM_PROGRAM_IDS[cluster] },
|
|
13345
|
+
provider
|
|
13346
|
+
);
|
|
12932
13347
|
}
|
|
12933
|
-
function
|
|
12934
|
-
|
|
12935
|
-
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
|
|
13348
|
+
function decodeAccount(program, accountName, buffer) {
|
|
13349
|
+
return program.coder.accounts.decode(accountName, buffer);
|
|
13350
|
+
}
|
|
13351
|
+
function getAccountDiscriminator(accountName) {
|
|
13352
|
+
return dlmm_default.accounts.find(
|
|
13353
|
+
(acc) => acc.name.toLowerCase() === accountName.toLowerCase()
|
|
13354
|
+
)?.discriminator;
|
|
13355
|
+
}
|
|
13356
|
+
function capSlippagePercentage(slippage) {
|
|
13357
|
+
if (slippage > 100) {
|
|
13358
|
+
slippage = 100;
|
|
12939
13359
|
}
|
|
12940
|
-
|
|
13360
|
+
if (slippage < 0) {
|
|
13361
|
+
slippage = 0;
|
|
13362
|
+
}
|
|
13363
|
+
return slippage;
|
|
12941
13364
|
}
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
12947
|
-
|
|
13365
|
+
|
|
13366
|
+
// src/dlmm/helpers/accountFilters.ts
|
|
13367
|
+
import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes";
|
|
13368
|
+
var presetParameter2BinStepFilter = (binStep) => {
|
|
13369
|
+
return {
|
|
13370
|
+
memcmp: {
|
|
13371
|
+
bytes: bs58.encode(binStep.toArrayLike(Buffer, "le", 2)),
|
|
13372
|
+
offset: 8
|
|
12948
13373
|
}
|
|
12949
|
-
|
|
12950
|
-
|
|
12951
|
-
|
|
13374
|
+
};
|
|
13375
|
+
};
|
|
13376
|
+
var presetParameter2BaseFactorFilter = (baseFactor) => {
|
|
13377
|
+
return {
|
|
13378
|
+
memcmp: {
|
|
13379
|
+
bytes: bs58.encode(baseFactor.toArrayLike(Buffer, "le", 2)),
|
|
13380
|
+
offset: 8 + 2
|
|
13381
|
+
}
|
|
13382
|
+
};
|
|
13383
|
+
};
|
|
13384
|
+
var presetParameter2BaseFeePowerFactor = (baseFeePowerFactor) => {
|
|
13385
|
+
return {
|
|
13386
|
+
memcmp: {
|
|
13387
|
+
bytes: bs58.encode(baseFeePowerFactor.toArrayLike(Buffer, "le", 1)),
|
|
13388
|
+
offset: 8 + 22
|
|
13389
|
+
}
|
|
13390
|
+
};
|
|
13391
|
+
};
|
|
13392
|
+
var binArrayLbPairFilter = (lbPair) => {
|
|
13393
|
+
return {
|
|
13394
|
+
memcmp: {
|
|
13395
|
+
bytes: lbPair.toBase58(),
|
|
13396
|
+
offset: 8 + 16
|
|
12952
13397
|
}
|
|
12953
|
-
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
12958
|
-
|
|
12959
|
-
|
|
12960
|
-
} else {
|
|
12961
|
-
binArrayIndex = binArrayIndex.add(new BN14(1));
|
|
12962
|
-
}
|
|
13398
|
+
};
|
|
13399
|
+
};
|
|
13400
|
+
var positionOwnerFilter = (owner) => {
|
|
13401
|
+
return {
|
|
13402
|
+
memcmp: {
|
|
13403
|
+
bytes: owner.toBase58(),
|
|
13404
|
+
offset: 8 + 32
|
|
12963
13405
|
}
|
|
12964
|
-
}
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
indexMap.set(binArrayIndex.toNumber(), true);
|
|
12972
|
-
const [binArrayLowerBinId, binArrayUpperBinId] = getBinArrayLowerUpperBinId(binArrayIndex);
|
|
12973
|
-
if (upperBinId.gte(binArrayLowerBinId) && upperBinId.lte(binArrayUpperBinId)) {
|
|
12974
|
-
break;
|
|
12975
|
-
} else {
|
|
12976
|
-
binArrayIndex = binArrayIndex.add(new BN14(1));
|
|
12977
|
-
}
|
|
13406
|
+
};
|
|
13407
|
+
};
|
|
13408
|
+
var positionLbPairFilter = (lbPair) => {
|
|
13409
|
+
return {
|
|
13410
|
+
memcmp: {
|
|
13411
|
+
bytes: bs58.encode(lbPair.toBuffer()),
|
|
13412
|
+
offset: 8
|
|
12978
13413
|
}
|
|
12979
|
-
}
|
|
12980
|
-
|
|
12981
|
-
|
|
12982
|
-
(index) => isOverflowDefaultBinArrayBitmap(new BN14(index))
|
|
12983
|
-
);
|
|
13414
|
+
};
|
|
13415
|
+
};
|
|
13416
|
+
var positionV2Filter = () => {
|
|
12984
13417
|
return {
|
|
12985
|
-
|
|
12986
|
-
|
|
13418
|
+
memcmp: {
|
|
13419
|
+
bytes: bs58.encode(Buffer.from(getAccountDiscriminator("positionV2"))),
|
|
13420
|
+
offset: 0
|
|
13421
|
+
}
|
|
12987
13422
|
};
|
|
12988
|
-
}
|
|
13423
|
+
};
|
|
12989
13424
|
|
|
12990
|
-
// src/dlmm/helpers/
|
|
13425
|
+
// src/dlmm/helpers/positions/index.ts
|
|
12991
13426
|
import BN18 from "bn.js";
|
|
12992
13427
|
|
|
12993
|
-
// src/dlmm/helpers/
|
|
12994
|
-
import
|
|
12995
|
-
function
|
|
12996
|
-
const
|
|
12997
|
-
const
|
|
12998
|
-
|
|
12999
|
-
|
|
13000
|
-
|
|
13001
|
-
|
|
13002
|
-
|
|
13003
|
-
}
|
|
13004
|
-
if (minDeltaId.eq(maxDeltaId)) {
|
|
13005
|
-
return amountY;
|
|
13428
|
+
// src/dlmm/helpers/positions/wrapper.ts
|
|
13429
|
+
import BN17 from "bn.js";
|
|
13430
|
+
function combineBaseAndExtendedPositionBinData(base, extended) {
|
|
13431
|
+
const combinedLiquidityShares = base.liquidityShares;
|
|
13432
|
+
const combinedRewardInfos = base.rewardInfos;
|
|
13433
|
+
const combinedFeeInfos = base.feeInfos;
|
|
13434
|
+
for (const binData of extended) {
|
|
13435
|
+
combinedLiquidityShares.push(binData.liquidityShare);
|
|
13436
|
+
combinedRewardInfos.push(binData.rewardInfo);
|
|
13437
|
+
combinedFeeInfos.push(binData.feeInfo);
|
|
13006
13438
|
}
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
const a = b.add(c.sub(d));
|
|
13013
|
-
const e = minY0;
|
|
13014
|
-
return amountY.sub(e).div(a);
|
|
13439
|
+
return {
|
|
13440
|
+
liquidityShares: combinedLiquidityShares,
|
|
13441
|
+
rewardInfos: combinedRewardInfos,
|
|
13442
|
+
feeInfos: combinedFeeInfos
|
|
13443
|
+
};
|
|
13015
13444
|
}
|
|
13016
|
-
function
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
const minY0 = findMinY0(amountY, minDeltaId, maxDeltaId);
|
|
13024
|
-
let baseDeltaY = findBaseDeltaY(amountY, minDeltaId, maxDeltaId, minY0);
|
|
13025
|
-
const y0 = baseDeltaY.neg().mul(maxDeltaId).add(minY0);
|
|
13026
|
-
while (true) {
|
|
13027
|
-
const amountInBins = getAmountInBinsBidSide(
|
|
13028
|
-
activeId,
|
|
13029
|
-
minDeltaId,
|
|
13030
|
-
maxDeltaId,
|
|
13031
|
-
baseDeltaY,
|
|
13032
|
-
y0
|
|
13445
|
+
function wrapPosition(program, key, account) {
|
|
13446
|
+
const disc = account.data.subarray(0, 8);
|
|
13447
|
+
if (disc.equals(Buffer.from(getAccountDiscriminator("positionV2")))) {
|
|
13448
|
+
const state = decodeAccount(
|
|
13449
|
+
program,
|
|
13450
|
+
"positionV2",
|
|
13451
|
+
account.data
|
|
13033
13452
|
);
|
|
13034
|
-
const
|
|
13035
|
-
|
|
13036
|
-
|
|
13037
|
-
|
|
13038
|
-
baseDeltaY = baseDeltaY.sub(new BN15(1));
|
|
13039
|
-
} else {
|
|
13040
|
-
return {
|
|
13041
|
-
base: y0,
|
|
13042
|
-
delta: baseDeltaY
|
|
13043
|
-
};
|
|
13044
|
-
}
|
|
13045
|
-
}
|
|
13046
|
-
}
|
|
13047
|
-
function findMinX0(amountX, minDeltaId, maxDeltaId, activeId, binStep) {
|
|
13048
|
-
const minBinId = activeId.add(minDeltaId);
|
|
13049
|
-
const maxBinId = activeId.add(maxDeltaId);
|
|
13050
|
-
let totalWeight = new BN15(0);
|
|
13051
|
-
for (let binId = minBinId.toNumber(); binId <= maxBinId.toNumber(); binId++) {
|
|
13052
|
-
const binDelta = binId - minBinId.toNumber() + 1;
|
|
13053
|
-
const binPrice = getQPriceFromId(new BN15(binId), binStep);
|
|
13054
|
-
const weight = new BN15(binDelta).mul(binPrice);
|
|
13055
|
-
totalWeight = totalWeight.add(weight);
|
|
13056
|
-
}
|
|
13057
|
-
return amountX.shln(SCALE_OFFSET).div(totalWeight);
|
|
13058
|
-
}
|
|
13059
|
-
function findBaseDeltaX(amountX, minDeltaId, maxDeltaId, binStep, activeId, minX0) {
|
|
13060
|
-
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN15(0))) {
|
|
13061
|
-
return new BN15(0);
|
|
13062
|
-
}
|
|
13063
|
-
let b = new BN15(0);
|
|
13064
|
-
let c = new BN15(0);
|
|
13065
|
-
let m1 = minDeltaId;
|
|
13066
|
-
let m2 = maxDeltaId;
|
|
13067
|
-
console.log(m1.toNumber(), m2.toNumber());
|
|
13068
|
-
for (let m = m1.toNumber(); m <= m2.toNumber(); m++) {
|
|
13069
|
-
const binId = activeId.addn(m);
|
|
13070
|
-
const pm = getQPriceFromId(binId.neg(), binStep);
|
|
13071
|
-
const bDelta = m1.mul(pm);
|
|
13072
|
-
b = b.add(bDelta);
|
|
13073
|
-
const cDelta = new BN15(m).mul(pm);
|
|
13074
|
-
c = c.add(cDelta);
|
|
13075
|
-
}
|
|
13076
|
-
console.log(amountX.sub(minX0).shln(SCALE_OFFSET).div(c.sub(b)).toString());
|
|
13077
|
-
return amountX.sub(minX0).shln(SCALE_OFFSET).div(c.sub(b));
|
|
13078
|
-
}
|
|
13079
|
-
function findX0AndDeltaX(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13080
|
-
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN15(0)) || amountX.isZero()) {
|
|
13081
|
-
return {
|
|
13082
|
-
base: new BN15(0),
|
|
13083
|
-
delta: new BN15(0)
|
|
13084
|
-
};
|
|
13085
|
-
}
|
|
13086
|
-
const minX0 = findMinX0(amountX, minDeltaId, maxDeltaId, activeId, binStep);
|
|
13087
|
-
let baseDeltaX = findBaseDeltaX(
|
|
13088
|
-
amountX,
|
|
13089
|
-
minDeltaId,
|
|
13090
|
-
maxDeltaId,
|
|
13091
|
-
binStep,
|
|
13092
|
-
activeId,
|
|
13093
|
-
minX0
|
|
13094
|
-
);
|
|
13095
|
-
console.log("\u{1F680} ~ baseDeltaX:", baseDeltaX.toString());
|
|
13096
|
-
const x0 = minDeltaId.neg().mul(baseDeltaX).add(minX0);
|
|
13097
|
-
console.log("\u{1F680} ~ x0:", x0.toString());
|
|
13098
|
-
while (true) {
|
|
13099
|
-
const amountInBins = getAmountInBinsAskSide(
|
|
13100
|
-
activeId,
|
|
13101
|
-
binStep,
|
|
13102
|
-
minDeltaId,
|
|
13103
|
-
maxDeltaId,
|
|
13104
|
-
baseDeltaX,
|
|
13105
|
-
x0
|
|
13453
|
+
const extended = decodeExtendedPosition(
|
|
13454
|
+
state,
|
|
13455
|
+
program,
|
|
13456
|
+
account.data.subarray(8 + POSITION_MIN_SIZE)
|
|
13106
13457
|
);
|
|
13107
|
-
const
|
|
13108
|
-
|
|
13109
|
-
|
|
13110
|
-
if (totalAmountX.gt(amountX)) {
|
|
13111
|
-
baseDeltaX = baseDeltaX.sub(new BN15(1));
|
|
13112
|
-
} else {
|
|
13113
|
-
return {
|
|
13114
|
-
base: x0,
|
|
13115
|
-
delta: baseDeltaX
|
|
13116
|
-
};
|
|
13117
|
-
}
|
|
13118
|
-
}
|
|
13119
|
-
}
|
|
13120
|
-
var BidAskStrategyParameterBuilder = class {
|
|
13121
|
-
findXParameters(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13122
|
-
return findX0AndDeltaX(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
13123
|
-
}
|
|
13124
|
-
findYParameters(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
13125
|
-
return findY0AndDeltaY(amountY, minDeltaId, maxDeltaId, activeId);
|
|
13126
|
-
}
|
|
13127
|
-
};
|
|
13128
|
-
|
|
13129
|
-
// src/dlmm/helpers/rebalance/liquidity_strategy/curve.ts
|
|
13130
|
-
import BN16 from "bn.js";
|
|
13131
|
-
function findBaseY0(amountY, minDeltaId, maxDeltaId) {
|
|
13132
|
-
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new BN16(0))) {
|
|
13133
|
-
return new BN16(0);
|
|
13134
|
-
}
|
|
13135
|
-
if (minDeltaId.eq(maxDeltaId)) {
|
|
13136
|
-
return amountY;
|
|
13137
|
-
}
|
|
13138
|
-
const m1 = minDeltaId.neg();
|
|
13139
|
-
const m2 = maxDeltaId.neg();
|
|
13140
|
-
const b = m1.sub(m2).addn(1);
|
|
13141
|
-
const c = m1.mul(m1.addn(1)).divn(2);
|
|
13142
|
-
const d = m2.mul(m2.subn(1)).divn(2);
|
|
13143
|
-
const a = b.sub(c.sub(d).div(m1.addn(1)));
|
|
13144
|
-
return amountY.div(a);
|
|
13145
|
-
}
|
|
13146
|
-
function findY0AndDeltaY2(amountY, minDeltaId, maxDeltaId, activeId) {
|
|
13147
|
-
if (minDeltaId.gt(maxDeltaId) || amountY.isZero()) {
|
|
13148
|
-
return {
|
|
13149
|
-
base: new BN16(0),
|
|
13150
|
-
delta: new BN16(0)
|
|
13151
|
-
};
|
|
13152
|
-
}
|
|
13153
|
-
let baseY0 = findBaseY0(amountY, minDeltaId, maxDeltaId);
|
|
13154
|
-
while (true) {
|
|
13155
|
-
const deltaY = baseY0.neg().div(minDeltaId.neg().addn(1));
|
|
13156
|
-
const amountInBins = getAmountInBinsBidSide(
|
|
13157
|
-
activeId,
|
|
13158
|
-
minDeltaId,
|
|
13159
|
-
maxDeltaId,
|
|
13160
|
-
deltaY,
|
|
13161
|
-
baseY0
|
|
13458
|
+
const combinedPositionBinData = combineBaseAndExtendedPositionBinData(
|
|
13459
|
+
state,
|
|
13460
|
+
extended
|
|
13162
13461
|
);
|
|
13163
|
-
|
|
13164
|
-
|
|
13165
|
-
|
|
13166
|
-
if (totalAmountY.gt(amountY)) {
|
|
13167
|
-
baseY0 = baseY0.sub(new BN16(1));
|
|
13168
|
-
} else {
|
|
13169
|
-
return {
|
|
13170
|
-
base: baseY0,
|
|
13171
|
-
delta: deltaY
|
|
13172
|
-
};
|
|
13173
|
-
}
|
|
13462
|
+
return new PositionV2Wrapper(key, state, extended, combinedPositionBinData);
|
|
13463
|
+
} else {
|
|
13464
|
+
throw new Error("Unknown position account");
|
|
13174
13465
|
}
|
|
13175
13466
|
}
|
|
13176
|
-
|
|
13177
|
-
|
|
13178
|
-
|
|
13467
|
+
var PositionV2Wrapper = class {
|
|
13468
|
+
constructor(positionAddress, inner, extended, combinedPositionBinData) {
|
|
13469
|
+
this.positionAddress = positionAddress;
|
|
13470
|
+
this.inner = inner;
|
|
13471
|
+
this.extended = extended;
|
|
13472
|
+
this.combinedPositionBinData = combinedPositionBinData;
|
|
13179
13473
|
}
|
|
13180
|
-
|
|
13181
|
-
|
|
13182
|
-
let m1 = minDeltaId;
|
|
13183
|
-
let m2 = maxDeltaId;
|
|
13184
|
-
for (let m = m1.toNumber(); m <= m2.toNumber(); m++) {
|
|
13185
|
-
const binId = activeId.addn(m);
|
|
13186
|
-
const pm = getQPriceFromId(binId.neg(), binStep);
|
|
13187
|
-
b = b.add(pm);
|
|
13188
|
-
const cDelta = new BN16(m).mul(pm).div(m2);
|
|
13189
|
-
c = c.add(cDelta);
|
|
13474
|
+
address() {
|
|
13475
|
+
return this.positionAddress;
|
|
13190
13476
|
}
|
|
13191
|
-
|
|
13192
|
-
|
|
13193
|
-
function findX0AndDeltaX2(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13194
|
-
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN16(0)) || amountX.isZero()) {
|
|
13195
|
-
return {
|
|
13196
|
-
base: new BN16(0),
|
|
13197
|
-
delta: new BN16(0)
|
|
13198
|
-
};
|
|
13477
|
+
totalClaimedRewards() {
|
|
13478
|
+
return this.inner.totalClaimedRewards;
|
|
13199
13479
|
}
|
|
13200
|
-
|
|
13201
|
-
|
|
13202
|
-
while (true) {
|
|
13203
|
-
const amountInBins = getAmountInBinsAskSide(
|
|
13204
|
-
activeId,
|
|
13205
|
-
binStep,
|
|
13206
|
-
minDeltaId,
|
|
13207
|
-
maxDeltaId,
|
|
13208
|
-
deltaX,
|
|
13209
|
-
baseX0
|
|
13210
|
-
);
|
|
13211
|
-
const totalAmountX = amountInBins.reduce((acc, { amountX: amountX2 }) => {
|
|
13212
|
-
return acc.add(amountX2);
|
|
13213
|
-
}, new BN16(0));
|
|
13214
|
-
if (totalAmountX.gt(amountX)) {
|
|
13215
|
-
baseX0 = baseX0.sub(new BN16(1));
|
|
13216
|
-
} else {
|
|
13217
|
-
return {
|
|
13218
|
-
base: baseX0,
|
|
13219
|
-
delta: deltaX
|
|
13220
|
-
};
|
|
13221
|
-
}
|
|
13480
|
+
feeOwner() {
|
|
13481
|
+
return this.inner.feeOwner;
|
|
13222
13482
|
}
|
|
13223
|
-
|
|
13224
|
-
|
|
13225
|
-
findXParameters(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13226
|
-
return findX0AndDeltaX2(amountX, minDeltaId, maxDeltaId, binStep, activeId);
|
|
13483
|
+
lockReleasePoint() {
|
|
13484
|
+
return this.inner.lockReleasePoint;
|
|
13227
13485
|
}
|
|
13228
|
-
|
|
13229
|
-
return
|
|
13486
|
+
operator() {
|
|
13487
|
+
return this.inner.operator;
|
|
13230
13488
|
}
|
|
13231
|
-
|
|
13232
|
-
|
|
13233
|
-
// src/dlmm/helpers/rebalance/liquidity_strategy/spot.ts
|
|
13234
|
-
import BN17 from "bn.js";
|
|
13235
|
-
function findY0(amountY, minDeltaId, maxDeltaId) {
|
|
13236
|
-
if (minDeltaId.gt(maxDeltaId) || amountY.lte(new BN17(0)) || amountY.isZero()) {
|
|
13237
|
-
return new BN17(0);
|
|
13489
|
+
totalClaimedFeeYAmount() {
|
|
13490
|
+
return this.inner.totalClaimedFeeYAmount;
|
|
13238
13491
|
}
|
|
13239
|
-
|
|
13240
|
-
|
|
13241
|
-
const delta = m1.sub(m2).addn(1);
|
|
13242
|
-
return amountY.div(delta);
|
|
13243
|
-
}
|
|
13244
|
-
function findBaseX02(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13245
|
-
let totalWeight = new BN17(0);
|
|
13246
|
-
const minBinId = activeId.add(minDeltaId);
|
|
13247
|
-
const maxBinId = activeId.add(maxDeltaId);
|
|
13248
|
-
let baseFactor = getQPriceBaseFactor(binStep);
|
|
13249
|
-
let basePrice = getQPriceFromId(maxBinId.neg(), binStep);
|
|
13250
|
-
for (let binId = minBinId.toNumber(); binId <= maxBinId.toNumber(); binId++) {
|
|
13251
|
-
totalWeight = totalWeight.add(basePrice);
|
|
13252
|
-
basePrice = basePrice.mul(baseFactor).shrn(SCALE_OFFSET);
|
|
13492
|
+
totalClaimedFeeXAmount() {
|
|
13493
|
+
return this.inner.totalClaimedFeeXAmount;
|
|
13253
13494
|
}
|
|
13254
|
-
|
|
13255
|
-
|
|
13256
|
-
function findX0(amountX, minDeltaId, maxDeltaId, binStep, activeId) {
|
|
13257
|
-
if (minDeltaId.gt(maxDeltaId) || amountX.lte(new BN17(0)) || amountX.isZero()) {
|
|
13258
|
-
return new BN17(0);
|
|
13495
|
+
lbPair() {
|
|
13496
|
+
return this.inner.lbPair;
|
|
13259
13497
|
}
|
|
13260
|
-
|
|
13261
|
-
|
|
13262
|
-
|
|
13263
|
-
|
|
13264
|
-
|
|
13265
|
-
|
|
13266
|
-
|
|
13267
|
-
|
|
13268
|
-
|
|
13269
|
-
|
|
13270
|
-
|
|
13271
|
-
|
|
13272
|
-
|
|
13273
|
-
|
|
13274
|
-
|
|
13498
|
+
lowerBinId() {
|
|
13499
|
+
return new BN17(this.inner.lowerBinId);
|
|
13500
|
+
}
|
|
13501
|
+
upperBinId() {
|
|
13502
|
+
return new BN17(this.inner.upperBinId);
|
|
13503
|
+
}
|
|
13504
|
+
liquidityShares() {
|
|
13505
|
+
return this.combinedPositionBinData.liquidityShares;
|
|
13506
|
+
}
|
|
13507
|
+
rewardInfos() {
|
|
13508
|
+
return this.combinedPositionBinData.rewardInfos;
|
|
13509
|
+
}
|
|
13510
|
+
feeInfos() {
|
|
13511
|
+
return this.combinedPositionBinData.feeInfos;
|
|
13512
|
+
}
|
|
13513
|
+
lastUpdatedAt() {
|
|
13514
|
+
return this.inner.lastUpdatedAt;
|
|
13515
|
+
}
|
|
13516
|
+
getBinArrayIndexesCoverage() {
|
|
13517
|
+
const isExtended = this.extended.length > 0;
|
|
13518
|
+
if (isExtended) {
|
|
13519
|
+
return getBinArrayIndexesCoverage(this.lowerBinId(), this.upperBinId());
|
|
13275
13520
|
} else {
|
|
13276
|
-
|
|
13277
|
-
|
|
13521
|
+
const lowerBinArrayIndex = binIdToBinArrayIndex(this.lowerBinId());
|
|
13522
|
+
const upperBinArrayIndex = lowerBinArrayIndex.add(new BN17(1));
|
|
13523
|
+
return [lowerBinArrayIndex, upperBinArrayIndex];
|
|
13278
13524
|
}
|
|
13279
13525
|
}
|
|
13280
|
-
|
|
13281
|
-
|
|
13282
|
-
|
|
13283
|
-
|
|
13284
|
-
base: findX0(amountX, minDeltaId, maxDeltaId, binStep, activeId),
|
|
13285
|
-
delta: new BN17(0)
|
|
13286
|
-
};
|
|
13526
|
+
getBinArrayKeysCoverage(programId) {
|
|
13527
|
+
return this.getBinArrayIndexesCoverage().map(
|
|
13528
|
+
(index) => deriveBinArray(this.lbPair(), index, programId)[0]
|
|
13529
|
+
);
|
|
13287
13530
|
}
|
|
13288
|
-
|
|
13289
|
-
return
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13531
|
+
version() {
|
|
13532
|
+
return 1 /* V2 */;
|
|
13533
|
+
}
|
|
13534
|
+
owner() {
|
|
13535
|
+
return this.inner.owner;
|
|
13536
|
+
}
|
|
13537
|
+
width() {
|
|
13538
|
+
return this.upperBinId().sub(this.lowerBinId()).add(new BN17(1));
|
|
13293
13539
|
}
|
|
13294
13540
|
};
|
|
13295
13541
|
|
|
13296
|
-
// src/dlmm/helpers/
|
|
13297
|
-
function
|
|
13298
|
-
|
|
13299
|
-
|
|
13300
|
-
|
|
13301
|
-
|
|
13302
|
-
|
|
13303
|
-
case 2 /* BidAsk */:
|
|
13304
|
-
return new BidAskStrategyParameterBuilder();
|
|
13305
|
-
default:
|
|
13306
|
-
throw new Error("Strategy not supported");
|
|
13542
|
+
// src/dlmm/helpers/positions/index.ts
|
|
13543
|
+
function getBinArrayIndexesCoverage(lowerBinId, upperBinId) {
|
|
13544
|
+
const lowerBinArrayIndex = binIdToBinArrayIndex(lowerBinId);
|
|
13545
|
+
const upperBinArrayIndex = binIdToBinArrayIndex(upperBinId);
|
|
13546
|
+
const binArrayIndexes = [];
|
|
13547
|
+
for (let i = lowerBinArrayIndex.toNumber(); i <= upperBinArrayIndex.toNumber(); i++) {
|
|
13548
|
+
binArrayIndexes.push(new BN18(i));
|
|
13307
13549
|
}
|
|
13550
|
+
return binArrayIndexes;
|
|
13308
13551
|
}
|
|
13309
|
-
function
|
|
13310
|
-
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
|
|
13552
|
+
function getBinArrayKeysCoverage2(lowerBinId, upperBinId, lbPair, programId) {
|
|
13553
|
+
const binArrayIndexes = getBinArrayIndexesCoverage(lowerBinId, upperBinId);
|
|
13554
|
+
return binArrayIndexes.map((index) => {
|
|
13555
|
+
return deriveBinArray(lbPair, index, programId)[0];
|
|
13556
|
+
});
|
|
13557
|
+
}
|
|
13558
|
+
function getBinArrayAccountMetasCoverage(lowerBinId, upperBinId, lbPair, programId) {
|
|
13559
|
+
return getBinArrayKeysCoverage2(lowerBinId, upperBinId, lbPair, programId).map(
|
|
13560
|
+
(key) => {
|
|
13561
|
+
return {
|
|
13562
|
+
pubkey: key,
|
|
13563
|
+
isSigner: false,
|
|
13564
|
+
isWritable: true
|
|
13565
|
+
};
|
|
13566
|
+
}
|
|
13567
|
+
);
|
|
13568
|
+
}
|
|
13569
|
+
function getPositionLowerUpperBinIdWithLiquidity(position) {
|
|
13570
|
+
const binWithLiquidity = position.positionBinData.filter(
|
|
13571
|
+
(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()
|
|
13572
|
+
);
|
|
13573
|
+
return binWithLiquidity.length > 0 ? {
|
|
13574
|
+
lowerBinId: new BN18(binWithLiquidity[0].binId),
|
|
13575
|
+
upperBinId: new BN18(binWithLiquidity[binWithLiquidity.length - 1].binId)
|
|
13576
|
+
} : null;
|
|
13577
|
+
}
|
|
13578
|
+
function isPositionNoFee(position) {
|
|
13579
|
+
return position.feeX.isZero() && position.feeY.isZero();
|
|
13580
|
+
}
|
|
13581
|
+
function isPositionNoReward(position) {
|
|
13582
|
+
return position.rewardOne.isZero() && position.rewardTwo.isZero();
|
|
13583
|
+
}
|
|
13584
|
+
function chunkBinRange(minBinId, maxBinId) {
|
|
13585
|
+
const chunkedBinRange = [];
|
|
13586
|
+
let startBinId = minBinId;
|
|
13587
|
+
while (startBinId <= maxBinId) {
|
|
13588
|
+
const endBinId = Math.min(
|
|
13589
|
+
startBinId + DEFAULT_BIN_PER_POSITION.toNumber() - 1,
|
|
13590
|
+
maxBinId
|
|
13591
|
+
);
|
|
13592
|
+
chunkedBinRange.push({
|
|
13593
|
+
lowerBinId: startBinId,
|
|
13594
|
+
upperBinId: endBinId
|
|
13595
|
+
});
|
|
13596
|
+
startBinId += DEFAULT_BIN_PER_POSITION.toNumber();
|
|
13317
13597
|
}
|
|
13318
|
-
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
|
|
13322
|
-
|
|
13323
|
-
|
|
13324
|
-
|
|
13325
|
-
|
|
13598
|
+
return chunkedBinRange;
|
|
13599
|
+
}
|
|
13600
|
+
async function getPositionExpandRentExemption(currentMinBinId, currentMaxBinId, connection, binCountToExpand) {
|
|
13601
|
+
const currentPositionWidth = currentMaxBinId.sub(currentMinBinId).addn(1);
|
|
13602
|
+
const positionWidthAfterExpand = currentPositionWidth.add(binCountToExpand);
|
|
13603
|
+
if (positionWidthAfterExpand.lte(DEFAULT_BIN_PER_POSITION)) {
|
|
13604
|
+
return 0;
|
|
13605
|
+
} else {
|
|
13606
|
+
const binCountInExpandedBytes = positionWidthAfterExpand.sub(
|
|
13607
|
+
DEFAULT_BIN_PER_POSITION
|
|
13326
13608
|
);
|
|
13327
|
-
|
|
13328
|
-
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
|
|
13609
|
+
const expandSize = binCountInExpandedBytes.toNumber() * POSITION_BIN_DATA_SIZE;
|
|
13610
|
+
const [minimumLamports, rentExemptionLamports] = await Promise.all([
|
|
13611
|
+
connection.getMinimumBalanceForRentExemption(0),
|
|
13612
|
+
connection.getMinimumBalanceForRentExemption(expandSize)
|
|
13613
|
+
]);
|
|
13614
|
+
return rentExemptionLamports - minimumLamports;
|
|
13333
13615
|
}
|
|
13334
|
-
|
|
13335
|
-
|
|
13336
|
-
|
|
13337
|
-
|
|
13338
|
-
|
|
13339
|
-
|
|
13340
|
-
|
|
13616
|
+
}
|
|
13617
|
+
function getExtendedPositionBinCount(minBinId, maxBinId) {
|
|
13618
|
+
const width = maxBinId.sub(minBinId).addn(1);
|
|
13619
|
+
const extended = width.sub(DEFAULT_BIN_PER_POSITION);
|
|
13620
|
+
return extended.lte(new BN18(0)) ? new BN18(0) : extended;
|
|
13621
|
+
}
|
|
13622
|
+
function decodeExtendedPosition(base, program, bytes) {
|
|
13623
|
+
const width = base.upperBinId - base.lowerBinId + 1;
|
|
13624
|
+
const extendedWidth = width - DEFAULT_BIN_PER_POSITION.toNumber();
|
|
13625
|
+
const extendedPosition = [];
|
|
13626
|
+
for (let i = 0; i < extendedWidth; i++) {
|
|
13627
|
+
const offset = i * POSITION_BIN_DATA_SIZE;
|
|
13628
|
+
const data = bytes.subarray(offset, offset + POSITION_BIN_DATA_SIZE);
|
|
13629
|
+
const decodedPositionBinData = program.coder.types.decode(
|
|
13630
|
+
// TODO: Find a type safe way
|
|
13631
|
+
"positionBinData",
|
|
13632
|
+
data
|
|
13341
13633
|
);
|
|
13342
|
-
|
|
13343
|
-
x0: base,
|
|
13344
|
-
deltaX: delta,
|
|
13345
|
-
y0: new BN18(0),
|
|
13346
|
-
deltaY: new BN18(0)
|
|
13347
|
-
};
|
|
13634
|
+
extendedPosition.push(decodedPositionBinData);
|
|
13348
13635
|
}
|
|
13349
|
-
|
|
13350
|
-
const minDeltaIdAskSide = favorXInActiveId ? new BN18(0) : new BN18(1);
|
|
13351
|
-
const { base: y0, delta: deltaY } = strategyParameterBuilder.findYParameters(
|
|
13352
|
-
amountY,
|
|
13353
|
-
minDeltaId,
|
|
13354
|
-
maxDeltaIdBidSide,
|
|
13355
|
-
activeId
|
|
13356
|
-
);
|
|
13357
|
-
const { base: x0, delta: deltaX } = strategyParameterBuilder.findXParameters(
|
|
13358
|
-
amountX,
|
|
13359
|
-
minDeltaIdAskSide,
|
|
13360
|
-
maxDeltaId,
|
|
13361
|
-
binStep,
|
|
13362
|
-
activeId
|
|
13363
|
-
);
|
|
13364
|
-
return {
|
|
13365
|
-
x0,
|
|
13366
|
-
deltaX,
|
|
13367
|
-
y0,
|
|
13368
|
-
deltaY
|
|
13369
|
-
};
|
|
13636
|
+
return extendedPosition;
|
|
13370
13637
|
}
|
|
13371
13638
|
|
|
13372
13639
|
// src/dlmm/helpers/rebalance/strategy/balanced.ts
|
|
@@ -14160,11 +14427,11 @@ var DLMM = class {
|
|
|
14160
14427
|
return positionsMap;
|
|
14161
14428
|
}
|
|
14162
14429
|
static getPricePerLamport(tokenXDecimal, tokenYDecimal, price) {
|
|
14163
|
-
return new
|
|
14430
|
+
return new Decimal8(price).mul(new Decimal8(10 ** (tokenYDecimal - tokenXDecimal))).toString();
|
|
14164
14431
|
}
|
|
14165
14432
|
static getBinIdFromPrice(price, binStep, min) {
|
|
14166
|
-
const binStepNum = new
|
|
14167
|
-
const binId = new
|
|
14433
|
+
const binStepNum = new Decimal8(binStep).div(new Decimal8(BASIS_POINT_MAX));
|
|
14434
|
+
const binId = new Decimal8(price).log().dividedBy(new Decimal8(1).add(binStepNum).log());
|
|
14168
14435
|
return (min ? binId.floor() : binId.ceil()).toNumber();
|
|
14169
14436
|
}
|
|
14170
14437
|
/**
|
|
@@ -14776,8 +15043,8 @@ var DLMM = class {
|
|
|
14776
15043
|
*/
|
|
14777
15044
|
static calculateFeeInfo(baseFactor, binStep, baseFeePowerFactor) {
|
|
14778
15045
|
const baseFeeRate = new BN21(baseFactor).mul(new BN21(binStep)).mul(new BN21(10)).mul(new BN21(10).pow(new BN21(baseFeePowerFactor ?? 0)));
|
|
14779
|
-
const baseFeeRatePercentage = new
|
|
14780
|
-
const maxFeeRatePercentage = new
|
|
15046
|
+
const baseFeeRatePercentage = new Decimal8(baseFeeRate.toString()).mul(new Decimal8(100)).div(new Decimal8(FEE_PRECISION.toString()));
|
|
15047
|
+
const maxFeeRatePercentage = new Decimal8(MAX_FEE_RATE.toString()).mul(new Decimal8(100)).div(new Decimal8(FEE_PRECISION.toString()));
|
|
14781
15048
|
return {
|
|
14782
15049
|
baseFeeRatePercentage,
|
|
14783
15050
|
maxFeeRatePercentage
|
|
@@ -14795,7 +15062,7 @@ var DLMM = class {
|
|
|
14795
15062
|
this.lbPair.binStep,
|
|
14796
15063
|
this.lbPair.parameters.baseFeePowerFactor
|
|
14797
15064
|
);
|
|
14798
|
-
const protocolFeePercentage = new
|
|
15065
|
+
const protocolFeePercentage = new Decimal8(protocolShare.toString()).mul(new Decimal8(100)).div(new Decimal8(BASIS_POINT_MAX));
|
|
14799
15066
|
return {
|
|
14800
15067
|
baseFeeRatePercentage,
|
|
14801
15068
|
maxFeeRatePercentage,
|
|
@@ -14827,7 +15094,7 @@ var DLMM = class {
|
|
|
14827
15094
|
sParameters3,
|
|
14828
15095
|
vParameterClone
|
|
14829
15096
|
);
|
|
14830
|
-
return new
|
|
15097
|
+
return new Decimal8(totalFee.toString()).div(new Decimal8(FEE_PRECISION.toString())).mul(100);
|
|
14831
15098
|
}
|
|
14832
15099
|
/**
|
|
14833
15100
|
* The function `getEmissionRate` returns the emission rates for two rewards.
|
|
@@ -14840,8 +15107,8 @@ var DLMM = class {
|
|
|
14840
15107
|
({ rewardRate, rewardDurationEnd }) => now > rewardDurationEnd.toNumber() ? void 0 : rewardRate
|
|
14841
15108
|
);
|
|
14842
15109
|
return {
|
|
14843
|
-
rewardOne: rewardOneEmissionRate ? new
|
|
14844
|
-
rewardTwo: rewardTwoEmissionRate ? new
|
|
15110
|
+
rewardOne: rewardOneEmissionRate ? new Decimal8(rewardOneEmissionRate.toString()).div(PRECISION) : void 0,
|
|
15111
|
+
rewardTwo: rewardTwoEmissionRate ? new Decimal8(rewardTwoEmissionRate.toString()).div(PRECISION) : void 0
|
|
14845
15112
|
};
|
|
14846
15113
|
}
|
|
14847
15114
|
/**
|
|
@@ -14934,8 +15201,8 @@ var DLMM = class {
|
|
|
14934
15201
|
* @returns {string} real price of bin
|
|
14935
15202
|
*/
|
|
14936
15203
|
fromPricePerLamport(pricePerLamport) {
|
|
14937
|
-
return new
|
|
14938
|
-
new
|
|
15204
|
+
return new Decimal8(pricePerLamport).div(
|
|
15205
|
+
new Decimal8(
|
|
14939
15206
|
10 ** (this.tokenY.mint.decimals - this.tokenX.mint.decimals)
|
|
14940
15207
|
)
|
|
14941
15208
|
).toString();
|
|
@@ -15093,12 +15360,12 @@ var DLMM = class {
|
|
|
15093
15360
|
const lowerBinArrayIndex = binIdToBinArrayIndex(currentMinBinId);
|
|
15094
15361
|
const upperBinArrayIndex = binIdToBinArrayIndex(currentMaxBinId);
|
|
15095
15362
|
const binArraysCount = (await this.binArraysToBeCreate(lowerBinArrayIndex, upperBinArrayIndex)).length;
|
|
15096
|
-
const binArrayCost = new
|
|
15097
|
-
new
|
|
15363
|
+
const binArrayCost = new Decimal8(binArraysCount).mul(
|
|
15364
|
+
new Decimal8(BIN_ARRAY_FEE)
|
|
15098
15365
|
);
|
|
15099
15366
|
return {
|
|
15100
|
-
positionExtendCost: new
|
|
15101
|
-
new
|
|
15367
|
+
positionExtendCost: new Decimal8(positionExtendCost).div(
|
|
15368
|
+
new Decimal8(LAMPORTS_PER_SOL2)
|
|
15102
15369
|
),
|
|
15103
15370
|
binArrayCost
|
|
15104
15371
|
};
|
|
@@ -16367,7 +16634,7 @@ var DLMM = class {
|
|
|
16367
16634
|
activeId.toNumber(),
|
|
16368
16635
|
this.lbPair.binStep
|
|
16369
16636
|
);
|
|
16370
|
-
const priceImpact = startPrice.sub(endPrice).abs().div(startPrice).mul(new
|
|
16637
|
+
const priceImpact = startPrice.sub(endPrice).abs().div(startPrice).mul(new Decimal8(100));
|
|
16371
16638
|
actualInAmount = calculateTransferFeeIncludedAmount(
|
|
16372
16639
|
actualInAmount.add(feeAmount),
|
|
16373
16640
|
inMint,
|
|
@@ -16554,7 +16821,7 @@ var DLMM = class {
|
|
|
16554
16821
|
),
|
|
16555
16822
|
swapForY
|
|
16556
16823
|
);
|
|
16557
|
-
const priceImpact = new
|
|
16824
|
+
const priceImpact = new Decimal8(totalOutAmount.toString()).sub(new Decimal8(outAmountWithoutSlippage.toString())).div(new Decimal8(outAmountWithoutSlippage.toString())).mul(new Decimal8(100)).abs();
|
|
16558
16825
|
const endPrice = getPriceOfBinByBinId(
|
|
16559
16826
|
lastFilledActiveBinId.toNumber(),
|
|
16560
16827
|
this.lbPair.binStep
|
|
@@ -17163,11 +17430,11 @@ var DLMM = class {
|
|
|
17163
17430
|
let totalBinArraysCount = new BN21(0);
|
|
17164
17431
|
let totalBinArraysLamports = new BN21(0);
|
|
17165
17432
|
let binArrayBitmapLamports = new BN21(0);
|
|
17166
|
-
const toLamportMultiplier = new
|
|
17433
|
+
const toLamportMultiplier = new Decimal8(
|
|
17167
17434
|
10 ** (this.tokenY.mint.decimals - this.tokenX.mint.decimals)
|
|
17168
17435
|
);
|
|
17169
|
-
const minPricePerLamport = new
|
|
17170
|
-
const maxPricePerLamport = new
|
|
17436
|
+
const minPricePerLamport = new Decimal8(minPrice).mul(toLamportMultiplier);
|
|
17437
|
+
const maxPricePerLamport = new Decimal8(maxPrice).mul(toLamportMultiplier);
|
|
17171
17438
|
const minBinId = new BN21(
|
|
17172
17439
|
DLMM.getBinIdFromPrice(minPricePerLamport, this.lbPair.binStep, false)
|
|
17173
17440
|
);
|
|
@@ -18158,7 +18425,6 @@ var DLMM = class {
|
|
|
18158
18425
|
shouldClaimReward: true,
|
|
18159
18426
|
pairAddress: this.pubkey
|
|
18160
18427
|
});
|
|
18161
|
-
console.log("\u{1F680} ~ DLMM ~ rebalancePosition:", rebalancePosition);
|
|
18162
18428
|
const rebalanceStrategyBuilder = new BalancedStrategyBuilder(
|
|
18163
18429
|
new BN21(rebalancePosition.lbPair.activeId),
|
|
18164
18430
|
new BN21(rebalancePosition.lbPair.binStep),
|
|
@@ -18184,10 +18450,65 @@ var DLMM = class {
|
|
|
18184
18450
|
withdraws,
|
|
18185
18451
|
deposits
|
|
18186
18452
|
);
|
|
18187
|
-
|
|
18453
|
+
const binArrayQuoteResult = await this.quoteBinArrayAccountsRentalCost(
|
|
18454
|
+
simulationResult.depositParams,
|
|
18455
|
+
simulationResult.withdrawParams,
|
|
18456
|
+
new BN21(rebalancePosition.lbPair.activeId)
|
|
18457
|
+
);
|
|
18188
18458
|
return {
|
|
18189
18459
|
rebalancePosition,
|
|
18190
|
-
simulationResult
|
|
18460
|
+
simulationResult,
|
|
18461
|
+
...binArrayQuoteResult
|
|
18462
|
+
};
|
|
18463
|
+
}
|
|
18464
|
+
async quoteBinArrayAccountsRentalCost(deposits, withdraws, activeId) {
|
|
18465
|
+
const { binArrayBitmap, binArrayIndexes } = getRebalanceBinArrayIndexesAndBitmapCoverage(
|
|
18466
|
+
deposits,
|
|
18467
|
+
withdraws,
|
|
18468
|
+
activeId.toNumber(),
|
|
18469
|
+
this.pubkey,
|
|
18470
|
+
this.program.programId
|
|
18471
|
+
);
|
|
18472
|
+
const binArrayPublicKeys = binArrayIndexes.map((index) => {
|
|
18473
|
+
const [binArrayPubkey] = deriveBinArray(
|
|
18474
|
+
this.pubkey,
|
|
18475
|
+
index,
|
|
18476
|
+
this.program.programId
|
|
18477
|
+
);
|
|
18478
|
+
return binArrayPubkey;
|
|
18479
|
+
});
|
|
18480
|
+
const accountPublicKeys = [...binArrayPublicKeys];
|
|
18481
|
+
if (!binArrayBitmap.equals(PublicKey10.default)) {
|
|
18482
|
+
accountPublicKeys.push(binArrayBitmap);
|
|
18483
|
+
}
|
|
18484
|
+
const accounts = await chunkedGetMultipleAccountInfos(
|
|
18485
|
+
this.program.provider.connection,
|
|
18486
|
+
binArrayPublicKeys
|
|
18487
|
+
);
|
|
18488
|
+
const binArrayAccounts = accounts.splice(0, binArrayPublicKeys.length);
|
|
18489
|
+
let binArrayCount = 0;
|
|
18490
|
+
let bitmapExtensionCost = 0;
|
|
18491
|
+
const binArraySet = /* @__PURE__ */ new Set();
|
|
18492
|
+
for (let i = 0; i < binArrayAccounts.length; i++) {
|
|
18493
|
+
const binArrayAccount = binArrayAccounts[i];
|
|
18494
|
+
const binArrayPubkey = binArrayPublicKeys[i];
|
|
18495
|
+
if (!binArrayAccount) {
|
|
18496
|
+
binArrayCount++;
|
|
18497
|
+
} else {
|
|
18498
|
+
binArraySet.add(binArrayPubkey.toBase58());
|
|
18499
|
+
}
|
|
18500
|
+
}
|
|
18501
|
+
if (!binArrayBitmap.equals(PublicKey10.default)) {
|
|
18502
|
+
const bitmapAccount = accounts.pop();
|
|
18503
|
+
if (!bitmapAccount) {
|
|
18504
|
+
bitmapExtensionCost = BIN_ARRAY_BITMAP_FEE;
|
|
18505
|
+
}
|
|
18506
|
+
}
|
|
18507
|
+
return {
|
|
18508
|
+
binArrayCost: binArrayCount * BIN_ARRAY_FEE,
|
|
18509
|
+
binArrayCount,
|
|
18510
|
+
binArrayExistence: binArraySet,
|
|
18511
|
+
bitmapExtensionCost
|
|
18191
18512
|
};
|
|
18192
18513
|
}
|
|
18193
18514
|
/**
|
|
@@ -18217,9 +18538,15 @@ var DLMM = class {
|
|
|
18217
18538
|
withdraws,
|
|
18218
18539
|
deposits
|
|
18219
18540
|
);
|
|
18541
|
+
const binArrayQuoteResult = await this.quoteBinArrayAccountsRentalCost(
|
|
18542
|
+
simulationResult.depositParams,
|
|
18543
|
+
simulationResult.withdrawParams,
|
|
18544
|
+
new BN21(rebalancePosition.lbPair.activeId)
|
|
18545
|
+
);
|
|
18220
18546
|
return {
|
|
18221
18547
|
rebalancePosition,
|
|
18222
|
-
simulationResult
|
|
18548
|
+
simulationResult,
|
|
18549
|
+
...binArrayQuoteResult
|
|
18223
18550
|
};
|
|
18224
18551
|
}
|
|
18225
18552
|
/**
|
|
@@ -18297,12 +18624,10 @@ var DLMM = class {
|
|
|
18297
18624
|
chunk,
|
|
18298
18625
|
activeId
|
|
18299
18626
|
);
|
|
18300
|
-
console.log("\u{1F680} ~ DLMM ~ chunkedDepositParams:", chunkedDepositParams);
|
|
18301
18627
|
const chunkedWithdrawParams = splitWithdrawParamsForChunk(
|
|
18302
18628
|
withdrawParams,
|
|
18303
18629
|
chunk
|
|
18304
18630
|
);
|
|
18305
|
-
console.log("\u{1F680} ~ DLMM ~ chunkedWithdrawParams:", chunkedWithdrawParams);
|
|
18306
18631
|
if (chunkedDepositParams.length === 0 && chunkedWithdrawParams.length === 0)
|
|
18307
18632
|
continue;
|
|
18308
18633
|
const { slices, accounts: transferHookAccounts } = this.getPotentialToken2022IxDataAndAccounts(0 /* Liquidity */);
|
|
@@ -18668,8 +18993,8 @@ var DLMM = class {
|
|
|
18668
18993
|
if (!bins.length)
|
|
18669
18994
|
return null;
|
|
18670
18995
|
const positionData = [];
|
|
18671
|
-
let totalXAmount = new
|
|
18672
|
-
let totalYAmount = new
|
|
18996
|
+
let totalXAmount = new Decimal8(0);
|
|
18997
|
+
let totalYAmount = new Decimal8(0);
|
|
18673
18998
|
const ZERO = new BN21(0);
|
|
18674
18999
|
let feeX = ZERO;
|
|
18675
19000
|
let feeY = ZERO;
|
|
@@ -18680,8 +19005,8 @@ var DLMM = class {
|
|
|
18680
19005
|
const posBinRewardInfo = positionRewardInfos[idx];
|
|
18681
19006
|
const positionXAmount = binSupply.eq(ZERO) ? ZERO : posShare.mul(bin.xAmount).div(binSupply);
|
|
18682
19007
|
const positionYAmount = binSupply.eq(ZERO) ? ZERO : posShare.mul(bin.yAmount).div(binSupply);
|
|
18683
|
-
totalXAmount = totalXAmount.add(new
|
|
18684
|
-
totalYAmount = totalYAmount.add(new
|
|
19008
|
+
totalXAmount = totalXAmount.add(new Decimal8(positionXAmount.toString()));
|
|
19009
|
+
totalYAmount = totalYAmount.add(new Decimal8(positionYAmount.toString()));
|
|
18685
19010
|
const feeInfo = feeInfos[idx];
|
|
18686
19011
|
const newFeeX = mulShr(
|
|
18687
19012
|
posShares[idx].shrn(SCALE_OFFSET),
|
|
@@ -18845,7 +19170,7 @@ var DLMM = class {
|
|
|
18845
19170
|
rewardPerTokenStored: [ZERO, ZERO],
|
|
18846
19171
|
price: pricePerLamport,
|
|
18847
19172
|
version: 2,
|
|
18848
|
-
pricePerToken: new
|
|
19173
|
+
pricePerToken: new Decimal8(pricePerLamport).mul(new Decimal8(10 ** (baseTokenDecimal - quoteTokenDecimal))).toString()
|
|
18849
19174
|
});
|
|
18850
19175
|
} else {
|
|
18851
19176
|
const bin = binArray.bins[i];
|
|
@@ -18859,7 +19184,7 @@ var DLMM = class {
|
|
|
18859
19184
|
rewardPerTokenStored: bin.rewardPerTokenStored,
|
|
18860
19185
|
price: pricePerLamport,
|
|
18861
19186
|
version: binArray.version,
|
|
18862
|
-
pricePerToken: new
|
|
19187
|
+
pricePerToken: new Decimal8(pricePerLamport).mul(new Decimal8(10 ** (baseTokenDecimal - quoteTokenDecimal))).toString()
|
|
18863
19188
|
});
|
|
18864
19189
|
}
|
|
18865
19190
|
}
|
|
@@ -19218,6 +19543,7 @@ export {
|
|
|
19218
19543
|
PairStatus,
|
|
19219
19544
|
PairType,
|
|
19220
19545
|
PositionVersion,
|
|
19546
|
+
RebalancePosition,
|
|
19221
19547
|
ResizeSide,
|
|
19222
19548
|
SCALE,
|
|
19223
19549
|
SCALE_OFFSET,
|
|
@@ -19232,6 +19558,7 @@ export {
|
|
|
19232
19558
|
autoFillYByStrategy,
|
|
19233
19559
|
autoFillYByWeight,
|
|
19234
19560
|
binIdToBinArrayIndex,
|
|
19561
|
+
buildLiquidityStrategyParameters,
|
|
19235
19562
|
calculateBidAskDistribution,
|
|
19236
19563
|
calculateNormalDistribution,
|
|
19237
19564
|
calculateSpotDistribution,
|
|
@@ -19268,6 +19595,9 @@ export {
|
|
|
19268
19595
|
fromWeightDistributionToAmount,
|
|
19269
19596
|
fromWeightDistributionToAmountOneSide,
|
|
19270
19597
|
getAccountDiscriminator,
|
|
19598
|
+
getAmountInBinsAskSide,
|
|
19599
|
+
getAmountInBinsBidSide,
|
|
19600
|
+
getAutoFillAmountByRebalancedPosition,
|
|
19271
19601
|
getBaseFee,
|
|
19272
19602
|
getBinArrayLowerUpperBinId,
|
|
19273
19603
|
getBinArraysRequiredByPositionRange,
|
|
@@ -19275,9 +19605,11 @@ export {
|
|
|
19275
19605
|
getBinIdIndexInBinArray,
|
|
19276
19606
|
getEstimatedComputeUnitIxWithBuffer,
|
|
19277
19607
|
getEstimatedComputeUnitUsageWithBuffer,
|
|
19608
|
+
getLiquidityStrategyParameterBuilder,
|
|
19278
19609
|
getOrCreateATAInstruction,
|
|
19279
19610
|
getOutAmount,
|
|
19280
19611
|
getPriceOfBinByBinId,
|
|
19612
|
+
getRebalanceBinArrayIndexesAndBitmapCoverage,
|
|
19281
19613
|
getTokenBalance,
|
|
19282
19614
|
getTokenDecimals,
|
|
19283
19615
|
getTokenProgramId,
|
|
@@ -19288,11 +19620,14 @@ export {
|
|
|
19288
19620
|
isOverflowDefaultBinArrayBitmap,
|
|
19289
19621
|
parseLogs,
|
|
19290
19622
|
range,
|
|
19623
|
+
suggestBalancedXParametersFromY,
|
|
19624
|
+
suggestBalancedYParametersFromX,
|
|
19291
19625
|
swapExactInQuoteAtBin,
|
|
19292
19626
|
swapExactOutQuoteAtBin,
|
|
19293
19627
|
toAmountAskSide,
|
|
19294
19628
|
toAmountBidSide,
|
|
19295
19629
|
toAmountBothSide,
|
|
19630
|
+
toAmountIntoBins,
|
|
19296
19631
|
toAmountsBothSideByStrategy,
|
|
19297
19632
|
toStrategyParameters,
|
|
19298
19633
|
toWeightDistribution,
|