Skip to content

Commit

Permalink
Merge branch 'abc-graph' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
sembrestels committed Oct 26, 2023
2 parents 25530c0 + 02a2d24 commit 84ca413
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 20 deletions.
9 changes: 5 additions & 4 deletions apps/abclaunch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@rainbow-me/rainbowkit": "1.0.11",
"commons-ui": "*",
"dao-utils": "*",
"framer-motion": "^10.16.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.16.0",
"viem": "1.16.5",
"wagmi": "1.4.2",
"recharts": "^2.9.0",
"recoil": "^0.7.7",
"commons-ui": "*",
"transactions-modal": "*",
"dao-utils": "*"
"viem": "1.16.5",
"wagmi": "1.4.2"
},
"devDependencies": {
"@types/react": "^18.2.15",
Expand Down
2 changes: 1 addition & 1 deletion apps/abclaunch/src/components/DaoStepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default function DaoStepper(
const navigate = useNavigate();

const { activeStep, goToNext, goToPrevious } = useSteps({
index: 0,
index: 2,
count: steps.length,
})

Expand Down
119 changes: 119 additions & 0 deletions apps/abclaunch/src/components/charts/ABCGraph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Flex } from "@chakra-ui/react";
import {
Area,
ComposedChart,
Label,
Tooltip,
XAxis,
YAxis
} from 'recharts';
import useABCGraphData from "../../hooks/useABCGraphData";
import { newDaoAbcState, newDaoTokenState } from "../../recoil";
import { useRecoilValue } from "recoil";
import { getCollateralTokenInfo } from "../../utils/token-info";
import { useCallback } from "react";

const tickFormatter = new Intl.NumberFormat("en-US", {
notation: "compact",
compactDisplay: "short",
}).format

const tooltipFormatter = new Intl.NumberFormat("en-US", {
notation: "standard",
minimumSignificantDigits: 5,
maximumSignificantDigits: 5,
}).format

function CustomTooltip({ active, supply, reserve, price, tokenSymbol, reserveTokenSymbol }: { active?: boolean, supply?: number, reserve?: number, price?: number, tokenSymbol?: string, reserveTokenSymbol?: string }) {
if (active && supply && reserve && price) {
return (
<div
style={{
color: "#E8E9E3",
background: "#003C00",
padding: "10px",
borderRadius: "4px",
boxShadow: "0px 4px 4px rgba(0, 0, 0, 0.25)"
}}
>
<p>
<b>Supply:</b> {tooltipFormatter(supply)} {tokenSymbol}
</p>
<p style={{ color: "#E8E9E3" }}>
<b>Reserve:</b> {tooltipFormatter(reserve)} {reserveTokenSymbol}
</p>
<p style={{ color: "#E8E9E3" }}>
<b>Price:</b> {tooltipFormatter(price)} {reserveTokenSymbol}/token
</p>
</div>
);
}
return null;
};

export default function ABCGraph() {

const data = useABCGraphData();
const { tokenSymbol } = useRecoilValue(newDaoTokenState);

const { collateralToken, reserveRatio } = useRecoilValue(newDaoAbcState);
const reserveTokenSymbol = getCollateralTokenInfo(collateralToken)?.tokenSymbol;

const tooltip = useCallback(({ active, payload, label }: { active?: boolean, payload?: any, label?: any }) => {
return (
<CustomTooltip
active={active}
supply={label}
reserve={Number(label) * Number(payload?.[0]?.payload?.y) * Number(reserveRatio) / 100}
price={payload?.[0]?.payload?.y}
tokenSymbol={tokenSymbol}
reserveTokenSymbol={reserveTokenSymbol} />
)
}, [tokenSymbol, reserveTokenSymbol, reserveRatio]);

return (
<Flex w="100%" h="100%">
<ComposedChart
data={data}
width={600}
height={400}
margin={{
top: 20,
left: 20,
bottom: 20,
}}
>
<defs>
<linearGradient id="colorUv" x1="0" y1="0" x2="1" y2="1">
<stop offset="10%" stopColor="#00E046" stopOpacity={1} />
<stop offset="95%" stopColor="#003C00" stopOpacity={1} />
</linearGradient>
</defs>
<XAxis dataKey="x" type="number" tickFormatter={tickFormatter}>
<Label
style={{
textAnchor: "middle",
fill: "#003C00",
fontWeight: "bold",
}}
value={"Supply" + (tokenSymbol ? ` (${tokenSymbol})` : "")}
dy={20} />
</XAxis>
<YAxis type="number" tickFormatter={tickFormatter}>
<Label
style={{
textAnchor: "middle",
fill: "#003C00",
fontWeight: "bold",
}}
angle={270}
value={"Price per token" + (reserveTokenSymbol ? ` (${reserveTokenSymbol})` : "")}
dx={-30} />
</YAxis>
<Tooltip content={tooltip} />
<Area type="monotone" dataKey="y" stroke="#00E046" strokeLinecap="round" strokeWidth={2} fillOpacity={0.4} fill="url(#colorUv)" unit={'USDC'} />
</ComposedChart>
</Flex>
)
}

28 changes: 17 additions & 11 deletions apps/abclaunch/src/components/dao-steps/ConfigureAbc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { newDaoAbcState } from "../../recoil";
import { collateralTokenList, getCollateralTokenInfo } from "../../utils/token-info";
import { BalanceInput } from "dao-utils";
import { Input } from 'commons-ui/src/components/Input';
import ABCGraph from "../charts/ABCGraph";

export default function ConfigureToken() {

Expand Down Expand Up @@ -39,7 +40,7 @@ export default function ConfigureToken() {
<Text fontFamily="VictorSerifTrial" fontSize="72px" color="brand.900">Augmented Bonding Curve</Text>
<Text fontSize="24px" color="brand.900" pt="16px">Configure the DAO's ABC parameters</Text>
<HStack w="100%">
<VStack spacing={3} minW="340px" maxW="400px" w="100%" justifyContent="center">
<VStack spacing={3} minW="340px" maxW="400px" w="40%" justifyContent="center">
<HStack alignSelf="start" w="100%">
<FormControl w="100%">
<FormLabel>
Expand Down Expand Up @@ -169,29 +170,34 @@ export default function ConfigureToken() {
</FormControl>
</HStack>
</VStack>
<VStack spacing={3} w="600px" justifyContent="center">
<ABCGraph />
</VStack>
</HStack>
<Divider paddingTop="24px"
borderColor="brand.900"
borderBottomWidth="1px"
width="100%"
margin="0 auto"
/>
{enoughBalance && <VStack mt="32px">
<VStack spacing={-1}>
<Text fontSize="16px" color="black">When you launch this ABC, that amount specified in the Initial Reserve Balance will be transferred</Text>
<Text fontSize="16px" color="black">from your wallet to the Reserve Pool. You can only proceed if your wallet contains funds equal to or</Text>
<Text fontSize="16px" color="black">exceeding the specified Initial Reserve Balance.</Text>
</VStack>
<Text fontSize="16px" color="black" pt="16px">The Reserve Ratio is fixed for the life of the ABC and cannot be changed.</Text>
</VStack>}
{!enoughBalance &&
{enoughBalance ?
<VStack mt="32px">
<VStack spacing={-1}>
<Text fontSize="16px" color="black">When you launch this ABC, that amount specified in the Initial Reserve Balance will be transferred</Text>
<Text fontSize="16px" color="black">from your wallet to the Reserve Pool. You can only proceed if your wallet contains funds equal to or</Text>
<Text fontSize="16px" color="black">exceeding the specified Initial Reserve Balance.</Text>
</VStack>
<Text fontSize="16px" color="black" pt="16px">The Reserve Ratio is fixed for the life of the ABC and cannot be changed.</Text>
</VStack> : null
}
{!enoughBalance ?
<HStack mt="32px">
<WarningTwoIcon color="red.500" w="32px" h="32px" mr="8px" />
<VStack spacing={0} alignItems="start">
<Text fontSize="16px" color="brand.1200">You do not have the amount specified in Initial Reserve Balance in your wallet.</Text>
<Text fontSize="16px" color="brand.1200">You must have at least that much in your wallet in order to proceed.</Text>
</VStack>
</HStack>
</HStack> : null
}
</VStack>
)
Expand Down
36 changes: 36 additions & 0 deletions apps/abclaunch/src/hooks/useABCGraphData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useRecoilValue } from "recoil";
import { newDaoAbcState, newDaoTokenSupplyState } from "../recoil";

const DOTS_LENGTH = 101; // we include the point (0,0) in the data

function bondingCurvePrice(x: number, m: number, n: number) {
const price = m * Math.pow(x, n);
return price;
}

function getBondingCurveData(reserveRatio: number, initialReserve: number, initialSupply: number) {
var data = [];
const maxX = initialSupply * 4;

// reserve ratio must have a value between 0 and 1
if(reserveRatio < 0 || reserveRatio > 1 || initialSupply === 0) return [];

const m = initialReserve / (reserveRatio * Math.pow(initialSupply, 1 / reserveRatio)); // slope
const n = (1 - reserveRatio) / reserveRatio; // exponent

for (let i = 0; i < DOTS_LENGTH; i++) {
const x = (maxX / (DOTS_LENGTH - 1)) * i;
const y = bondingCurvePrice(x, m, n);
data.push({ x, y });
}
return data;
}

export default function useABCGraphData(): {x: number, y: number}[] {
const tokenSupply = useRecoilValue(newDaoTokenSupplyState)
const abcSettings = useRecoilValue(newDaoAbcState);

const initialReserve = Number.parseFloat(abcSettings.reserveInitialBalance);
const reserveRatio = Number.parseFloat(abcSettings.reserveRatio) / 100;
return getBondingCurveData(reserveRatio, initialReserve, tokenSupply);
}
2 changes: 1 addition & 1 deletion apps/abclaunch/src/pages/NewDao.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function StepInfo({ image, children }: { image: string, children: React.ReactNod
export default function NewDao() {

const { address } = useAccount();
const { data: balance } = useBalance({ address });
const { data: balance } = useBalance({ address, watch: true });
const navigate = useNavigate();
const location = useLocation();
const txSteps = useLaunchSteps();
Expand Down
4 changes: 2 additions & 2 deletions apps/abcswap/src/pages/Swap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ export default function SimpleConvert() {

const steps = useSwapSteps(bondingCurve.address, reserveToken.address, inverted, parseFromToken(amount));

const { data: fromTokenBalance } = useBalance({ token: fromToken.address, address });
const { data: toTokenBalance } = useBalance({ token: toToken.address, address });
const { data: fromTokenBalance } = useBalance({ token: fromToken.address, address, watch: true });
const { data: toTokenBalance } = useBalance({ token: toToken.address, address, watch: true });

const amountBigInt = parseFromToken(amount)
const convertedAmount = useBondingCurvePrice(amountBigInt, inverted, reserveToken.address, bondingCurve.address);
Expand Down
2 changes: 1 addition & 1 deletion pkg/dao-utils/src/hooks/useIsBalanceEnough.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function useIsBalanceEnough({value, token, decimals}: {value: string, token: `0x

const [debouncedValue, isDebouncing] = useDebounce(value, delay);
const { address } = useAccount()
const { data: balance, error, isLoading: isFetching } = useBalance({address, token});
const { data: balance, error, isLoading: isFetching } = useBalance({address, token, watch: true});

const isLoading = !address || isFetching || isDebouncing;
const isEnough = !isLoading && token && balance ? balance.value >= parseUnits(debouncedValue, decimals) : undefined;
Expand Down

0 comments on commit 84ca413

Please sign in to comment.