synapsecns/sanguine

View on GitHub
packages/synapse-constants/src/constants/tokens/index.ts

Summary

Maintainability
D
1 day
Test Coverage
import _ from 'lodash'

import { Token } from '../../types/index'
import * as CHAINS from '../chains/master'
import * as all from './bridgeable'
import * as allPool from './poolMaster'
import { GMX, ETH, USDC, USDT, WETH } from './bridgeable'
import { SYN_ETH_SUSHI_TOKEN } from './sushiMaster'

const allSwap = [WETH, USDC, USDT]

export * from './bridgeable'
export * from './auxilliary'

// TODO change this to token by key
interface TokensByChain {
  [cID: string]: Token[]
}

interface TokenByKey {
  [cID: string]: Token
}

interface TokenMap {
  [chainId: string]: {
    [address: string]: Token
  }
}
export const sortTokens = (tokens: Token[]) =>
  Object.values(tokens).sort((a, b) => b.visibilityRank - a.visibilityRank)

const sortedTokens = Object.values(all).sort(
  (a, b) => b.visibilityRank - a.visibilityRank
)

// Key value pairs here will override bridgeMap to hide particular chain-token pairs
export const PAUSED_TOKENS_BY_CHAIN: { [key: string]: any } = {
  [CHAINS.ETH.id]: ['WETH'],
  [CHAINS.OPTIMISM.id]: ['WETH'],
  [CHAINS.BOBA.id]: ['WETH'],
  [CHAINS.MOONBEAM.id]: ['WETH'],
  [CHAINS.BASE.id]: ['WETH'],
  [CHAINS.ARBITRUM.id]: ['WETH'],
  [CHAINS.FANTOM.id]: [],
  [CHAINS.DOGE.id]: ['BUSD', 'WETH'],
  [CHAINS.KLAYTN.id]: ['WETH'],
}

export const findChainIdsWithPausedToken = (routeSymbol: string) => {
  return _.reduce(
    PAUSED_TOKENS_BY_CHAIN,
    (result, tokens, chainId) => {
      if (_.includes(tokens, routeSymbol)) {
        result.push(chainId as never)
      }
      return result
    },
    []
  )
}

export const getBridgeableTokens = (): TokensByChain => {
  const bridgeableTokens: TokensByChain = {}
  Object.entries(all).map(([key, token]) => {
    for (const cID of Object.keys(token.addresses)) {
      // Skip if the token is paused on the current chain
      if (PAUSED_TOKENS_BY_CHAIN[cID]?.includes(key)) {
        continue
      }

      if (!bridgeableTokens[cID]) {
        bridgeableTokens[cID] = [token]
      } else {
        if (!bridgeableTokens[cID]?.includes(token)) {
          bridgeableTokens[cID] = [...bridgeableTokens[cID], token]
        }
      }
    }
  })
  return bridgeableTokens
}

const getTokenHashMap = () => {
  const tokenHashMap: TokenMap = {}

  for (const [chainId, tokensOnChain] of _.toPairs(BRIDGABLE_TOKENS) as [
    any,
    any
  ][]) {
    for (const token of tokensOnChain) {
      tokenHashMap[chainId] = tokenHashMap[chainId] || {}
      tokenHashMap[chainId][token.addresses[chainId]] = token
    }
  }
  GMX.wrapperAddresses = GMX.wrapperAddresses as { [key: string]: any }
  if (GMX.wrapperAddresses) {
    tokenHashMap[CHAINS.AVALANCHE.id][
      GMX.wrapperAddresses[CHAINS.AVALANCHE.id]
    ] = GMX
  }
  Object.keys(WETH.addresses).map((chain: any) => {
    tokenHashMap[chain][WETH.addresses[chain]] = ETH
  })
  return tokenHashMap
}
export const TOKENS_SORTED_BY_SWAPABLETYPE = Array.from(
  new Set(sortedTokens.map((token) => token.swapableType))
)
export const TOKENS_SORTED_BY_SYMBOL = Array.from(
  new Set(sortedTokens.map((token) => token.symbol))
)
export const BRIDGABLE_TOKENS = getBridgeableTokens()

export const tokenSymbolToToken = (chainId: number, symbol: string) => {
  if (chainId) {
    if (symbol === 'ETH') {
      return ETH
    } else if (symbol === 'WETH') {
      return WETH
    } else if (symbol === 'USDC') {
      return USDC
    } else {
      const foundToken = BRIDGABLE_TOKENS[chainId]?.find(
        (token: Token) => token.symbol === symbol
      )
      return foundToken
    }
    return undefined
  }
}
export const tokenAddressToToken = (
  chainId: number,
  tokenAddress: string
): Token | undefined => {
  if (chainId) {
    if (tokenAddress === '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') {
      return ETH
    } else if (tokenAddress === WETH.addresses[chainId]) {
      return WETH
    } else {
      const foundToken = TOKEN_HASH_MAP[chainId][tokenAddress]
      return foundToken || undefined
    }
  }
}

export const TOKEN_HASH_MAP = getTokenHashMap()

// SWAPS
const allTokensWithSwap = [...Object.values(all), ...Object.values(allSwap)]

const getSwapPriorityRanking = () => {
  const swapPriorityRanking: { [key: string]: any } = {}
  allTokensWithSwap.map((token) => {
    if (!token.priorityPool) {
      return
    }
    for (const cID of Object.keys(token.addresses)) {
      if (!swapPriorityRanking[cID]) {
        swapPriorityRanking[cID] = {}
      }
      if (token.poolTokens) {
        for (const poolToken of token.poolTokens) {
          if (poolToken.symbol) {
            swapPriorityRanking[cID][poolToken.symbol] = token
          }
        }
      }
    }
  })
  return swapPriorityRanking
}
export const POOL_PRIORITY_RANKING = getSwapPriorityRanking()

// POOLS
const getPoolsByChain = (displayOnly: boolean): TokensByChain => {
  const poolTokens: TokensByChain = {}
  Object.values(allPool).map((token) => {
    if (displayOnly && !token.display) {
      return
    }
    for (const cID of Object.keys(token.addresses)) {
      if (!poolTokens[cID]) {
        poolTokens[cID] = [token]
      } else {
        if (!poolTokens[cID]?.includes(token)) {
          poolTokens[cID] = [...poolTokens[cID], token]
        }
      }
    }
  })
  return poolTokens
}

const getChainsByPoolName = () => {
  const CHAINS_BY_POOL_NAME: { [key: string]: any } = {}
  const poolsByChain = getPoolsByChain(false)
  Object.keys(poolsByChain).map((chainId) => {
    for (const swapToken of poolsByChain[chainId]) {
      if (swapToken.poolName) {
        CHAINS_BY_POOL_NAME[swapToken.poolName] = chainId
      }
    }
  })
  return CHAINS_BY_POOL_NAME
}

const getTokensByPoolTypeByChain = (type: string) => {
  const poolTokens: { [key: string]: any } = {}
  Object.values(allPool).map((token) => {
    if (!token.display || !token?.poolType?.includes(type)) {
      return
    }
    for (const cID of Object.keys(token.addresses)) {
      if (!poolTokens[cID]) {
        poolTokens[cID] = [token]
      } else {
        if (!poolTokens[cID]?.includes(token)) {
          poolTokens[cID] = [...poolTokens[cID], token]
        }
      }
    }
  })
  return poolTokens
}

const getLegacyTokensByChain = () => {
  const poolTokens: TokensByChain = {}
  Object.values(allPool).map((token) => {
    if (!token.legacy) {
      return
    }
    for (const cID of Object.keys(token.addresses)) {
      if (!poolTokens[cID]) {
        poolTokens[cID] = [token]
      } else {
        if (!poolTokens[cID]?.includes(token)) {
          poolTokens[cID] = [...poolTokens[cID], token]
        }
      }
    }
  })
  return poolTokens
}

const getPoolByRouterIndex = () => {
  const poolTokensByRouterIndex: TokenByKey = {}
  Object.values(allPool).map((token) => {
    if (token.routerIndex !== undefined) {
      poolTokensByRouterIndex[token.routerIndex] = token
    }
  })
  return poolTokensByRouterIndex
}

export const POOL_CHAINS_BY_NAME = getChainsByPoolName()
export const POOL_BY_ROUTER_INDEX = getPoolByRouterIndex()

export const POOLS_BY_CHAIN = getPoolsByChain(false)
export const DISPLAY_POOLS_BY_CHAIN = getPoolsByChain(true)
export const USD_POOLS_BY_CHAIN = getTokensByPoolTypeByChain('USD')
export const ETH_POOLS_BY_CHAIN = getTokensByPoolTypeByChain('ETH')
export const LEGACY_POOLS_BY_CHAIN = getLegacyTokensByChain()

interface StakableTokens {
  [chainId: string]: Token[]
}

export const STAKABLE_TOKENS: StakableTokens = {
  ...getPoolsByChain(false),
  [CHAINS.ETH.id]: [SYN_ETH_SUSHI_TOKEN],
}

const getStakingMap = () => {
  const stakingMap: { [key: string]: any } = {}
  Object.keys(POOLS_BY_CHAIN).map((chainId) => {
    if (!stakingMap[chainId]) {
      stakingMap[chainId] = {}
    }

    stakingMap[chainId] = {}
    for (const token of STAKABLE_TOKENS[chainId]) {
      if (token.poolName) {
        stakingMap[chainId][token.poolName] = token
      }
    }
  })
  return stakingMap
}
export const STAKING_MAP_TOKENS = getStakingMap()