Skip to content

Commit

Permalink
Merge pull request #370 from merofinance/polygon-launch-2
Browse files Browse the repository at this point in the history
Polygon Launch
  • Loading branch information
chase-manning committed Jul 17, 2023
2 parents 74a9600 + f0f9d03 commit 16ad7b2
Show file tree
Hide file tree
Showing 21 changed files with 235 additions and 99 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ jobs:
with:
repoToken: "${{ secrets.GITHUB_TOKEN }}"
firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT }}"
expires: 4d
expires: 30d
projectId: backd-ffbef
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"dependencies": {
"@material-ui/core": "^4.12.3",
"@material-ui/icons": "^4.11.2",
"@merofinance/protocol": "^1.3.0",
"@merofinance/protocol": "^1.4.0",
"@reduxjs/toolkit": "^1.7.1",
"@sentry/react": "^6.16.1",
"@sentry/tracing": "^6.16.1",
Expand Down
14 changes: 8 additions & 6 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@
"gasBank": {
"header": "Gas Bank",
"topupAmount": "Gas Bank top-up amount",
"topupAmountTooltip": "The amount of ETH send to the Gas Bank to cover the gas cost of executing the transactions. Unspend ETH will be refunded to your wallet."
"topupAmountTooltip": "The amount of {{nativeToken}} send to the Gas Bank to cover the gas cost of executing the transactions. Unspend {{nativeToken}} will be refunded to your wallet."
},
"debtRepayment": {
"header": "Debt repayment",
Expand Down Expand Up @@ -546,7 +546,7 @@
"gas": {
"label": "Max gas price",
"question": "What is the maximum gas price to pay per debt repayment?",
"tooltip": "The maximum gas price used when paying for each debt repayment. Value is in Gwei units. If value is too low, then your debt repayment may not execute in time which could result in liquidation. A value of at least 200 Gwei is recommended.",
"tooltip": "The maximum gas price used when paying for each debt repayment. Value is in Gwei units. If value is too low, then your debt repayment may not execute in time which could result in liquidation. A value of at least {{maximumGas}} Gwei is recommended.",
"hover": "Enter max gas price"
}
}
Expand Down Expand Up @@ -647,20 +647,22 @@
"priority": {
"label": "Priority fee",
"question": "What priority fee should be used for your top-up?",
"tooltip": "An additional fee paid to Ethereum miners to prioritise your transaction and have it completed quicker. 3 Gwei is a suitable amount.",
"placeholder": "{{priorityFee}} Gwei",
"tooltip": "An additional fee paid to Ethereum miners to prioritise your transaction and have it completed quicker. {{priorityFee}} Gwei is a suitable amount.",
"hover": "Enter priority fee",
"invalid": "Invalid number",
"required": "Priority fee required"
},
"gas": {
"label": "Max gas price",
"question": "What is the maximum gas price to pay per top-up?",
"tooltip": "The maximum gas price used when paying for each top-up. Value is in Gwei units. If value is too low, then your top-up may not execute in time which could result in liquidation. A value of at least 200 Gwei is recommended.",
"tooltip": "The maximum gas price used when paying for each top-up. Value is in Gwei units. If value is too low, then your top-up may not execute in time which could result in liquidation. A value of at least {{maximumGas}} Gwei is recommended.",
"placeholder": "{{maximumGas}} Gwei",
"hover": "Enter max gas price",
"required": "Max gas price required",
"invalid": "Invalid number",
"positive": "Must be positive number",
"notEnoughEth": "Not enough ETH in wallet to cover gas, {{needed}} ETH needed",
"notEnoughEth": "Not enough {{nativeToken}} in wallet to cover gas, {{needed}} {{nativeToken}} needed",
"maxFeeTooLow": "The maximum gas price must be at least 2 Gwei",
"maxFeeGTPriorityFee": "The maximum gas price must be greater than the priority fee"
}
Expand Down Expand Up @@ -849,7 +851,7 @@
"button": "Decrease threshold"
},
"singleLow": {
"text": "Your max gas cost is {{maxGas}} ({{ethAmount}} ETH), however the single amount is only {{single}} ({{underlyingAmount}} {{underlyingSymbol}}). I recommend increasing the single amount to {{suggestion}} {{underlyingSymbol}} for more efficient actions.",
"text": "Your max gas cost is {{maxGas}} ({{ethAmount}} {{nativeToken}}), however the single amount is only {{single}} ({{underlyingAmount}} {{underlyingSymbol}}). I recommend increasing the single amount to {{suggestion}} {{underlyingSymbol}} for more efficient actions.",
"button": "Increase single amount"
},
"topupPositionLow": {
Expand Down
3 changes: 2 additions & 1 deletion src/app/hooks/use-ens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import { useEffect, useState } from "react";
import { Optional } from "../../lib/types";

const useENS = (): { ensName: Optional<string>; ensAvatar: Optional<string> } => {
const { account, library } = useWeb3React();
const { account, library, chainId } = useWeb3React();
const [ensName, setENSName] = useState<Optional<string>>(null);
const [ensAvatar, setENSAvatar] = useState<Optional<string>>(null);

const resolveENS = async (): Promise<void> => {
if (chainId === 137) return;
setENSAvatar(null);
if (!account) return;
const ensName = await library.provider.lookupAddress(account);
Expand Down
21 changes: 11 additions & 10 deletions src/app/hooks/use-pools-preview.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from "react";
import { ScaledNumber } from "scaled-number";
import POOL_METADATA from "../../lib/data/pool-metadata";
import POOL_METADATA, { PoolMetadata } from "../../lib/data/pool-metadata";
import { Optional, Pool } from "../../lib/types";

interface DataResponse {
Expand All @@ -18,14 +18,16 @@ const usePoolsPreview = (): Optional<Pool[]> => {
const [pools, setPools] = useState<Optional<Pool[]>>(null);

const fetchPools = async () => {
const queries = POOL_METADATA.map(async (data) => {
const response = await fetch(`https://yields.llama.fi/chart/${data.id}`);
const json = await response.json();
return {
symbol: data.symbol,
...json.data.slice(-1)[0],
};
});
const queries = POOL_METADATA.filter((metadata: PoolMetadata) => metadata.id).map(
async (data) => {
const response = await fetch(`https://yields.llama.fi/chart/${data.id}`);
const json = await response.json();
return {
symbol: data.symbol,
...json.data.slice(-1)[0],
};
}
);
const response = await Promise.all(queries);
const pools_: Pool[] = response.map((poolResponse: DataResponse) => {
const pool_: Pool = {
Expand All @@ -50,7 +52,6 @@ const usePoolsPreview = (): Optional<Pool[]> => {
name: "",
symbol: poolResponse.symbol,
},
harvestable: ScaledNumber.fromUnscaled(1),
strategyInfo: null,
isPaused: false,
};
Expand Down
2 changes: 1 addition & 1 deletion src/app/web3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { PrivateKeyConnector } from "../lib/private-key-connector";
import { RPC } from "../lib/constants";

export const privateKeyConnector = new PrivateKeyConnector({
supportedChainIds: [42],
supportedChainIds: [42, 137],
});

export const supportedChainIds = [
Expand Down
30 changes: 28 additions & 2 deletions src/lib/apys.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
const apiURL = "https://mero.finance/api/apys";
const API_URL = "https://mero.finance/api/apys";

// Temporary Polygon constants
const POLYGON_API_URL = "https://www.convexfinance.com/api/curve-polygon-apys";
const POLYGON_USDC_POOL_ID = "polygon-0xa138341185a9d0429b0021a11fb717b225e13e1f-11";
const POLYGON_USDC_POOL = "0x3d1004B2856b9d35228ec28f8F152FE9f9e51f81";

export interface Apy {
pool: string;
apy: number;
}

export async function getApys(): Promise<Apy[]> {
return (await fetch(apiURL)).json();
const [mainnetApys, polygonApys] = await Promise.all([getMainnetApys(), getPolygonApys()]);
return [...mainnetApys, ...polygonApys];
}

export async function getMainnetApys(): Promise<Apy[]> {
return (await fetch(API_URL)).json();
}

// This is temporary while the pool is new and volatile
// We will switch to the same APY system as the other pools once it stabilizes
export async function getPolygonApys(): Promise<Apy[]> {
const response = await fetch(POLYGON_API_URL);
const data = await response.json();
const aprData = data.apys[POLYGON_USDC_POOL_ID];
const apr = aprData.baseApy + aprData.crvApy;
const apy = ((1 + apr / 100 / 52) ** 52 - 1) * 100;
return [
{
pool: POLYGON_USDC_POOL,
apy,
},
];
}
28 changes: 28 additions & 0 deletions src/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { BigNumber } from "ethers";
import { Token } from "./types";

// Feature toggles
export const STAKING_LIVE = false;

// Variables
export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
export const DUMMY_ETH_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
export const ETH_TOKEN: Token = {
address: ZERO_ADDRESS,
decimals: 18,
name: "Ether",
symbol: "ETH",
};
export const ETH_DECIMALS = 18;
export const GWEI_DECIMALS = 9;
export const INFINITE_APPROVE_AMMOUNT = 10 ** 10;
Expand All @@ -27,6 +34,7 @@ export const chainIds: Record<string, string> = {
"4": "Rinkeby",
"5": "Goerli",
"42": "Kovan",
"137": "Polygon",
};

export const etherscanUrls: Record<string, string> = {
Expand All @@ -36,6 +44,7 @@ export const etherscanUrls: Record<string, string> = {
"5": "https://goerli.etherscan.io/",
"42": "https://kovan.etherscan.io/",
"1337": "https://etherscan.io/", // NOTE: only here to have some dummy URL in dev
"137": "https://polygonscan.com/",
};

export const oldPools: Record<string, string[]> = {
Expand All @@ -55,3 +64,22 @@ export const oldAddressProviders: Record<string, string> = {
"1": "0x139c15e21b0f6e43Fc397faCe5De5b7D5ae6874a",
"42": "0xFCf9099D09dBf9498Ad356006C95bDb988022e7E",
};

interface ChainSpecificCopy {
nativeToken: string;
priorityFee: string;
maximumGas: string;
}

export const chainSpecificCopy: Record<number, ChainSpecificCopy> = {
1: {
nativeToken: "ETH",
priorityFee: "3",
maximumGas: "200",
},
137: {
nativeToken: "MATIC",
priorityFee: "50",
maximumGas: "2,000",
},
};
10 changes: 7 additions & 3 deletions src/lib/contracts/aave/LendingPool.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Contract, Signer } from "ethers";
import { Provider } from "@ethersproject/providers";

const ADDRESS = "0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9";
const ADDRESS: Record<number, string> = {
1: "0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9",
137: "0x8dFf5E27EA6b7AC08EbFdf9eB090F32ee9a30fcf",
};

export class LendingPoolFactory {
static connect(signerOrProvider: Signer | Provider): Contract {
return new Contract(ADDRESS, _abi, signerOrProvider);
static connect(signerOrProvider: Signer | Provider, chainId: number): Contract {
const address = ADDRESS[chainId];
return new Contract(address, _abi, signerOrProvider);
}
}

Expand Down
59 changes: 47 additions & 12 deletions src/lib/data/pool-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,84 @@ import dai from "../../assets/tokens/dai.png";
import usdt from "../../assets/tokens/usdt.png";
import frax from "../../assets/tokens/frax.png";

interface ChainSpecificPoolData {
aaveStableDebtToken: string;
aaveVariableDebtToken: string;
}

export interface PoolMetadata {
icon: string;
id: string;
symbol: string;
aaveStableDebtToken: string;
aaveVariableDebtToken: string;
chainSpecificData: Record<number, ChainSpecificPoolData>;
}

const POOL_METADATA: PoolMetadata[] = [
{
id: "42cd9ead-de9e-4878-99a1-a984e2ffb4d9",
symbol: "FRAX",
icon: frax,
aaveStableDebtToken: "0x3916e3B6c84b161df1b2733dFfc9569a1dA710c2",
aaveVariableDebtToken: "0xfE8F19B17fFeF0fDbfe2671F248903055AFAA8Ca",
chainSpecificData: {
1: {
aaveStableDebtToken: "0x3916e3B6c84b161df1b2733dFfc9569a1dA710c2",
aaveVariableDebtToken: "0xfE8F19B17fFeF0fDbfe2671F248903055AFAA8Ca",
},
},
},
{
id: "2e9d6ab7-4329-48fd-b962-2ae0e58fc162",
symbol: "USDT",
icon: usdt,
aaveStableDebtToken: "0xe91D55AB2240594855aBd11b3faAE801Fd4c4687",
aaveVariableDebtToken: "0x531842cEbbdD378f8ee36D171d6cC9C4fcf475Ec",
chainSpecificData: {
1: {
aaveStableDebtToken: "0xe91D55AB2240594855aBd11b3faAE801Fd4c4687",
aaveVariableDebtToken: "0x531842cEbbdD378f8ee36D171d6cC9C4fcf475Ec",
},
},
},
{
id: "d9b38ffb-b796-454c-a115-7643fee20f5d",
symbol: "ETH",
icon: eth,
aaveStableDebtToken: "0x4e977830ba4bd783C0BB7F15d3e243f73FF57121",
aaveVariableDebtToken: "0xF63B34710400CAd3e044cFfDcAb00a0f32E33eCf",
chainSpecificData: {
1: {
aaveStableDebtToken: "0x4e977830ba4bd783C0BB7F15d3e243f73FF57121",
aaveVariableDebtToken: "0xF63B34710400CAd3e044cFfDcAb00a0f32E33eCf",
},
},
},
{
id: "65f68bad-18ed-45a7-b089-813780516cdd",
symbol: "DAI",
icon: dai,
aaveStableDebtToken: "0x778A13D3eeb110A4f7bb6529F99c000119a08E92",
aaveVariableDebtToken: "0x6C3c78838c761c6Ac7bE9F59fe808ea2A6E4379d",
chainSpecificData: {
1: {
aaveStableDebtToken: "0x778A13D3eeb110A4f7bb6529F99c000119a08E92",
aaveVariableDebtToken: "0x6C3c78838c761c6Ac7bE9F59fe808ea2A6E4379d",
},
},
},
{
id: "9078aa8f-7378-4969-925e-567e0c9b8da9",
symbol: "USDC",
icon: usdc,
aaveStableDebtToken: "0xE4922afAB0BbaDd8ab2a88E0C79d884Ad337fcA6",
aaveVariableDebtToken: "0x619beb58998eD2278e08620f97007e1116D5D25b",
chainSpecificData: {
1: {
aaveStableDebtToken: "0xE4922afAB0BbaDd8ab2a88E0C79d884Ad337fcA6",
aaveVariableDebtToken: "0x619beb58998eD2278e08620f97007e1116D5D25b",
},
},
},
{
id: "",
symbol: "USDC",
icon: usdc,
chainSpecificData: {
137: {
aaveStableDebtToken: "0xdeb05676dB0DB85cecafE8933c903466Bf20C572",
aaveVariableDebtToken: "0x248960A9d75EdFa3de94F7193eae3161Eb349a12",
},
},
},
];

Expand Down
Loading

0 comments on commit 16ad7b2

Please sign in to comment.