Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix reading meteora #450

Merged
merged 46 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
f8a0ed3
Update IDL + add meteora IDL
alittlezz Jan 8, 2024
104dbda
Modify kamino SDK with new IDL
alittlezz Jan 8, 2024
e31d185
Add meteora to ignore prettier
alittlezz Jan 8, 2024
3fa6b2d
Add more meteora handling
alittlezz Jan 8, 2024
c6b2e91
Add meteora logic
alittlezz Jan 9, 2024
d2715f9
v3.0.29-staging
alittlezz Jan 9, 2024
55901b5
Add changes
alittlezz Jan 10, 2024
ca08782
Update gitignore
alittlezz Jan 10, 2024
39f19a2
v3.0.30-staging
alittlezz Jan 10, 2024
6bff447
v3.0.29-staging-01
silviutroscot Jan 10, 2024
f75ee7b
Update with latest changes
alittlezz Jan 10, 2024
caf0bcb
Merge branch 'vali/add-meteora' of github.com:hubbleprotocol/hubble-c…
silviutroscot Jan 10, 2024
f6b2190
v3.0.29-staging-02
silviutroscot Jan 10, 2024
d9cfedf
update fee tier computation for meteora
silviutroscot Jan 11, 2024
c7627c9
v3.0.29-staging-03
silviutroscot Jan 11, 2024
f12ddb0
Override global config automatically when staging
alittlezz Jan 11, 2024
15ccdec
Merge branch 'vali/add-meteora' of github.com:hubbleprotocol/hubble-c…
silviutroscot Jan 11, 2024
e53af8b
v3.0.29-staging-04
silviutroscot Jan 11, 2024
8670976
.
silviutroscot Jan 11, 2024
cca2d47
Change === to equals
alittlezz Jan 12, 2024
b9352b4
wip: tests
silviutroscot Jan 12, 2024
ca6d4eb
Merge branch 'vali/add-meteora' of github.com:hubbleprotocol/hubble-c…
silviutroscot Jan 12, 2024
7817cbb
v3.0.29-staging-05
silviutroscot Jan 12, 2024
6349653
3.0.29-staging-06
alittlezz Jan 12, 2024
8da5c45
fix decimals reading
silviutroscot Jan 12, 2024
fe297d1
Merge branch 'vali/add-meteora' of github.com:hubbleprotocol/hubble-c…
silviutroscot Jan 12, 2024
65c1b0f
v3.0.29-staging-07
silviutroscot Jan 12, 2024
6a4d600
return explicit tupe
silviutroscot Jan 12, 2024
382a3f1
Update meteora service
alittlezz Jan 17, 2024
a2c7825
v3.0.29-staging-08
alittlezz Jan 17, 2024
a212bae
Merge branch 'vali/add-meteora' of github.com:hubbleprotocol/hubble-c…
silviutroscot Jan 17, 2024
64adf81
One small fix
alittlezz Jan 17, 2024
4402608
v3.0.29-staging-09
alittlezz Jan 17, 2024
3954326
Merge branch 'vali/add-meteora' of github.com:hubbleprotocol/hubble-c…
silviutroscot Jan 18, 2024
a7936be
fix account size
silviutroscot Jan 18, 2024
3ac83a1
v3.0.29-staging-10
silviutroscot Jan 18, 2024
0e43215
Merge branch 'vali/add-meteora' of github.com:hubbleprotocol/hubble-c…
alittlezz Jan 19, 2024
82a82d6
Merge branch 'master' of github.com:hubbleprotocol/hubble-common into…
alittlezz Jan 19, 2024
dadadbd
wip
silviutroscot Jan 22, 2024
21381ff
Merge branch 'vali/add-meteora' of github.com:hubbleprotocol/hubble-c…
silviutroscot Jan 22, 2024
11d431d
fix meteora NaN issues
silviutroscot Jan 26, 2024
3660e0c
Merge branch 'master' of github.com:hubbleprotocol/hubble-common into…
silviutroscot Jan 26, 2024
574d48e
linting
silviutroscot Jan 26, 2024
0f028c4
cleanup
silviutroscot Jan 26, 2024
2d79ca6
address Nejc's comments
silviutroscot Jan 26, 2024
e502898
fix lint
silviutroscot Jan 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,4 @@ packages/kamino-sdk/deps/scope.so
packages/kamino-sdk/deps/whirlpool.so
.DS_Store


keypair.json
8 changes: 2 additions & 6 deletions lerna.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
{
"packages": [
"packages/*"
],
"packages": ["packages/*"],
"version": "4.0.0",
"command": {
"publish": {
"ignoreChanges": [
"tests/**"
]
"ignoreChanges": ["tests/**"]
}
}
}
94 changes: 56 additions & 38 deletions packages/kamino-sdk/src/Kamino.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1587,9 +1587,10 @@ export class Kamino {
collateralInfos: CollateralInfo[],
prices?: OraclePrices
): Promise<StrategyBalances> => {
const strategyPrices = await this.getStrategyPrices(strategy, collateralInfos, prices);
const strategyPricesPromise = this.getStrategyPrices(strategy, collateralInfos, prices);
const rebalanceKind = numberToRebalanceType(strategy.rebalanceType);
const tokenHoldings = await this.getMeteoraTokensBalances(strategy);
const tokenHoldingsPromise = this.getMeteoraTokensBalances(strategy);
let [strategyPrices, tokenHoldings] = await Promise.all([strategyPricesPromise, tokenHoldingsPromise]);

let computedHoldings: Holdings = this.getStrategyHoldingsUsd(
tokenHoldings.available.a,
Expand Down Expand Up @@ -2307,7 +2308,7 @@ export class Kamino {
decimalsA: number,
decimalsB: number
): Promise<PositionRange> => {
if (positionPk.toString() === PublicKey.default.toString()) {
if (positionPk.equals(PublicKey.default)) {
return { lowerPrice: ZERO, upperPrice: ZERO };
}
let position = await PositionV2.fetch(this._connection, positionPk);
Expand Down Expand Up @@ -2399,7 +2400,7 @@ export class Kamino {
};

getMeteoraPositions = async (positions: PublicKey[]): Promise<(PositionV2 | null)[]> => {
const nonDefaults = positions.filter((value) => value.toBase58() !== PublicKey.default.toBase58());
const nonDefaults = positions.filter((value) => !value.equals(PublicKey.default));
const fetched = await batchFetch(nonDefaults, (chunk) => PositionV2.fetchMultiple(this._connection, chunk));
const fetchedMap: Record<string, PositionV2 | null> = fetched.reduce((map, position, i) => {
map[nonDefaults[i].toBase58()] = position;
Expand Down Expand Up @@ -3881,10 +3882,8 @@ export class Kamino {
}
poolRewardVault0 = poolState.rewardInfos[0].vault;
poolRewardVault1 = poolState.rewardInfos[1].vault;
poolRewardVault2 = poolState.rewardInfos[2].vault;
rewardMint0 = poolState.rewardInfos[0].mint;
rewardMint1 = poolState.rewardInfos[1].mint;
rewardMint2 = poolState.rewardInfos[2].mint;
}

const accounts: CollectFeesAndRewardsAccounts = {
Expand All @@ -3906,13 +3905,12 @@ export class Kamino {
baseVaultAuthority: strategyState.baseVaultAuthority,
reward0Vault: strategyState.reward0Vault,
reward1Vault: strategyState.reward1Vault,
reward2Vault: strategyState.reward2Vault,
reward2Vault: strategyState.baseVaultAuthority,
poolRewardVault0:
strategyState.reward0Decimals.toNumber() > 0 ? poolRewardVault0 : strategyState.baseVaultAuthority,
poolRewardVault1:
strategyState.reward1Decimals.toNumber() > 0 ? poolRewardVault1 : strategyState.baseVaultAuthority,
poolRewardVault2:
strategyState.reward2Decimals.toNumber() > 0 ? poolRewardVault2 : strategyState.baseVaultAuthority,
poolRewardVault2: strategyState.baseVaultAuthority,
tickArrayLower: strategyState.tickArrayLower,
tickArrayUpper: strategyState.tickArrayUpper,
raydiumProtocolPositionOrBaseVaultAuthority: strategyState.raydiumProtocolPositionOrBaseVaultAuthority,
Expand All @@ -3921,7 +3919,7 @@ export class Kamino {
instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
reward0Mint: strategyState.reward0Decimals.toNumber() > 0 ? rewardMint0 : this._kaminoProgramId,
reward1Mint: strategyState.reward1Decimals.toNumber() > 0 ? rewardMint1 : this._kaminoProgramId,
reward2Mint: strategyState.reward2Decimals.toNumber() > 0 ? rewardMint2 : this._kaminoProgramId,
reward2Mint: this._kaminoProgramId,
eventAuthority,
};

Expand Down Expand Up @@ -4036,21 +4034,27 @@ export class Kamino {

private readMeteoraPosition = async (poolPk: PublicKey, positionPk: PublicKey): Promise<MeteoraPosition> => {
let pool = await LbPair.fetch(this._connection, poolPk);
if (!pool) {
throw new Error(`Could not find position ${poolPk}`);
}
let position = await PositionV2.fetch(this._connection, positionPk);
if (!position) {
throw new Error(`Could not find position ${positionPk} for pool ${poolPk}`);
if (!pool || !position) {
return {
publicKey: positionPk,
amountX: new Decimal(0),
amountY: new Decimal(0),
};
}

let { lowerTick: lowerTickPk, upperTick: upperTickPk } = this.getStartEndTicketIndexProgramAddressesMeteora(
poolPk,
position.lowerBinId
);
let lowerBinArray = await BinArray.fetch(this._connection, lowerTickPk);
let upperBinArray = await BinArray.fetch(this._connection, upperTickPk);
if (!lowerBinArray || !upperBinArray) {
throw new Error(`Could not find either ${lowerTickPk} or ${upperTickPk}`);
return {
publicKey: positionPk,
amountX: new Decimal(0),
amountY: new Decimal(0),
};
}
let binArrays = [lowerBinArray, upperBinArray];
let totalAmountX = new Decimal(0);
Expand Down Expand Up @@ -4763,12 +4767,6 @@ export class Kamino {
getNearestValidTickIndexFromTickIndex(rebalanceParams[0].toNumber(), whilrpoolState.tickSpacing)
);
}
} else if (dex == 'RAYDIUM') {
// no processing needed
} else if (dex == 'METEORA') {
// no processing needed
} else {
throw Error(`Invalid dex ${dex}`);
}

return processedRebalanceParams;
Expand Down Expand Up @@ -6602,17 +6600,41 @@ export class Kamino {
let amountADecimal = new Decimal(0);
let amountBDecimal = new Decimal(0);
if (bin) {
amountADecimal = new Decimal(bin.amountX.toString());
amountBDecimal = new Decimal(bin.amountY.toString());
if (!bin.amountX.eq(new BN(0))) {
amountADecimal = new Decimal(bin.amountX.toString());
}
if (!bin.amountY.eq(new BN(0))) {
amountBDecimal = new Decimal(bin.amountY.toString());
}
} else {
throw new Error(`bin ${poolState.activeId.toString()} is not found`);
}

if (amountADecimal.eq(ZERO) && amountBDecimal.eq(ZERO)) {
const decimalsA = await getMintDecimals(this._connection, strategyState.tokenAMint);
const decimalsB = await getMintDecimals(this._connection, strategyState.tokenBMint);
const poolPrice = getPriceOfBinByBinIdWithDecimals(poolState.activeId, poolState.binStep, decimalsA, decimalsB);
return [tokenAAmount || tokenBAmount!.div(poolPrice), tokenBAmount || tokenAAmount!.mul(poolPrice)];
}

if (amountBDecimal.eq(ZERO)) {
return [tokenAAmount!, ZERO];
}

if (amountADecimal.eq(ZERO)) {
return [ZERO, tokenBAmount!];
}

const ratio = amountADecimal.div(amountBDecimal);
peroxy marked this conversation as resolved.
Show resolved Hide resolved
if (tokenAAmount === undefined || tokenAAmount.eq(ZERO)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return [tokenBAmount!.mul(ratio), tokenBAmount!];
let amountA = tokenBAmount!.mul(ratio) || new Decimal(0);
return [amountA, tokenBAmount!];
}

if (tokenBAmount === undefined || tokenBAmount.eq(ZERO)) {
return [tokenAAmount, tokenAAmount.div(ratio)];
let amountB = tokenAAmount.div(ratio) || new Decimal(0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure ratio !== 0 here as well, otherwise infinity issue again

return [tokenAAmount, amountB];
}
}

Expand Down Expand Up @@ -6744,16 +6766,14 @@ export class Kamino {
): Promise<{ amountSlippageA: BN; amountSlippageB: BN }> {
const { strategy: strategyState } = await this.getStrategyStateIfNotFetched(strategy);

const poolState = await LbPair.fetch(this._connection, strategyState.pool);
const poolStatePromise = LbPair.fetch(this._connection, strategyState.pool);
const positionPromise = PositionV2.fetch(this._connection, strategyState.position);

let [poolState, _position] = await Promise.all([poolStatePromise, positionPromise]);
if (!poolState) {
throw Error(`Could not fetch lb pair state with pubkey ${strategyState.pool.toString()}`);
}

const position = await PositionV2.fetch(this._connection, strategyState.position);
if (!position) {
throw new Error(`Meteora position ${strategyState.position} does not exist`);
}

return { amountSlippageA: new BN(0), amountSlippageB: new BN(0) };
}

Expand All @@ -6763,16 +6783,14 @@ export class Kamino {
): Promise<{ amountSlippageA: BN; amountSlippageB: BN }> {
const { strategy: strategyState } = await this.getStrategyStateIfNotFetched(strategy);

const poolState = await LbPair.fetch(this._connection, strategyState.pool);
const poolStatePromise = await LbPair.fetch(this._connection, strategyState.pool);
const positionPromise = await PositionV2.fetch(this._connection, strategyState.position);
let [poolState, _position] = await Promise.all([poolStatePromise, positionPromise]);

if (!poolState) {
throw Error(`Could not fetch lb pair state with pubkey ${strategyState.pool.toString()}`);
}

const position = await PositionV2.fetch(this._connection, strategyState.position);
if (!position) {
throw new Error(`Meteora position ${strategyState.position} does not exist`);
}

return { amountSlippageA: new BN(0), amountSlippageB: new BN(0) };
}

Expand Down
Loading
Loading