Skip to content

Commit

Permalink
Use past upkeep balances for effective gain calc (#471)
Browse files Browse the repository at this point in the history
* Remove view token link while queueing (#419)

Remove view token link while queueing

* Add Pool Details Modal (#453)

* Add Pool Details Modal

* Address PR comments and add link to price feed

* Update icon color for light theme

* Update follow link color for light theme

Co-authored-by: Steven Yulong Yan <[email protected]>

* Use past upkeep balances for effective gain calc

* Add pools-js

* Remove logs

Co-authored-by: dweberdev <[email protected]>
Co-authored-by: Steven Yulong Yan <[email protected]>
  • Loading branch information
3 people authored Jan 31, 2022
1 parent 9b48a8c commit d808271
Show file tree
Hide file tree
Showing 15 changed files with 399 additions and 1,787 deletions.
151 changes: 151 additions & 0 deletions archetypes/Pools/PoolDetailsModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import React from 'react';
import { TWModal } from '@components/General/TWModal';
import { Table, TableRow, TableRowCell } from '@components/General/TWTable';
import styled from 'styled-components';

import FollowLink from '/public/img/general/follow-link.svg';
import Close from '/public/img/general/close.svg';

type PoolProps = {
name: string;
leverage: string;
keeper: string;
committer: string;
collateralAsset: string;
collateralAssetAddress: string;
};

export default (({ open, onClose, poolDetails, previewUrl, isDark }) => {
const { name, leverage, keeper, committer, collateralAsset, collateralAssetAddress } = poolDetails || {};

const formatAddress = (addr: string) => `${addr?.slice(0, 4)}...${addr?.slice(40, 42)}`;

const getContractDetailsUrl = (v: string) => {
const BASE_URL = `${previewUrl}address/${v}` || 'https://arbiscan.io/address/';
return v ? BASE_URL : 'https://arbiscan.io';
};

const getPriceFeedUrl = (v: string) => {
if (!v) {
return 'https://data.chain.link/arbitrum/mainnet/crypto-usd/';
}

let name = v?.split('-')[1];
name = name?.toLowerCase();
name = /\//.test(name) ? name?.replace('/', '-') : '';

const market = /eur/.test(name) ? 'fiat' : 'crypto-usd';
const FEED_URL = `https://data.chain.link/arbitrum/mainnet/${market}/`;

return `${FEED_URL}${name}`;
};

const poolDetailsData = [
{ name: 'Pool Ticker', value: name },
{
name: 'Price Feed',
value: name?.split('-')[1],
href: getPriceFeedUrl(name),
},
{
name: 'Power Leverage',
value: leverage,
},
{
name: 'Collateral Asset',
value: collateralAsset,
href: getContractDetailsUrl(collateralAssetAddress),
},
{
name: 'Deployer',
value: formatAddress(committer),
href: getContractDetailsUrl(committer),
},
{
name: 'Keeper Contract',
value: formatAddress(keeper),
href: getContractDetailsUrl(keeper),
},
];

return (
<TWModal open={open} onClose={onClose} className="py-10 px-5 sm:p-10">
<ModalHeader>
<div className="title">Pool Details</div>
<div className="close" onClick={onClose}>
<Close />
</div>
</ModalHeader>
<br />

<Table showDivider={false}>
{poolDetailsData.map((v, i) => (
<TableRow rowNumber={i} key={`${v.name}-${i}`}>
<TableRowCell className="px-2">
<CellContent>
<div className="name">{v.name}</div>
<div className="info">
{v.value}
{v.href ? (
<a href={v.href} target="_blank" rel="noopener noreferrer">
<FollowLinkIcon isDark={isDark} />
</a>
) : null}
</div>
</CellContent>
</TableRowCell>
</TableRow>
))}
</Table>
</TWModal>
);
}) as React.FC<{
open: boolean;
onClose: () => void;
poolDetails: PoolProps;
previewUrl: string;
isDark: boolean;
}>;

const ModalHeader = styled((props: any) => <div className={props.className}>{props.children}</div>)`
display: flex;
justify-content: space-between;
.title {
font-size: 24px;
margin-bottom: -17px;
}
.close {
width: 12px;
height: 12px;
:hover {
cursor: pointer;
}
}
`;

const FollowLinkIcon = styled(FollowLink)`
margin-left: 15px;
path {
stroke: ${(props) => (props.isDark ? '#ffffff' : '#374151')};
}
`;

const CellContent = styled((props: any) => <div className={props.className}>{props.children}</div>)`
display: flex;
.name {
width: 150px;
@media (min-width: 768px) {
width: 195px;
}
}
.info {
display: flex;
align-items: center;
}
`;
66 changes: 57 additions & 9 deletions archetypes/Pools/PoolsTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@ import { LinkOutlined } from '@ant-design/icons';

import Close from '/public/img/general/close.svg';
import ArrowDown from '/public/img/general/arrow-circle-down.svg';
import Info from '/public/img/general/info.svg';
import Equal from '/public/img/general/circle-equal.svg';
import { classNames } from '@libs/utils/functions';
import { constructBalancerLink } from '@archetypes/Exchange/Summary';
import { StyledTooltip } from '@components/Tooltips';
import PoolDetailsModal from '../PoolDetailsModal';
import { useTheme } from '@context/ThemeContext';
import styled from 'styled-components';

type TProps = {
onClickMintBurn: (pool: string, side: SideEnum, commitAction: CommitActionEnum) => void;
Expand Down Expand Up @@ -67,9 +71,30 @@ const NoBalancerPoolTip: React.FC<{ market: string }> = ({ children, market }) =
<StyledTooltip title={`There are no Balancer pools for the ${market} market yet.`}>{children}</StyledTooltip>
);

const InfoIcon = styled(Info)`
margin-left: 15px;
:hover {
cursor: pointer;
}
path {
fill: ${(props) => (props.isDark ? '#ffffff' : '#111928')};
}
`;

export default (({ rows, onClickMintBurn, showNextRebalance, deltaDenotion }) => {
const [showModalEffectiveGain, setShowModalEffectiveGain] = useState(false);
const { provider, account } = useWeb3();
const [showModalPoolDetails, setShowModalPoolDetails] = useState(false);
const [poolDetails, setPoolDetails] = useState<any>({});
const { provider, account, config } = useWeb3();
const { isDark } = useTheme();

const handlePoolDetailsClick = (data: any) => {
setShowModalPoolDetails(true);
setPoolDetails(data);
};

return (
<>
<Table>
Expand Down Expand Up @@ -157,12 +182,14 @@ export default (({ rows, onClickMintBurn, showNextRebalance, deltaDenotion }) =>
<PoolRow
pool={pool}
onClickMintBurn={onClickMintBurn}
onClickShowPoolDetailsModal={() => handlePoolDetailsClick(pool)}
index={index}
showNextRebalance={showNextRebalance}
key={pool.address}
account={account}
provider={provider}
deltaDenotion={deltaDenotion}
isDark={isDark}
/>
);
})}
Expand All @@ -188,6 +215,13 @@ export default (({ rows, onClickMintBurn, showNextRebalance, deltaDenotion }) =>
depending on the capital in the other side of the pool.
</div>
</TWModal>
<PoolDetailsModal
open={showModalPoolDetails}
onClose={() => setShowModalPoolDetails(false)}
poolDetails={poolDetails}
previewUrl={config?.previewUrl || ''}
isDark={isDark}
/>
</>
);
}) as React.FC<
Expand All @@ -203,8 +237,20 @@ const PoolRow: React.FC<
account: string | undefined;
index: number;
provider: ethers.providers.JsonRpcProvider | undefined;
onClickShowPoolDetailsModal: () => void;
isDark: boolean;
} & TProps
> = ({ pool, account, onClickMintBurn, index, provider, showNextRebalance, deltaDenotion }) => {
> = ({
pool,
account,
onClickMintBurn,
index,
provider,
showNextRebalance,
deltaDenotion,
onClickShowPoolDetailsModal,
isDark,
}) => {
const [pendingUpkeep, setPendingUpkeep] = useState(false);

const isBeforeFrontRunning = useIntervalCheck(pool.nextRebalance, pool.frontRunning);
Expand All @@ -220,7 +266,7 @@ const PoolRow: React.FC<
<TableRow rowNumber={index}>
{/** Pool rows */}
<TableRowCell rowSpan={2}>
<div style={{ minHeight: '3rem' }} className="flex">
<div style={{ minHeight: '3rem' }} className="flex items-center">
<Logo
className="inline mr-2 my-auto"
size={'md'}
Expand All @@ -230,6 +276,7 @@ const PoolRow: React.FC<
<div className="font-bold">{tickerToName(pool.name)}</div>
<div className="text-xs">{pool.name.split('-')[1]}</div>
</div>
<InfoIcon onClick={onClickShowPoolDetailsModal} isDark={isDark} />
</div>
</TableRowCell>
<TableRowCell rowSpan={2}>
Expand Down Expand Up @@ -370,6 +417,7 @@ const PoolRow: React.FC<
pastUpkeepTokenInfo={{
tokenPrice: pool.pastUpkeep.longTokenPrice,
tokenBalance: pool.pastUpkeep.longTokenBalance,
effectiveGain: pool.pastUpkeep.longTokenEffectiveGain,
}}
account={account}
tokenInfo={pool.longToken}
Expand All @@ -395,6 +443,7 @@ const PoolRow: React.FC<
pastUpkeepTokenInfo={{
tokenPrice: pool.pastUpkeep.shortTokenPrice,
tokenBalance: pool.pastUpkeep.shortTokenBalance,
effectiveGain: pool.pastUpkeep.shortTokenEffectiveGain,
}}
tokenInfo={pool.shortToken}
deltaDenotion={deltaDenotion}
Expand Down Expand Up @@ -434,6 +483,7 @@ const TokenRows: React.FC<
pastUpkeepTokenInfo: {
tokenPrice: number;
tokenBalance: number;
effectiveGain: number;
};
antecedentUpkeepTokenInfo: {
tokenPrice: number;
Expand All @@ -460,6 +510,8 @@ const TokenRows: React.FC<
}) => {
const styles = side === SideEnum.long ? longStyles : shortStyles;

const effectiveGain = showNextRebalance ? tokenInfo.effectiveGain : pastUpkeepTokenInfo.effectiveGain;

return (
<>
<TableRowCell size={'sm'} className={classNames(styles, 'border-l-2 border-theme-background')}>
Expand Down Expand Up @@ -501,14 +553,10 @@ const TokenRows: React.FC<
<TableRowCell size={'sm'} className={styles}>
<div
className={
tokenInfo.effectiveGain > leverage
? 'text-green-600'
: tokenInfo.effectiveGain < leverage
? 'text-red-600'
: ''
effectiveGain > leverage ? 'text-green-600' : effectiveGain < leverage ? 'text-red-600' : ''
}
>
{tokenInfo.effectiveGain.toFixed(3)}
{effectiveGain.toFixed(3)}
</div>
</TableRowCell>
<TableRowCell size={'sm'} className={styles}>
Expand Down
5 changes: 5 additions & 0 deletions archetypes/Pools/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ export interface BrowseTableRowData {

pastUpkeep: Upkeep;
antecedentUpkeep: Upkeep;

keeper: string;
committer: string;
collateralAsset: string;
collateralAssetAddress: string;
}

export interface BrowseState {
Expand Down
4 changes: 2 additions & 2 deletions archetypes/Stake/FarmsTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ export default (({ rows, onClickStake, onClickUnstake, onClickClaim, fetchingFar
const LARGE_DECIMAL = 10000000000;
const largeDecimal: (num: BigNumber) => string = (num) => {
if (num.gt(LARGE_DECIMAL)) {
return `> ${LARGE_DECIMAL}`
return `> ${LARGE_DECIMAL}`;
} else {
return num.times(100).toFixed(2);
}
}
};

const PoolRow: React.FC<{
farm: FarmTableRowData;
Expand Down
4 changes: 3 additions & 1 deletion components/General/TWModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ interface TWModalProps {
open: boolean;
onClose: () => any;
size?: Size;
className?: string;
}

type Size = 'default' | 'wide';
Expand All @@ -16,7 +17,7 @@ const SIZES: Record<Size, string> = {
wide: 'max-w-[1010px] h-[700px]',
};

export const TWModal: React.FC<TWModalProps> = ({ open, onClose, size = 'default', children }) => {
export const TWModal: React.FC<TWModalProps> = ({ open, onClose, size = 'default', className = '', children }) => {
return (
<Transition.Root show={open} as={Fragment}>
<Dialog as="div" className="fixed z-10 inset-0 overflow-y-auto" onClose={() => onClose()}>
Expand Down Expand Up @@ -50,6 +51,7 @@ export const TWModal: React.FC<TWModalProps> = ({ open, onClose, size = 'default
className={classNames(
'p-10 inline-block w-full align-bottom self-center bg-theme-background rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle',
SIZES[size],
className,
)}
>
{children}
Expand Down
12 changes: 9 additions & 3 deletions components/General/TWTable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { classNames } from '@libs/utils/functions';
import React from 'react';

export const Table: React.FC<{ className?: string }> = ({ className, children }) => {
export const Table: React.FC<{ showDivider?: boolean; className?: string }> = ({
showDivider = true,
className,
children,
}) => {
return (
<div className={classNames('flex flex-col overflow-hidden h-full', className ?? '')}>
<div className="overflow-x-auto h-full">
<div className="py-2 align-middle inline-block min-w-full">
<div className="border-b border-theme-border sm:rounded-lg">
<table className="min-w-full divide-y divide-theme-border">{children}</table>
<div className={`${showDivider ? 'border-b border-theme-border sm:rounded-lg' : ''}`}>
<table className={`min-w-full ${showDivider ? 'divide-y divide-theme-border' : ''}`}>
{children}
</table>
</div>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions context/PoolContext/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export const initPool: (
return [ethers.BigNumber.from(0), ethers.BigNumber.from(0)];
});

console.log(pool.name, 'Short token supply', shortTokenSupply.toString());

// fetch minimum commit size
const poolCommitterInstance = new ethers.Contract(
pool.committer.address,
Expand Down
Loading

0 comments on commit d808271

Please sign in to comment.