diff --git a/src/App.tsx b/src/App.tsx index 70501ca..dbd38ca 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,6 +15,12 @@ import SupplyVsDemandChart from "./SupplyVsDemandChart"; import ResultParams from "./ResultParams"; import PriceSimulationChart from "./PriceSimulationChart"; import HelpText from "./HelpText"; +// Text content +import { + parameterDescriptions, + simulationParameterDescriptions, + resultParameterDescriptions +} from "./parametersDescriptions"; // Utils import { getLast, getAvg, pause } from "./utils"; import { @@ -122,11 +128,10 @@ const useStyles = makeStyles((theme: Theme) => } }, descriptionTitle: { - fontWeight: theme.typography.fontWeightBold, padding: theme.spacing(0.5) }, - descriptionName: { - fontWeight: theme.typography.fontWeightBold + descriptionBody: { + color: "#dbdfe4" }, descriptionPadding: { padding: theme.spacing(0.5) @@ -134,73 +139,6 @@ const useStyles = makeStyles((theme: Theme) => }) ); -const parameterDescriptions = [ - { - name: "Initial raise", - text: "Total funds raised in the hatch period of the ABC launch" - }, - { - name: "Allocation to funding pool", - text: - "The percentage of the funds raised in the Hatch sale that go directly into the project funding pool to compensate future work done in the project" - }, - { - name: "Hatch price", - text: - "The price paid per 'ABC token' by community members involved in hatching the project" - }, - { - name: "Post-hatch price", - text: - "The price of the 'ABC token' when the curve enters the open phase and is live for public participation" - }, - { - name: "Exit tribute", - text: - "The percentage of funds that are diverted to the project funding pool from community members who exit funds from the project by burning 'ABC tokens' in exchange for collateral" - } -]; - -const simulationParameterDescriptions = [ - { - name: "Price", - text: "Price of the token over time." - }, - { - name: "Floor price", - text: - "Lower bound of the price guaranteed by the vesting of hatch tokens. It decreases over time as more hatch tokens are allowed to be traded" - }, - { - name: "Total exit tributes", - text: - "Cumulative sum of exit tributes collected from only exit /sell transactions" - } -]; - -const resultParameterDescriptions = [ - { - name: "Total reserve", - text: - "Total DAI in the smart contract reserve at the end of the simulated period" - }, - { - name: "Funds generated from initial hatch", - text: - "Fraction of the funds (theta) raised during the hatch that go directly to the cause (analytic result)" - }, - { - name: "Funds generated from exit tributes", - text: - "Cumulative sum of exit tributes collected from only exit /sell transactions" - }, - { - name: "Average slippage", - text: - "Average of the slippage of each transaction occured during the simulation period" - } -]; - export default function App() { const [curveParams, setCurveParams] = useState({ theta: 0.35, // fraction allocated to reserve (.) @@ -386,14 +324,17 @@ export default function App() { const resultFields = [ { label: `Total reserve`, + description: resultParameterDescriptions.totalReserve.text, value: (+totalReserve.toPrecision(3)).toLocaleString() + " DAI" }, { label: `Funds generated from initial hatch`, + description: resultParameterDescriptions.initialHatchFunds.text, value: Math.round(d0 * theta).toLocaleString() + " DAI" }, { label: `Funds generated from exit tributes (${withdrawCount} txs)`, + description: resultParameterDescriptions.exitTributes.text, value: (+getLast(withdrawFeeTimeseries).toPrecision(3)).toLocaleString() + " DAI" @@ -402,6 +343,7 @@ export default function App() { label: `Average slippage (avg tx size ${Math.round( avgTxSize ).toLocaleString()} DAI)`, + description: resultParameterDescriptions.slippage.text, value: +(100 * avgSlippage).toFixed(3) + "%" } ]; @@ -432,15 +374,21 @@ export default function App() { - {parameterDescriptions.map(({ name, text }) => ( + {[ + parameterDescriptions.theta, + parameterDescriptions.p0, + parameterDescriptions.p1, + parameterDescriptions.wFee, + parameterDescriptions.d0 + ].map(({ name, text }) => ( ))} @@ -478,7 +426,7 @@ export default function App() { - + Visualization of the token bonding curve analytic function on a specific range of reserve [0, 4 * R0]. This result is deterministic given the current set of @@ -533,7 +481,7 @@ export default function App() { text={
- + This chart shows a 52 week simulation of discrete transactions interacting with the token bonding curve. Each transaction adds or substract reserve @@ -546,22 +494,22 @@ export default function App() {
- - {name} - + {name} - {text} + + {text} +
- {simulationParameterDescriptions.map( - ({ name, text }) => ( - - - - - ) - )} + {Object.values( + simulationParameterDescriptions + ).map(({ name, text }) => ( + + + + + ))}
- - {name} - - - {text} -
+ {name} + + + {text} + +
@@ -595,18 +543,18 @@ export default function App() { - {resultParameterDescriptions.map( + {Object.values(resultParameterDescriptions).map( ({ name, text }) => ( ) diff --git a/src/CurveDesignInputParams.tsx b/src/CurveDesignInputParams.tsx index d0d9134..e9f7298 100644 --- a/src/CurveDesignInputParams.tsx +++ b/src/CurveDesignInputParams.tsx @@ -1,6 +1,7 @@ import React, { useState, useEffect } from "react"; import { InputFieldInterface, CurveParamsInterface } from "./types"; import InputParams from "./InputParams"; +import { parameterDescriptions } from "./parametersDescriptions"; export default function CurveDesignInputParams({ curveParams, @@ -42,6 +43,7 @@ export default function CurveDesignInputParams({ const inputFields: InputFieldInterface[] = [ { label: "Allocation to funding pool", + description: parameterDescriptions.theta.text, value: theta, setter: setTheta, min: 0, @@ -54,6 +56,7 @@ export default function CurveDesignInputParams({ }, { label: "Hatch price (DAI/token)", + description: parameterDescriptions.p0.text, value: p0, setter: _setP0, min: 0.01, @@ -65,6 +68,7 @@ export default function CurveDesignInputParams({ }, { label: "Post-hatch price (DAI/token)", + description: parameterDescriptions.p1.text, value: p1, setter: setP1, min: p0 || 0.1, @@ -76,6 +80,7 @@ export default function CurveDesignInputParams({ }, { label: "Exit tribute", + description: parameterDescriptions.wFee.text, value: wFee, setter: setWFee, min: 0, diff --git a/src/InputParams.tsx b/src/InputParams.tsx index fd9f603..3d06aaa 100644 --- a/src/InputParams.tsx +++ b/src/InputParams.tsx @@ -1,11 +1,11 @@ import React from "react"; import { createStyles, makeStyles, Theme } from "@material-ui/core/styles"; -import Typography from "@material-ui/core/Typography"; import Grid from "@material-ui/core/Grid"; import TextField from "@material-ui/core/TextField"; import NumberFormat from "react-number-format"; import { InputFieldInterface } from "./types"; import PrettoSlider from "./PrettoSlider"; +import TextWithPopover from "./TextWithPopover"; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -81,6 +81,7 @@ export default function InputParams({ {inputFields.map( ({ label, + description, value, setter, min, @@ -103,9 +104,7 @@ export default function InputParams({ return ( - - {label} - + diff --git a/src/ResultParams.tsx b/src/ResultParams.tsx index 26ff4b6..9642b95 100644 --- a/src/ResultParams.tsx +++ b/src/ResultParams.tsx @@ -2,6 +2,7 @@ import React from "react"; import { createStyles, makeStyles, Theme } from "@material-ui/core/styles"; import Typography from "@material-ui/core/Typography"; import Grid from "@material-ui/core/Grid"; +import TextWithPopover from "./TextWithPopover"; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -45,6 +46,7 @@ export default function ResultParams({ }: { resultFields: { label: string; + description: string; value: number | string; }[]; }) { @@ -52,12 +54,10 @@ export default function ResultParams({ return (
- {resultFields.map(({ label, value }) => ( + {resultFields.map(({ label, description, value }) => ( - - {label} - + diff --git a/src/SimulationInputParams.tsx b/src/SimulationInputParams.tsx index e02f36e..93dcc55 100644 --- a/src/SimulationInputParams.tsx +++ b/src/SimulationInputParams.tsx @@ -1,6 +1,7 @@ import React, { useState, useEffect } from "react"; import { InputFieldInterface, CurveParamsInterface } from "./types"; import InputParams from "./InputParams"; +import { parameterDescriptions } from "./parametersDescriptions"; export default function CurveDesignInputParams({ curveParams, @@ -25,6 +26,7 @@ export default function CurveDesignInputParams({ const inputFields: InputFieldInterface[] = [ { label: "Initial raise (DAI)", + description: parameterDescriptions.d0.text, value: d0, setter: setD0, min: 0.1e6, diff --git a/src/TextWithPopover.tsx b/src/TextWithPopover.tsx new file mode 100644 index 0000000..781e1e5 --- /dev/null +++ b/src/TextWithPopover.tsx @@ -0,0 +1,93 @@ +import React from "react"; +import { makeStyles } from "@material-ui/core/styles"; +import Popover from "@material-ui/core/Popover"; +import Typography from "@material-ui/core/Typography"; +import Box from "@material-ui/core/Box"; + +const useStyles = makeStyles(theme => ({ + container: { + color: theme.palette.text.secondary, + display: "flex", + marginLeft: "6px", + fontSize: "0.9rem", + cursor: "pointer", + transition: "color ease 150ms", + "&:hover": { + color: "#c3c9d0" + } + }, + popoverContainer: { + padding: theme.spacing(2), + "& > p:not(:last-child)": { + paddingBottom: theme.spacing(1), + marginBottom: theme.spacing(1), + borderBottom: "1px solid #3f5463" + } + }, + paper: { + backgroundColor: "#384b59", + maxWidth: theme.breakpoints.values.md * 0.9, + [`@media screen and (max-width: ${theme.breakpoints.values.md}px)`]: { + maxWidth: "90vw" + }, + padding: theme.spacing(0.5) + }, + descriptionBody: { + color: "#dbdfe4" + } +})); + +export default function TextWithPopover({ + content, + popoverText +}: { + content: string; + popoverText: string; +}) { + const classes = useStyles(); + const [anchorEl, setAnchorEl] = React.useState(null); + + function handleClick(event: any) { + setAnchorEl(event.currentTarget); + } + + function handleClose() { + setAnchorEl(null); + } + + const open = Boolean(anchorEl); + const id = open ? "simple-popover" : undefined; + + return ( +
+
+ {content} +
+ + + {content} + + {popoverText} + + + +
+ ); +} diff --git a/src/parametersDescriptions.ts b/src/parametersDescriptions.ts new file mode 100644 index 0000000..0b7ebf7 --- /dev/null +++ b/src/parametersDescriptions.ts @@ -0,0 +1,69 @@ +export interface DescriptionObject { + [key: string]: { name: string; text: string }; +} + +export const parameterDescriptions: DescriptionObject = { + theta: { + name: "Allocation to funding pool", + text: + "The percentage of the funds raised in the Hatch sale that go directly into the project funding pool to compensate future work done in the project" + }, + p0: { + name: "Hatch price", + text: + "The price paid per 'ABC token' by community members involved in hatching the project" + }, + p1: { + name: "Post-hatch price", + text: + "The price of the 'ABC token' when the curve enters the open phase and is live for public participation" + }, + wFee: { + name: "Exit tribute", + text: + "The percentage of funds that are diverted to the project funding pool from community members who exit funds from the project by burning 'ABC tokens' in exchange for collateral" + }, + d0: { + name: "Initial raise", + text: "Total funds raised in the hatch period of the ABC launch" + } +}; + +export const simulationParameterDescriptions: DescriptionObject = { + price: { + name: "Price", + text: "Price of the token over time." + }, + floorPrice: { + name: "Floor price", + text: + "Lower bound of the price guaranteed by the vesting of hatch tokens. It decreases over time as more hatch tokens are allowed to be traded" + }, + exitTributes: { + name: "Total exit tributes", + text: + "Cumulative sum of exit tributes collected from only exit /sell transactions" + } +}; + +export const resultParameterDescriptions: DescriptionObject = { + totalReserve: { + name: "Total reserve", + text: + "Total DAI in the smart contract reserve at the end of the simulated period" + }, + initialHatchFunds: { + name: "Funds generated from initial hatch", + text: + "Fraction of the funds (theta) raised during the hatch that go directly to the cause (analytic result)" + }, + exitTributes: { + name: "Funds generated from exit tributes", + text: simulationParameterDescriptions.exitTributes.text + }, + slippage: { + name: "Average slippage", + text: + "Average of the slippage of each transaction occured during the simulation period" + } +}; diff --git a/src/types.ts b/src/types.ts index 2fcc5e2..e0f426c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,6 @@ export interface InputFieldInterface { label: string; + description: string; value: number; setter(newValue: any): void; min: number;
- - {name} - + {name} - {text} + + {text} +