From cdff27f3a02a5cf2ca4ea192823f926f2dd0ecac Mon Sep 17 00:00:00 2001 From: MirthFutures Date: Wed, 27 Mar 2024 11:08:36 -0400 Subject: [PATCH] Add Fraxtal --- .../address-book/fraxtal/index.ts | 15 +++++++++++ .../fraxtal/platforms/beefyfinance.ts | 20 +++++++++++++++ .../address-book/fraxtal/tokens/tokens.ts | 25 +++++++++++++++++++ packages/address-book/address-book/index.ts | 6 +++++ packages/address-book/types/chainid.ts | 1 + packages/address-book/util/chainIdMap.ts | 1 + src/api/rpc/chains.ts | 25 +++++++++++++++++++ src/api/rpc/rpcs.ts | 1 + src/api/zap/swap/blocked-tokens.ts | 1 + src/constants.ts | 9 +++++++ src/utils/ethersHelpers.ts | 8 ++++++ src/utils/fetchAmmPrices.js | 1 + src/utils/web3.js | 3 +++ src/utils/web3Helpers.ts | 9 +++++++ 14 files changed, 125 insertions(+) create mode 100644 packages/address-book/address-book/fraxtal/index.ts create mode 100644 packages/address-book/address-book/fraxtal/platforms/beefyfinance.ts create mode 100644 packages/address-book/address-book/fraxtal/tokens/tokens.ts diff --git a/packages/address-book/address-book/fraxtal/index.ts b/packages/address-book/address-book/fraxtal/index.ts new file mode 100644 index 000000000..0dd897878 --- /dev/null +++ b/packages/address-book/address-book/fraxtal/index.ts @@ -0,0 +1,15 @@ +import { beefyfinance } from './platforms/beefyfinance'; +import { tokens } from './tokens/tokens'; +import { convertSymbolTokenMapToAddressTokenMap } from '../../util/convertSymbolTokenMapToAddressTokenMap'; +import Chain from '../../types/chain'; +import { ConstInterface } from '../../types/const'; + +const _fraxtal = { + platforms: { + beefyfinance, + }, + tokens, + tokenAddressMap: convertSymbolTokenMapToAddressTokenMap(tokens), +} as const; + +export const fraxtal: ConstInterface = _fraxtal; diff --git a/packages/address-book/address-book/fraxtal/platforms/beefyfinance.ts b/packages/address-book/address-book/fraxtal/platforms/beefyfinance.ts new file mode 100644 index 000000000..040a3916a --- /dev/null +++ b/packages/address-book/address-book/fraxtal/platforms/beefyfinance.ts @@ -0,0 +1,20 @@ +const devMultisig = '0x6eA680acb92497F6dbe64d93d8a00a6d20106616'; +const treasuryMultisig = '0x944819832B287bFb85BB94a163480516a33E819d'; + +export const beefyfinance = { + devMultisig: devMultisig, + treasuryMultisig: treasuryMultisig, + strategyOwner: '0x73F97432Adb2a1c39d0E1a6e554c7d4BbDaFC316', + vaultOwner: '0xC35a456138dE0634357eb47Ba5E74AFE9faE9a98', + keeper: '0x4fED5491693007f0CD49f4614FFC38Ab6A04B619', + treasurer: treasuryMultisig, + launchpoolOwner: devMultisig, + rewardPool: '0x0000000000000000000000000000000000000000', + treasury: treasuryMultisig, + beefyFeeRecipient: '0x02Ae4716B9D5d48Db1445814b0eDE39f5c28264B', + multicall: '0x2840463Ea288c26B66E24f92E8C704e1aB6b095c', + bifiMaxiStrategy: '0x0000000000000000000000000000000000000000', // Not used + voter: '0x5e1caC103F943Cd84A1E92dAde4145664ebf692A', + beefyFeeConfig: '0xfc69704cC3cAac545cC7577009Ea4AA04F1a61Eb', + vaultFactory: '0x91BB303E972995EbE5f593BCddBb6F5Ef49Dbcbd', // todo +} as const; diff --git a/packages/address-book/address-book/fraxtal/tokens/tokens.ts b/packages/address-book/address-book/fraxtal/tokens/tokens.ts new file mode 100644 index 000000000..a3eda05cb --- /dev/null +++ b/packages/address-book/address-book/fraxtal/tokens/tokens.ts @@ -0,0 +1,25 @@ +import { ConstRecord } from '../../../types/const'; +import Token from '../../../types/token'; + +const frxETH = { + name: 'Frax Wrapped Ether', + address: '0xFC00000000000000000000000000000000000006', + symbol: 'frxETH', + oracleId: 'frxETH', + decimals: 18, + chainId: 252, + website: 'https://app.frax.finance/frxeth/mint', + description: + 'frxETH acts as a stablecoin loosely pegged to ETH, so that 1 frxETH always represents 1 ETH and the amount of frxETH in circulation matches the amount of ETH in the Frax ETH system. When ETH is sent to the frxETHMinter, an equivalent amount of frxETH is minted. Holding frxETH on its own is not eligible for staking yield and should be thought of as analogous as holding ETH.', + bridge: 'fraxtal-canonical', + logoURI: '', + documentation: 'https://docs.frax.finance/frax-ether/frxeth-and-sfrxeth', +} as const; + +const _tokens = { + frxETH, + wfrxETH: frxETH, + WNATIVE: frxETH, +} as const; + +export const tokens: ConstRecord = _tokens; diff --git a/packages/address-book/address-book/index.ts b/packages/address-book/address-book/index.ts index b987adf97..951bc765e 100644 --- a/packages/address-book/address-book/index.ts +++ b/packages/address-book/address-book/index.ts @@ -23,6 +23,8 @@ import { base } from './base'; import { gnosis } from './gnosis'; import { linea } from './linea'; import { mantle } from './mantle'; +import { fraxtal } from './fraxtal'; + import Chain from '../types/chain'; import { ChainId } from '../types/chainid'; import { ConstRecord } from '../types/const'; @@ -55,6 +57,7 @@ const _addressBook: { readonly gnosis: Chain; readonly linea: Chain; readonly mantle: Chain; + readonly fraxtal: Chain; } = { polygon, bsc, @@ -81,6 +84,7 @@ const _addressBook: { gnosis, linea, mantle, + fraxtal, } as const; const _addressBookByChainId: { @@ -109,6 +113,7 @@ const _addressBookByChainId: { readonly '100': Chain; readonly '59144': Chain; readonly '5000': Chain; + readonly '252': Chain; } = { [ChainId.polygon]: polygon, [ChainId.bsc]: bsc, @@ -135,6 +140,7 @@ const _addressBookByChainId: { [ChainId.gnosis]: gnosis, [ChainId.linea]: linea, [ChainId.mantle]: mantle, + [ChainId.fraxtal]: fraxtal, } as const; export const addressBook: ConstRecord = _addressBook; diff --git a/packages/address-book/types/chainid.ts b/packages/address-book/types/chainid.ts index 6fc0e6ecc..4109157d1 100644 --- a/packages/address-book/types/chainid.ts +++ b/packages/address-book/types/chainid.ts @@ -24,4 +24,5 @@ export enum ChainId { gnosis = 100, linea = 59144, mantle = 5000, + fraxtal = 252, } diff --git a/packages/address-book/util/chainIdMap.ts b/packages/address-book/util/chainIdMap.ts index fe32ed9ce..e763c4111 100644 --- a/packages/address-book/util/chainIdMap.ts +++ b/packages/address-book/util/chainIdMap.ts @@ -24,6 +24,7 @@ const chainIdMap = { gnosis: 100, linea: 59144, mantle: 5000, + fraxtal: 252, }; export default chainIdMap; diff --git a/src/api/rpc/chains.ts b/src/api/rpc/chains.ts index e48037b84..43692dd18 100644 --- a/src/api/rpc/chains.ts +++ b/src/api/rpc/chains.ts @@ -25,6 +25,7 @@ import { GNOSIS_RPC, LINEA_RPC, MANTLE_RPC, + FRAXTAL_RPC, } from '../../constants'; import { ChainId } from '../../../packages/address-book/address-book'; @@ -644,6 +645,29 @@ const mantleChain = { }, } as const satisfies Chain; +const fraxtalChain = { + id: 252, + name: 'Fraxtal', + network: 'fraxtal', + nativeCurrency: { + decimals: 18, + name: 'Frax Staked Ether', + symbol: 'frxETH', + }, + rpcUrls: { + public: { http: [FRAXTAL_RPC] }, + default: { http: [FRAXTAL_RPC] }, + }, + blockExplorers: { + default: { name: 'Fraxtal Explorer', url: 'https://fraxscan.com/' }, + }, + contracts: { + multicall3: { + address: '0xca11bde05977b3631167028862be2a173976ca11', + }, + }, +} as const satisfies Chain; + //build a map from chainId to chain object export const getChain: Partial> = { [ChainId.avax]: avalancheChain, @@ -671,4 +695,5 @@ export const getChain: Partial> = { [ChainId.gnosis]: gnosisChain, [ChainId.linea]: lineaChain, [ChainId.mantle]: mantleChain, + [ChainId.fraxtal]: fraxtalChain, } as const; diff --git a/src/api/rpc/rpcs.ts b/src/api/rpc/rpcs.ts index 557a84b7d..fc6314052 100644 --- a/src/api/rpc/rpcs.ts +++ b/src/api/rpc/rpcs.ts @@ -249,6 +249,7 @@ const rpcs: Record = { 'https://rpc.ankr.com/mantle', 'https://1rpc.io/mantle', ], + [ChainId.fraxtal]: ['https://rpc.frax.com'], }; export const getChainRpcs = (chainId: ChainId): string[] => rpcs[chainId] ?? []; diff --git a/src/api/zap/swap/blocked-tokens.ts b/src/api/zap/swap/blocked-tokens.ts index 1e63dc278..378306f5c 100644 --- a/src/api/zap/swap/blocked-tokens.ts +++ b/src/api/zap/swap/blocked-tokens.ts @@ -604,4 +604,5 @@ export const blockedTokensByChain: Record> = { gnosis: new Set([]), linea: new Set([]), mantle: new Set([]), + fraxtal: new Set([]), }; diff --git a/src/constants.ts b/src/constants.ts index ac702036b..c02e1898c 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -64,6 +64,7 @@ const BASE_RPC = process.env.BASE_RPC || 'https://mainnet.base.org'; const GNOSIS_RPC = process.env.GNOSIS_RPC || 'https://gnosis.publicnode.com'; const LINEA_RPC = process.env.LINEA_RPC || 'https://rpc.linea.build'; const MANTLE_RPC = process.env.MANTLE_RPC || 'https://rpc.mantle.xyz'; +const FRAXTAL_RPC = process.env.FRAXTAL_RPC || 'https://rpc.frax.com'; const BSC_CHAIN_ID = ChainId.bsc; const HECO_CHAIN_ID = ChainId.heco; @@ -90,6 +91,7 @@ const BASE_CHAIN_ID = ChainId.base; const GNOSIS_CHAIN_ID = ChainId.gnosis; const LINEA_CHAIN_ID = ChainId.linea; const MANTLE_CHAIN_ID = ChainId.mantle; +const FRAXTAL_CHAIN_ID = ChainId.fraxtal; const DFYN_LPF = 0.003; const SUSHI_LPF = 0.003; @@ -137,6 +139,7 @@ const MULTICHAIN_RPC: Record = { [ChainId.gnosis]: GNOSIS_RPC, [ChainId.linea]: LINEA_RPC, [ChainId.mantle]: MANTLE_RPC, + [ChainId.fraxtal]: FRAXTAL_RPC, }; const BSC_VAULTS_ENDPOINT = @@ -189,6 +192,8 @@ const LINEA_VAULTS_ENDPOINT = 'https://raw.githubusercontent.com/beefyfinance/beefy-v2/prod/src/config/vault/linea.json'; const MANTLE_VAULTS_ENDPOINT = 'https://raw.githubusercontent.com/beefyfinance/beefy-v2/prod/src/config/vault/mantle.json'; +const FRAXTAL_VAULTS_ENDPOINT = + 'https://raw.githubusercontent.com/beefyfinance/beefy-v2/prod/src/config/vault/fraxtal.json'; const MULTICHAIN_ENDPOINTS: Partial> = { bsc: BSC_VAULTS_ENDPOINT, @@ -216,6 +221,7 @@ const MULTICHAIN_ENDPOINTS: Partial> = { gnosis: GNOSIS_VAULTS_ENDPOINT, linea: LINEA_VAULTS_ENDPOINT, mantle: MANTLE_VAULTS_ENDPOINT, + fraxtal: FRAXTAL_VAULTS_ENDPOINT, } as const; const EXCLUDED_IDS_FROM_TVL = ['venus-wbnb']; @@ -298,6 +304,9 @@ export { MANTLE_RPC, MANTLE_CHAIN_ID, MANTLE_VAULTS_ENDPOINT, + FRAXTAL_RPC, + FRAXTAL_CHAIN_ID, + //FRAXTAL_VAULTS_ENDPOINT, BASE_HPY, MINUTELY_HPY, HOURLY_HPY, diff --git a/src/utils/ethersHelpers.ts b/src/utils/ethersHelpers.ts index 7abcdaac4..3a130e76a 100644 --- a/src/utils/ethersHelpers.ts +++ b/src/utils/ethersHelpers.ts @@ -53,6 +53,8 @@ import { LINEA_CHAIN_ID, MANTLE_RPC, MANTLE_CHAIN_ID, + FRAXTAL_RPC, + FRAXTAL_CHAIN_ID, } from '../constants'; console.log(addressBookByChainId[ChainId.fantom].platforms.beefyfinance.multicall); @@ -82,6 +84,7 @@ const MULTICALLS: Record['multicall']> [ChainId.gnosis]: addressBookByChainId[ChainId.gnosis].platforms.beefyfinance.multicall, [ChainId.linea]: addressBookByChainId[ChainId.linea].platforms.beefyfinance.multicall, [ChainId.mantle]: addressBookByChainId[ChainId.mantle].platforms.beefyfinance.multicall, + [ChainId.fraxtal]: addressBookByChainId[ChainId.fraxtal].platforms.beefyfinance.multicall, }; const clients: Record = { @@ -110,6 +113,7 @@ const clients: Record gnosis: [], linea: [], mantle: [], + fraxtal: [], }; BSC_RPC_ENDPOINTS.forEach(endpoint => { clients.bsc.push(new ethers.providers.JsonRpcProvider(endpoint)); @@ -138,6 +142,7 @@ clients.base.push(new ethers.providers.JsonRpcProvider(BASE_RPC)); clients.gnosis.push(new ethers.providers.JsonRpcProvider(GNOSIS_RPC)); clients.linea.push(new ethers.providers.JsonRpcProvider(LINEA_RPC)); clients.mantle.push(new ethers.providers.JsonRpcProvider(MANTLE_RPC)); +clients.fraxtal.push(new ethers.providers.JsonRpcProvider(FRAXTAL_RPC)); export const chainRandomClients = { bscRandomClient: () => clients.bsc[~~(clients.bsc.length * Math.random())], @@ -165,6 +170,7 @@ export const chainRandomClients = { gnosisRandomClient: () => clients.gnosis[~~(clients.gnosis.length * Math.random())], lineaRandomClient: () => clients.linea[~~(clients.linea.length * Math.random())], mantleRandomClient: () => clients.mantle[~~(clients.mantle.length * Math.random())], + fraxtalRandomClient: () => clients.fraxtal[~~(clients.fraxtal.length * Math.random())], }; export const _ethersFactory = (chainId: ChainId) => { @@ -219,6 +225,8 @@ export const _ethersFactory = (chainId: ChainId) => { return chainRandomClients.lineaRandomClient(); case MANTLE_CHAIN_ID: return chainRandomClients.mantleRandomClient(); + case FRAXTAL_CHAIN_ID: + return chainRandomClients.fraxtalRandomClient(); } }; diff --git a/src/utils/fetchAmmPrices.js b/src/utils/fetchAmmPrices.js index 311c41a14..84de3d004 100644 --- a/src/utils/fetchAmmPrices.js +++ b/src/utils/fetchAmmPrices.js @@ -30,6 +30,7 @@ const MULTICALLS = { 100: '0x07f1ad98b725Af45485646aC431b7757f50C598A', 59144: '0xe103ab2f922aa1a56EC058AbfDA2CeEa1e95bCd7', 5000: '0xee59DE6E749cc6cF6ebD30878D8B4222C4aea37C', + 252: '0x9C18deE5290925f596fbEfee2f6745b640f3A4C6', }; const BATCH_SIZE = 128; diff --git a/src/utils/web3.js b/src/utils/web3.js index c4bdc2152..eb2296dee 100644 --- a/src/utils/web3.js +++ b/src/utils/web3.js @@ -78,6 +78,9 @@ module.exports = { get mantleWeb3() { return chainRandomClients.mantleRandomClient(); }, + get fraxtalWeb3() { + return chainRandomClients.fraxtalRandomClient(); + }, web3Factory: _web3Factory, diff --git a/src/utils/web3Helpers.ts b/src/utils/web3Helpers.ts index c70a9c811..79fad8320 100644 --- a/src/utils/web3Helpers.ts +++ b/src/utils/web3Helpers.ts @@ -54,6 +54,8 @@ import { LINEA_CHAIN_ID, MANTLE_RPC, MANTLE_CHAIN_ID, + FRAXTAL_RPC, + FRAXTAL_CHAIN_ID, } from '../constants'; const MULTICALLS: Record['multicall']> = { @@ -82,6 +84,7 @@ const MULTICALLS: Record['multicall']> [ChainId.gnosis]: addressBookByChainId[ChainId.gnosis].platforms.beefyfinance.multicall, [ChainId.linea]: addressBookByChainId[ChainId.linea].platforms.beefyfinance.multicall, [ChainId.mantle]: addressBookByChainId[ChainId.mantle].platforms.beefyfinance.multicall, + [ChainId.fraxtal]: addressBookByChainId[ChainId.fraxtal].platforms.beefyfinance.multicall, }; export const MULTICALL_V3: Partial>> = { @@ -110,6 +113,7 @@ export const MULTICALL_V3: Partial>> = { [ChainId.gnosis]: '0xcA11bde05977b3631167028862bE2a173976CA11', [ChainId.linea]: '0xcA11bde05977b3631167028862bE2a173976CA11', [ChainId.mantle]: '0xcA11bde05977b3631167028862bE2a173976CA11', + [ChainId.fraxtal]: '0xcA11bde05977b3631167028862bE2a173976CA11', }; const clients: Record = { @@ -138,6 +142,7 @@ const clients: Record = { gnosis: [], linea: [], mantle: [], + fraxtal: [], }; BSC_RPC_ENDPOINTS.forEach(endpoint => { clients.bsc.push(new Web3(endpoint)); @@ -166,6 +171,7 @@ clients.base.push(new Web3(BASE_RPC)); clients.gnosis.push(new Web3(GNOSIS_RPC)); clients.linea.push(new Web3(LINEA_RPC)); clients.mantle.push(new Web3(MANTLE_RPC)); +clients.fraxtal.push(new Web3(FRAXTAL_RPC)); export const chainRandomClients = { bscRandomClient: () => clients.bsc[~~(clients.bsc.length * Math.random())], @@ -193,6 +199,7 @@ export const chainRandomClients = { gnosisRandomClient: () => clients.gnosis[~~(clients.gnosis.length * Math.random())], lineaRandomClient: () => clients.linea[~~(clients.linea.length * Math.random())], mantleRandomClient: () => clients.mantle[~~(clients.mantle.length * Math.random())], + fraxtalRandomClient: () => clients.fraxtal[~~(clients.fraxtal.length * Math.random())], }; export const _web3Factory = (chainId: ChainId) => { @@ -247,6 +254,8 @@ export const _web3Factory = (chainId: ChainId) => { return chainRandomClients.lineaRandomClient(); case MANTLE_CHAIN_ID: return chainRandomClients.mantleRandomClient(); + case FRAXTAL_CHAIN_ID: + return chainRandomClients.fraxtalRandomClient(); } };