@dahlia-labs/stableswap-sdk
Version:
SDK for Mobius's StableSwap program.
135 lines (118 loc) • 3.98 kB
text/typescript
import { Fraction, Percent } from "@dahlia-labs/token-utils";
import type { Multicall, ProviderOrSigner } from "@dahlia-labs/use-ethers";
import { getContract } from "@dahlia-labs/use-ethers";
import { Interface } from "@ethersproject/abi";
import type { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import JSBI from "jsbi";
import LPTOKEN_ABI from "./abis/LPToken.json";
import SWAP_ABI from "./abis/Swap.json";
import type { LPToken, LPTokenInterface } from "./generated/LPToken";
import type { Swap, SwapInterface } from "./generated/Swap";
import type { Fees } from "./index";
export const FEE_BASE = JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(10));
export function getLPTokenInterface(): LPTokenInterface {
return new Interface(LPTOKEN_ABI) as LPTokenInterface;
}
export function getSwapInterface(): SwapInterface {
return new Interface(SWAP_ABI) as SwapInterface;
}
export const lpTokenInterface = getLPTokenInterface();
export const swapInterface = getSwapInterface();
export const getLPTokenContract = (
address: string,
provider: ProviderOrSigner
): LPToken => getContract(address, LPTOKEN_ABI, provider) as LPToken;
export const getSwapContract = (
address: string,
provider: ProviderOrSigner
): Swap => getContract(address, SWAP_ABI, provider) as Swap;
export interface SwapStorage {
swapFee: BigNumber;
adminFee: BigNumber;
defaultDepositFee: BigNumber;
defaultWithdrawFee: BigNumber;
}
export const LPMulticall = (swapAddress: string): Multicall<string> =>
({
call: {
target: swapAddress,
callData: swapInterface.encodeFunctionData("getLpToken"),
},
parseReturn: (returnData: string) => returnData,
} as const);
export const ampMulticall = (swapAddress: string): Multicall<JSBI> =>
({
call: {
target: swapAddress,
callData: swapInterface.encodeFunctionData("getA"),
},
parseReturn: (returnData: string) => JSBI.BigInt(returnData),
} as const);
export const pausedMulticall = (swapAddress: string): Multicall<boolean> =>
({
call: {
target: swapAddress,
callData: swapInterface.encodeFunctionData("paused"),
},
parseReturn: (returnData: string) =>
(
swapInterface.decodeFunctionResult("paused", returnData) as [boolean]
)[0],
} as const);
export const feesMulticall = (swapAddress: string): Multicall<Fees> =>
({
call: {
target: swapAddress,
callData: swapInterface.encodeFunctionData("swapStorage"),
},
parseReturn: (returnData: string) => {
const data = swapInterface.decodeFunctionResult(
"swapStorage",
returnData
) as unknown as Awaited<ReturnType<Swap["swapStorage"]>>;
return {
trade: new Percent(data.swapFee.toString(), FEE_BASE),
admin: new Percent(data.adminFee.toString(), FEE_BASE),
deposit: new Percent(data.defaultDepositFee.toString(), FEE_BASE),
withdraw: new Percent(data.defaultWithdrawFee.toString(), FEE_BASE),
};
},
} as const);
export const tokenBalanceMulticall = (
swapAddress: string,
index: number
): Multicall<Fraction> =>
({
call: {
target: swapAddress,
callData: swapInterface.encodeFunctionData("getTokenBalance", [index]),
},
parseReturn: (returnData: string) =>
new Fraction(
swapInterface
.decodeFunctionResult("getTokenBalance", returnData)
.toString()
),
} as const);
export const calculateSwapMulticall = (
swapAddress: string,
fromIndex: number,
toIndex: number,
amountIn: BigNumberish
): Multicall<Fraction> =>
({
call: {
target: swapAddress,
callData: swapInterface.encodeFunctionData("calculateSwap", [
fromIndex,
toIndex,
amountIn,
]),
},
parseReturn: (returnData: string) =>
new Fraction(
swapInterface
.decodeFunctionResult("calculateSwap", returnData)
.toString()
),
} as const);