{"version":3,"sources":["webpack:///./src/pages/tools/impermanent-loss-calculator.js","webpack:///./src/components/page-layout.js","webpack:///./src/components/seo.js"],"names":["Header","styled","h1","HeaderInfo","div","HeaderInfoRow","p","Section","SectionTitle","h3","InputRow","InputLabel","span","InputBox","Input","input","Results","calculcateImpermanentLoss","priceInitialA","priceInitialB","priceFutureA","priceFutureB","tokenQtyStartB","constantProduct","priceAInBFinal","tokenQtyFutureA","aPrice","Math","sqrt","calcAPoolSize","tokenQtyFutureB","calcBPoolSize","impermanentLoss","formatNumber","num","decimalPlaces","numberWithCommas","toFixed","x","toString","replace","ImpermanentLossCalculator","qtyTokenAInitialExample","qtyTokenBInitialExample","qtyTokenAFutureExample","qtyTokenBFutureExample","totalHoldWorth","totalLiquidityWorth","useState","setPriceInitialA","setPriceInitialB","setPriceFutureA","setPriceFutureB","impermanentLossRes","isValidInput","showAffiliateLink","title","description","href","value","onChange","e","target","type","min","PageContainer","HeaderLeft","HeaderRight","SiteTitle","StyledLink","Link","TwitterLink","a","AboutLink","Body","Footer","FooterText","PageLayout","children","data","useStaticQuery","to","site","siteMetadata","rel","SEO","lang","meta","metaDescription","htmlAttributes","name","content","property","author","concat","defaultProps"],"mappings":"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","file":"component---src-pages-tools-impermanent-loss-calculator-js-49db31351e1b3afcfb9c.js","sourcesContent":["import React, { useState } from \"react\"\r\nimport PageLayout from \"../../components/page-layout\"\r\nimport SEO from \"../../components/seo\"\r\nimport styled from \"styled-components\"\r\n\r\nconst Header = styled.h1`\r\n @media (max-width: 540px) {\r\n margin-top: 0.5rem;\r\n }\r\n`\r\n\r\nconst HeaderInfo = styled.div`\r\n padding-bottom: 0.25rem;\r\n`\r\n\r\nconst HeaderInfoRow = styled.p``\r\n\r\nconst Section = styled.div``\r\n\r\nconst SectionTitle = styled.h3``\r\n\r\nconst InputRow = styled.div`\r\n padding-bottom: 1rem;\r\n`\r\n\r\nconst InputLabel = styled.span`\r\n padding-right: 12px;\r\n\r\n &::after {\r\n content: '-';\r\n padding-left: 10px;\r\n }\r\n`\r\n\r\nconst InputBox = styled.div`\r\n border: 1px solid #ccc;\r\n border-radius: 10px;\r\n display: inline-block;\r\n padding: 0.2rem;\r\n padding-left: 0.5rem;\r\n`\r\n\r\nconst Input = styled.input`\r\n padding: .3rem;\r\n padding-left: 0.2rem;\r\n border: none;\r\n width: 80px;\r\n font-size: 1rem;\r\n\r\n &:focus {\r\n outline: none;\r\n }\r\n`\r\n\r\nconst Results = styled.div``\r\n\r\nconst calcAPoolSize = (aPrice, constantProduct) => {\r\n return Math.sqrt(constantProduct / aPrice)\r\n}\r\n\r\nconst calcBPoolSize = (aPrice, constantProduct) => {\r\n return Math.sqrt(constantProduct * aPrice)\r\n}\r\n\r\nconst calculcateImpermanentLoss = (priceInitialA, priceInitialB, priceFutureA, priceFutureB) => {\r\n const priceAInBInitial = priceInitialA / priceInitialB\r\n const tokenQtyStartA = 1\r\n const tokenQtyStartB = tokenQtyStartA * priceAInBInitial\r\n const constantProduct = tokenQtyStartA * tokenQtyStartB\r\n\r\n const priceAInBFinal = priceFutureA / priceFutureB\r\n const tokenQtyFutureA = calcAPoolSize(priceAInBFinal, constantProduct)\r\n const tokenQtyFutureB = calcBPoolSize(priceAInBFinal, constantProduct)\r\n\r\n const valueIfHeld = (tokenQtyStartA * priceFutureA) + (tokenQtyStartB * priceFutureB)\r\n const valueIfProvidedLiquidity = (tokenQtyFutureA * priceFutureA) + (tokenQtyFutureB * priceFutureB)\r\n const pctRemaining = (valueIfProvidedLiquidity / valueIfHeld) * 100\r\n const impermanentLoss = (pctRemaining - 100) * -1\r\n\r\n return {\r\n impermanentLoss,\r\n tokenQtyFutureA,\r\n tokenQtyFutureB\r\n }\r\n}\r\n\r\nconst formatNumber = (num, decimalPlaces) => {\r\n return numberWithCommas(num.toFixed(decimalPlaces))\r\n}\r\n\r\nconst isValidInput = (priceInitialA, priceInitialB, priceFutureA, priceFutureB) => {\r\n return (priceInitialA && priceInitialB && priceFutureA && priceFutureB)\r\n && (priceInitialA > 0 && priceInitialB > 0 && priceFutureA > 0&& priceFutureB > 0)\r\n}\r\n\r\nconst numberWithCommas = x => {\r\n return x.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\")\r\n}\r\n\r\nexport default function ImpermanentLossCalculator() {\r\n const [priceInitialA, setPriceInitialA] = useState(0)\r\n const [priceInitialB, setPriceInitialB] = useState(0)\r\n const [priceFutureA, setPriceFutureA] = useState(0)\r\n const [priceFutureB, setPriceFutureB] = useState(0)\r\n\r\n const impermanentLossRes = isValidInput(priceInitialA, priceInitialB, priceFutureA, priceFutureB)\r\n ? calculcateImpermanentLoss(priceInitialA, priceInitialB, priceFutureA, priceFutureB)\r\n : null\r\n\r\n const renderResults = ({impermanentLoss, tokenQtyFutureA, tokenQtyFutureB}) => {\r\n const qtyTokenAInitialExample = 500 / priceInitialA\r\n const qtyTokenBInitialExample = 500 / priceInitialB\r\n const qtyTokenAFutureExample = tokenQtyFutureA * qtyTokenAInitialExample\r\n const qtyTokenBFutureExample = tokenQtyFutureB * qtyTokenAInitialExample\r\n\r\n const tokenAHoldWorth = qtyTokenAInitialExample * priceFutureA\r\n const tokenBHoldWorth = qtyTokenBInitialExample * priceFutureB\r\n const totalHoldWorth = tokenAHoldWorth + tokenBHoldWorth\r\n\r\n const tokenALiquidtyWorth = qtyTokenAFutureExample * priceFutureA\r\n const tokenBLiquidityWorth = qtyTokenBFutureExample * priceFutureB\r\n const totalLiquidityWorth = tokenALiquidtyWorth + tokenBLiquidityWorth\r\n\r\n return (\r\n \r\n

{`Impermanent loss: ${formatNumber(impermanentLoss, 2)}%`}

\r\n
\r\n\r\n

If $500 of Token A and $500 of Token B were held

\r\n

{`- Have ${formatNumber(qtyTokenAInitialExample, 2)} Token A and ${formatNumber(qtyTokenBInitialExample, 2)} Token B`}

\r\n

{`- Value if held: $${formatNumber(totalHoldWorth, 2)}`}

\r\n
\r\n\r\n

If $500 of Token A and $500 of Token B were provided as liquidity

\r\n

{`- Have ${formatNumber(qtyTokenAFutureExample, 2)} Token A and ${formatNumber(qtyTokenBFutureExample, 2)} Token B (in liquidity pool)`}

\r\n

{`- Value if providing liquidity: $${formatNumber(totalLiquidityWorth, 2)}`}

\r\n
\r\n )\r\n }\r\n\r\n return (\r\n \r\n \r\n
\r\n Impermanent Loss Calculator\r\n
\r\n \r\n \r\n This calculator uses\r\n Uniswap's constant product formula to\r\n determine impermanent loss.\r\n \r\n \r\n Fees are not included within results.\r\n \r\n \r\n
\r\n \r\n Initial Prices\r\n \r\n \r\n Token A\r\n \r\n $ setPriceInitialA(e.target.value)}\r\n type=\"number\"\r\n min=\"0\"\r\n />\r\n \r\n \r\n \r\n Token B\r\n \r\n $ setPriceInitialB(e.target.value)}\r\n type=\"number\"\r\n min=\"0\"\r\n />\r\n \r\n \r\n
\r\n
\r\n \r\n Future Prices\r\n \r\n \r\n Token A\r\n \r\n $ setPriceFutureA(e.target.value)}\r\n type=\"number\"\r\n min=\"0\"\r\n />\r\n \r\n \r\n \r\n Token B\r\n \r\n $ setPriceFutureB(e.target.value)}\r\n type=\"number\"\r\n min=\"0\"\r\n />\r\n \r\n \r\n
\r\n
\r\n \r\n Results\r\n \r\n {\r\n impermanentLossRes\r\n ? renderResults(impermanentLossRes)\r\n : 'Enter valid prices to see results'\r\n }\r\n
\r\n
\r\n )\r\n}","import React from \"react\"\r\nimport styled from \"styled-components\"\r\nimport { useStaticQuery, Link, graphql } from \"gatsby\"\r\nimport \"@fontsource/montserrat\"\r\nimport \"./page-layout.css\"\r\n\r\nconst PageContainer = styled.div`\r\n font-family: 'Montserrat', sans-serif;\r\n display: flex;\r\n flex-direction: column;\r\n margin: 0 auto;\r\n max-width: 650px;\r\n min-height: calc(100vh - 2rem);\r\n padding: 1rem;\r\n\r\n @media (max-width: 540px) {\r\n padding-top: 0.3rem;\r\n }\r\n`\r\n\r\nconst Header = styled.div`\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n`\r\n\r\nconst HeaderLeft = styled.div``\r\n\r\nconst HeaderRight = styled.div``\r\n\r\nconst SiteTitle = styled.h3``\r\n\r\nconst StyledLink = styled(Link)`\r\n text-decoration: none;\r\n`\r\n\r\nconst TwitterLink = styled.a``\r\n\r\nconst AboutLink = styled(Link)`\r\n padding-left: 2rem;\r\n text-decoration: none;\r\n`\r\n\r\nconst Body = styled.div``\r\n\r\nconst Footer = styled.div`\r\n flex-grow: 1;\r\n display: flex;\r\n justify-content: center;\r\n align-items: flex-end;\r\n padding-top: 1rem;\r\n`\r\n\r\nconst FooterText = styled.div`\r\n text-align: center;\r\n`\r\n\r\nexport default function PageLayout({ children, showAffiliateLink }) {\r\n\r\n const data = useStaticQuery(\r\n graphql`\r\n query {\r\n site {\r\n siteMetadata {\r\n title\r\n }\r\n }\r\n }\r\n `\r\n )\r\n\r\n return (\r\n \r\n
\r\n \r\n \r\n \r\n {data.site.siteMetadata.title}\r\n \r\n \r\n \r\n \r\n \r\n Twitter\r\n \r\n \r\n About\r\n \r\n \r\n
\r\n \r\n {children}\r\n \r\n \r\n
\r\n )\r\n}","import React from \"react\"\r\nimport PropTypes from \"prop-types\"\r\nimport { Helmet } from \"react-helmet\"\r\nimport { useStaticQuery, graphql } from \"gatsby\"\r\n\r\nfunction SEO({ description, lang, meta, title }) {\r\n const { site } = useStaticQuery(\r\n graphql`\r\n query {\r\n site {\r\n siteMetadata {\r\n title\r\n description\r\n author\r\n }\r\n }\r\n }\r\n `\r\n )\r\n\r\n const metaDescription = description || site.siteMetadata.description\r\n\r\n return (\r\n \r\n )\r\n}\r\n\r\nSEO.defaultProps = {\r\n lang: `en`,\r\n meta: [],\r\n description: ``,\r\n}\r\n\r\nSEO.propTypes = {\r\n description: PropTypes.string,\r\n lang: PropTypes.string,\r\n meta: PropTypes.arrayOf(PropTypes.object),\r\n title: PropTypes.string.isRequired,\r\n}\r\n\r\nexport default SEO"],"sourceRoot":""}