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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 60 additions & 38 deletions src/pools/pools.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Signer } from "@reef-chain/evm-provider";
import { Contract } from "ethers";
import { BigNumber, Contract } from "ethers";
import { getReefswapFactory } from "../network/rpc";
import {
EMPTY_ADDRESS,
Expand All @@ -13,6 +13,7 @@ import { ReefswapPair } from "../token/abi/ReefswapPair";
import {
catchError,
combineLatest,
firstValueFrom,
map,
Observable,
of,
Expand All @@ -28,6 +29,14 @@ import {
} from "../reefState/model/statusDataObject";
import { ensure } from "../utils/utils";
import { Signer as EthersSigner } from "@ethersproject/abstract-signer";
import axios from "axios";
import { getReefswapNetworkConfig } from "../network";
import {
selectedAccount$,
selectedAddress$,
selectedNetwork$,
} from "../reefState";
import { queryGql$ } from "../graphql";

const findPoolTokenAddress = async (
address1: string,
Expand All @@ -40,6 +49,23 @@ const findPoolTokenAddress = async (
return address;
};

const getPoolInfoQuery = (
address: string,
time: string,
selectedAddress: string
) => `
query PoolInfoQuery {
poolInfo(address: "${address}", fromTime: "${time}", signerAddress: "${selectedAddress}", toTime: "${time}") {
totalSupply
userSupply
reserves {
reserved1
reserved2
}
}
}
`;

export const loadPool = async (
token1: Token | TokenBalance,
token2: Token,
Expand All @@ -53,58 +79,54 @@ export const loadPool = async (
factoryAddress
);
ensure(address !== EMPTY_ADDRESS, "Pool does not exist!");
const contract = new Contract(
address,
ReefswapPair,
signer as unknown as EthersSigner
);

const decimals = await contract.decimals();
const reserves = await contract.getReserves();
const totalSupply = await contract.totalSupply();
const liquidity = await contract.balanceOf(await signer.getAddress());
let date = new Date();
date.setDate(date.getDate() - 2);

const address1 = await contract.token1();
const network = await firstValueFrom(selectedNetwork$);
const selectedAccount = await firstValueFrom(selectedAccount$);

const [finalReserve1, finalReserve2] =
token1.address !== address1
? [reserves[0], reserves[1]]
: [reserves[1], reserves[0]];
const dexHttpClient = axios.create({
baseURL: getReefswapNetworkConfig(network).graphqlDexsUrl,
});

const tokenBalance1 = finalReserve1.mul(liquidity).div(totalSupply);
const tokenBalance2 = finalReserve2.mul(liquidity).div(totalSupply);
let res = (
await firstValueFrom(
queryGql$(dexHttpClient, {
query: getPoolInfoQuery(
address,
date.toISOString(),
selectedAccount.evmAddress
),
variables: {},
})
)
).data.poolInfo;

const decimals = "18"; // not sure if it is always 18 or what
const liquidity = res.userSupply;
const totalSupply = res.totalSupply;

const tokenBalance1 = BigNumber.from(res.reserves.reserved1)
.mul(liquidity)
.div(totalSupply);
const tokenBalance2 = BigNumber.from(res.reserves.reserved2)
.mul(liquidity)
.div(totalSupply);

return {
poolAddress: address,
decimals: parseInt(decimals, 10),
reserve1: finalReserve1.toString(),
reserve2: finalReserve2.toString(),
reserve1: res.reserves.reserved1,
reserve2: res.reserves.reserved2,
totalSupply: totalSupply.toString(),
userPoolBalance: liquidity.toString(),
//@ts-ignore
token1: { ...token1, balance: tokenBalance1 },
token2: { ...token2, balance: tokenBalance2 },
};
};

/*export const loadPools = async (
tokens: Token[],
signer: Signer,
factoryAddress: string,
): Promise<Pool[]> => {
const tokenCombinations = uniqueCombinations(tokens);
const pools: Pool[] = [];
for (let index = 0; index < tokenCombinations.length; index += 1) {
try {
const [token1, token2] = tokenCombinations[index];
/!* eslint-disable no-await-in-loop *!/
const pool = await loadPool(token1, token2, signer, factoryAddress);
/!* eslint-disable no-await-in-loop *!/
pools.push(pool);
} catch (e) {}
}
return pools;
};*/

const cachePool$: Map<
string,
Observable<StatusDataObject<Pool | null>>
Expand Down
28 changes: 28 additions & 0 deletions test/pools/loadPools.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { beforeAll, describe, it, expect } from "vitest";
import { firstValueFrom, skip, skipWhile, tap } from "rxjs";
import { initReefState, selectedPools_status$ } from "../../src/reefState";
import { AVAILABLE_NETWORKS } from "../../src/network";
import { fetchPools$, loadPool } from "../../src/pools/pools";

describe("pools", () => {
const signingKey = {};

beforeAll(async () => {
initReefState({
network: AVAILABLE_NETWORKS.testnet,
jsonAccounts: {
accounts: [
{
address: "5EnY9eFwEDcEJ62dJWrTXhTucJ4pzGym4WZ2xcDKiT3eJecP",
isSelected: true,
},
],
injectedSigner: signingKey,
},
});
});
it("should load pool details", async () => {
const res = await firstValueFrom(selectedPools_status$.pipe(skip(10)));
expect(res.data.length).toBeGreaterThan(0);
});
});