Skip to content

Commit

Permalink
Merge pull request #320 from yieldprotocol/marcomariscal/issue308
Browse files Browse the repository at this point in the history
issue308: update pool view to include strategy language instead of pool
  • Loading branch information
brucedonovan authored Sep 18, 2021
2 parents f442778 + b55cb7a commit 4c6c15d
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 68 deletions.
26 changes: 9 additions & 17 deletions src/components/positionItems/StrategyItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,11 @@ import { cleanValue, nFormatter } from '../../utils/appUtils';
import PositionAvatar from '../PositionAvatar';
import ItemWrap from '../wraps/ItemWrap';

function StrategyItem({
strategy,
index,
condensed,
}: {
strategy: IStrategy;
index: number;
condensed?: boolean;
}) {
function StrategyItem({ strategy, index, condensed }: { strategy: IStrategy; index: number; condensed?: boolean }) {
const history = useHistory();

const { userState, userActions } = useContext(UserContext) as IUserContext;

const handleSelect = (_series: IStrategy) => {
userActions.setSelectedBase(strategy.baseId);
userActions.setSelectedSeries(strategy.currentSeriesId);
Expand All @@ -41,13 +33,13 @@ function StrategyItem({
{strategy.name}
</Text>
<Box direction="row" gap="small">
<Text weight={450} size="xsmall">
{/* Tokens: {cleanValue(series.poolTokens_, 2)} */}
Tokens: {nFormatter(parseFloat(strategy.accountBalance_!), 2)}
</Text>
<Text weight={450} size="xsmall">
Strategy %: {cleanValue(strategy.accountBalance_, 2)}
</Text>
<Text weight={450} size="xsmall">
{/* Tokens: {cleanValue(series.poolTokens_, 2)} */}
Tokens: {nFormatter(parseFloat(strategy.accountBalance_!), 2)}
</Text>
<Text weight={450} size="xsmall">
Strategy %: {cleanValue(strategy.accountStrategyPercent, 2)}
</Text>
</Box>
</Box>
</Box>
Expand Down
29 changes: 13 additions & 16 deletions src/contexts/ChainContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ const ChainProvider = ({ children }: any) => {
// const [lastSeriesUpdate, setLastSeriesUpdate] = useCachedState('lastSeriesUpdate', 27090000);
const [lastSeriesUpdate, setLastSeriesUpdate] = useCachedState('lastSeriesUpdate', 0);


/**
* Update on FALLBACK connection/state on network changes (id/library)
*/
Expand Down Expand Up @@ -270,7 +269,7 @@ const ChainProvider = ({ children }: any) => {
const { assetId: id, asset: address } = Cauldron.interface.parseLog(x).args;
const ERC20 = contracts.ERC20Permit__factory.connect(address, fallbackLibrary);
/* Add in any extra static asset Data */ // TODO is there any other fixed asset data needed?
const [ name, symbol, decimals ] = await Promise.all([
const [name, symbol, decimals] = await Promise.all([
ERC20.name(),
ERC20.symbol(),
ERC20.decimals(),
Expand Down Expand Up @@ -337,7 +336,7 @@ const ChainProvider = ({ children }: any) => {
oppStartColor,
oppEndColor,
oppTextColor,
seriesMark: <YieldMark colors={[startColor, endColor] } />,
seriesMark: <YieldMark colors={[startColor, endColor]} />,

// built-in helper functions:
getTimeTillMaturity: () => series.maturity - Math.round(new Date().getTime() / 1000),
Expand Down Expand Up @@ -373,17 +372,16 @@ const ChainProvider = ({ children }: any) => {
const poolContract = contracts.Pool__factory.connect(poolAddress, fallbackLibrary);
const fyTokenContract = contracts.FYToken__factory.connect(fyToken, fallbackLibrary);
// const baseContract = contracts.ERC20__factory.connect(fyToken, fallbackLibrary);
const [name, symbol, version, decimals, poolName, poolVersion, poolSymbol ] =
await Promise.all([
fyTokenContract.name(),
fyTokenContract.symbol(),
fyTokenContract.version(),
fyTokenContract.decimals(),
poolContract.name(),
poolContract.version(),
poolContract.symbol(),
// poolContract.decimals(),
]);
const [name, symbol, version, decimals, poolName, poolVersion, poolSymbol] = await Promise.all([
fyTokenContract.name(),
fyTokenContract.symbol(),
fyTokenContract.version(),
fyTokenContract.decimals(),
poolContract.name(),
poolContract.version(),
poolContract.symbol(),
// poolContract.decimals(),
]);
const newSeries = {
id,
baseId,
Expand Down Expand Up @@ -426,11 +424,10 @@ const ChainProvider = ({ children }: any) => {
const newStrategyList: any[] = [];
await Promise.all(
strategyAddresses.map(async (strategyAddr: string) => {

/* if the strategy is already in the cache : */
if (cachedStrategies.findIndex((_s: any) => _s.address === strategyAddr) === -1) {
const Strategy = contracts.Strategy__factory.connect(strategyAddr, fallbackLibrary);
const [name, symbol, baseId, decimals, version ] = await Promise.all([
const [name, symbol, baseId, decimals, version] = await Promise.all([
Strategy.name(),
Strategy.symbol(),
Strategy.baseId(),
Expand Down
48 changes: 46 additions & 2 deletions src/hooks/actionHelperHooks/usePoolHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,48 @@
import { useContext, useEffect, useState } from 'react';
import { ethers, BigNumber } from 'ethers';
import { UserContext } from '../../contexts/UserContext';
import { ChainContext } from '../../contexts/ChainContext';
import { IAsset, IStrategy } from '../../types';
import { cleanValue } from '../../utils/appUtils';
import { mulDecimal, divDecimal } from '../../utils/yieldMath';

export const usePoolHelpers = (input: string | undefined) => {
const poolMax = input;
return { poolMax };
/* STATE FROM CONTEXT */
const {
userState: { selectedStrategyAddr, strategyMap, assetMap, activeAccount },
} = useContext(UserContext);

const strategy: IStrategy | undefined = strategyMap?.get(selectedStrategyAddr);
const strategyBase: IAsset | undefined = assetMap?.get(strategy?.baseId);

/* LOCAL STATE */
const [poolPercentPreview, setPoolPercentPreview] = useState<string | undefined>();
const [poolTokenPreview, setPoolTokenPreview] = useState<string | undefined>(input);
const [maxPool, setMaxPool] = useState<string | undefined>();

/* SET MAX VALUES */
useEffect(() => {
if (activeAccount) {
/* Checks asset selection and sets the max available value */
(async () => {
const max = await strategyBase?.getBalance(activeAccount);
if (max) setMaxPool(ethers.utils.formatUnits(max, strategyBase?.decimals).toString());
})();
}
}, [input, activeAccount, strategyBase]);

useEffect(() => {
if (input && strategy) {
// update the below to get an actual estimated token value based on the input
const _poolTokenPreview = BigNumber.from(ethers.utils.parseUnits(input, strategyBase?.decimals));
const _poolPercentPreview = cleanValue(
mulDecimal(divDecimal(_poolTokenPreview, strategy.strategyTotalSupply!), '100'),
2
);

setPoolPercentPreview(_poolPercentPreview);
}
}, [input, strategy, strategyBase]);

return { maxPool, poolTokenPreview, poolPercentPreview };
};
5 changes: 2 additions & 3 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ export interface IStrategyRoot extends ISignable {
baseId: string;
decimals: number;
strategyContract: Strategy;
strategyTotalSupply?: BigNumber;
strategyTotalSupply_?: string;
}

export interface IVaultRoot {
Expand Down Expand Up @@ -191,9 +193,6 @@ export interface IStrategy extends IStrategyRoot {
nextSeries: ISeries | undefined;
active: boolean;

strategyTotalSupply?: BigNumber;
strategyTotalSupply_?: string;

poolTotalSupply?: BigNumber;
poolTotalSupply_?: string;

Expand Down
12 changes: 6 additions & 6 deletions src/utils/yieldMath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export function burn(
* @param { BigNumber | string } fyToken
* @param { BigNumber | string } timeTillMaturity
* @param { number } decimals
*
*
* @returns {[BigNumber, BigNumber]}
*/
export function mintWithBase(
Expand All @@ -175,7 +175,7 @@ export function mintWithBase(
supply: BigNumber | string,
fyToken: BigNumber | string,
timeTillMaturity: BigNumber | string,
decimals: number = 18,
decimals: number = 18
): [BigNumber, BigNumber] {
const Z = new Decimal(baseReserves.toString());
const YR = new Decimal(fyTokenReservesReal.toString());
Expand All @@ -198,8 +198,8 @@ export function mintWithBase(
* @param { BigNumber | string } totalSupply
* @param { BigNumber | string } lpTokens
* @param { BigNumber | string } timeTillMaturity
*
* @param { number } decimals
*
* @param { number } decimals
* @returns { BigNumber }
*/
export function burnForBase(
Expand All @@ -209,7 +209,7 @@ export function burnForBase(
supply: BigNumber,
lpTokens: BigNumber,
timeTillMaturity: BigNumber,
decimals: number=18,
decimals: number = 18
): BigNumber {
// Burn FyToken
const [z1, y] = burn(baseReserves, fyTokenReservesReal, supply, lpTokens);
Expand Down Expand Up @@ -299,7 +299,7 @@ export function sellFYToken(
const Yxa = fyTokenReserves_.add(fyDai_).pow(a);
const sum = Za.add(Ya.sub(Yxa));
const y = baseReserves_.sub(sum.pow(invA));

const yFee = y.sub(precisionFee);

// return yFee.isNaN() ? ethers.constants.Zero : toBn(yFee);
Expand Down
50 changes: 28 additions & 22 deletions src/views/Pool.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { Box, RadioButtonGroup, ResponsiveContext, Text, TextInput } from 'grommet';
import { Box, RadioButtonGroup, ResponsiveContext, Text, TextInput, Tip } from 'grommet';

import { ethers } from 'ethers';

import { FiClock, FiPercent } from 'react-icons/fi';
import { FiClock, FiInfo, FiPercent } from 'react-icons/fi';
import { BiCoinStack, BiMessageSquareAdd } from 'react-icons/bi';
import { MdAutorenew } from 'react-icons/md';
import { cleanValue, nFormatter } from '../utils/appUtils';
import AssetSelector from '../components/selectors/AssetSelector';
import MainViewWrap from '../components/wraps/MainViewWrap';
Expand All @@ -29,26 +30,29 @@ import YieldCardHeader from '../components/YieldCardHeader';
import { useAddLiquidity } from '../hooks/actionHooks/useAddLiquidity';
import StrategySelector from '../components/selectors/StrategySelector';
import ColorText from '../components/texts/ColorText';
import { usePoolHelpers } from '../hooks/actionHelperHooks/usePoolHelpers';
import { useProcess } from '../hooks/useProcess';

function Pool() {
const mobile: boolean = useContext<any>(ResponsiveContext) === 'small';

/* STATE FROM CONTEXT */
const { userState } = useContext(UserContext) as IUserContext;
const { activeAccount, assetMap, seriesMap, selectedSeriesId, selectedBaseId } = userState;
const { activeAccount, assetMap, seriesMap, selectedSeriesId, selectedBaseId, selectedStrategyAddr, strategyMap } =
userState;
const selectedSeries = seriesMap.get(selectedSeriesId!);
const selectedBase = assetMap.get(selectedBaseId!);
const selectedStrategy = strategyMap.get(selectedStrategyAddr!);

/* LOCAL STATE */
const [poolInput, setPoolInput] = useState<string | undefined>(undefined);
const [maxPool, setMaxPool] = useState<string | undefined>();
const [poolDisabled, setPoolDisabled] = useState<boolean>(true);
const [poolMethod, setPoolMethod] = useState<'BUY' | 'BORROW'>('BUY');
const [stepPosition, setStepPosition] = useState<number>(0);

/* HOOK FNS */
const addLiquidity = useAddLiquidity();
const { maxPool, poolPercentPreview } = usePoolHelpers(poolInput);

/* input validation hooks */
const { inputError: poolError } = useInputValidation(poolInput, ActionCodes.ADD_LIQUIDITY, selectedSeries, [
Expand All @@ -61,24 +65,14 @@ function Pool() {
/* LOCAL ACTION FNS */
const handleAdd = () => {
// !poolDisabled &&
// TODO update for strategy
selectedSeries && addLiquidity(poolInput!, selectedSeries, poolMethod);
};

/* SET MAX VALUES */
useEffect(() => {
if (activeAccount) {
/* Checks asset selection and sets the max available value */
(async () => {
const max = await selectedBase?.getBalance(activeAccount);
if (max) setMaxPool(ethers.utils.formatUnits(max, selectedSeries?.decimals).toString());
})();
}
}, [activeAccount, poolInput, selectedBase, setMaxPool]);

/* ACTION DISABLING LOGIC - if ANY conditions are met: block action */
useEffect(() => {
!activeAccount || !poolInput || !selectedSeries || poolError ? setPoolDisabled(true) : setPoolDisabled(false);
}, [poolInput, activeAccount, poolError, selectedSeries]);
!activeAccount || !poolInput || poolError || !selectedStrategy ? setPoolDisabled(true) : setPoolDisabled(false);
}, [poolInput, activeAccount, poolError, selectedStrategy]);

const resetInputs = useCallback(() => {
setPoolInput(undefined);
Expand Down Expand Up @@ -171,7 +165,19 @@ function Pool() {
{!selectedSeries?.seriesIsMature && (
<SectionWrap>
<Box direction="row" justify="between" fill align="center">
{!mobile && <Text size="small"> Pooling method: </Text>}
{!mobile && (
<Box direction="row" gap="xsmall">
<Text size="small">Pooling method:</Text>
{/* <Tip
content={<Text size="xsmall">some info</Text>}
dropProps={{ align: { bottom: 'top' } }}
>
<Text size="small">
<FiInfo />
</Text>
</Tip> */}
</Box>
)}
<RadioButtonGroup
name="strategy"
options={[
Expand Down Expand Up @@ -199,13 +205,13 @@ function Pool() {
icon={<BiMessageSquareAdd />}
value={`${cleanValue(poolInput, selectedBase?.digitFormat!)} ${selectedBase?.symbol}`}
/>
<InfoBite label="Series Maturity" icon={<FiClock />} value={`${selectedSeries?.displayName}`} />
<InfoBite
<InfoBite label="Strategy" icon={<MdAutorenew />} value={`${selectedStrategy?.name}`} />
{/* <InfoBite
label="Amount of liquidity tokens recieved"
icon={<BiCoinStack />}
value={`${'[todo]'} Liquidity tokens`}
/>
<InfoBite label="Percentage of pool" icon={<FiPercent />} value={`${'[todo]'}%`} />
/> */}
<InfoBite label="Percentage of pool" icon={<FiPercent />} value={`~${poolPercentPreview}%`} />
</Box>
</SectionWrap>
</Box>
Expand Down
4 changes: 2 additions & 2 deletions src/views/PoolPosition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ const PoolPosition = () => {
{selectedStrategy.currentSeries && (
<InfoBite
label="Strategy Token percentage"
value={`${cleanValue(selectedStrategy?.accountStrategyPercent, 4)} % of ${nFormatter(
value={`${cleanValue(selectedStrategy?.accountStrategyPercent, 2)} % of ${nFormatter(
parseFloat(selectedStrategy?.strategyTotalSupply_!),
2
)}`}
Expand All @@ -213,7 +213,7 @@ const PoolPosition = () => {
{selectedStrategy.currentSeries && (
<InfoBite
label="Returns in current Pool"
value={`${cleanValue(selectedStrategy?.accountStrategyPercent, 4)}% `}
value={`${cleanValue(selectedStrategy?.accountStrategyPercent, 2)}% `}
icon={<FiTrendingUp />}
loading={seriesLoading}
/>
Expand Down

0 comments on commit 4c6c15d

Please sign in to comment.