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

chore: Add Fantom config #69

Closed
wants to merge 5 commits into from
Closed
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
5 changes: 5 additions & 0 deletions .changeset/angry-toes-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@balancer/sdk": minor
---

Add Fantom network config/support.
2 changes: 1 addition & 1 deletion src/entities/swap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export class Swap {
});

const queriesContract = getContract({
address: BALANCER_QUERIES,
address: BALANCER_QUERIES[this.chainId],
abi: balancerQueriesAbi,
publicClient,
});
Expand Down
24 changes: 23 additions & 1 deletion src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export enum ChainId {
ARBITRUM_ONE = 42161,
AVALANCHE = 43114,
BASE_GOERLI = 84531,
FANTOM = 250,
}

export const CHAINS: Record<number, Chain> = {
Expand Down Expand Up @@ -100,6 +101,8 @@ export const SUBGRAPH_URLS = {
'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-avalanche-v2',
[ChainId.BASE_GOERLI]:
'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-base-goerli-v2',
[ChainId.FANTOM]:
'https://api.thegraph.com/subgraphs/name/beethovenxfi/beethovenx-v2-fantom',
};

export const STELLATE_URLS = {
Expand All @@ -111,7 +114,17 @@ export const STELLATE_URLS = {
[ChainId.ARBITRUM_ONE]: 'https://balancer-arbitrum-v2.stellate.balancer.fi',
};

export const BALANCER_QUERIES = '0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5';
export const BALANCER_QUERIES: Record<number, Address> = {
[ChainId.ARBITRUM_ONE]: '0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5',
[ChainId.AVALANCHE]: '0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5',
[ChainId.GNOSIS_CHAIN]: '0x0f3e0c4218b7b0108a3643cfe9d3ec0d4f57c54e',
[ChainId.MAINNET]: '0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5',
[ChainId.OPTIMISM]: '0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5',
[ChainId.POLYGON]: '0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5',
[ChainId.ZKEVM]: '0x809b79b53f18e9bc08a961ed4678b901ac93213a',
[ChainId.FANTOM]: '0x1B0A42663DF1edeA171cD8732d288a81EFfF6d23',
};

export const BALANCER_POOL_DATA_QUERIES_ADDRESSES: Record<number, Address> = {
[ChainId.ARBITRUM_ONE]: '0x7Ba29fE8E83dd6097A7298075C4AFfdBda3121cC',
[ChainId.AVALANCHE]: '0x67af5D428d38C5176a286a2371Df691cDD914Fb8',
Expand All @@ -120,6 +133,7 @@ export const BALANCER_POOL_DATA_QUERIES_ADDRESSES: Record<number, Address> = {
[ChainId.OPTIMISM]: '0x6B5dA774890Db7B7b96C6f44e6a4b0F657399E2e',
[ChainId.POLYGON]: '0x84813aA3e079A665C0B80F944427eE83cBA63617',
[ChainId.ZKEVM]: '0xF24917fB88261a37Cc57F686eBC831a5c0B9fD39',
[ChainId.FANTOM]: '0x9642Dbba0753B1518022d7617Be079f0d7EFD165',
};

export const NATIVE_ASSETS = {
Expand Down Expand Up @@ -163,6 +177,14 @@ export const NATIVE_ASSETS = {
'Ether',
'0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
),
[ChainId.FANTOM]: new Token(
ChainId.FANTOM,
NATIVE_ADDRESS,
18,
'FANTOM',
'Fantom',
'0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83',
),
};

export const ETH = NATIVE_ASSETS[ChainId.MAINNET];
Expand Down
92 changes: 92 additions & 0 deletions test/sor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
BALANCER_POOL_DATA_QUERIES_ADDRESSES,
ChainId,
ETH,
NATIVE_ASSETS,
} from '../src/utils';
import { Token, TokenAmount } from '../src/entities';
import { OnChainPoolDataEnricher } from '../src/data/enrichers/onChainPoolDataEnricher';
Expand Down Expand Up @@ -191,4 +192,95 @@ describe('SmartOrderRouter', () => {
});
});
});
describe('Fantom', () => {
const chainId = ChainId.FANTOM;
const inputToken = NATIVE_ASSETS[chainId];
const rpcUrl = process.env['FANTOM_RPC_URL'] || '';
const subgraphPoolDataService = new SubgraphPoolProvider(chainId);
const onChainPoolDataEnricher = new OnChainPoolDataEnricher(
chainId,
rpcUrl,
BALANCER_POOL_DATA_QUERIES_ADDRESSES[chainId],
{
loadAmpForPools: {
poolTypes: ['ComposableStable'],
},
},
);

const sor = new SmartOrderRouter({
chainId,
poolDataProviders: subgraphPoolDataService,
poolDataEnrichers: onChainPoolDataEnricher,
rpcUrl: rpcUrl,
});

const BEETS = new Token(
chainId,
'0xF24Bcf4d1e507740041C9cFd2DddB29585aDCe1e',
18,
'BEETS',
);

const swapOptions: SwapOptions = {
block: 65313450n,
};

let pools: BasePool[];
// Since constructing a Swap mutates the pool balances, we refetch for each test
// May be a better way to deep clone a BasePool[] class instead
beforeEach(async () => {
pools = await sor.fetchAndCachePools(swapOptions.block);
});

describe('Native Swaps', () => {
test('Native -> Token givenIn', async () => {
const inputAmount = TokenAmount.fromHumanAmount(
inputToken,
'100',
);

const swap = await sorGetSwapsWithPools(
inputToken,
BEETS,
SwapKind.GivenIn,
inputAmount,
pools,
swapOptions,
);

if (!swap) throw new Error('Swap is undefined');

const onchain = await swap.query(rpcUrl, swapOptions.block);

expect(swap.quote.amount).toEqual(onchain.amount);
expect(swap.inputAmount.amount).toEqual(inputAmount.amount);
expect(swap.outputAmount.amount).toEqual(swap.quote.amount);
});

test('Native ETH -> Token givenOut', async () => {
const outputAmount = TokenAmount.fromHumanAmount(
BEETS,
'100000',
);

const swap = await sorGetSwapsWithPools(
inputToken,
BEETS,
SwapKind.GivenOut,
outputAmount,
pools,
swapOptions,
);

if (!swap) throw new Error('Swap is undefined');

const onchain = await swap.query(rpcUrl, swapOptions.block);

expect(swap.quote.amount).toEqual(onchain.amount);
expect(swap.inputAmount.amount).toEqual(swap.quote.amount);
expect(swap.outputAmount.amount).toEqual(outputAmount.amount);
});
});
});
});
13 changes: 13 additions & 0 deletions test/subgraph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ describe('SubgraphPoolProvider', () => {
timestamp: BigInt(Math.floor(new Date().getTime() / 1000)),
};

const { pools } = await subgraphPoolDataService.getPools(
providerOptions,
);
expect(pools.length).toBeGreaterThan(0);
});
test('getPools fantom', async () => {
const chainId = ChainId.FANTOM;
const subgraphPoolDataService = new SubgraphPoolProvider(chainId);

const providerOptions: ProviderSwapOptions = {
timestamp: BigInt(Math.floor(new Date().getTime() / 1000)),
};

const { pools } = await subgraphPoolDataService.getPools(
providerOptions,
);
Expand Down