{"version":3,"sources":["utils/formatBalance.ts","utils/provider.ts","tomb-finance/ERC20.ts","tomb-finance/TombFinance.ts","contexts/TombFinanceProvider/TombFinanceProvider.tsx","hooks/useTombFinance.ts","contexts/Banks/context.ts","contexts/Banks/Banks.tsx","contexts/Modals/Modals.tsx","contexts/RefreshContext/RefreshContextProvider.tsx","config.ts","state/application/actions.ts","utils/constants.ts","hooks/useNetworkPrompt.ts","state/transactions/reducer.ts","state/application/reducer.ts","state/index.ts","theme/colors.ts","theme/index.ts","newTheme.js","hooks/useIsWindowVisible.ts","state/application/updater.ts","hooks/useDebounce.ts","state/transactions/updater.tsx","state/Updaters.tsx","components/Loader/Loader.js","components/Loader/index.js","components/Popups/TransactionPopup.tsx","components/Popups/ErrorPopup.tsx","components/Popups/PopupItem.tsx","components/Popups/index.tsx","App.tsx","serviceWorker.js","index.tsx","state/transactions/actions.ts","state/application/hooks.ts","tomb-finance/config.ts","tomb-finance/ether-utils.ts"],"names":["getDisplayBalance","balance","decimals","fractionDigits","isTruncated","number","getBalance","ret","toFixed","length","slice","getFullDisplayBalance","Number","div","BigNumber","from","pow","provider","getDefaultProvider","ethers","providers","Web3Provider","web3ProviderFrom","config","defaultProvider","chainId","ERC20","constructor","address","symbol","decimal","contract","this","Contract","ABI","connect","signerOrProvider","estimateGas","totalSupply","balanceOf","account","transfer","recipient","amount","allowance","owner","spender","approve","transferFrom","sender","formatUnits","supply","inputs","internalType","name","type","stateMutability","anonymous","indexed","outputs","TombFinance","cfg","myAccount","signer","contracts","externalTokens","masonryVersionOfUser","TOMBWFTM_LP","TOMB","TSHARE","TBOND","WAVAX","FTM","DAI","MIM","deployments","deployment","Object","entries","abi","tomb","tShare","tBond","IUniswapV2PairABI","unlockWallet","newProvider","getSigner","tokens","values","token","console","log","fetchMasonryVersionOfUser","then","version","catch","err","error","stack","user","getNodes","poolName","pool","userInfo","users","total_claims","poolId","tierAmounts","TombFtmRewardPool","tombRewardPoolSupply","tombCirculatingSupply","sub","priceInFTM","getTokenPriceFromPancakeswap","priceOfOneFTM","getWFTMPriceFromPancakeswap","tokenInFtm","priceInDollars","circulatingSupply","lpToken","lpTokenSupplyBN","lpTokenSupply","token0","startsWith","isTomb","tokenAmountBN","tokenAmount","ftmAmountBN","ftmAmount","tokenAmountInOneLP","ftmAmountInOneLP","lpTokenPrice","getLPTokenPrice","lpTokenPriceFixed","toString","liquidity","priceOfOne","totalLiquidity","Treasury","tombStat","getTombStat","bondTombRatioBN","getBondPremiumRate","modifier","bondPriceInFTM","priceOfTBondInDollars","displayedTotalSupply","TombFtmLPTShareRewardPool","tShareCirculatingSupply","SeigniorageOracle","expectedPrice","twap","utils","parseEther","getTombUpdatedPrice","getBurnableTombLeft","bank","undefined","depositToken","poolContract","sectionInUI","depositTokenPrice","points","totalPoints","tierAmount","poolBalance","totalBalance","dripRate","dailyUserDrip","Promise","all","getDepositTokenPriceInDollars","depositTokenName","tierAllocPoints","totalAllocPoints","getBalancePool","getDayDripEstimate","stakeAmount","dailyDrip","mul","dailyDripAPR","yearlyDripAPR","dailyDripUser","yearlyDripUser","TVL","userDailyBurst","userYearlyBurst","dailyAPR","yearlyAPR","stakeInPool","stat","tokenPerSecond","earnTokenName","getShareStat","getTokenPerSecond","tokenPerHour","totalRewardPricePerYear","totalRewardPricePerDay","totalStakingTokenInPool","contractName","endsWith","rewardPerSecond","tombPerSecond","poolStartTime","startDateTime","Date","toNumber","FOUR_DAYS","now","getTime","epochTombPerSecond","tSharePerSecond","ready","fusdt_wftm_lp_pair","ftm_amount_BN","ftm_amount","fusdt_amount_BN","wavaxInDollars","getWAVAXPriceFromPancakeswap","CSHARE","CREAM","FUDGE","STRAW","tokenName","tokenPrice","priceOfOneFtmInDollars","priceOfOneAvaxInDollars","getAVAXPriceFromPancakeswap","priceOfOneCshareInDollars","getCSHAREPriceFromPancakeswap","priceOfOneCreamInDollars","getCREAMPriceFromPancakeswap","priceOfOneStrawInDollars","getSTRAWPriceFromPancakeswap","getLPV2TokenPrice","epoch","treasuryTombPrice","getTombPrice","buyBonds","decimalToBalance","priceForTomb","redeemBonds","totalValue","bankInfo","bankDefinitions","tokenAmountInPool","value","isNaN","TSHAREPrice","masonrytShareBalanceOf","currentMasonry","isFake","tokenSupply","priceOfToken","getTombStatFake","getShareStatFake","tokenInLP","fetch","res","json","usd","getFUDGEPriceFromPancakeswap","includes","getTotalRewards","pendingTOMB","pendingShare","total_deposits","deposit","create","withdraw","claim","Masonry","isOldMasonryMember","tokenContract","wftm","Token","wftmToToken","Fetcher","fetchPairData","Route","midPrice","WFTM","FUSDT","latestSnapshotIndex","lastRewardsReceived","masonryHistory","TOMBPrice","amountOfRewardsPerDay","canClaimReward","canWithdraw","stakedAmount","getStakedSharesOnMasonry","Error","stake","getShareOf","getCashEarningsOf","earned","claimDividends","claimReward","exit","nextEpochTimestamp","nextEpochPoint","nextAllocation","prevAllocation","to","currentEpoch","startTimeEpoch","masons","epochTimerStart","periodInHours","PERIOD","rewardLockupEpochs","targetEpochForClaimUnlock","fromDate","toDate","delta","moment","add","PeriodInHours","withdrawLockupEpochs","assetName","ethereum","window","networkVersion","asset","assetUrl","request","method","params","options","image","tombAmount","TaxOffice","overrides","parseUnits","addLiquidityETHTaxFree","SpookyRouter","_reserve0","_reserve1","getReserves","quote","treasuryDaoFundedFilter","filters","DaoFundFunded","treasuryDevFundedFilter","DevFundFunded","treasuryMasonryFundedFilter","MasonryFunded","boughtBondsFilter","BoughtBonds","redeemBondsFilter","RedeemedBonds","epochBlocksRanges","masonryFundEvents","queryFilter","events","forEach","index","push","masonryFund","args","startBlock","blockNumber","boughBonds","redeemedBonds","endBlock","async","bondsBought","getBondsWithFilterForPeriod","bondsRedeemed","devFund","daoFund","filter","lpName","zapper","estimate","FTM_TICKER","estimateZapIn","SPOOKY_ROUTER_ADDR","TOMB_TICKER","estimateZapInToken","zapIn","zapInToken","tbondAmount","TShareSwapper","swapTBondToTShare","estimateBN","estimateAmountOfTShare","tshareBalanceBN","getTShareBalance","tbondBalanceBN","getTBondBalance","rateTSharePerTombBN","getTShareAmountPerTomb","tshareBalance","tbondBalance","rateTSharePerTomb","Context","createContext","tombFinance","TombFinanceProvider","children","useWallet","setTombFinance","useState","useEffect","Provider","useTombFinance","useContext","context","banks","Banks","setBanks","isUnlocked","fetchPools","useCallback","finished","stakedBalanceOnBank","lte","earnToken","sort","a","b","onPresent","onDismiss","StyledModalWrapper","styled","StyledModalBackdrop","Modals","isOpen","setIsOpen","content","setContent","handlePresent","modalContent","handleDismiss","onClick","React","isValidElement","cloneElement","RefreshContext","slow","fast","RefreshContextProvider","setSlow","setFast","interval","setInterval","prev","clearInterval","configurations","production","ChainId","AVALANCHE","networkName","ftmscanUrl","require","SHIBA","BELUGA","BIFI","BLOOM","baseLaunchDate","bondLaunchesAt","masonryLaunchesAt","refreshInterval","FudgeDaiLPTShareRewardPool","multiplier","buyLink","site","closedForStaking","StrawAvaxLPTShareRewardPool","StrawDaiLPTShareRewardPool","FudgeStrawLPTShareRewardPool","FudgeLPTShareRewardPool","FudgeCreamLPTShareRewardPool","CreamStrawLPTShareRewardPool","CreamRewardPool","MasterNode","updateBlockNumber","createAction","toggleWalletModal","toggleSettingsMenu","addPopup","removePopup","TSHARE_TICKER","ZAPPER_ROUTER_ADDR","usePromptNetwork","networkPrompt","setNetworkPrompt","chainName","nativeCurrency","rpcUrls","blockExplorerUrls","connectToNetwork","createReducer","builder","addCase","addTransaction","transactions","payload","hash","approval","summary","txs","addedTime","clearAllTransactions","checkedTransaction","tx","lastCheckedBlockNumber","Math","max","finalizeTransaction","receipt","confirmedTime","popupList","walletModalOpen","settingsMenuOpen","state","action","key","removeAfterMs","popup","concat","nanoid","show","p","PERSISTED_KEYS","store","configureStore","reducer","application","middleware","getDefaultMiddleware","thunk","save","states","preloadedState","load","grey","100","200","300","400","500","600","700","800","900","theme","borderRadius","color","black","purple","primary","light","main","secondary","white","teal","siteWidth","spacing","1","2","3","4","5","6","7","topBarSize","newTheme","createMuiTheme","palette","text","background","default","paper","dark","contrastText","discord","disabledBackground","active","hover","typography","fontFamily","join","VISIBILITY_STATE_SUPPORTED","document","isWindowVisible","visibilityState","Updater","dispatch","useDispatch","windowVisible","focused","setFocused","listener","addEventListener","removeEventListener","useIsWindowVisible","setState","blockNumberCallback","getBlockNumber","on","removeListener","debouncedState","delay","debouncedValue","setDebouncedValue","handler","setTimeout","clearTimeout","useDebounce","lastBlockNumber","useBlockNumber","useSelector","useAddPopup","keys","blocksSinceCheck","minutesPending","shouldCheck","getTransactionReceipt","blockHash","contractAddress","status","transactionHash","transactionIndex","txn","success","Updaters","Loader","style","position","left","top","transform","Typography","RowNoFlex","TransactionPopup","ThemeContext","paddingRight","size","StyledPopupDesc","StyledLink","target","href","span","props","ErrorPopup","message","copyErrorDetails","navigator","clipboard","writeText","StyledClose","X","Popup","Fader","AnimatedFader","animated","PopupItem","popKey","useRemovePopup","removeThisPopup","timeout","popupContent","faderStyle","useSpring","width","duration","text2","MobilePopupWrapper","height","MobilePopupInner","FixedPopupColumn","Popups","activePopups","useActivePopups","map","item","reverse","Home","lazy","Farms","Boardroom","Bonds","NoMatch","Providers","connectors","walletconnect","rpcUrl","walletlink","url","appName","appLogoUrl","App","localStorage","version_app","clear","setItem","fallback","exact","path","component","Boolean","location","hostname","match","ReactDOM","render","StrictMode","getElementById","serviceWorker","registration","unregister","list","useMemo","defaultEthereumConfig","testing","autoGasMultiplier","defaultConfirmations","defaultGas","defaultGasPrice","ethereumNodeTimeout","endpoint","ethConfig","assign","Web3","WebsocketProvider","HttpProvider","d","String"],"mappings":"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","file":"static/js/main.93c03e48.chunk.js","sourcesContent":["import { BigNumber } from 'ethers';\n\nexport const getDisplayBalance = (\n balance: BigNumber,\n decimals = 18,\n fractionDigits = 4,\n isTruncated: boolean = false,\n) => {\n if (decimals === 0) {\n fractionDigits = 0;\n }\n const number = getBalance(balance, decimals - fractionDigits);\n const ret = (number / 10 ** fractionDigits).toFixed(fractionDigits);\n if (ret.length > 12 && isTruncated) {\n return ret.slice(0, 12) + '...';\n }\n return ret;\n};\n\nexport const getFullDisplayBalance = (balance: BigNumber, decimals = 18, isTruncated = false) => {\n return getDisplayBalance(balance, decimals, 4, isTruncated);\n};\n\nexport function getBalance(balance: BigNumber, decimals = 18): number {\n return Number(balance.div(BigNumber.from(10).pow(decimals)));\n}\n","import { ethers } from 'ethers';\nimport config from '../config';\nimport { web3ProviderFrom } from '../tomb-finance/ether-utils';\n\nlet provider: ethers.providers.Web3Provider = null;\n\nexport function getDefaultProvider(): ethers.providers.Web3Provider {\n if (!provider) {\n provider = new ethers.providers.Web3Provider(web3ProviderFrom(config.defaultProvider), config.chainId);\n }\n\n return provider;\n}","import { BigNumber, Contract } from 'ethers';\nimport { Signer } from '@ethersproject/abstract-signer';\nimport { Provider } from '@ethersproject/abstract-provider';\nimport { TransactionResponse } from '@ethersproject/providers';\nimport { formatUnits } from 'ethers/lib/utils';\n\nclass ERC20 {\n private contract: Contract;\n\n address: string;\n symbol: string;\n decimal: number;\n\n constructor(address: string, provider: Signer | Provider, symbol: string, decimal = 18) {\n this.contract = new Contract(address, ABI, provider);\n this.address = address;\n this.symbol = symbol;\n this.decimal = decimal;\n }\n\n connect(signerOrProvider: Signer | Provider) {\n this.contract = new Contract(this.address, ABI, signerOrProvider);\n }\n\n get estimateGas() {\n return this.contract.estimateGas;\n }\n\n totalSupply(): Promise {\n return this.contract.totalSupply();\n }\n\n balanceOf(account: string): Promise {\n return this.contract.balanceOf(account);\n }\n\n transfer(recipient: string, amount: BigNumber): Promise {\n return this.contract.transfer(recipient, amount);\n }\n\n allowance(owner: string, spender: string): Promise {\n return this.contract.allowance(owner, spender);\n }\n\n approve(spender: string, amount: BigNumber): Promise {\n return this.contract.approve(spender, amount);\n }\n\n transferFrom(sender: string, recipient: string, amount: BigNumber): Promise {\n return this.contract.transferFrom(sender, recipient, amount);\n }\n\n async displayedBalanceOf(account: string): Promise {\n const balance = await this.balanceOf(account);\n return formatUnits(balance, this.decimal);\n }\n\n async displayedTotalSupply(): Promise {\n const supply = await this.totalSupply();\n return Number(formatUnits(supply, this.decimal)).toFixed(0);\n }\n}\n\nexport default ERC20;\n\nconst ABI = [\n {\n inputs: [\n { internalType: 'string', name: 'name', type: 'string' },\n {\n internalType: 'string',\n name: 'symbol',\n type: 'string',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'constructor',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: 'address',\n name: 'owner',\n type: 'address',\n },\n {\n indexed: true,\n internalType: 'address',\n name: 'spender',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'value',\n type: 'uint256',\n },\n ],\n name: 'Approval',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: 'address',\n name: 'from',\n type: 'address',\n },\n {\n indexed: true,\n internalType: 'address',\n name: 'to',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'value',\n type: 'uint256',\n },\n ],\n name: 'Transfer',\n type: 'event',\n },\n {\n inputs: [],\n name: 'name',\n outputs: [\n {\n internalType: 'string',\n name: '',\n type: 'string',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'symbol',\n outputs: [\n {\n internalType: 'string',\n name: '',\n type: 'string',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'decimals',\n outputs: [\n {\n internalType: 'uint8',\n name: '',\n type: 'uint8',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'totalSupply',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'balanceOf',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'recipient',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n name: 'transfer',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'owner',\n type: 'address',\n },\n {\n internalType: 'address',\n name: 'spender',\n type: 'address',\n },\n ],\n name: 'allowance',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'spender',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n name: 'approve',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'sender',\n type: 'address',\n },\n {\n internalType: 'address',\n name: 'recipient',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n name: 'transferFrom',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'spender',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'addedValue',\n type: 'uint256',\n },\n ],\n name: 'increaseAllowance',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'spender',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'subtractedValue',\n type: 'uint256',\n },\n ],\n name: 'decreaseAllowance',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n];\n","// import { Fetcher, Route, Token } from '@uniswap/sdk';\n//import { Fetcher as FetcherSpirit, Token as TokenSpirit } from '@traderjoe-xyz/sdk';\nimport { Fetcher, Route, Token } from '@traderjoe-xyz/sdk';\nimport { Configuration } from './config';\nimport { ContractName, TokenStat, AllocationTime, LPStat, Bank, PoolStats, TShareSwapperStat } from './types';\nimport { BigNumber, Contract, ethers, EventFilter } from 'ethers';\nimport { decimalToBalance } from './ether-utils';\nimport { TransactionResponse } from '@ethersproject/providers';\nimport ERC20 from './ERC20';\nimport { getFullDisplayBalance, getDisplayBalance } from '../utils/formatBalance';\nimport { getDefaultProvider } from '../utils/provider';\nimport IUniswapV2PairABI from './IUniswapV2Pair.abi.json';\nimport config, { bankDefinitions } from '../config';\nimport moment from 'moment';\nimport { parseUnits } from 'ethers/lib/utils';\nimport { FTM_TICKER, SPOOKY_ROUTER_ADDR, TOMB_TICKER } from '../utils/constants';\n/**\n * An API module of 2omb Finance contracts.\n * All contract-interacting domain logic should be defined in here.\n */\nexport class TombFinance {\n myAccount: string;\n provider: ethers.providers.Web3Provider;\n signer?: ethers.Signer;\n config: Configuration;\n contracts: { [name: string]: Contract };\n externalTokens: { [name: string]: ERC20 };\n masonryVersionOfUser?: string;\n\n TOMBWFTM_LP: Contract;\n TOMB: ERC20;\n TSHARE: ERC20;\n TBOND: ERC20;\n WAVAX: ERC20;\n FTM: ERC20;\n DAI: ERC20;\n MIM: ERC20;\n\n\n constructor(cfg: Configuration) {\n const { deployments, externalTokens } = cfg;\n const provider = getDefaultProvider();\n\n // loads contracts from deployments\n this.contracts = {};\n for (const [name, deployment] of Object.entries(deployments)) {\n this.contracts[name] = new Contract(deployment.address, deployment.abi, provider);\n }\n this.externalTokens = {};\n for (const [symbol, [address, decimal]] of Object.entries(externalTokens)) {\n this.externalTokens[symbol] = new ERC20(address, provider, symbol, decimal);\n }\n this.TOMB = new ERC20(deployments.tomb.address, provider, 'FUDGE');\n this.TSHARE = new ERC20(deployments.tShare.address, provider, 'STRAW');\n this.TBOND = new ERC20(deployments.tBond.address, provider, 'CARAML');\n this.WAVAX = this.externalTokens['WAVAX'];\n this.DAI = this.externalTokens['DAI'];\n this.FTM = this.externalTokens['WFTM'];\n this.MIM = this.externalTokens['MIM']\n\n // Uniswap V2 Pair\n this.TOMBWFTM_LP = new Contract(externalTokens['FUDGE-DAI LP'][0], IUniswapV2PairABI, provider);\n\n this.config = cfg;\n this.provider = provider;\n }\n\n /**\n * @param provider From an unlocked wallet. (e.g. Metamask)\n * @param account An address of unlocked wallet account.\n */\n unlockWallet(provider: any, account: string) {\n const newProvider = new ethers.providers.Web3Provider(provider, this.config.chainId);\n this.signer = newProvider.getSigner(0);\n this.myAccount = account;\n for (const [name, contract] of Object.entries(this.contracts)) {\n this.contracts[name] = contract.connect(this.signer);\n }\n const tokens = [this.TOMB, this.TSHARE, this.TBOND, ...Object.values(this.externalTokens)];\n for (const token of tokens) {\n token.connect(this.signer);\n }\n this.TOMBWFTM_LP = this.TOMBWFTM_LP.connect(this.signer);\n console.log(`🔓 Wallet is unlocked. Welcome, ${account}!`);\n this.fetchMasonryVersionOfUser()\n .then((version) => (this.masonryVersionOfUser = version))\n .catch((err) => {\n console.error(`Failed to fetch masonry version: ${err.stack}`);\n this.masonryVersionOfUser = 'latest';\n });\n }\n\n get isUnlocked(): boolean {\n return !!this.myAccount;\n }\n //===================================================================\n //===================== GET NODE STATS =============================\n //=========================== START ===================================\n //===================================================================\n\n async getNodes(contract: string, user: string): Promise {\n return await this.contracts[contract].getNodes(user);\n }\n\n async claimedBalanceNode(poolName: ContractName, account = this.myAccount): Promise {\n const pool = this.contracts[poolName];\n try {\n let userInfo = await pool.users(account);\n return await userInfo.total_claims;\n } catch (err) {\n console.error(`Failed to call userInfo() on pool ${pool.address}: ${err}`);\n return BigNumber.from(0);\n }\n }\n\n async getNodePrice(poolName: ContractName, poolId: Number): Promise {\n const pool = this.contracts[poolName];\n try {\n return await pool.tierAmounts(poolId);\n } catch (err) {\n console.error(`Failed to call tierAmounts on contract ${pool.address}: ${err}`);\n return BigNumber.from(0);\n }\n }\n\n\n\n\n //===================================================================\n //===================== GET ASSET STATS =============================\n //===================FROM SPOOKY TO DISPLAY =========================\n //=========================IN HOME PAGE==============================\n //===================================================================\n\n async getTombStat(): Promise {\n const { TombFtmRewardPool } = this.contracts;\n const supply = await this.TOMB.totalSupply();\n const tombRewardPoolSupply = await this.TOMB.balanceOf(TombFtmRewardPool.address);\n // const tombRewardPoolSupplyOld = await this.TOMB.balanceOf(TombFtmLpTombRewardPoolOld.address);\n const tombCirculatingSupply = supply.sub(tombRewardPoolSupply);\n // .sub(tombRewardPoolSupplyOld);\n const priceInFTM = await this.getTokenPriceFromPancakeswap(this.TOMB);\n const priceOfOneFTM = await this.getWFTMPriceFromPancakeswap();\n const priceOfTombInDollars = (Number(priceInFTM) * Number(priceOfOneFTM)).toFixed(2);\n\n return {\n tokenInFtm: priceInFTM,\n priceInDollars: priceOfTombInDollars,\n totalSupply: getDisplayBalance(supply, this.TOMB.decimal, 0),\n circulatingSupply: getDisplayBalance(tombCirculatingSupply, this.TOMB.decimal, 0),\n };\n }\n\n /**\n * Calculates various stats for the requested LP\n * @param name of the LP token to load stats for\n * @returns\n */\n async getLPStat(name: string): Promise {\n const lpToken = this.externalTokens[name];\n const lpTokenSupplyBN = await lpToken.totalSupply();\n const lpTokenSupply = getDisplayBalance(lpTokenSupplyBN, 18);\n const token0 = name.startsWith('FUDGE') ? this.TOMB : this.TSHARE;\n const isTomb = name.startsWith('FUDGE');\n const tokenAmountBN = await token0.balanceOf(lpToken.address);\n const tokenAmount = getDisplayBalance(tokenAmountBN, 18);\n\n const ftmAmountBN = await this.FTM.balanceOf(lpToken.address);\n const ftmAmount = getDisplayBalance(ftmAmountBN, 18);\n const tokenAmountInOneLP = Number(tokenAmount) / Number(lpTokenSupply);\n const ftmAmountInOneLP = Number(ftmAmount) / Number(lpTokenSupply);\n const lpTokenPrice = await this.getLPTokenPrice(lpToken, token0, isTomb, false);\n const lpTokenPriceFixed = Number(lpTokenPrice).toFixed(2).toString();\n const liquidity = (Number(lpTokenSupply) * Number(lpTokenPrice)).toFixed(2).toString();\n return {\n tokenAmount: tokenAmountInOneLP.toFixed(2).toString(),\n ftmAmount: ftmAmountInOneLP.toFixed(2).toString(),\n priceOfOne: lpTokenPriceFixed,\n totalLiquidity: liquidity,\n totalSupply: Number(lpTokenSupply).toFixed(2).toString(),\n };\n }\n\n /**\n * Use this method to get price for Tomb\n * @returns TokenStat for TBOND\n * priceInFTM\n * priceInDollars\n * TotalSupply\n * CirculatingSupply (always equal to total supply for bonds)\n */\n async getBondStat(): Promise {\n const { Treasury } = this.contracts;\n const tombStat = await this.getTombStat();\n const bondTombRatioBN = await Treasury.getBondPremiumRate();\n const modifier = bondTombRatioBN / 1e18 > 1 ? bondTombRatioBN / 1e18 : 1;\n const bondPriceInFTM = (Number(tombStat.tokenInFtm)).toFixed(2);\n const priceOfTBondInDollars = (Number(tombStat.priceInDollars)* modifier).toFixed(2);\n const supply = await this.TBOND.displayedTotalSupply();\n return {\n tokenInFtm: bondPriceInFTM,\n priceInDollars: priceOfTBondInDollars,\n totalSupply: supply,\n circulatingSupply: supply,\n };\n }\n\n /**\n * @returns TokenStat for TSHARE\n * priceInFTM\n * priceInDollars\n * TotalSupply\n * CirculatingSupply (always equal to total supply for bonds)\n */\n async getShareStat(): Promise {\n const { TombFtmLPTShareRewardPool } = this.contracts;\n\n const supply = await this.TSHARE.totalSupply();\n\n const priceInFTM = await this.getTokenPriceFromPancakeswap(this.TSHARE);\n const tombRewardPoolSupply = await this.TSHARE.balanceOf(TombFtmLPTShareRewardPool.address);\n const tShareCirculatingSupply = supply.sub(tombRewardPoolSupply);\n const priceOfOneFTM = await this.getWFTMPriceFromPancakeswap();\n const priceOfSharesInDollars = (Number(priceInFTM) * Number(priceOfOneFTM)).toFixed(2);\n\n return {\n tokenInFtm: priceInFTM,\n priceInDollars: priceOfSharesInDollars,\n totalSupply: getDisplayBalance(supply, this.TSHARE.decimal, 0),\n circulatingSupply: getDisplayBalance(tShareCirculatingSupply, this.TSHARE.decimal, 0),\n };\n }\n\n async getTombStatInEstimatedTWAP(): Promise {\n const { SeigniorageOracle, TombFtmRewardPool } = this.contracts;\n const expectedPrice = await SeigniorageOracle.twap(this.TOMB.address, ethers.utils.parseEther('1'));\n console.log(expectedPrice)\n const supply = await this.TOMB.totalSupply();\n const tombRewardPoolSupply = await this.TOMB.balanceOf(TombFtmRewardPool.address);\n const tombCirculatingSupply = supply.sub(tombRewardPoolSupply);\n return {\n tokenInFtm: getDisplayBalance(expectedPrice),\n priceInDollars: getDisplayBalance(expectedPrice),\n totalSupply: getDisplayBalance(supply, this.TOMB.decimal, 0),\n circulatingSupply: getDisplayBalance(tombCirculatingSupply, this.TOMB.decimal, 0),\n };\n }\n\n async getTombPriceInLastTWAP(): Promise {\n const { Treasury } = this.contracts;\n return Treasury.getTombUpdatedPrice();\n }\n\n async getBondsPurchasable(): Promise {\n const { Treasury } = this.contracts;\n return Treasury.getBurnableTombLeft();\n }\n\n /**\n * Calculates the TVL, APR and daily APR of a provided pool/bank\n * @param bank\n * @returns\n */\n async getPoolAPRs(bank: Bank): Promise {\n if (this.myAccount === undefined) return;\n const depositToken = bank.depositToken;\n const poolContract = this.contracts[bank.contract];\n\n if (bank.sectionInUI === 3) {\n const [depositTokenPrice, points, totalPoints, tierAmount, poolBalance, totalBalance, dripRate, dailyUserDrip] = await Promise.all([\n this.getDepositTokenPriceInDollars(bank.depositTokenName, depositToken),\n poolContract.tierAllocPoints(bank.poolId),\n poolContract.totalAllocPoints(),\n poolContract.tierAmounts(bank.poolId),\n poolContract.getBalancePool(),\n depositToken.balanceOf(bank.address),\n poolContract.dripRate(),\n poolContract.getDayDripEstimate(this.myAccount),\n ]);\n const stakeAmount = Number(getDisplayBalance(tierAmount))\n\n\n const dailyDrip = totalPoints && +totalPoints > 0\n ? getDisplayBalance(poolBalance.mul(BigNumber.from(86400)).mul(points).div(totalPoints).div(dripRate))\n : 0;\n const dailyDripAPR = (Number(dailyDrip) / stakeAmount) * 100;\n const yearlyDripAPR = (Number(dailyDrip) * 365 / stakeAmount) * 100;\n\n const dailyDripUser = Number(getDisplayBalance(dailyUserDrip));\n const yearlyDripUser = Number(dailyDripUser) * 365;\n\n const TVL = Number(depositTokenPrice) * Number(getDisplayBalance(totalBalance, depositToken.decimal));\n\n return {\n userDailyBurst: dailyDripUser.toFixed(2).toString(),\n userYearlyBurst: yearlyDripUser.toFixed(2).toString(),\n dailyAPR: dailyDripAPR.toFixed(2).toString(),\n yearlyAPR: yearlyDripAPR.toFixed(2).toString(),\n TVL: TVL.toFixed(2).toString(),\n };\n } else {\n const [depositTokenPrice, stakeInPool, stat, tokenPerSecond] = await Promise.all([\n this.getDepositTokenPriceInDollars(bank.depositTokenName, depositToken),\n depositToken.balanceOf(bank.address),\n bank.earnTokenName === 'FUDGE' ? this.getTombStat() : this.getShareStat(),\n this.getTokenPerSecond(\n bank.earnTokenName,\n bank.contract,\n poolContract,\n bank.depositTokenName,\n )\n ]);\n\n const TVL = Number(depositTokenPrice) * Number(getDisplayBalance(stakeInPool, depositToken.decimal));\n\n const tokenPerHour = tokenPerSecond.mul(60).mul(60);\n const totalRewardPricePerYear =\n Number(stat.priceInDollars) * Number(getDisplayBalance(tokenPerHour.mul(24).mul(365)));\n const totalRewardPricePerDay = Number(stat.priceInDollars) * Number(getDisplayBalance(tokenPerHour.mul(24)));\n const totalStakingTokenInPool =\n Number(depositTokenPrice) * Number(getDisplayBalance(stakeInPool, depositToken.decimal));\n const dailyAPR = (totalRewardPricePerDay / totalStakingTokenInPool) * 100;\n const yearlyAPR = (totalRewardPricePerYear / totalStakingTokenInPool) * 100;\n return {\n dailyAPR: dailyAPR.toFixed(2).toString(),\n yearlyAPR: yearlyAPR.toFixed(2).toString(),\n TVL: TVL.toFixed(2).toString(),\n };\n }\n }\n\n /**\n * Method to return the amount of tokens the pool yields per second\n * @param earnTokenName the name of the token that the pool is earning\n * @param contractName the contract of the pool/bank\n * @param poolContract the actual contract of the pool\n * @returns\n */\n async getTokenPerSecond(\n earnTokenName: string,\n contractName: string,\n poolContract: Contract,\n depositTokenName: string,\n ) {\n if (earnTokenName === 'FUDGE') {\n if (!contractName.endsWith('TombRewardPool')) {\n const rewardPerSecond = await poolContract.tombPerSecond();\n if (depositTokenName === 'CSHARE') {\n return rewardPerSecond.mul(0).div(2000).div(24);\n } else if (depositTokenName === 'CREAM') {\n return rewardPerSecond.mul(0).div(2000).div(24);\n } else if (depositTokenName === 'WAVAX') {\n return rewardPerSecond.mul(0).div(2000).div(24);\n } else if (depositTokenName === 'DAI') {\n return rewardPerSecond.mul(0).div(2000).div(24);\n } else if (depositTokenName === 'CREAM-AVAX LP') {\n return rewardPerSecond.mul(0).div(2000).div(24);\n } else if (depositTokenName === 'CSHARE-AVAX LP') {\n return rewardPerSecond.mul(0).div(2000).div(24);\n } else if (depositTokenName === 'FUDGE-DAI LP') {\n return rewardPerSecond.mul(0).div(2000).div(24);\n }\n return rewardPerSecond.div(24);\n }\n const poolStartTime = await poolContract.poolStartTime();\n const startDateTime = new Date(poolStartTime.toNumber() * 1000);\n const FOUR_DAYS = 4 * 24 * 60 * 60 * 1000;\n if (Date.now() - startDateTime.getTime() > FOUR_DAYS) {\n return await poolContract.epochTombPerSecond(1);\n }\n return await poolContract.epochTombPerSecond(0);\n }\n const rewardPerSecond = await poolContract.tSharePerSecond();\n if (depositTokenName === 'FUDGE') {\n return rewardPerSecond.mul(2000).div(55000);\n } else if (depositTokenName === 'FUDGE-STRAW LP') {\n return rewardPerSecond.mul(0).div(55000);\n } else if (depositTokenName === 'STRAW-DAI LP') {\n return rewardPerSecond.mul(23375).div(55000);\n } else if (depositTokenName === 'STRAW-AVAX LP') {\n return rewardPerSecond.mul(0).div(55000);\n } else if (depositTokenName === 'CREAM-STRAW LP') {\n return rewardPerSecond.mul(0).div(55000);\n } else if (depositTokenName === 'FUDGE-DAI LP') {\n return rewardPerSecond.mul(29625).div(55000);\n } else {\n return rewardPerSecond.mul(0).div(55000);\n }\n }\n async getAVAXPriceFromPancakeswap(): Promise {\n //not here\n const ready = await this.provider.ready;\n if (!ready) return;\n const { WAVAX, MIM } = this.externalTokens;\n try {\n const fusdt_wftm_lp_pair = this.externalTokens['MIM-WAVAX-LP'];\n let ftm_amount_BN = await WAVAX.balanceOf(fusdt_wftm_lp_pair.address);\n let ftm_amount = Number(getFullDisplayBalance(ftm_amount_BN, WAVAX.decimal));\n let fusdt_amount_BN = await MIM.balanceOf(fusdt_wftm_lp_pair.address);\n let fusdt_amount = Number(getFullDisplayBalance(fusdt_amount_BN, MIM.decimal));\n return (fusdt_amount / ftm_amount).toString();\n } catch (err) {\n console.error(`Failed to fetch token price of AVAX: ${err}`);\n }\n }\n async getWAVAXPriceFromPancakeswap(): Promise {\n //not here\n const ready = await this.provider.ready;\n if (!ready) return;\n const { WAVAX, MIM } = this.externalTokens;\n try {\n const fusdt_wftm_lp_pair = this.externalTokens['MIM-WAVAX-LP'];\n let ftm_amount_BN = await WAVAX.balanceOf(fusdt_wftm_lp_pair.address);\n let ftm_amount = Number(getFullDisplayBalance(ftm_amount_BN, WAVAX.decimal));\n let fusdt_amount_BN = await MIM.balanceOf(fusdt_wftm_lp_pair.address);\n let fusdt_amount = Number(getFullDisplayBalance(fusdt_amount_BN, MIM.decimal));\n return (fusdt_amount / ftm_amount).toString();\n } catch (err) {\n console.error(`Failed to fetch token price of AVAX: ${err}`);\n }\n }\n\n\n async getCSHAREPriceFromPancakeswap(): Promise {\n //not here\n const ready = await this.provider.ready;\n const wavaxInDollars = await this.getWAVAXPriceFromPancakeswap();\n if (!ready) return;\n const { WAVAX, CSHARE } = this.externalTokens;\n try {\n const fusdt_wftm_lp_pair = this.externalTokens['CSHARE-AVAX LP'];\n let ftm_amount_BN = await WAVAX.balanceOf(fusdt_wftm_lp_pair.address);\n let ftm_amount = Number(getFullDisplayBalance(ftm_amount_BN, WAVAX.decimal));\n let fusdt_amount_BN = await CSHARE.balanceOf(fusdt_wftm_lp_pair.address);\n let fusdt_amount = Number(getFullDisplayBalance(fusdt_amount_BN, CSHARE.decimal));\n let cshare_price = (ftm_amount / fusdt_amount) * Number(wavaxInDollars);\n return cshare_price.toString();\n\n } catch (err) {\n console.error(`Failed to fetch token price of AVAX: ${err}`);\n }\n }\n\n\n async getCREAMPriceFromPancakeswap(): Promise {\n //not here\n const ready = await this.provider.ready;\n const wavaxInDollars = await this.getWAVAXPriceFromPancakeswap();\n if (!ready) return;\n const { WAVAX, CREAM } = this.externalTokens;\n try {\n const fusdt_wftm_lp_pair = this.externalTokens['CREAM-AVAX LP'];\n let ftm_amount_BN = await WAVAX.balanceOf(fusdt_wftm_lp_pair.address);\n let ftm_amount = Number(getFullDisplayBalance(ftm_amount_BN, WAVAX.decimal));\n let fusdt_amount_BN = await CREAM.balanceOf(fusdt_wftm_lp_pair.address);\n let fusdt_amount = Number(getFullDisplayBalance(fusdt_amount_BN, CREAM.decimal));\n let cream_price = (ftm_amount / fusdt_amount) * Number(wavaxInDollars);\n return cream_price.toString();\n\n } catch (err) {\n console.error(`Failed to fetch token price of AVAX: ${err}`);\n }\n }\n\n async getFUDGEPriceFromPancakeswap(): Promise {\n //not here\n const ready = await this.provider.ready;\n const daiInDollars = '1'\n if (!ready) return;\n const { DAI, FUDGE } = this.externalTokens;\n try {\n const fusdt_wftm_lp_pair = this.externalTokens['FUDGE-DAI LP'];\n let ftm_amount_BN = await DAI.balanceOf(fusdt_wftm_lp_pair.address);\n let ftm_amount = Number(getFullDisplayBalance(ftm_amount_BN, DAI.decimal));\n let fusdt_amount_BN = await FUDGE.balanceOf(fusdt_wftm_lp_pair.address);\n let fusdt_amount = Number(getFullDisplayBalance(fusdt_amount_BN, FUDGE.decimal));\n let cream_price = (ftm_amount / fusdt_amount);\n return cream_price.toString();\n\n } catch (err) {\n console.error(`Failed to fetch token price of AVAX: ${err}`);\n }\n }\n\n async getSTRAWPriceFromPancakeswap(): Promise {\n //not here\n const ready = await this.provider.ready;\n if (!ready) return;\n const { DAI, STRAW } = this.externalTokens;\n try {\n const fusdt_wftm_lp_pair = this.externalTokens['STRAW-DAI LP'];\n let ftm_amount_BN = await DAI.balanceOf(fusdt_wftm_lp_pair.address);\n let ftm_amount = Number(getFullDisplayBalance(ftm_amount_BN, DAI.decimal));\n let fusdt_amount_BN = await STRAW.balanceOf(fusdt_wftm_lp_pair.address);\n let fusdt_amount = Number(getFullDisplayBalance(fusdt_amount_BN, STRAW.decimal));\n let cream_price = (ftm_amount / fusdt_amount);\n return cream_price.toString();\n\n } catch (err) {\n console.error(`Failed to fetch token price of AVAX: ${err}`);\n }\n }\n\n /**\n * Method to calculate the tokenPrice of the deposited asset in a pool/bank\n * If the deposited token is an LP it will find the price of its pieces\n * @param tokenName\n * @param pool\n * @param token\n * @returns\n */\n\n async getDepositTokenPriceInDollars(tokenName: string, token: ERC20) {\n let tokenPrice;\n const priceOfOneFtmInDollars = await this.getWFTMPriceFromPancakeswap();\n const priceOfOneAvaxInDollars = await this.getAVAXPriceFromPancakeswap();\n const priceOfOneCshareInDollars = await this.getCSHAREPriceFromPancakeswap();\n const priceOfOneCreamInDollars = await this.getCREAMPriceFromPancakeswap();\n const priceOfOneStrawInDollars = await this.getSTRAWPriceFromPancakeswap();\n if (tokenName === 'WAVAX') {\n tokenPrice = priceOfOneAvaxInDollars;\n } else if (tokenName === 'CSHARE') {\n tokenPrice = priceOfOneCshareInDollars;\n } else if (tokenName === 'CREAM') {\n tokenPrice = priceOfOneCreamInDollars;\n } else {\n if (tokenName === 'FUDGE-DAI LP') {\n tokenPrice = await this.getLPTokenPrice(token, this.TOMB, true, false);\n } else if (tokenName === 'STRAW-DAI LP') {\n tokenPrice = await this.getLPTokenPrice(token, this.TSHARE, false, false);\n } else if (tokenName === 'CSHARE-AVAX LP') {\n tokenPrice = await this.getLPTokenPrice(\n token,\n new ERC20('0x155f794b56353533E0AfBF76e1B1FC57DFAd5Bd7', this.provider, 'CSHARE'),\n false,\n true,\n );\n } else if (tokenName === 'STRAW-AVAX LP') {\n tokenPrice = await this.getLPV2TokenPrice(\n token,\n this.TSHARE,\n false,\n );\n } else if (tokenName === 'FUDGE-STRAW LP') {\n tokenPrice = await this.getLPV2TokenPrice(\n token,\n this.TOMB,\n true\n );\n }\n else if (tokenName === 'CREAM-STRAW LP') {\n tokenPrice = await this.getLPV2TokenPrice(\n token,\n new ERC20('0xAE21d31a6494829a9E4B2B291F4984AAE8121757', this.provider, 'CREAM'),\n false,\n );\n } else if (tokenName === 'FUDGE-CREAM LP') {\n tokenPrice = await this.getLPV2TokenPrice(\n token,\n this.TOMB,\n true\n );\n }\n else if (tokenName === 'CREAM-AVAX LP') {\n tokenPrice = await this.getLPTokenPrice(\n token,\n new ERC20('0xAE21d31a6494829a9E4B2B291F4984AAE8121757', this.provider, 'CREAM'),\n true,\n true,\n );\n } else if (tokenName === 'CREAM-CSHARE LP') {\n tokenPrice = await this.getLPTokenPrice(\n token,\n new ERC20('0x155f794b56353533E0AfBF76e1B1FC57DFAd5Bd7', this.provider, 'CSHARE'),\n true,\n true,\n );\n } else if (tokenName === 'DAI') {\n tokenPrice = priceOfOneFtmInDollars;\n } else if (tokenName === 'STRAW') {\n tokenPrice = priceOfOneStrawInDollars;\n } else {\n tokenPrice = await this.getTokenPriceFromPancakeswap(token);\n tokenPrice = (Number(tokenPrice) * Number(priceOfOneFtmInDollars)).toString();\n }\n }\n return tokenPrice;\n }\n\n //===================================================================\n //===================== GET ASSET STATS =============================\n //=========================== END ===================================\n //===================================================================\n\n async getCurrentEpoch(): Promise {\n const { Treasury } = this.contracts;\n return Treasury.epoch();\n }\n\n async getBondOraclePriceInLastTWAP(): Promise {\n const { Treasury } = this.contracts;\n return Treasury.getBondPremiumRate();\n }\n\n /**\n * Buy bonds with cash.\n * @param amount amount of cash to purchase bonds with.\n */\n async buyBonds(amount: string | number): Promise {\n const { Treasury } = this.contracts;\n const treasuryTombPrice = await Treasury.getTombPrice();\n return await Treasury.buyBonds(decimalToBalance(amount), treasuryTombPrice);\n }\n\n /**\n * Redeem bonds for cash.\n * @param amount amount of bonds to redeem.\n */\n async redeemBonds(amount: string): Promise {\n const { Treasury } = this.contracts;\n const priceForTomb = await Treasury.getTombPrice();\n return await Treasury.redeemBonds(decimalToBalance(amount), priceForTomb);\n }\n\n async getTotalValueLocked(): Promise {\n let totalValue = 0;\n for (const bankInfo of Object.values(bankDefinitions)) {\n const pool = this.contracts[bankInfo.contract];\n const token = this.externalTokens[bankInfo.depositTokenName];\n const tokenPrice = await this.getDepositTokenPriceInDollars(bankInfo.depositTokenName, token);\n const tokenAmountInPool = await token.balanceOf(pool.address);\n const value = Number(getDisplayBalance(tokenAmountInPool, token.decimal)) * Number(tokenPrice);\n const poolValue = Number.isNaN(value) ? 0 : value;\n totalValue += poolValue;\n }\n\n const TSHAREPrice = (await this.getShareStat()).priceInDollars;\n const masonrytShareBalanceOf = await this.TSHARE.balanceOf(this.currentMasonry().address);\n const masonryTVL = Number(getDisplayBalance(masonrytShareBalanceOf, this.TSHARE.decimal)) * Number(TSHAREPrice);\n\n return totalValue + masonryTVL;\n }\n\n /**\n * Calculates the price of an LP token\n * Reference https://github.com/DefiDebauchery/discordpricebot/blob/4da3cdb57016df108ad2d0bb0c91cd8dd5f9d834/pricebot/pricebot.py#L150\n * @param lpToken the token under calculation\n * @param token the token pair used as reference (the other one would be FTM in most cases)\n * @param isTomb sanity check for usage of tomb token or tShare\n * @returns price of the LP token\n */\n async getLPTokenPrice(lpToken: ERC20, token: ERC20, isTomb: boolean, isFake: boolean): Promise {\n const totalSupply = getFullDisplayBalance(await lpToken.totalSupply(), lpToken.decimal);\n //Get amount of tokenA\n const tokenSupply = getFullDisplayBalance(await token.balanceOf(lpToken.address), token.decimal);\n const stat =\n isFake === true\n ? isTomb === true\n ? await this.getTombStatFake()\n : await this.getShareStatFake()\n : isTomb === true\n ? await this.getTombStat()\n : await this.getShareStat();\n const priceOfToken = stat.priceInDollars;\n const tokenInLP = Number(tokenSupply) / Number(totalSupply);\n const tokenPrice = (Number(priceOfToken) * tokenInLP * 2) //We multiply by 2 since half the price of the lp token is the price of each piece of the pair. So twice gives the total\n .toString();\n return tokenPrice;\n }\n\n async getTombStatFake() {\n const price = await fetch(\n 'https://api.coingecko.com/api/v3/simple/price?ids=icecream-finance&vs_currencies=usd',\n ).then((res) => res.json());\n return { priceInDollars: price['icecream-finance'].usd };\n }\n\n async getShareStatFake() {\n const price = await fetch('https://api.coingecko.com/api/v3/simple/price?ids=cream-shares&vs_currencies=usd').then(\n (res) => res.json(),\n );\n return { priceInDollars: price['cream-shares'].usd };\n }\n\n async getLPV2TokenPrice(lpToken: ERC20, token: ERC20, isTomb: boolean): Promise {\n const totalSupply = getFullDisplayBalance(await lpToken.totalSupply(), lpToken.decimal);\n //Get amount of tokenA\n const tokenSupply = getFullDisplayBalance(await token.balanceOf(lpToken.address), token.decimal);\n const stat = isTomb === true\n ? await this.getTombStat()\n : await this.getShareStat();\n const priceOfToken = stat.priceInDollars;\n console.log(priceOfToken)\n const tokenInLP = Number(tokenSupply) / Number(totalSupply);\n const tokenPrice = (Number(priceOfToken) * tokenInLP * 2) //We multiply by 2 since half the price of the lp token is the price of each piece of the pair. So twice gives the total\n .toString();\n console.log(tokenPrice)\n return tokenPrice;\n }\n\n\n async getFudgeStat() {\n const price = await this.getFUDGEPriceFromPancakeswap()\n return price\n }\n\n async getStrawStat() {\n const price = await this.getSTRAWPriceFromPancakeswap()\n return price\n }\n\n\n async earnedFromBank(\n poolName: ContractName,\n earnTokenName: String,\n poolId: Number,\n account = this.myAccount,\n ): Promise {\n const pool = this.contracts[poolName];\n try {\n if (earnTokenName === 'FUDGE' && poolName.includes('Node')) {\n return await pool.getTotalRewards(account);\n } else if (earnTokenName === 'FUDGE') {\n return await pool.pendingTOMB(poolId, account);\n } else {\n return await pool.pendingShare(poolId, account);\n }\n } catch (err) {\n console.error(`Failed to call pendingShare() on pool ${pool.address}: ${err}`);\n return BigNumber.from(0);\n }\n }\n\n async stakedBalanceOnBank(poolName: ContractName, poolId: Number, sectionInUI: Number, account = this.myAccount): Promise {\n const pool = this.contracts[poolName];\n try {\n let userInfo = sectionInUI !== 3\n ? await pool.userInfo(poolId, account)\n : await pool.users(account);\n return sectionInUI !== 3\n ? await userInfo.amount\n : await userInfo.total_deposits;\n } catch (err) {\n console.error(`Failed to call userInfo() on pool ${pool.address}: ${err}`);\n return BigNumber.from(0);\n }\n }\n\n /**\n * Deposits token to given pool.\n * @param poolName A name of pool contract.\n * @param amount Number of tokens with decimals applied. (e.g. 1.45 DAI * 10^18)\n * @returns {string} Transaction hash\n */\n async stake(poolName: ContractName, poolId: Number, sectionInUI: Number, amount: BigNumber): Promise {\n const pool = this.contracts[poolName];\n return sectionInUI !== 3\n ? await pool.deposit(poolId, amount)\n : await pool.create(poolId, amount);\n }\n\n /**\n * Withdraws token from given pool.\n * @param poolName A name of pool contract.\n * @param amount Number of tokens with decimals applied. (e.g. 1.45 DAI * 10^18)\n * @returns {string} Transaction hash\n */\n async unstake(poolName: ContractName, poolId: Number, amount: BigNumber): Promise {\n const pool = this.contracts[poolName];\n return await pool.withdraw(poolId, amount);\n }\n\n /**\n * Transfers earned token reward from given pool to my account.\n */\n async harvest(poolName: ContractName, poolId: Number, sectionInUI: Number): Promise {\n const pool = this.contracts[poolName];\n //By passing 0 as the amount, we are asking the contract to only redeem the reward and not the currently staked token\n return sectionInUI !== 3\n ? await pool.withdraw(poolId, 0)\n : await pool.claim();\n }\n\n /**\n * Harvests and withdraws deposited tokens from the pool.\n */\n async exit(poolName: ContractName, poolId: Number, account = this.myAccount): Promise {\n const pool = this.contracts[poolName];\n let userInfo = await pool.userInfo(poolId, account);\n return await pool.withdraw(poolId, userInfo.amount);\n }\n\n async fetchMasonryVersionOfUser(): Promise {\n return 'latest';\n }\n\n currentMasonry(): Contract {\n if (!this.masonryVersionOfUser) {\n //throw new Error('you must unlock the wallet to continue.');\n }\n return this.contracts.Masonry;\n }\n\n isOldMasonryMember(): boolean {\n return this.masonryVersionOfUser !== 'latest';\n }\n\n async getTokenPriceFromPancakeswap(tokenContract: ERC20): Promise {\n const ready = await this.provider.ready;\n if (!ready) return;\n const { chainId } = this.config;\n const { DAI } = this.config.externalTokens;\n\n const wftm = new Token(chainId, DAI[0], DAI[1], 'DAI');\n const token = new Token(chainId, tokenContract.address, tokenContract.decimal, tokenContract.symbol);\n try {\n const wftmToToken = await Fetcher.fetchPairData(wftm, token, this.provider);\n const priceInBUSD = new Route([wftmToToken], token);\n\n return priceInBUSD.midPrice.toFixed(4);\n } catch (err) {\n console.error(`Failed to fetch token price of ${tokenContract.symbol}: ${err}`);\n }\n }\n\n // async getTokenPriceFromSpiritswap(tokenContract: ERC20): Promise {\n // const ready = await this.provider.ready;\n // if (!ready) return;\n // const { chainId } = this.config;\n\n // const { WFTM } = this.externalTokens;\n\n // const wftm = new TokenSpirit(chainId, WFTM.address, WFTM.decimal);\n // const token = new TokenSpirit(chainId, tokenContract.address, tokenContract.decimal, tokenContract.symbol);\n // try {\n // const wftmToToken = await FetcherSpirit.fetchPairData(wftm, token, this.provider);\n // const liquidityToken = wftmToToken.liquidityToken;\n // let ftmBalanceInLP = await WFTM.balanceOf(liquidityToken.address);\n // let ftmAmount = Number(getFullDisplayBalance(ftmBalanceInLP, WFTM.decimal));\n // let shibaBalanceInLP = await tokenContract.balanceOf(liquidityToken.address);\n // let shibaAmount = Number(getFullDisplayBalance(shibaBalanceInLP, tokenContract.decimal));\n // const priceOfOneFtmInDollars = await this.getWFTMPriceFromPancakeswap();\n // let priceOfShiba = (ftmAmount / shibaAmount) * Number(priceOfOneFtmInDollars);\n // return priceOfShiba.toString();\n // } catch (err) {\n // console.error(`Failed to fetch token price of ${tokenContract.symbol}: ${err}`);\n // }\n // }\n\n async getWFTMPriceFromPancakeswap(): Promise {\n const ready = await this.provider.ready;\n if (!ready) return;\n const { WFTM, FUSDT } = this.externalTokens;\n try {\n const fusdt_wftm_lp_pair = this.externalTokens['USDT-FTM LP'];\n let ftm_amount_BN = await WFTM.balanceOf(fusdt_wftm_lp_pair.address);\n let ftm_amount = Number(getFullDisplayBalance(ftm_amount_BN, WFTM.decimal));\n let fusdt_amount_BN = await FUSDT.balanceOf(fusdt_wftm_lp_pair.address);\n let fusdt_amount = Number(getFullDisplayBalance(fusdt_amount_BN, FUSDT.decimal));\n return (fusdt_amount / ftm_amount).toString();\n } catch (err) {\n console.error(`Failed to fetch token price of WFTM: ${err}`);\n }\n }\n\n //===================================================================\n //===================================================================\n //===================== MASONRY METHODS =============================\n //===================================================================\n //===================================================================\n\n async getMasonryAPR() {\n const Masonry = this.currentMasonry();\n const latestSnapshotIndex = await Masonry.latestSnapshotIndex();\n const lastHistory = await Masonry.masonryHistory(latestSnapshotIndex);\n\n const lastRewardsReceived = lastHistory[1];\n\n const TSHAREPrice = (await this.getShareStat()).priceInDollars;\n const TOMBPrice = (await this.getTombStat()).priceInDollars;\n const epochRewardsPerShare = lastRewardsReceived / 1e18;\n\n //Mgod formula\n const amountOfRewardsPerDay = epochRewardsPerShare * Number(TOMBPrice) * 4;\n const masonrytShareBalanceOf = await this.TSHARE.balanceOf(Masonry.address);\n const masonryTVL = Number(getDisplayBalance(masonrytShareBalanceOf, this.TSHARE.decimal)) * Number(TSHAREPrice);\n const realAPR = ((amountOfRewardsPerDay * 100) / masonryTVL) * 365;\n return realAPR;\n }\n\n /**\n * Checks if the user is allowed to retrieve their reward from the Masonry\n * @returns true if user can withdraw reward, false if they can't\n */\n async canUserClaimRewardFromMasonry(): Promise {\n const Masonry = this.currentMasonry();\n return await Masonry.canClaimReward(this.myAccount);\n }\n\n /**\n * Checks if the user is allowed to retrieve their reward from the Masonry\n * @returns true if user can withdraw reward, false if they can't\n */\n async canUserUnstakeFromMasonry(): Promise {\n const Masonry = this.currentMasonry();\n const canWithdraw = await Masonry.canWithdraw(this.myAccount);\n const stakedAmount = await this.getStakedSharesOnMasonry();\n const notStaked = Number(getDisplayBalance(stakedAmount, this.TSHARE.decimal)) === 0;\n const result = notStaked ? true : canWithdraw;\n return result;\n }\n\n async timeUntilClaimRewardFromMasonry(): Promise {\n // const Masonry = this.currentMasonry();\n // const mason = await Masonry.masons(this.myAccount);\n return BigNumber.from(0);\n }\n\n async getTotalStakedInMasonry(): Promise {\n const Masonry = this.currentMasonry();\n return await Masonry.totalSupply();\n }\n\n async stakeShareToMasonry(amount: string): Promise {\n if (this.isOldMasonryMember()) {\n throw new Error(\"you're using old masonry. please withdraw and deposit the TSHARE again.\");\n }\n const Masonry = this.currentMasonry();\n return await Masonry.stake(decimalToBalance(amount));\n }\n\n async getStakedSharesOnMasonry(): Promise {\n const Masonry = this.currentMasonry();\n if (this.masonryVersionOfUser === 'v1') {\n return await Masonry.getShareOf(this.myAccount);\n }\n return await Masonry.balanceOf(this.myAccount);\n }\n\n async getEarningsOnMasonry(): Promise {\n const Masonry = this.currentMasonry();\n if (this.masonryVersionOfUser === 'v1') {\n return await Masonry.getCashEarningsOf(this.myAccount);\n }\n return await Masonry.earned(this.myAccount);\n }\n\n async withdrawShareFromMasonry(amount: string): Promise {\n const Masonry = this.currentMasonry();\n return await Masonry.withdraw(decimalToBalance(amount));\n }\n\n async harvestCashFromMasonry(): Promise {\n const Masonry = this.currentMasonry();\n if (this.masonryVersionOfUser === 'v1') {\n return await Masonry.claimDividends();\n }\n return await Masonry.claimReward();\n }\n\n async exitFromMasonry(): Promise {\n const Masonry = this.currentMasonry();\n return await Masonry.exit();\n }\n\n async getTreasuryNextAllocationTime(): Promise {\n const { Treasury } = this.contracts;\n const nextEpochTimestamp: BigNumber = await Treasury.nextEpochPoint();\n const nextAllocation = new Date(nextEpochTimestamp.mul(1000).toNumber());\n const prevAllocation = new Date(Date.now());\n console.log(nextEpochTimestamp.toNumber());\n return { from: prevAllocation, to: nextAllocation };\n }\n /**\n * This method calculates and returns in a from to to format\n * the period the user needs to wait before being allowed to claim\n * their reward from the masonry\n * @returns Promise\n */\n async getUserClaimRewardTime(): Promise {\n const { Masonry, Treasury } = this.contracts;\n const nextEpochTimestamp = await Masonry.nextEpochPoint(); //in unix timestamp\n const currentEpoch = await Masonry.epoch();\n const mason = await Masonry.masons(this.myAccount);\n const startTimeEpoch = mason.epochTimerStart;\n const period = await Treasury.PERIOD();\n const periodInHours = period / 60 / 60; // 6 hours, period is displayed in seconds which is 21600\n const rewardLockupEpochs = await Masonry.rewardLockupEpochs();\n const targetEpochForClaimUnlock = Number(startTimeEpoch) + Number(rewardLockupEpochs);\n\n const fromDate = new Date(Date.now());\n if (targetEpochForClaimUnlock - currentEpoch <= 0) {\n return { from: fromDate, to: fromDate };\n } else if (targetEpochForClaimUnlock - currentEpoch === 1) {\n const toDate = new Date(nextEpochTimestamp * 1000);\n return { from: fromDate, to: toDate };\n } else {\n const toDate = new Date(nextEpochTimestamp * 1000);\n const delta = targetEpochForClaimUnlock - currentEpoch - 1;\n const endDate = moment(toDate)\n .add(delta * periodInHours, 'hours')\n .toDate();\n return { from: fromDate, to: endDate };\n }\n }\n\n /**\n * This method calculates and returns in a from to to format\n * the period the user needs to wait before being allowed to unstake\n * from the masonry\n * @returns Promise\n */\n async getUserUnstakeTime(): Promise {\n const { Masonry, Treasury } = this.contracts;\n const nextEpochTimestamp = await Masonry.nextEpochPoint();\n const currentEpoch = await Masonry.epoch();\n const mason = await Masonry.masons(this.myAccount);\n const startTimeEpoch = mason.epochTimerStart;\n const period = await Treasury.PERIOD();\n const PeriodInHours = period / 60 / 60;\n const withdrawLockupEpochs = await Masonry.withdrawLockupEpochs();\n const fromDate = new Date(Date.now());\n const targetEpochForClaimUnlock = Number(startTimeEpoch) + Number(withdrawLockupEpochs);\n const stakedAmount = await this.getStakedSharesOnMasonry();\n if (currentEpoch <= targetEpochForClaimUnlock && Number(stakedAmount) === 0) {\n return { from: fromDate, to: fromDate };\n } else if (targetEpochForClaimUnlock - currentEpoch === 1) {\n const toDate = new Date(nextEpochTimestamp * 1000);\n return { from: fromDate, to: toDate };\n } else {\n const toDate = new Date(nextEpochTimestamp * 1000);\n const delta = targetEpochForClaimUnlock - Number(currentEpoch) - 1;\n const endDate = moment(toDate)\n .add(delta * PeriodInHours, 'hours')\n .toDate();\n return { from: fromDate, to: endDate };\n }\n }\n\n async watchAssetInMetamask(assetName: string): Promise {\n const { ethereum } = window as any;\n if (ethereum && ethereum.networkVersion === config.chainId.toString()) {\n let asset;\n let assetUrl;\n if (assetName === 'TOMB') {\n asset = this.TOMB;\n assetUrl = 'https://raw.githubusercontent.com/IceCreamFinancial/contracts-public/main/fudge.png';\n } else if (assetName === 'TSHARE') {\n asset = this.TSHARE;\n assetUrl = 'https://raw.githubusercontent.com/IceCreamFinancial/contracts-public/main/straw.png';\n } else if (assetName === 'TBOND') {\n asset = this.TBOND;\n assetUrl = 'https://raw.githubusercontent.com/IceCreamFinancial/contracts-public/main/caraml.png';\n }\n await ethereum.request({\n method: 'wallet_watchAsset',\n params: {\n type: 'ERC20',\n options: {\n address: asset.address,\n symbol: asset.symbol,\n decimals: 18,\n image: assetUrl,\n },\n },\n });\n }\n return true;\n }\n\n async provideTombFtmLP(ftmAmount: string, tombAmount: BigNumber): Promise {\n const { TaxOffice } = this.contracts;\n let overrides = {\n value: parseUnits(ftmAmount, 18),\n };\n return await TaxOffice.addLiquidityETHTaxFree(\n tombAmount,\n tombAmount.mul(992).div(1000),\n parseUnits(ftmAmount, 18).mul(992).div(1000),\n overrides,\n );\n }\n\n async quoteFromSpooky(tokenAmount: string, tokenName: string): Promise {\n const { SpookyRouter } = this.contracts;\n const { _reserve0, _reserve1 } = await this.TOMBWFTM_LP.getReserves();\n let quote;\n if (tokenName === 'TOMB') {\n quote = await SpookyRouter.quote(parseUnits(tokenAmount), _reserve1, _reserve0);\n } else {\n quote = await SpookyRouter.quote(parseUnits(tokenAmount), _reserve0, _reserve1);\n }\n return (quote / 1e18).toString();\n }\n\n /**\n * @returns an array of the regulation events till the most up to date epoch\n */\n async listenForRegulationsEvents(): Promise {\n const { Treasury } = this.contracts;\n\n const treasuryDaoFundedFilter = Treasury.filters.DaoFundFunded();\n const treasuryDevFundedFilter = Treasury.filters.DevFundFunded();\n const treasuryMasonryFundedFilter = Treasury.filters.MasonryFunded();\n const boughtBondsFilter = Treasury.filters.BoughtBonds();\n const redeemBondsFilter = Treasury.filters.RedeemedBonds();\n\n let epochBlocksRanges: any[] = [];\n let masonryFundEvents = await Treasury.queryFilter(treasuryMasonryFundedFilter);\n var events: any[] = [];\n masonryFundEvents.forEach(function callback(value, index) {\n events.push({ epoch: index + 1 });\n events[index].masonryFund = getDisplayBalance(value.args[1]);\n if (index === 0) {\n epochBlocksRanges.push({\n index: index,\n startBlock: value.blockNumber,\n boughBonds: 0,\n redeemedBonds: 0,\n });\n }\n if (index > 0) {\n epochBlocksRanges.push({\n index: index,\n startBlock: value.blockNumber,\n boughBonds: 0,\n redeemedBonds: 0,\n });\n epochBlocksRanges[index - 1].endBlock = value.blockNumber;\n }\n });\n\n epochBlocksRanges.forEach(async (value, index) => {\n events[index].bondsBought = await this.getBondsWithFilterForPeriod(\n boughtBondsFilter,\n value.startBlock,\n value.endBlock,\n );\n events[index].bondsRedeemed = await this.getBondsWithFilterForPeriod(\n redeemBondsFilter,\n value.startBlock,\n value.endBlock,\n );\n });\n let DEVFundEvents = await Treasury.queryFilter(treasuryDevFundedFilter);\n DEVFundEvents.forEach(function callback(value, index) {\n events[index].devFund = getDisplayBalance(value.args[1]);\n });\n let DAOFundEvents = await Treasury.queryFilter(treasuryDaoFundedFilter);\n DAOFundEvents.forEach(function callback(value, index) {\n events[index].daoFund = getDisplayBalance(value.args[1]);\n });\n return events;\n }\n\n /**\n * Helper method\n * @param filter applied on the query to the treasury events\n * @param from block number\n * @param to block number\n * @returns the amount of bonds events emitted based on the filter provided during a specific period\n */\n async getBondsWithFilterForPeriod(filter: EventFilter, from: number, to: number): Promise {\n const { Treasury } = this.contracts;\n const bondsAmount = await Treasury.queryFilter(filter, from, to);\n return bondsAmount.length;\n }\n\n async estimateZapIn(tokenName: string, lpName: string, amount: string): Promise {\n const { zapper } = this.contracts;\n const lpToken = this.externalTokens[lpName];\n let estimate;\n if (tokenName === FTM_TICKER) {\n estimate = await zapper.estimateZapIn(lpToken.address, SPOOKY_ROUTER_ADDR, parseUnits(amount, 18));\n } else {\n const token = tokenName === TOMB_TICKER ? this.TOMB : this.TSHARE;\n estimate = await zapper.estimateZapInToken(\n token.address,\n lpToken.address,\n SPOOKY_ROUTER_ADDR,\n parseUnits(amount, 18),\n );\n }\n return [estimate[0] / 1e18, estimate[1] / 1e18];\n }\n async zapIn(tokenName: string, lpName: string, amount: string): Promise {\n const { zapper } = this.contracts;\n const lpToken = this.externalTokens[lpName];\n if (tokenName === FTM_TICKER) {\n let overrides = {\n value: parseUnits(amount, 18),\n };\n return await zapper.zapIn(lpToken.address, SPOOKY_ROUTER_ADDR, this.myAccount, overrides);\n } else {\n const token = tokenName === TOMB_TICKER ? this.TOMB : this.TSHARE;\n return await zapper.zapInToken(\n token.address,\n parseUnits(amount, 18),\n lpToken.address,\n SPOOKY_ROUTER_ADDR,\n this.myAccount,\n );\n }\n }\n async swapTBondToTShare(tbondAmount: BigNumber): Promise {\n const { TShareSwapper } = this.contracts;\n return await TShareSwapper.swapTBondToTShare(tbondAmount);\n }\n async estimateAmountOfTShare(tbondAmount: string): Promise {\n const { TShareSwapper } = this.contracts;\n try {\n const estimateBN = await TShareSwapper.estimateAmountOfTShare(parseUnits(tbondAmount, 18));\n return getDisplayBalance(estimateBN, 18, 6);\n } catch (err) {\n console.error(`Failed to fetch estimate tshare amount: ${err}`);\n }\n }\n\n async getTShareSwapperStat(address: string): Promise {\n const { TShareSwapper } = this.contracts;\n const tshareBalanceBN = await TShareSwapper.getTShareBalance();\n const tbondBalanceBN = await TShareSwapper.getTBondBalance(address);\n // const tombPriceBN = await TShareSwapper.getTombPrice();\n // const tsharePriceBN = await TShareSwapper.getTSharePrice();\n const rateTSharePerTombBN = await TShareSwapper.getTShareAmountPerTomb();\n const tshareBalance = getDisplayBalance(tshareBalanceBN, 18, 5);\n const tbondBalance = getDisplayBalance(tbondBalanceBN, 18, 5);\n return {\n tshareBalance: tshareBalance.toString(),\n tbondBalance: tbondBalance.toString(),\n // tombPrice: tombPriceBN.toString(),\n // tsharePrice: tsharePriceBN.toString(),\n rateTSharePerTomb: rateTSharePerTombBN.toString(),\n };\n }\n}\n","import React, { createContext, useEffect, useState } from 'react';\nimport { useWallet } from 'use-wallet';\nimport TombFinance from '../../tomb-finance';\nimport config from '../../config';\n\nexport interface TombFinanceContext {\n tombFinance?: TombFinance;\n}\n\nexport const Context = createContext({ tombFinance: null });\n\nexport const TombFinanceProvider: React.FC = ({ children }) => {\n const { ethereum, account } = useWallet();\n const [tombFinance, setTombFinance] = useState();\n\n useEffect(() => {\n if (!tombFinance) {\n const tomb = new TombFinance(config);\n if (account) {\n // wallet was unlocked at initialization\n tomb.unlockWallet(ethereum, account);\n }\n setTombFinance(tomb);\n } else if (account) {\n tombFinance.unlockWallet(ethereum, account);\n }\n }, [account, ethereum, tombFinance]);\n\n return {children};\n};\n","import { useContext } from 'react';\nimport { Context } from '../contexts/TombFinanceProvider';\n\nconst useTombFinance = () => {\n const { tombFinance } = useContext(Context);\n return tombFinance;\n};\n\nexport default useTombFinance;\n","import { createContext } from 'react';\nimport { Bank } from '../../tomb-finance';\n\nexport interface BanksContext {\n banks: Bank[];\n}\n\nconst context = createContext({\n banks: [],\n});\n\nexport default context;\n","import React, {useCallback, useEffect, useState} from 'react';\nimport Context from './context';\nimport useTombFinance from '../../hooks/useTombFinance';\nimport {Bank} from '../../tomb-finance';\nimport config, {bankDefinitions} from '../../config';\n\nconst Banks: React.FC = ({children}) => {\n const [banks, setBanks] = useState([]);\n const tombFinance = useTombFinance();\n const isUnlocked = tombFinance?.isUnlocked;\n\n const fetchPools = useCallback(async () => {\n const banks: Bank[] = [];\n\n for (const bankInfo of Object.values(bankDefinitions)) {\n if (bankInfo.finished) {\n if (!tombFinance.isUnlocked) continue;\n\n // only show pools staked by user\n const balance = await tombFinance.stakedBalanceOnBank(\n bankInfo.contract,\n bankInfo.poolId,\n bankInfo.sectionInUI,\n tombFinance.myAccount,\n );\n if (balance.lte(0)) {\n continue;\n }\n }\n banks.push({\n ...bankInfo,\n address: config.deployments[bankInfo.contract].address,\n depositToken: tombFinance.externalTokens[bankInfo.depositTokenName],\n earnToken: bankInfo.earnTokenName === 'FUDGE' ? tombFinance.TOMB : tombFinance.TSHARE,\n });\n }\n banks.sort((a, b) => (a.sort > b.sort ? 1 : -1));\n setBanks(banks);\n }, [tombFinance, setBanks]);\n\n useEffect(() => {\n if (tombFinance) {\n fetchPools().catch((err) => console.error(`Failed to fetch pools: ${err.stack}`));\n }\n }, [isUnlocked, tombFinance, fetchPools]);\n\n return {children};\n};\n\nexport default Banks;","import React, { createContext, useCallback, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface ModalsContext {\n content?: React.ReactNode;\n isOpen?: boolean;\n onPresent: (content: React.ReactNode) => void;\n onDismiss: () => void;\n}\n\nexport const Context = createContext({\n onPresent: () => {},\n onDismiss: () => {},\n});\n\nconst Modals: React.FC = ({ children }) => {\n const [isOpen, setIsOpen] = useState(false);\n const [content, setContent] = useState();\n\n const handlePresent = useCallback(\n (modalContent: React.ReactNode) => {\n setContent(modalContent);\n setIsOpen(true);\n },\n [setContent, setIsOpen],\n );\n\n const handleDismiss = useCallback(() => {\n setContent(undefined);\n setIsOpen(false);\n }, [setContent, setIsOpen]);\n\n return (\n \n {children}\n {isOpen && (\n \n \n {React.isValidElement(content) &&\n React.cloneElement(content, {\n onDismiss: handleDismiss,\n })}\n \n )}\n \n );\n};\n\nconst StyledModalWrapper = styled.div`\n align-items: center;\n display: flex;\n justify-content: center;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n`;\n\nconst StyledModalBackdrop = styled.div`\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n`;\n\nexport default Modals;\n","import React, { useState, useEffect } from 'react'\n\nconst FAST_INTERVAL = 10000\nconst SLOW_INTERVAL = 60000\n\nexport const RefreshContext = React.createContext({ slow: 0, fast: 0 })\n\n// This context maintain 2 counters that can be used as a dependencies on other hooks to force a periodic refresh\nexport const RefreshContextProvider: React.FC = ({ children }) => {\n const [slow, setSlow] = useState(0)\n const [fast, setFast] = useState(0)\n\n useEffect(() => {\n const interval = setInterval(async () => {\n setFast((prev) => prev + 1)\n }, FAST_INTERVAL)\n return () => clearInterval(interval)\n }, [])\n\n useEffect(() => {\n const interval = setInterval(async () => { \n setSlow((prev) => prev + 1)\n }, SLOW_INTERVAL)\n return () => clearInterval(interval)\n }, [])\n\n return {children}\n}\n\n","// import { ChainId } from '@pancakeswap-libs/sdk';\nimport { ChainId } from '@traderjoe-xyz/sdk';\nimport { Configuration } from './tomb-finance/config';\nimport { BankInfo } from './tomb-finance';\n\nconst configurations: { [env: string]: Configuration } = {\n production: {\n chainId: ChainId.AVALANCHE,\n networkName: 'Avalanche Mainnet',\n ftmscanUrl: 'https://snowtrace.io/',\n defaultProvider: 'https://api.avax.network/ext/bc/C/rpc',\n deployments: require('./tomb-finance/deployments/deployments.mainnet.json'),\n externalTokens: {\n WFTM: ['0xd586e7f844cea2f87f50152665bcbc2c279d8d70', 18], //DAI\n FUSDT: ['0xc7198437980c041c805A1EDcbA50c1Ce5db95118', 6], // This is actually usdc on mainnet not fusdt\n WAVAX: ['0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7', 18], //WAVAX\n MIM: ['0x130966628846BFd36ff31a822705796e8cb8C18D', 18],\n SHIBA: ['0x9ba3e4f84a34df4e08c112e1a0ff148b81655615', 9],\n BELUGA: ['0x4A13a2cf881f5378DEF61E430139Ed26d843Df9A', 18],\n BIFI: ['0xd6070ae98b8069de6B494332d1A1a81B6179D960', 18],\n BLOOM: ['0x9B2e37cDC711CfcAC1E1482B5741c74dd3924199', 9],\n DAI: ['0xd586e7f844cea2f87f50152665bcbc2c279d8d70', 18], //DAI\n CREAM: ['0xAE21d31a6494829a9E4B2B291F4984AAE8121757', 18], //CREAM\n 'CREAM-CSHARE LP': ['0xeC1e129BbAac3DdE156643F5d41FC9b5a59033a7', 18], //CREAM-CSHARE\n 'CREAM-AVAX LP': ['0x00C87ce7188F7652d0C0940274cEC5db62f1e825', 18], //CREAM-AVAX\n 'CSHARE-AVAX LP': ['0xbD61dFAd83Fc19960476abca1324FfD798234c66', 18], //CSHARE-AVAX\n 'CSHARE': ['0x155f794b56353533E0AfBF76e1B1FC57DFAd5Bd7', 18], //CSHARE\n 'FUDGE-DAI LP': ['0xE367414f29E247b2D92edd610aA6Dd5A7FD631BA', 18],\n 'FUDGE-AVAX LP': ['0xE367414f29E247b2D92edd610aA6Dd5A7FD631BA', 18], //FUDGE-DAI\n 'STRAW-DAI LP': ['0xf71149502bc064a7Da58C4E275DA7896ed3f14F3', 18], //STRAW-DAI\n 'STRAW': ['0xf8D0C6c3ddC03F43A0687847f2b34bfd6941C2A2', 18], //STRAW\n 'USDT-FTM LP': ['0xa6908C7E3Be8F4Cd2eB704B5cB73583eBF56Ee62', 18], //UDST-DAI\n 'FUDGE-STRAW LP': ['0x771d02022102a67931De319782D0507511982d56', 18], //FUDGE-STRAW\n 'FUDGE': ['0xD9FF12172803c072a36785DeFea1Aa981A6A0C18', 18], //FUDGE\n 'USDT-BNB-LP': ['0x781655d802670bbA3c89aeBaaEa59D3182fD755D', 18],\n 'MIM-WAVAX-LP': ['0x781655d802670bba3c89aebaaea59d3182fd755d', 18],\n 'STRAW-AVAX LP': ['0x5eeF38855090ccc49A1b7391F4C7B9efbDFE1456', 18],\n 'FUDGE-CREAM LP': ['0x39f3F5aB8b49a00Ba8121CC17C2B84943C885a62', 18],\n 'CREAM-STRAW LP': ['0x89BA86a9e3E0821493591b1fa07183F358b5B7d2', 18],\n },\n baseLaunchDate: new Date('2021-06-02 13:00:00Z'),\n bondLaunchesAt: new Date('2020-12-03T15:00:00Z'),\n masonryLaunchesAt: new Date('2020-12-11T00:00:00Z'),\n refreshInterval: 10000,\n },\n};\n\nexport const bankDefinitions: { [contractName: string]: BankInfo } = {\n /*\n Explanation:\n name: description of the card\n poolId: the poolId assigned in the contract\n sectionInUI: way to distinguish in which of the 3 pool groups it should be listed\n - 0 = Single asset stake pools\n - 1 = LP asset staking rewarding TOMB\n - 2 = LP asset staking rewarding TSHARE\n contract: the contract name which will be loaded from the deployment.environmnet.json\n depositTokenName : the name of the token to be deposited\n earnTokenName: the rewarded token\n finished: will disable the pool on the UI if set to true\n sort: the order of the pool\n */\n /* FudgeCshareRewardPool: {\n name: 'Earn FUDGE by staking CSHARE',\n poolId: 0,\n sectionInUI: 0,\n contract: 'FudgeCshare2RewardPool',\n depositTokenName: 'CSHARE',\n earnTokenName: 'FUDGE',\n finished: true,\n multiplier: '0x',\n site: 'https://2omb.finance',\n buyLink: 'https://traderjoexyz.com/trade?outputCurrency=0x155f794b56353533E0AfBF76e1B1FC57DFAd5Bd7#/',\n sort: 0,\n closedForStaking: false,\n },\n FudgeCshareAvaxLPRewardPool: {\n name: 'Earn FUDGE by staking CSHARE-AVAX LP',\n poolId: 1,\n sectionInUI: 0,\n contract: 'FudgeCshareAvaxLPRewardPool',\n depositTokenName: 'CSHARE-AVAX LP',\n earnTokenName: 'FUDGE',\n finished: true,\n multiplier: '0x',\n site: 'https://2omb.finance',\n buyLink: 'https://traderjoexyz.com/pool/AVAX/0x155f794b56353533E0AfBF76e1B1FC57DFAd5Bd7#/',\n sort: 1,\n closedForStaking: false,\n },\n FudgeCreamAvaxLPRewardPool: {\n name: 'Earn FUDGE by staking CREAM-AVAX LP',\n poolId: 3,\n sectionInUI: 0,\n contract: 'FudgeCreamAvaxLPRewardPool',\n depositTokenName: 'CREAM-AVAX LP',\n earnTokenName: 'FUDGE',\n finished: true,\n multiplier: '0x',\n site: 'https://2omb.finance',\n buyLink: 'https://traderjoexyz.com/pool/AVAX/0xAE21d31a6494829a9E4B2B291F4984AAE8121757#/',\n sort: 2,\n closedForStaking: false,\n },\n FudgeCreamRewardPool: {\n name: 'Earn FUDGE by staking CREAM',\n poolId: 4,\n sectionInUI: 0,\n contract: 'FudgeCream2RewardPool',\n depositTokenName: 'CREAM',\n earnTokenName: 'FUDGE',\n finished: true,\n multiplier: '0x',\n site: 'https://2omb.finance',\n buyLink: 'https://traderjoexyz.com/trade?outputCurrency=0xAE21d31a6494829a9E4B2B291F4984AAE8121757#/',\n sort: 3,\n closedForStaking: false,\n },\n FudgeFudgeAvaxLPRewardPool: {\n name: 'Earn FUDGE by staking FUDGE-AVAX',\n poolId: 7,\n sectionInUI: 0,\n contract: 'FudgeFudgeAvaxLPRewardPool',\n depositTokenName: 'FUDGE-AVAX LP',\n earnTokenName: 'FUDGE',\n finished: true,\n multiplier: '0x',\n site: 'https://beluga.fi',\n buyLink: 'https://traderjoexyz.com/pool/AVAX/0xD9FF12172803c072a36785DeFea1Aa981A6A0C18#/',\n sort: 4,\n closedForStaking: true,\n },\n FudgeFudgeDaiLPRewardPool: {\n name: 'Earn FUDGE by staking FUDGE-DAI LP',\n poolId: 8,\n sectionInUI: 0,\n contract: 'FudgeFudgeDaiLPRewardPool',\n depositTokenName: 'FUDGE-DAI LP',\n earnTokenName: 'FUDGE',\n finished: true,\n multiplier: '0x',\n site: 'https://app.beefy.finance/#/fantom',\n buyLink: 'https://traderjoexyz.com/pool/0xd586E7F844cEa2F87f50152665BCbc2C279D8d70/0xD9FF12172803c072a36785DeFea1Aa981A6A0C18',\n sort: 5,\n closedForStaking: false,\n },\n FudgeDaiRewardPool: {\n name: 'Earn FUDGE by staking DAI',\n poolId: 5,\n sectionInUI: 0,\n contract: 'FudgeDaiRewardPool',\n depositTokenName: 'DAI',\n earnTokenName: 'FUDGE',\n finished: true,\n multiplier: '0x',\n site: 'https://traderjoexyz.com/trade/0xd586e7f844cea2f87f50152665bcbc2c279d8d70',\n buyLink: 'https://traderjoexyz.com/trade/0xd586e7f844cea2f87f50152665bcbc2c279d8d70',\n sort: 6,\n closedForStaking: false,\n },\n FudgeAvaxRewardPool: {\n name: 'Earn FUDGE by staking WAVAX',\n poolId: 6,\n sectionInUI: 0,\n contract: 'FudgeAvaxRewardPool',\n depositTokenName: 'WAVAX',\n earnTokenName: 'FUDGE',\n finished: true,\n multiplier: '0x',\n site: 'https://abracadabra.money/',\n buyLink: 'https://traderjoexyz.com/trade?outputCurrency=0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7#/',\n sort: 7,\n closedForStaking: false,\n },\n */\n // TombBloomRewardPool: {\n // name: 'Earn 3OMB by staking BLOOM',\n // poolId: 8,\n // sectionInUI: 0,\n // contract: 'TombBloomGenesisRewardPool',\n // depositTokenName: 'BLOOM',\n // earnTokenName: '3OMB',\n // finished: false,\n // multiplier: '500x (0.04% Deposit Fee)',\n // site: 'https://bloom.thetulipdao.com/',\n // buyLink: 'https://swap.spiritswap.finance/#/exchange/swap/FTM/0x9B2e37cDC711CfcAC1E1482B5741c74dd3924199',\n // sort: 9,\n // closedForStaking: true,\n // },\n \n FudgeDaiLPTShareRewardPool: {\n name: 'Earn STRAW by FUDGE-DAI LP',\n poolId: 0,\n sectionInUI: 2,\n contract: 'FudgeDaiLPTShareRewardPool',\n depositTokenName: 'FUDGE-DAI LP',\n earnTokenName: 'STRAW',\n finished: false,\n multiplier: '24750x',\n buyLink: 'https://traderjoexyz.com/pool/0xd586E7F844cEa2F87f50152665BCbc2C279D8d70/0xD9FF12172803c072a36785DeFea1Aa981A6A0C18#/',\n site: '/',\n sort: 8,\n closedForStaking: false,\n },\n StrawAvaxLPTShareRewardPool: {\n name: 'Earn STRAW by STRAW-AVAX LP',\n poolId: 1,\n sectionInUI: 2,\n contract: 'StrawAvaxLPTShareRewardPool',\n depositTokenName: 'STRAW-AVAX LP',\n earnTokenName: 'STRAW',\n finished: false,\n multiplier: 'POOL CLOSED',\n buyLink: 'https://traderjoexyz.com/pool/AVAX/0xf8D0C6c3ddC03F43A0687847f2b34bfd6941C2A2',\n site: '/',\n sort: 9,\n closedForStaking: false,\n },\n StrawDaiLPTShareRewardPool: {\n name: 'Earn STRAW by STRAW-DAI LP',\n poolId: 7,\n sectionInUI: 2,\n contract: 'StrawDaiLPTShareRewardPool',\n depositTokenName: 'STRAW-DAI LP',\n earnTokenName: 'STRAW',\n finished: false,\n multiplier: '23375x',\n buyLink: 'https://traderjoexyz.com/pool/0xd586E7F844cEa2F87f50152665BCbc2C279D8d70/0xf8D0C6c3ddC03F43A0687847f2b34bfd6941C2A2',\n site: '/',\n sort: 9,\n closedForStaking: false,\n },\n FudgeStrawLPTShareRewardPool: {\n name: 'Earn STRAW by FUDGE-STRAW LP',\n poolId: 2,\n sectionInUI: 0,\n contract: 'FudgeStrawLPTShareRewardPool',\n depositTokenName: 'FUDGE-STRAW LP',\n earnTokenName: 'STRAW',\n finished: false,\n multiplier: '0x',\n buyLink: 'https://traderjoexyz.com/pool/0xD9FF12172803c072a36785DeFea1Aa981A6A0C18/0xf8D0C6c3ddC03F43A0687847f2b34bfd6941C2A2',\n site: 'https://2omb.finance',\n sort: 14,\n closedForStaking: false,\n },\n FudgeLPTShareRewardPool: {\n name: 'Earn STRAW by Staking Fudge',\n poolId: 3,\n sectionInUI: 2,\n contract: 'FudgeLPTShareRewardPool',\n depositTokenName: 'FUDGE',\n earnTokenName: 'STRAW',\n finished: false,\n multiplier: '6875x',\n buyLink: 'https://traderjoexyz.com/trade#/0xD9FF12172803c072a36785DeFea1Aa981A6A0C18',\n site: 'https://2omb.finance',\n sort: 11,\n closedForStaking: false,\n },\n FudgeCreamLPTShareRewardPool: {\n name: 'Earn STRAW by FUDGE-CREAM LP',\n poolId: 4,\n sectionInUI: 0,\n contract: 'FudgeCreamLPTShareRewardPool',\n depositTokenName: 'FUDGE-CREAM LP',\n earnTokenName: 'STRAW',\n finished: false,\n multiplier: '0x',\n buyLink: 'https://traderjoexyz.com/pool/0xAE21d31a6494829a9E4B2B291F4984AAE8121757/0xD9FF12172803c072a36785DeFea1Aa981A6A0C18',\n site: '',\n sort: 12,\n closedForStaking: false,\n },\n CreamStrawLPTShareRewardPool: {\n name: 'Earn STRAW by CREAM-STRAW LP',\n poolId: 5,\n sectionInUI: 0,\n contract: 'CreamStrawLPTShareRewardPool',\n depositTokenName: 'CREAM-STRAW LP',\n earnTokenName: 'STRAW',\n finished: false,\n multiplier: '0x',\n buyLink: 'https://traderjoexyz.com/pool/0xAE21d31a6494829a9E4B2B291F4984AAE8121757/0xf8D0C6c3ddC03F43A0687847f2b34bfd6941C2A2',\n site: '',\n sort: 13,\n closedForStaking: false,\n },\n CreamRewardPool: {\n name: 'Earn STRAW by staking CREAM',\n poolId: 6,\n sectionInUI: 0,\n contract: 'CreamRewardPool',\n depositTokenName: 'CREAM',\n earnTokenName: 'STRAW',\n finished: false,\n multiplier: '0x',\n site: 'https://abracadabra.money/',\n buyLink: 'https://traderjoexyz.com/trade?outputCurrency=0xAE21d31a6494829a9E4B2B291F4984AAE8121757#/',\n sort: 10,\n closedForStaking: false,\n },\n\n MasterNode: {\n name: 'Generate FUDGE with Nodes',\n poolId: 0,\n sectionInUI: 3,\n contract: 'MasterNode',\n depositTokenName: 'FUDGE',\n earnTokenName: 'FUDGE',\n finished: false,\n multiplier: 'NODE',\n site: 'sundaefinance.app',\n buyLink: 'https://traderjoexyz.com/trade#/0xD9FF12172803c072a36785DeFea1Aa981A6A0C18',\n sort: 2,\n closedForStaking: false,\n },\n\n\n};\n\nexport default configurations['production'];\n","import { createAction } from '@reduxjs/toolkit';\n\nexport type PopupContent = {\n txn?: {\n hash: string;\n success: boolean;\n summary?: string;\n };\n error?: {\n message: string;\n stack: string;\n };\n};\n\nexport const updateBlockNumber = createAction<{ chainId: number; blockNumber: number }>('app/updateBlockNumber');\n\nexport const toggleWalletModal = createAction('app/toggleWalletModal');\n\nexport const toggleSettingsMenu = createAction('app/toggleSettingsMenu');\n\nexport const addPopup = createAction<{\n key?: string;\n removeAfterMs?: number | null;\n content: PopupContent;\n}>('app/addPopup');\n\nexport const removePopup = createAction<{ key: string }>('app/removePopup');\n","export const TOMB_TICKER = 'FUDGE';\nexport const TSHARE_TICKER = 'STRAW';\nexport const TBOND_TICKER = 'CARAML';\nexport const FTM_TICKER = 'DAI';\nexport const WFTM_TICKER = 'DAI';\nexport const SPOOKY_ROUTER_ADDR = '0x60aE616a2155Ee3d9A68541Ba4544862310933d4';\nexport const ZAPPER_ROUTER_ADDR = '0x0d0E877F52A3FBEa9f6682102b613aDDBE0CF972';\nexport const TAX_OFFICE_ADDR = '0x2A637BEE0D76136d8ee44B96cf0A5f9198657AaF';","import { useEffect, useState } from 'react';\nimport config from './../config';\n\nconst usePromptNetwork = () => {\n const [networkPrompt, setNetworkPrompt] = useState(false);\n const { ethereum } = window as any;\n\n /**\n * For more read https://github.com/NoahZinsmeister/web3-react/blob/6737868693adb7e1e28ae80499e19901e9aae45a/example/hooks.ts#L33\n * And https://docs.metamask.io/guide/ethereum-provider.html\n * @param provider ethereum provider in this case is the window.ethereum available due to metamask being installed\n * @returns\n */\n const connectToNetwork = async (provider: any) => {\n await provider.request({\n method: 'wallet_addEthereumChain',\n params: [\n {\n chainId: `0x${config.chainId.toString(16)}`,\n chainName: config.networkName,\n nativeCurrency: {\n name: 'FTM',\n symbol: 'ftm',\n decimals: 18,\n },\n rpcUrls: [config.defaultProvider],\n blockExplorerUrls: [config.ftmscanUrl],\n },\n ],\n });\n };\n useEffect(() => {\n if (!networkPrompt) {\n if (ethereum && ethereum.networkVersion !== config.chainId.toString()) {\n connectToNetwork(ethereum);\n setNetworkPrompt(true);\n }\n }\n }, [networkPrompt, ethereum]);\n};\n\nexport default usePromptNetwork;\n","import { createReducer } from '@reduxjs/toolkit';\nimport {\n addTransaction,\n checkedTransaction,\n clearAllTransactions,\n finalizeTransaction,\n SerializableTransactionReceipt,\n} from './actions';\n\nconst now = () => new Date().getTime();\n\nexport interface TransactionDetails {\n hash: string;\n approval?: { tokenAddress: string; spender: string };\n summary?: string;\n receipt?: SerializableTransactionReceipt;\n lastCheckedBlockNumber?: number;\n addedTime: number;\n confirmedTime?: number;\n from: string;\n}\n\nexport interface TransactionState {\n [chainId: number]: {\n [txHash: string]: TransactionDetails;\n };\n}\n\nexport const initialState: TransactionState = {};\n\nexport default createReducer(initialState, (builder) =>\n builder\n .addCase(addTransaction, (transactions, { payload: { chainId, from, hash, approval, summary } }) => {\n if (transactions[chainId]?.[hash]) {\n throw Error('Attempted to add existing transaction.');\n }\n const txs = transactions[chainId] ?? {};\n txs[hash] = { hash, approval, summary, from, addedTime: now() };\n transactions[chainId] = txs;\n })\n .addCase(clearAllTransactions, (transactions, { payload: { chainId } }) => {\n if (!transactions[chainId]) return;\n transactions[chainId] = {};\n })\n .addCase(checkedTransaction, (transactions, { payload: { chainId, hash, blockNumber } }) => {\n const tx = transactions[chainId]?.[hash];\n if (!tx) {\n return;\n }\n if (!tx.lastCheckedBlockNumber) {\n tx.lastCheckedBlockNumber = blockNumber;\n } else {\n tx.lastCheckedBlockNumber = Math.max(blockNumber, tx.lastCheckedBlockNumber);\n }\n })\n .addCase(finalizeTransaction, (transactions, { payload: { hash, chainId, receipt } }) => {\n const tx = transactions[chainId]?.[hash];\n if (!tx) {\n return;\n }\n tx.receipt = receipt;\n tx.confirmedTime = now();\n }),\n);\n","import { createReducer, nanoid } from '@reduxjs/toolkit';\nimport {\n addPopup,\n PopupContent,\n removePopup,\n toggleWalletModal,\n toggleSettingsMenu,\n updateBlockNumber,\n} from './actions';\n\ntype PopupList = Array<{\n key: string;\n show: boolean;\n content: PopupContent;\n removeAfterMs: number | null;\n}>;\n\nexport interface ApplicationState {\n blockNumber: { [chainId: number]: number };\n popupList: PopupList;\n walletModalOpen: boolean;\n settingsMenuOpen: boolean;\n}\n\nconst initialState: ApplicationState = {\n blockNumber: {},\n popupList: [],\n walletModalOpen: false,\n settingsMenuOpen: false,\n};\n\nexport default createReducer(initialState, (builder) =>\n builder\n .addCase(updateBlockNumber, (state, action) => {\n const { chainId, blockNumber } = action.payload;\n if (typeof state.blockNumber[chainId] !== 'number') {\n state.blockNumber[chainId] = blockNumber;\n } else {\n state.blockNumber[chainId] = Math.max(blockNumber, state.blockNumber[chainId]);\n }\n })\n .addCase(toggleWalletModal, (state) => {\n state.walletModalOpen = !state.walletModalOpen;\n })\n .addCase(toggleSettingsMenu, (state) => {\n state.settingsMenuOpen = !state.settingsMenuOpen;\n })\n .addCase(addPopup, (state, { payload: { content, key, removeAfterMs = 15000 } }) => {\n state.popupList = (key ? state.popupList.filter((popup) => popup.key !== key) : state.popupList).concat([\n {\n key: key || nanoid(),\n show: true,\n content,\n removeAfterMs,\n },\n ]);\n })\n .addCase(removePopup, (state, { payload: { key } }) => {\n state.popupList.forEach((p) => {\n if (p.key === key) {\n p.show = false;\n }\n });\n }),\n);\n","import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';\nimport { save, load } from 'redux-localstorage-simple';\nimport transactions from './transactions/reducer';\nimport application from './application/reducer';\n\nconst PERSISTED_KEYS: string[] = ['transactions'];\n\nconst store = configureStore({\n reducer: {\n application,\n transactions,\n },\n middleware: [...getDefaultMiddleware({ thunk: false }), save({ states: PERSISTED_KEYS })],\n preloadedState: load({ states: PERSISTED_KEYS }),\n});\n\nexport default store;\n\nexport type AppState = ReturnType;\nexport type AppDispatch = typeof store.dispatch;\n","export const white = '#FFF';\nexport const black = '#000';\n\nexport const green = {\n 500: '#00D110',\n};\n\nexport const purple = {\n 200: '#bd7cfe',\n 400: '#ab47bc',\n 700: '#7b1fa2',\n};\n\nexport const red = {\n 100: '#C1C1FF',\n 200: '#7575FF',\n 500: '#9090FF',\n};\n\nexport const grey = {\n 100: '#f5f5f5',\n 200: '#eeeeee',\n 300: '#e0e0e0',\n 400: '#bdbdbd',\n 500: '#9e9e9e',\n 600: '#757575',\n 700: '#616161',\n 800: '#424242',\n 900: '#212121',\n};\n\nexport const bg = '#000000';\n\nexport const teal = {\n 200: '#64ffda',\n};\n","import { black, purple, teal, grey, red, white } from './colors';\n\nconst theme = {\n borderRadius: 12,\n color: {\n black,\n grey,\n purple,\n primary: {\n light: red[200],\n main: red[500],\n },\n secondary: {\n main: grey[400],\n },\n white,\n teal,\n },\n siteWidth: 1200,\n spacing: {\n 1: 4,\n 2: 8,\n 3: 16,\n 4: 24,\n 5: 32,\n 6: 48,\n 7: 64,\n },\n topBarSize: 72,\n};\n\nexport default theme;\n","//Your theme for the new stuff using material UI has been copied here so it doesn't conflict\nimport { createMuiTheme } from '@material-ui/core/styles';\n\nconst newTheme = createMuiTheme({\n palette: {\n type: 'dark',\n text: {\n primary: '#000',\n },\n background: {\n default: '#121212',\n paper: 'rgba(255, 255, 255, 0.9)',\n },\n primary: {\n light: '#dd0093',\n main: '#ff0093',\n dark: '#ef0093',\n contrastText: '#000',\n },\n discord :{\n light: '#6043f7',\n main: '#6043f7',\n },\n secondary: {\n light: '#6043f7',\n main: '#6043f7',\n dark: '#757ce8',\n contrastText: '#000',\n },\n action: {\n disabledBackground: '#CDCDCD',\n active: '#000',\n hover: '#000',\n },\n },\n typography: {\n color: '#E6E9EE',\n fontFamily: ['\"Gilroy\"', 'sans-serif'].join(','),\n },\n});\n\nexport default newTheme;\n","import { useCallback, useEffect, useState } from 'react';\n\nconst VISIBILITY_STATE_SUPPORTED = 'visibilityState' in document;\n\nfunction isWindowVisible() {\n return !VISIBILITY_STATE_SUPPORTED || document.visibilityState !== 'hidden';\n}\n\n/**\n * Returns whether the window is currently visible to the user.\n */\nexport default function useIsWindowVisible(): boolean {\n const [focused, setFocused] = useState(isWindowVisible());\n const listener = useCallback(() => {\n setFocused(isWindowVisible());\n }, [setFocused]);\n\n useEffect(() => {\n if (!VISIBILITY_STATE_SUPPORTED) return undefined;\n\n document.addEventListener('visibilitychange', listener);\n return () => {\n document.removeEventListener('visibilitychange', listener);\n };\n }, [listener]);\n\n return focused;\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useWallet } from 'use-wallet';\nimport useDebounce from '../../hooks/useDebounce';\nimport useIsWindowVisible from '../../hooks/useIsWindowVisible';\nimport { updateBlockNumber } from './actions';\nimport { getDefaultProvider } from '../../utils/provider';\n\nexport default function Updater(): null {\n const { ethereum, chainId } = useWallet();\n\n const dispatch = useDispatch();\n\n const windowVisible = useIsWindowVisible();\n\n const [state, setState] = useState<{\n chainId: number | undefined;\n blockNumber: number | null;\n }>({\n chainId,\n blockNumber: null,\n });\n\n const blockNumberCallback = useCallback(\n (blockNumber: number) => {\n setState((state) => {\n if (chainId === state.chainId) {\n if (typeof state.blockNumber !== 'number') return { chainId, blockNumber };\n return { chainId, blockNumber: Math.max(blockNumber, state.blockNumber) };\n }\n return state;\n });\n },\n [chainId, setState],\n );\n\n // attach/detach listeners\n // @ts-ignore\n useEffect(() => {\n if (!ethereum || !chainId || !windowVisible) return undefined;\n setState({ chainId, blockNumber: null });\n\n const provider = getDefaultProvider();\n provider\n .getBlockNumber()\n .then(blockNumberCallback)\n .catch((error) => console.error(`Failed to get block number for chainId: ${chainId}`, error));\n\n provider.on('block', blockNumberCallback);\n return () => provider.removeListener('block', blockNumberCallback);\n }, [dispatch, chainId, ethereum, blockNumberCallback, windowVisible]);\n\n const debouncedState = useDebounce(state, 100);\n\n useEffect(() => {\n if (!debouncedState.chainId || !debouncedState.blockNumber || !windowVisible) return;\n dispatch(\n updateBlockNumber({\n chainId: debouncedState.chainId,\n blockNumber: debouncedState.blockNumber,\n }),\n );\n }, [windowVisible, dispatch, debouncedState.blockNumber, debouncedState.chainId]);\n\n return null;\n}\n","import { useEffect, useState } from 'react';\n\n// modified from https://usehooks.com/useDebounce/\nexport default function useDebounce(value: T, delay: number): T {\n const [debouncedValue, setDebouncedValue] = useState(value);\n\n useEffect(() => {\n // Update debounced value after delay\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n // Cancel the timeout if value changes (also on delay change or unmount)\n // This is how we prevent debounced value from updating if value is changed ...\n // .. within the delay period. Timeout gets cleared and restarted.\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n","import { useEffect } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useWallet } from 'use-wallet';\nimport { useAddPopup, useBlockNumber } from '../application/hooks';\nimport { AppDispatch, AppState } from '../index';\nimport { checkedTransaction, finalizeTransaction } from './actions';\nimport { getDefaultProvider } from '../../utils/provider';\n\nexport function shouldCheck(\n lastBlockNumber: number,\n tx: { addedTime: number; receipt?: {}; lastCheckedBlockNumber?: number },\n): boolean {\n if (tx.receipt) return false;\n if (!tx.lastCheckedBlockNumber) return true;\n const blocksSinceCheck = lastBlockNumber - tx.lastCheckedBlockNumber;\n if (blocksSinceCheck < 1) return false;\n const minutesPending = (new Date().getTime() - tx.addedTime) / 1000 / 60;\n if (minutesPending > 60) {\n // every 10 blocks if pending for longer than an hour\n return blocksSinceCheck > 9;\n } else if (minutesPending > 5) {\n // every 3 blocks if pending more than 5 minutes\n return blocksSinceCheck > 2;\n } else {\n // otherwise every block\n return true;\n }\n}\n\nexport default function Updater(): null {\n const { chainId, ethereum } = useWallet();\n\n const lastBlockNumber = useBlockNumber();\n\n const dispatch = useDispatch();\n const state = useSelector((state) => state.transactions);\n\n const transactions = chainId ? state[chainId] ?? {} : {};\n\n // show popup on confirm\n const addPopup = useAddPopup();\n\n useEffect(() => {\n if (!chainId || !ethereum || !lastBlockNumber) {\n return;\n }\n\n const provider = getDefaultProvider();\n Object.keys(transactions)\n .filter((hash) => shouldCheck(lastBlockNumber, transactions[hash]))\n .forEach((hash) => {\n provider\n .getTransactionReceipt(hash)\n .then((receipt) => {\n if (receipt) {\n dispatch(\n finalizeTransaction({\n chainId,\n hash,\n receipt: {\n blockHash: receipt.blockHash,\n blockNumber: receipt.blockNumber,\n contractAddress: receipt.contractAddress,\n from: receipt.from,\n status: receipt.status,\n to: receipt.to,\n transactionHash: receipt.transactionHash,\n transactionIndex: receipt.transactionIndex,\n },\n }),\n );\n\n addPopup(\n {\n txn: {\n hash,\n success: receipt.status === 1,\n summary: transactions[hash]?.summary,\n },\n },\n hash,\n );\n } else {\n dispatch(checkedTransaction({ chainId, hash, blockNumber: lastBlockNumber }));\n }\n })\n .catch((error) => {\n console.error(`failed to check transaction hash: ${hash}`, error);\n });\n });\n }, [chainId, ethereum, transactions, lastBlockNumber, dispatch, addPopup]);\n\n return null;\n}\n","import React from 'react';\nimport ApplicationUpdater from './application/updater';\nimport TransactionUpdater from './transactions/updater';\n\nconst Updaters = () => (\n <>\n \n \n \n);\n\nexport default Updaters;\n","import React from 'react';\nimport Typography from '@material-ui/core/Typography';\n\nconst Loader = () => {\n return (\n \n Loading\n \n );\n};\n\nexport default Loader;\n","import Loader from './Loader';\n\nexport default Loader;\n","import React, { useContext } from 'react';\nimport { AlertCircle, CheckCircle } from 'react-feather';\nimport styled, { ThemeContext } from 'styled-components';\nimport { useWallet } from 'use-wallet';\nimport config from '../../config';\n\nconst RowNoFlex = styled.div`\n flex-wrap: nowrap;\n`;\n\nexport default function TransactionPopup({\n hash,\n success,\n summary,\n}: {\n hash: string;\n success?: boolean;\n summary?: string;\n}) {\n const { chainId } = useWallet();\n const theme = useContext(ThemeContext);\n\n return (\n \n
\n {success ? : }\n
\n
\n {summary ?? 'Hash: ' + hash.slice(0, 8) + '...' + hash.slice(58, 65)}\n {chainId && (\n \n View on Snowtrace\n \n )}\n
\n
\n );\n}\n\nconst StyledPopupDesc = styled.span`\n font-weight: 500;\n color: ${(props) => props.theme.color.grey[300]};\n`;\n\nconst StyledLink = styled.a`\n color: ${(props) => props.theme.color.grey[500]};\n`;\n","import React, { useCallback } from 'react';\nimport { AlertCircle } from 'react-feather';\nimport styled from 'styled-components';\n\nconst RowNoFlex = styled.div`\n flex-wrap: nowrap;\n`;\n\nexport default function ErrorPopup({ message, stack }: { message: string; stack: string }) {\n const copyErrorDetails = useCallback(async () => {\n await navigator.clipboard.writeText(`${message}\\n${stack}`);\n }, [message, stack]);\n\n return (\n \n
\n \n
\n
\n {message}\n \n Copy error details\n \n
\n
\n );\n}\n\nconst StyledPopupDesc = styled.span`\n font-weight: 500;\n color: ${(props) => props.theme.color.grey[300]};\n`;\n\nconst StyledLink = styled.a`\n color: ${(props) => props.theme.color.grey[500]};\n`;\n","import React, { useCallback, useContext, useEffect } from 'react';\nimport { X } from 'react-feather';\nimport { useSpring } from 'react-spring/web';\nimport styled, { ThemeContext } from 'styled-components';\nimport { animated } from 'react-spring';\nimport { PopupContent } from '../../state/application/actions';\nimport { useRemovePopup } from '../../state/application/hooks';\nimport TransactionPopup from './TransactionPopup';\nimport ErrorPopup from './ErrorPopup';\n\nexport const StyledClose = styled(X)`\n position: absolute;\n right: 10px;\n top: 10px;\n\n :hover {\n cursor: pointer;\n }\n`;\nexport const Popup = styled.div`\n display: inline-block;\n width: 100%;\n padding: 1em;\n background-color: ${({ theme }) => theme.color.grey[700]};\n position: relative;\n border-radius: 10px;\n padding: 20px;\n padding-right: 35px;\n overflow: hidden;\n\n @media (max-width: 768px) {\n min-width: 290px;\n }\n`;\nconst Fader = styled.div`\n position: absolute;\n bottom: 0px;\n left: 0px;\n width: 100%;\n height: 2px;\n background-color: ${({ theme }) => theme.color.grey[400]};\n`;\n\nconst AnimatedFader = animated(Fader);\n\nexport default function PopupItem({\n removeAfterMs,\n content,\n popKey,\n}: {\n removeAfterMs: number | null;\n content: PopupContent;\n popKey: string;\n}) {\n const removePopup = useRemovePopup();\n const removeThisPopup = useCallback(() => removePopup(popKey), [popKey, removePopup]);\n useEffect(() => {\n if (removeAfterMs === null) return undefined;\n\n const timeout = setTimeout(() => {\n removeThisPopup();\n }, removeAfterMs);\n\n return () => {\n clearTimeout(timeout);\n };\n }, [removeAfterMs, removeThisPopup]);\n\n const theme = useContext(ThemeContext);\n\n let popupContent;\n if ('txn' in content) {\n const {\n txn: { hash, success, summary },\n } = content;\n popupContent = ;\n }\n if ('error' in content) {\n const {\n error: { message, stack },\n } = content;\n popupContent = ;\n }\n\n const faderStyle = useSpring({\n from: { width: '100%' },\n to: { width: '0%' },\n config: { duration: removeAfterMs ?? undefined },\n });\n\n return (\n \n \n {popupContent}\n {removeAfterMs !== null ? : null}\n \n );\n}\n","import React from 'react';\nimport styled from 'styled-components';\nimport { useActivePopups } from '../../state/application/hooks';\nimport PopupItem from './PopupItem';\n\nconst MobilePopupWrapper = styled.div<{ height: string | number }>`\n position: relative;\n max-width: 100%;\n height: ${({ height }) => height};\n margin: ${({ height }) => (height ? '0 auto;' : 0)};\n margin-bottom: ${({ height }) => (height ? '20px' : 0)}};\n\n display: none;\n @media (max-width: 768px) {\n display: block;\n };\n`;\n\nconst MobilePopupInner = styled.div`\n height: 99%;\n overflow-x: auto;\n overflow-y: hidden;\n display: flex;\n flex-direction: row;\n -webkit-overflow-scrolling: touch;\n ::-webkit-scrollbar {\n display: none;\n }\n`;\n\nconst FixedPopupColumn = styled.div`\n position: fixed;\n top: 64px;\n margin-right: 24px;\n right: 3rem;\n max-width: 355px !important;\n width: 100%;\n z-index: 2;\n\n @media (max-width: 768px) {\n display: none;\n } ;\n`;\n\nexport default function Popups() {\n // get all popups\n const activePopups = useActivePopups();\n\n return (\n <>\n \n {activePopups.map((item) => (\n \n ))}\n \n 0 ? 'fit-content' : 0}>\n \n {activePopups // reverse so new items up front\n .slice(0)\n .reverse()\n .map((item) => (\n \n ))}\n \n \n \n );\n}\n","import React, { Suspense, lazy } from 'react';\nimport { Provider } from 'react-redux';\nimport { HashRouter as Router, Route, Switch } from 'react-router-dom';\nimport { ThemeProvider as TP } from '@material-ui/core/styles';\nimport { ThemeProvider as TP1 } from 'styled-components';\nimport { UseWalletProvider } from 'use-wallet';\nimport usePromptNetwork from './hooks/useNetworkPrompt';\nimport BanksProvider from './contexts/Banks';\nimport TombFinanceProvider from './contexts/TombFinanceProvider';\nimport ModalsProvider from './contexts/Modals';\nimport store from './state';\nimport theme from './theme';\nimport newTheme from './newTheme';\nimport config from './config';\nimport Updaters from './state/Updaters';\nimport Loader from './components/Loader';\nimport Popups from './components/Popups';\nimport Regulations from './views/Regulations/Regulations';\nimport { RefreshContextProvider } from './contexts/RefreshContext';\nimport Particles from 'react-tsparticles'; //'react-particles-js';\n\nconst Home = lazy(() => import('./views/Home'));\nconst Farms = lazy(() => import('./views/Cemetery'));\nconst Boardroom = lazy(() => import('./views/Masonry'));\nconst Rebates = lazy(() => import('./views/Rebates'));\nconst Bonds = lazy(() => import('./views/Pit'));\nconst Treasury = lazy(() => import('./views/Treasury'));\n// const SBS = lazy(() => import('./views/Sbs'));\n// const Liquidity = lazy(() => import('./views/Liquidity'));\n\nconst NoMatch = () => (\n

\n URL Not Found. Go back home.\n

\n);\n\nconst App: React.FC = () => {\n // Clear localStorage for mobile users\n if (typeof localStorage.version_app === 'undefined' || localStorage.version_app !== '1.1') {\n localStorage.clear();\n localStorage.setItem('connectorId', '');\n localStorage.setItem('version_app', '1.1');\n }\n\n usePromptNetwork();\n\n return (\n
\n {/* */}\n \n \n }>\n \n \n \n \n {/* \n \n */}\n \n \n {/* \n \n \n \n \n \n \n \n */}\n \n \n \n \n \n
\n );\n};\n\nconst Providers: React.FC = ({ children }) => {\n return (\n \n \n \n \n \n \n \n \n \n <>\n \n {children}\n \n \n \n \n \n \n \n \n \n );\n};\n\nexport default App;\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(/^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/),\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA',\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then((registration) => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n // console.log(\n // 'New content is available and will be used when all ' +\n // 'tabs for this page are closed. See https://bit.ly/CRA-PWA.',\n // );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n //console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch((error) => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' },\n })\n .then((response) => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1)) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then((registration) => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log('No internet connection found. App is running in offline mode.');\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready\n .then((registration) => {\n registration.unregister();\n })\n .catch((error) => {\n console.error(error.message);\n });\n }\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport * as serviceWorker from './serviceWorker';\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root'),\n);\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n","import { createAction } from '@reduxjs/toolkit';\n// import { ChainId } from '@uniswap/sdk';\n// import { ChainId } from '@spookyswap/sdk';\nimport { ChainId } from '@traderjoe-xyz/sdk';\n\nexport interface SerializableTransactionReceipt {\n to: string;\n from: string;\n contractAddress: string;\n transactionIndex: number;\n blockHash: string;\n transactionHash: string;\n blockNumber: number;\n status?: number;\n}\n\nexport const addTransaction = createAction<{\n chainId: ChainId;\n hash: string;\n from: string;\n approval?: { tokenAddress: string; spender: string };\n summary?: string;\n}>('transactions/addTransaction');\n\nexport const clearAllTransactions = createAction<{ chainId: ChainId }>('transactions/clearAllTransactions');\n\nexport const finalizeTransaction = createAction<{\n chainId: ChainId;\n hash: string;\n receipt: SerializableTransactionReceipt;\n}>('transactions/finalizeTransaction');\n\nexport const checkedTransaction = createAction<{\n chainId: ChainId;\n hash: string;\n blockNumber: number;\n}>('transactions/checkedTransaction');\n","import { useCallback, useMemo } from 'react';\nimport { addPopup, PopupContent, removePopup, toggleWalletModal, toggleSettingsMenu } from './actions';\nimport { useSelector, useDispatch } from 'react-redux';\nimport { AppState } from '../index';\nimport { useWallet } from 'use-wallet';\n\nexport function useBlockNumber(): number | undefined {\n const { chainId } = useWallet();\n return useSelector((state: AppState) => state.application.blockNumber[chainId ?? -1]);\n}\n\nexport function useWalletModalOpen(): boolean {\n return useSelector((state: AppState) => state.application.walletModalOpen);\n}\n\nexport function useWalletModalToggle(): () => void {\n const dispatch = useDispatch();\n return useCallback(() => dispatch(toggleWalletModal()), [dispatch]);\n}\n\nexport function useSettingsMenuOpen(): boolean {\n return useSelector((state: AppState) => state.application.settingsMenuOpen);\n}\n\nexport function useToggleSettingsMenu(): () => void {\n const dispatch = useDispatch();\n return useCallback(() => dispatch(toggleSettingsMenu()), [dispatch]);\n}\n\n// returns a function that allows adding a popup\nexport function useAddPopup(): (content: PopupContent, key?: string) => void {\n const dispatch = useDispatch();\n\n return useCallback(\n (content: PopupContent, key?: string) => {\n dispatch(addPopup({ content, key }));\n },\n [dispatch],\n );\n}\n\n// returns a function that allows removing a popup via its key\nexport function useRemovePopup(): (key: string) => void {\n const dispatch = useDispatch();\n return useCallback(\n (key: string) => {\n dispatch(removePopup({ key }));\n },\n [dispatch],\n );\n}\n\n// get the list of active popups\nexport function useActivePopups(): AppState['application']['popupList'] {\n const list = useSelector((state: AppState) => state.application.popupList);\n return useMemo(() => list.filter((item) => item.show), [list]);\n}\n","import { Deployments } from './deployments';\nimport { ChainId } from '@traderjoe-xyz/sdk';\n\nexport type Configuration = {\n chainId: ChainId;\n networkName: string;\n ftmscanUrl: string;\n defaultProvider: string;\n deployments: Deployments;\n externalTokens: { [contractName: string]: [string, number] };\n config?: EthereumConfig;\n\n baseLaunchDate: Date;\n bondLaunchesAt: Date;\n masonryLaunchesAt: Date;\n\n refreshInterval: number;\n};\n\nexport type EthereumConfig = {\n testing: boolean;\n autoGasMultiplier: number;\n defaultConfirmations: number;\n defaultGas: string;\n defaultGasPrice: string;\n ethereumNodeTimeout: number;\n};\n\nexport const defaultEthereumConfig = {\n testing: false,\n autoGasMultiplier: 1.5,\n defaultConfirmations: 1,\n defaultGas: '6000000',\n defaultGasPrice: '1000000000000',\n ethereumNodeTimeout: 10000,\n};\n","import Web3 from 'web3';\nimport { defaultEthereumConfig, EthereumConfig } from './config';\nimport { formatUnits, parseUnits } from 'ethers/lib/utils';\nimport { BigNumber } from 'ethers';\n\nexport function web3ProviderFrom(endpoint: string, config?: EthereumConfig): any {\n const ethConfig = Object.assign(defaultEthereumConfig, config || {});\n\n const providerClass = endpoint.includes('wss') ? Web3.providers.WebsocketProvider : Web3.providers.HttpProvider;\n\n return new providerClass(endpoint, {\n timeout: ethConfig.ethereumNodeTimeout,\n });\n}\n\nexport function balanceToDecimal(s: string): string {\n return formatUnits(s);\n}\n\nexport function decimalToBalance(d: string | number, decimals = 18): BigNumber {\n return parseUnits(String(d), decimals);\n}\n"],"sourceRoot":""}