Skip to content

Commit

Permalink
Release 11/01/23 (#352)
Browse files Browse the repository at this point in the history
* dont calc graph if there are no events

* Subgraph: Add arbitrum

* TVL Fix

* TVL to uni & backlink dayData fields

* add token symbol to config

* add rewardsClaimedEvents to tenderizer

* Subgraph: ID to protocol name in TenderSwap entity

* Cleanup old DPY data

* fix tokenID comparison

* add local subgraph deployment tools

* update docker-compose.tml

* small changes to work with local hardhat network (#348)

* Unstake and Withdraw UI (#343)

* start impl

* withdraw modal added

* change calculations and update the UI a bit

* fix bug with graph withdraw

* change to using processUnstakes, graph changes, calc fixes

* fix date

* address pr comments and fix calculation done on the ui

* prettier

* refresh on tenderbalance change

* make time remaining more granular, add unit tests (#351)

* make time remaining more granular, add unit tests

* remove code duplication

* add unit tests to the ci

* subgraph: node migration unstake/withdraw

Co-authored-by: Reuben Rodrigues <[email protected]>
Co-authored-by: kyriediculous <[email protected]>
  • Loading branch information
3 people authored Jan 11, 2023
1 parent 03efa0a commit ac51ba7
Show file tree
Hide file tree
Showing 40 changed files with 3,490 additions and 565 deletions.
38 changes: 19 additions & 19 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ name: Node.js CI

on:
push:
branches: [ develop ]
branches: [develop]
pull_request:
branches: [ master, develop ]
branches: [master, develop]

jobs:
build:

runs-on: ubuntu-latest

strategy:
Expand All @@ -20,19 +19,20 @@ jobs:
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- run: yarn install
- run: yarn workspace @tender/shared build
- run: yarn workspace @tender/shared lint
- run: yarn workspace @tender/shared pretty
- run: yarn workspace @tender/app build
- run: yarn workspace @tender/app lint
- run: yarn workspace @tender/app pretty
- run: yarn workspace @tender/landing build
- run: yarn workspace @tender/landing lint
- run: yarn workspace @tender/landing pretty
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: "yarn"
- run: yarn install
- run: yarn workspace @tender/shared build
- run: yarn workspace @tender/shared lint
- run: yarn workspace @tender/shared pretty
- run: yarn workspace @tender/app build
- run: yarn workspace @tender/app test
- run: yarn workspace @tender/app lint
- run: yarn workspace @tender/app pretty
- run: yarn workspace @tender/landing build
- run: yarn workspace @tender/landing lint
- run: yarn workspace @tender/landing pretty
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ yarn-error.log*

# subgraph
packages/subgraph/build/
packages/subgraph/data/
packages/subgraph/src/types/
packages/subgraph/subgraph.yaml
9 changes: 9 additions & 0 deletions packages/app/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
preset: "ts-jest",
transform: { "^.+\\.ts?$": "ts-jest" },
testEnvironment: "node",
testRegex: "/test/.*\\.(test|spec)?\\.(ts|tsx)$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
automock: false,
setupFiles: ["./setupJest.js"],
};
5 changes: 4 additions & 1 deletion packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"startprod": "next start",
"start": "next dev",
"lint": "next lint",
"test": "yarn jest",
"eject": "react-scripts eject",
"pretty": "npx prettier --check 'src/**/*.{ts,tsx,js,jsx}'",
"format": "npx prettier --write 'src/**/*.{ts,tsx,js,jsx}'"
Expand All @@ -19,7 +20,7 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",
"@types/jest": "^29.2.5",
"@types/lru-cache": "^5.1.1",
"@types/node": "^12.0.0",
"@types/react": "^17.0.0",
Expand All @@ -35,6 +36,7 @@
"framer-motion": "^4.1.17",
"grommet": "^2.19.1",
"grommet-icons": "^4.7.0",
"jest": "^29.3.1",
"lru-cache": "^6.0.0",
"next": "12.0.8",
"polished": "^4.1.3",
Expand All @@ -44,6 +46,7 @@
"react-scripts": "4.0.3",
"styled-components": "^5.3.3",
"swr": "^1.0.1",
"ts-jest": "^29.0.3",
"typescript": "^4.6.4",
"utf-8-validate": "^5.0.8",
"web-vitals": "^1.0.1"
Expand Down
Empty file added packages/app/setupJest.js
Empty file.
8 changes: 8 additions & 0 deletions packages/app/src/components/BrandedALink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { theme } from "@tender/shared/src";
import { normalizeColor } from "grommet/utils";
import styled from "styled-components";

const brandColor = normalizeColor("brand", theme);
export const BrandedALink = styled.a`
color: ${brandColor};
`;
28 changes: 28 additions & 0 deletions packages/app/src/components/ChangeChainWarning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { FC } from "react";
import { stakers } from "@tender/shared/src/index";
import { useIsCorrectChain } from "utils/useEnsureRinkebyConnect";
import { SwitchNetwork } from "components/account/SwitchNetwork";
import { ProtocolName } from "@tender/shared/src/data/stakers";
import { Box } from "grommet";
import { useEthers } from "@usedapp/core";

const ChangeChainWarning: FC<{ protocolName: ProtocolName }> = ({ children, protocolName }) => {
const { account } = useEthers();

const requiredChain = stakers[protocolName].chainId;
const isCorrectChain = useIsCorrectChain(requiredChain);

return (
<>
{!isCorrectChain && account ? (
<Box pad={{ vertical: "large" }}>
<SwitchNetwork chainId={requiredChain} protocol={stakers[protocolName].title} />
</Box>
) : (
<>{children}</>
)}
</>
);
};

export default ChangeChainWarning;
12 changes: 2 additions & 10 deletions packages/app/src/components/account/AccountModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import styled from "styled-components";
import { useEthers, useEtherBalance, getChainById, useTokenBalance } from "@usedapp/core";
import { addresses } from "@tender/contracts/src/index";
import { TransactionsList } from "../transactions";
import { formatEther } from "@ethersproject/units";
import { BigNumber, constants } from "ethers";
import { constants } from "ethers";
import { ShareIcon } from "../transactions/Icons";
import { Link } from "../base";
import {
Expand All @@ -29,14 +28,7 @@ import {
import { Staker, stakers } from "@tender/shared/src/index";
import { AddToken } from "./AddToken";
import { FormClose } from "grommet-icons";

const formatter = new Intl.NumberFormat("en-us", {
minimumFractionDigits: 4,
maximumFractionDigits: 4,
});

const formatBalance = (balance: BigNumber | undefined) =>
formatter.format(parseFloat(formatEther(balance ?? BigNumber.from("0"))));
import { formatBalance } from "components/formatting";

type AccountModalProps = {
showModal: boolean;
Expand Down
14 changes: 4 additions & 10 deletions packages/app/src/components/deposit/ConfirmDepositModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from "grommet";

import { FormClose } from "grommet-icons";
import { stakers, theme } from "@tender/shared/src/index";
import { stakers } from "@tender/shared/src/index";
import { weiToEthWithDecimals } from "utils/amountFormat";
import { useBalanceValidation } from "utils/inputValidation";
import { AmountInputFooter } from "components/AmountInputFooter";
Expand All @@ -26,8 +26,7 @@ import { isPendingTransaction } from "utils/transactions";
import { TransactionStatus } from "@usedapp/core";
import { LoadingButtonContent } from "components/LoadingButtonContent";
import { useCalcDepositOut } from "utils/tenderDepositHooks";
import styled from "styled-components";
import { normalizeColor } from "grommet/utils";
import { BrandedALink } from "components/BrandedALink";

type Props = {
show: boolean;
Expand Down Expand Up @@ -142,9 +141,9 @@ const ConfirmDepositModal: FC<Props> = ({
<Box>
<Text>
Notice: staking GRT infers a 0.5%{" "}
<StyledA href="https://thegraph.com/docs/en/network/delegating/#the-delegation-tax">
<BrandedALink href="https://thegraph.com/docs/en/network/delegating/#the-delegation-tax">
delegation
</StyledA>{" "}
</BrandedALink>{" "}
fee towards the Graph Protocol.
</Text>
</Box>
Expand Down Expand Up @@ -179,8 +178,3 @@ const ConfirmDepositModal: FC<Props> = ({
};

export default ConfirmDepositModal;

const brandColor = normalizeColor("brand", theme);
const StyledA = styled.a`
color: ${brandColor};
`;
156 changes: 156 additions & 0 deletions packages/app/src/components/deposit/UnstakeModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { FC, MouseEventHandler, useState } from "react";
import { utils, BigNumberish } from "ethers";
import {
Button,
Box,
Card,
CardHeader,
CardBody,
CardFooter,
Layer,
Form,
FormField,
Image,
TextInput,
Text,
Heading,
} from "grommet";

import { FormClose } from "grommet-icons";
import { stakers } from "@tender/shared/src/index";
import { weiToEthWithDecimals } from "utils/amountFormat";
import { isLargerThanMax, isPositive, useBalanceValidation } from "utils/inputValidation";
import { AmountInputFooter } from "components/AmountInputFooter";
import { ProtocolName } from "@tender/shared/src/data/stakers";
import { useUnstake } from "utils/tenderDepositHooks";
import { BrandedALink } from "components/BrandedALink";

type Props = {
show: boolean;
tenderTokenBalance: BigNumberish;
protocolName: ProtocolName;
onDismiss: () => void;
};

const UnstakeModal: FC<Props> = ({ show, tenderTokenBalance, protocolName, onDismiss }) => {
const staker = stakers[protocolName];
const symbol = staker.symbol;
const bwTenderLogo = `/${staker.bwTenderLogo}`;

const [unstakeInput, setUnstakeInput] = useState("");

const { validationMessage } = useBalanceValidation(unstakeInput, tenderTokenBalance, symbol);

const maxUnstake = () => {
setUnstakeInput(utils.formatEther(tenderTokenBalance.toString()));
};

const handleInputChange = (e: any) => {
const val = e.target.value;
if (val && !val.match(/^(\d+\.?\d*|\.\d+)$/)) return;
setUnstakeInput(val);
};

const { unstake } = useUnstake(protocolName);

const handleUnstake: MouseEventHandler<HTMLElement> = async (e) => {
e.preventDefault();
await unstake(utils.parseEther(unstakeInput || "0"));
setUnstakeInput("");
onDismiss();
};

return (
<>
{show && (
<Layer style={{ overflow: "auto" }} animation="fadeIn" onEsc={onDismiss} onClickOutside={onDismiss}>
<Card
flex={false}
pad={{ vertical: "medium", horizontal: "xlarge" }}
width="large"
style={{ position: "relative" }}
>
<Button
style={{ position: "absolute", top: 10, right: 10 }}
plain
icon={<FormClose />}
onClick={onDismiss}
/>
<CardHeader justify="center" pad="none">
<Heading level={2} alignSelf="center">
{`Unstake t${symbol} for ${symbol}`}
</Heading>
</CardHeader>
<CardBody>
<Box pad={{ top: "medium", horizontal: "large" }} align="center">
<Form style={{ width: "100%" }}>
<Box gap="medium">
<FormField label={`Unstake t${symbol}`}>
<TextInput
id="formUnstake"
type="number"
placeholder="0"
value={unstakeInput}
onChange={handleInputChange}
required={true}
style={{ textAlign: "right", padding: "20px 50px" }}
icon={
<Box pad="xsmall" direction="row" align="center" gap="small">
<Image height="35" src={bwTenderLogo} />
<Text>{`t${symbol}`}</Text>
</Box>
}
/>
<Text color="red">{validationMessage}</Text>
<AmountInputFooter
label={`Balance: ${weiToEthWithDecimals(tenderTokenBalance, 6)} t${symbol}`}
onClick={maxUnstake}
/>
</FormField>

<Box>
<Text>
After unstaking, the tokens will have to go through an unbonding period. The exact withdrawing
date depends on the <BrandedALink href={getWithdrawLink(protocolName)}>underlying</BrandedALink>{" "}
protocol.
</Text>
</Box>
</Box>
</Form>
</Box>
</CardBody>
<CardFooter justify="center" pad={{ vertical: "medium" }}>
<Box style={{ width: "100%" }} pad={{ horizontal: "large" }} justify="center" gap="small">
<Button
primary
disabled={
!isPositive(unstakeInput) ||
isLargerThanMax(unstakeInput, tenderTokenBalance) ||
unstakeInput.toString() === "0"
}
onClick={handleUnstake}
label={"Unstake"}
/>
</Box>
</CardFooter>
</Card>
</Layer>
)}
</>
);
};

export default UnstakeModal;

const getWithdrawLink = (protocolName: ProtocolName): string => {
switch (protocolName) {
case "audius":
return "https://docs.audius.org/token/staking#staking-on-audius";
case "graph":
return "https://thegraph.com/docs/en/network/delegating/#the-delegation-tax";
case "livepeer":
return "https://www.figment.io/resources/livepeer-staking-delegation-guide-2";
case "matic":
return "https://polygon.technology/staking/";
}
};
Loading

2 comments on commit ac51ba7

@vercel
Copy link

@vercel vercel bot commented on ac51ba7 Jan 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on ac51ba7 Jan 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

tender-app – ./packages/app

tender-app-git-master-tenderize.vercel.app
app.tenderize.me
tender-app-tenderize.vercel.app

Please sign in to comment.