@pump-fun/pump-swap-sdk
Version:
Official SDK for interacting with Pump Swap AMM protocol on Solana
188 lines (168 loc) • 5.49 kB
text/typescript
import { expect } from "chai";
import BN from "bn.js";
import { PublicKey } from "@solana/web3.js";
import { computeFeesBps } from "../sdk/fees";
import { Fees, FeeConfig, FeeTier, GlobalConfig } from "../types/sdk";
import { pumpPoolAuthorityPda } from "../sdk/pda";
import { poolMarketCap } from "../sdk/util";
describe("computeFeesBps", () => {
const tier1Fees: FeeTier = {
marketCapLamportsThreshold: new BN(100_000_000_000_000),
fees: {
lpFeeBps: new BN(15),
protocolFeeBps: new BN(5),
creatorFeeBps: new BN(5),
},
};
const tier2Fees: FeeTier = {
marketCapLamportsThreshold: new BN(500_000_000_000_000),
fees: {
lpFeeBps: new BN(20),
protocolFeeBps: new BN(5),
creatorFeeBps: new BN(5),
},
};
const tier3Fees: FeeTier = {
marketCapLamportsThreshold: new BN(2_500_000_000_000_000),
fees: {
lpFeeBps: new BN(15),
protocolFeeBps: new BN(2),
creatorFeeBps: new BN(3),
},
};
const flatFees: Fees = {
lpFeeBps: new BN(25),
protocolFeeBps: new BN(5),
creatorFeeBps: new BN(0),
};
const globalConfig: GlobalConfig = {
admin: PublicKey.unique(),
lpFeeBasisPoints: new BN(42),
protocolFeeBasisPoints: new BN(42),
disableFlags: 0,
protocolFeeRecipients: [],
coinCreatorFeeBasisPoints: new BN(42),
adminSetCoinCreatorAuthority: PublicKey.unique(),
whitelistPda: PublicKey.unique(),
reservedFeeRecipient: PublicKey.unique(),
mayhemModeEnabled: false,
reservedFeeRecipients: [],
};
const feeConfig: FeeConfig = {
admin: PublicKey.unique(),
flatFees,
feeTiers: [tier1Fees, tier2Fees, tier3Fees],
};
const baseMint = PublicKey.unique();
const baseMintSupply = new BN(1_000_000);
const pumpPool = {
poolBump: 1,
index: 0,
creator: pumpPoolAuthorityPda(baseMint),
baseMint,
quoteMint: PublicKey.unique(),
lpMint: PublicKey.unique(),
poolBaseTokenAccount: PublicKey.unique(),
poolQuoteTokenAccount: PublicKey.unique(),
lpSupply: new BN(1_000_000),
coinCreator: PublicKey.unique(),
};
const tradeSize = new BN(10_000);
it("market cap should be correct", () => {
let baseReserve = new BN(1_000_000);
let quoteReserve = new BN(2_000_000);
let marketCap = poolMarketCap({
baseMintSupply,
baseReserve,
quoteReserve,
});
let expectedMarketCap = quoteReserve.mul(baseMintSupply).div(baseReserve);
expect(marketCap.toString()).to.equal(expectedMarketCap.toString());
quoteReserve = new BN(500_000_000_000_000);
marketCap = poolMarketCap({
baseMintSupply,
baseReserve,
quoteReserve,
});
expectedMarketCap = quoteReserve.mul(baseMintSupply).div(baseReserve);
expect(marketCap.toString()).to.equal(expectedMarketCap.toString());
baseReserve = new BN(1_000_000);
quoteReserve = new BN(2_500_000_000_000_000);
marketCap = poolMarketCap({
baseMintSupply,
baseReserve,
quoteReserve,
});
expectedMarketCap = quoteReserve.mul(baseMintSupply).div(baseReserve);
expect(marketCap.toString()).to.equal(expectedMarketCap.toString());
});
it("non pump pool should use flat fees", () => {
const nonPumpPool = {
...pumpPool,
creator: PublicKey.unique(),
};
const result = computeFeesBps({
globalConfig,
feeConfig,
creator: nonPumpPool.creator,
baseMintSupply,
baseMint: nonPumpPool.baseMint,
baseReserve: new BN(1_000_000),
quoteReserve: new BN(2_000_000),
tradeSize: new BN(10_000),
});
expectCalculatedFeesEqualFees(result, flatFees);
});
it("pump pool should use first tier when market cap is below first tier", () => {
const result = computeFeesBps({
globalConfig,
feeConfig,
creator: pumpPool.creator,
baseMintSupply,
baseMint: pumpPool.baseMint,
baseReserve: new BN(1_000_000),
quoteReserve: new BN(tier1Fees.marketCapLamportsThreshold).sub(new BN(1)),
tradeSize,
});
expectCalculatedFeesEqualFees(result, tier1Fees.fees);
});
it("pump pool should use last tier when market cap is above last tier", () => {
const result = computeFeesBps({
globalConfig,
feeConfig,
creator: pumpPool.creator,
baseMintSupply,
baseMint: pumpPool.baseMint,
baseReserve: new BN(1_000_000),
quoteReserve: new BN(tier3Fees.marketCapLamportsThreshold).add(new BN(1)),
tradeSize,
});
expectCalculatedFeesEqualFees(result, tier3Fees.fees);
});
it("should use global config fees when fee config is null", () => {
const result = computeFeesBps({
globalConfig,
feeConfig: null,
creator: pumpPool.creator,
baseMintSupply,
baseMint: pumpPool.baseMint,
baseReserve: new BN(1_000_000),
quoteReserve: new BN(2_000_000),
tradeSize,
});
expectCalculatedFeesEqualFees(result, {
lpFeeBps: globalConfig.lpFeeBasisPoints,
protocolFeeBps: globalConfig.protocolFeeBasisPoints,
creatorFeeBps: globalConfig.coinCreatorFeeBasisPoints,
});
});
});
function expectCalculatedFeesEqualFees(actual: Fees, expected: Fees) {
expect(actual.creatorFeeBps.toString()).to.equal(
expected.creatorFeeBps.toString()
);
expect(actual.lpFeeBps.toString()).to.equal(expected.lpFeeBps.toString());
expect(actual.protocolFeeBps.toString()).to.equal(
expected.protocolFeeBps.toString()
);
}