Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

Commit

Permalink
feat(biswap): Added Biswap on BSC (pools and farms) (#945)
Browse files Browse the repository at this point in the history
  • Loading branch information
wpoulin authored Jul 25, 2022
1 parent c547bef commit b91d797
Show file tree
Hide file tree
Showing 20 changed files with 5,052 additions and 0 deletions.
Binary file added src/apps/biswap/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 70 additions & 0 deletions src/apps/biswap/binance-smart-chain/biswap.balance-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Inject } from '@nestjs/common';

import { APP_TOOLKIT, IAppToolkit } from '~app-toolkit/app-toolkit.interface';
import { Register } from '~app-toolkit/decorators';
import { presentBalanceFetcherResponse } from '~app-toolkit/helpers/presentation/balance-fetcher-response.present';
import { BalanceFetcher } from '~balance/balance-fetcher.interface';
import { Network } from '~types/network.interface';

import { BISWAP_DEFINITION } from '../biswap.definition';
import { BiswapContractFactory, BiswapMasterchef } from '../contracts';

const appId = BISWAP_DEFINITION.id;
const network = Network.BINANCE_SMART_CHAIN_MAINNET;

@Register.BalanceFetcher(appId, network)
export class BinanceSmartChainBiswapBalanceFetcher implements BalanceFetcher {
constructor(
@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit,
@Inject(BiswapContractFactory) private readonly contractFactory: BiswapContractFactory,
) {}

async getPoolBalances(address: string) {
return this.appToolkit.helpers.tokenBalanceHelper.getTokenBalances({
address,
network,
appId,
groupId: BISWAP_DEFINITION.groups.pool.id,
});
}

async getFarmBalances(address: string) {
return this.appToolkit.helpers.masterChefContractPositionBalanceHelper.getBalances<BiswapMasterchef>({
address,
appId,
groupId: BISWAP_DEFINITION.groups.farm.id,
network,
resolveChefContract: ({ contractAddress }) =>
this.contractFactory.biswapMasterchef({ network, address: contractAddress }),
resolveStakedTokenBalance: this.appToolkit.helpers.masterChefDefaultStakedBalanceStrategy.build({
resolveStakedBalance: ({ contract, multicall, contractPosition }) =>
multicall
.wrap(contract)
.userInfo(contractPosition.dataProps.poolIndex, address)
.then(v => v.amount),
}),
resolveClaimableTokenBalances: this.appToolkit.helpers.masterChefDefaultClaimableBalanceStrategy.build({
resolveClaimableBalance: ({ multicall, contract, contractPosition, address }) =>
multicall.wrap(contract).pendingBSW(contractPosition.dataProps.poolIndex, address),
}),
});
}

async getBalances(address: string) {
const [poolBalances, farmBalances] = await Promise.all([
this.getPoolBalances(address),
this.getFarmBalances(address),
]);

return presentBalanceFetcherResponse([
{
label: 'Pools',
assets: poolBalances,
},
{
label: 'Farms',
assets: farmBalances,
},
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Inject } from '@nestjs/common';

import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface';
import { Register } from '~app-toolkit/decorators';
import { PositionFetcher } from '~position/position-fetcher.interface';
import { ContractPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { BISWAP_DEFINITION } from '../biswap.definition';
import { BiswapContractFactory, BiswapMasterchef } from '../contracts';

const appId = BISWAP_DEFINITION.id;
const groupId = BISWAP_DEFINITION.groups.farm.id;
const network = Network.BINANCE_SMART_CHAIN_MAINNET;

@Register.ContractPositionFetcher({ appId, groupId, network })
export class BinanceSmartChainBiswapContractPositionFetcher implements PositionFetcher<ContractPosition> {
constructor(
@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit,
@Inject(BiswapContractFactory) private readonly contractFactory: BiswapContractFactory,
) {}

async getPositions() {
return this.appToolkit.helpers.masterChefContractPositionHelper.getContractPositions<BiswapMasterchef>({
address: '0xdbc1a13490deef9c3c12b44fe77b503c1b061739',
appId,
groupId,
network,
dependencies: [{ appId, groupIds: [BISWAP_DEFINITION.groups.pool.id], network }],
resolveContract: ({ address, network }) => this.contractFactory.biswapMasterchef({ address, network }),
resolvePoolLength: ({ multicall, contract }) => multicall.wrap(contract).poolLength(),
resolveDepositTokenAddress: ({ poolIndex, contract, multicall }) =>
multicall
.wrap(contract)
.poolInfo(poolIndex)
.then(v => v.lpToken),
resolveRewardTokenAddresses: ({ multicall, contract }) => multicall.wrap(contract).BSW(),
resolveRewardRate: this.appToolkit.helpers.masterChefDefaultRewardsPerBlockStrategy.build({
resolvePoolAllocPoints: async ({ poolIndex, contract, multicall }) =>
multicall
.wrap(contract)
.poolInfo(poolIndex)
.then(v => v.allocPoint),
resolveTotalAllocPoints: ({ multicall, contract }) => multicall.wrap(contract).totalAllocPoint(),
resolveTotalRewardRate: ({ multicall, contract }) => multicall.wrap(contract).BSWPerBlock(),
}),
});
}
}
55 changes: 55 additions & 0 deletions src/apps/biswap/binance-smart-chain/biswap.pool.token-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Inject } from '@nestjs/common';

import { Register } from '~app-toolkit/decorators';
import { UniswapV2OnChainPoolTokenAddressStrategy, UniswapV2PoolTokenHelper } from '~apps/uniswap-v2';
import { PositionFetcher } from '~position/position-fetcher.interface';
import { AppTokenPosition } from '~position/position.interface';
import { Network } from '~types/network.interface';

import { BISWAP_DEFINITION } from '../biswap.definition';
import { BiswapContractFactory } from '../contracts';

const appId = BISWAP_DEFINITION.id;
const groupId = BISWAP_DEFINITION.groups.pool.id;
const network = Network.BINANCE_SMART_CHAIN_MAINNET;

@Register.TokenPositionFetcher({ appId, groupId, network })
export class BinanceSmartChainBiswapPoolTokenFetcher implements PositionFetcher<AppTokenPosition> {
constructor(
@Inject(UniswapV2PoolTokenHelper) private readonly poolTokenHelper: UniswapV2PoolTokenHelper,
@Inject(BiswapContractFactory) private readonly contractFactory: BiswapContractFactory,
@Inject(UniswapV2OnChainPoolTokenAddressStrategy)
private readonly uniswapV2OnChainPoolTokenAddressStrategy: UniswapV2OnChainPoolTokenAddressStrategy,
) {}

async getPositions() {
return this.poolTokenHelper.getTokens({
network,
appId,
groupId,
minLiquidity: 10000,
fee: 0.003,
factoryAddress: '0x858e3312ed3a876947ea49d572a7c42de08af7ee',
resolveFactoryContract: ({ address, network }) =>
this.contractFactory.biswapFactory({
address,
network,
}),
resolvePoolContract: ({ address, network }) => this.contractFactory.biswapPool({ address, network }),
resolvePoolTokenAddresses: this.uniswapV2OnChainPoolTokenAddressStrategy.build({
resolvePoolsLength: ({ multicall, factoryContract }) => multicall.wrap(factoryContract).allPairsLength(),
resolvePoolAddress: ({ multicall, factoryContract, poolIndex }) =>
multicall.wrap(factoryContract).allPairs(poolIndex),
}),
resolvePoolTokenSymbol: ({ multicall, poolContract }) => multicall.wrap(poolContract).symbol(),
resolvePoolTokenSupply: ({ multicall, poolContract }) => multicall.wrap(poolContract).totalSupply(),
resolvePoolReserves: async ({ multicall, poolContract }) => {
const reserves = await multicall.wrap(poolContract).getReserves();
return [reserves[0], reserves[1]];
},
resolvePoolUnderlyingTokenAddresses: async ({ multicall, poolContract }) => {
return Promise.all([multicall.wrap(poolContract).token0(), multicall.wrap(poolContract).token1()]);
},
});
}
}
29 changes: 29 additions & 0 deletions src/apps/biswap/biswap.definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Register } from '~app-toolkit/decorators';
import { appDefinition, AppDefinition } from '~app/app.definition';
import { GroupType, AppTag, AppAction } from '~app/app.interface';
import { Network } from '~types/network.interface';

export const BISWAP_DEFINITION = appDefinition({
id: 'biswap',
name: 'Biswap',
description: `Enjoy the lowest exchange fee, profitable features & Multi-type Referral program`,
groups: {
pool: { id: 'pool', type: GroupType.TOKEN, label: 'Pools' },
farm: { id: 'farm', type: GroupType.POSITION, label: 'Farms' },
},
url: 'https://app.beets.fi/',
links: {
github: 'https://github.com/biswap-org',
twitter: 'https://twitter.com/Biswap_DEX',
medium: 'https://biswap-dex.medium.com/',
},
tags: [AppTag.DECENTRALIZED_EXCHANGE],
supportedNetworks: { [Network.BINANCE_SMART_CHAIN_MAINNET]: [AppAction.VIEW] },
});

@Register.AppDefinition(BISWAP_DEFINITION.id)
export class BiswapAppDefinition extends AppDefinition {
constructor() {
super(BISWAP_DEFINITION);
}
}
22 changes: 22 additions & 0 deletions src/apps/biswap/biswap.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Register } from '~app-toolkit/decorators';
import { AbstractApp } from '~app/app.dynamic-module';
import { UniswapV2AppModule } from '~apps/uniswap-v2';

import { BinanceSmartChainBiswapBalanceFetcher } from './binance-smart-chain/biswap.balance-fetcher';
import { BinanceSmartChainBiswapContractPositionFetcher } from './binance-smart-chain/biswap.farm.contract-position-fetcher';
import { BinanceSmartChainBiswapPoolTokenFetcher } from './binance-smart-chain/biswap.pool.token-fetcher';
import { BiswapAppDefinition, BISWAP_DEFINITION } from './biswap.definition';
import { BiswapContractFactory } from './contracts';

@Register.AppModule({
appId: BISWAP_DEFINITION.id,
imports: [UniswapV2AppModule],
providers: [
BiswapAppDefinition,
BiswapContractFactory,
BinanceSmartChainBiswapBalanceFetcher,
BinanceSmartChainBiswapPoolTokenFetcher,
BinanceSmartChainBiswapContractPositionFetcher,
],
})
export class BiswapAppModule extends AbstractApp() {}
130 changes: 130 additions & 0 deletions src/apps/biswap/contracts/abis/biswap-factory.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
[
{
"inputs": [{ "internalType": "address", "name": "_feeToSetter", "type": "address" }],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "token0", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "token1", "type": "address" },
{ "indexed": false, "internalType": "address", "name": "pair", "type": "address" },
{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }
],
"name": "PairCreated",
"type": "event"
},
{
"constant": true,
"inputs": [],
"name": "INIT_CODE_HASH",
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"name": "allPairs",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "allPairsLength",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{ "internalType": "address", "name": "tokenA", "type": "address" },
{ "internalType": "address", "name": "tokenB", "type": "address" }
],
"name": "createPair",
"outputs": [{ "internalType": "address", "name": "pair", "type": "address" }],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "feeTo",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "feeToSetter",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{ "internalType": "address", "name": "", "type": "address" },
{ "internalType": "address", "name": "", "type": "address" }
],
"name": "getPair",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{ "internalType": "address", "name": "_pair", "type": "address" },
{ "internalType": "uint8", "name": "_devFee", "type": "uint8" }
],
"name": "setDevFee",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [{ "internalType": "address", "name": "_feeTo", "type": "address" }],
"name": "setFeeTo",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [{ "internalType": "address", "name": "_feeToSetter", "type": "address" }],
"name": "setFeeToSetter",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{ "internalType": "address", "name": "_pair", "type": "address" },
{ "internalType": "uint32", "name": "_swapFee", "type": "uint32" }
],
"name": "setSwapFee",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
]
Loading

0 comments on commit b91d797

Please sign in to comment.