Skip to content

Commit

Permalink
Init and migrate to new pyth endpoint (#720)
Browse files Browse the repository at this point in the history
* Init and migrate to new pyth endpoint

* Use env variables
  • Loading branch information
Sahilgat authored Sep 13, 2023
1 parent ff7e5ab commit 75e88dc
Show file tree
Hide file tree
Showing 10 changed files with 2,319 additions and 0 deletions.
1 change: 1 addition & 0 deletions webapp/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
/lib
.vercel
181 changes: 181 additions & 0 deletions webapp/api/_onchain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import { ethers } from "ethers";
import axios from "axios";
import ORACLE_ABI from "./abis/oracle.json";
import wstETH_ABI from "./abis/wstETH.json";
import rETH_ABI from "./abis/rETH.json";
import sAVAX_ABI from "./abis/sAVAX.json";

const CHAIN_IDS: {
[chainName: string]: number;
} = {
ETH_MAINNET: 1,
AVAX_MAINNET: 43114,
};

const ORACLES: {
[chainId: number]: string;
} = {
1: "0x789cD7AB3742e23Ce0952F6Bc3Eb3A73A0E08833",
777: "0xb5711dAeC960c9487d95bA327c570a7cCE4982c0",
43114: "0x108abfBa5AD61bd61A930BFe73394558d60f0b10",
};

const ASSETS: {
[chainId: number]: { [asset: string]: string };
} = {
1: {
USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
WBTC: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
WETH: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
wstETH: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
rETH: "0xae78736Cd615f374D3085123A210448E74Fc6393",
AAVE: "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9",
UNI: "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
SPELL: "0x090185f2135308BaD17527004364eBcC2D37e5F6",
BADGER: "0x3472A5A71965499acd81997a54BBA8D852C6E53d",
BAL: "0xba100000625a3754423978a60c9317c58a424e3D",
PERP: "0xbC396689893D065F41bc2C6EcbeE5e0085233447",
},
777: {
sAMB: "0x683aae5cD37AC94943D05C19E9109D5876113562",
},
43114: {
WAVAX: "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",
sAVAX: "0x2b2C81e08f1Af8835a78Bb2A90AE924ACE0eA4bE",
},
};

const PROVIDERS: { [chainId: number]: ethers.providers.StaticJsonRpcProvider } =
{
1: new ethers.providers.StaticJsonRpcProvider(
process.env.REACT_APP_MAINNET_URI
),
43114: new ethers.providers.StaticJsonRpcProvider(
process.env.REACT_APP_AVAX_URI
),
777: new ethers.providers.StaticJsonRpcProvider(
process.env.REACT_APP_MAINNET_URI
),
};

/**
* 1. Get contract settlement state
* 2. Use the pyth price for the listed majors
*/

type OracleResponse = [ethers.BigNumber, boolean];

export interface PriceResponse {
asset: string;
expiryPrice: string;
finalized: boolean;
}

async function getExpiryPricesForChainId(
chainid: number,
expiryTimestamp: number
) {
let prices: PriceResponse[] = [];
const provider = PROVIDERS[chainid];
const oracle = new ethers.Contract(ORACLES[chainid], ORACLE_ABI, provider);
const assets = ASSETS[chainid];

let promises: Promise<OracleResponse>[] = [];

const assetKeys = Object.keys(assets);

for (const asset of assetKeys) {
const assetAddress = assets[asset];
const promise = oracle.getExpiryPrice(assetAddress, expiryTimestamp);
promises.push(promise);
}
const responses = await Promise.all(promises);

for (let i = 0; i < assetKeys.length; i++) {
const asset = assetKeys[i];
const [expiryPrice, finalized] = responses[i];
prices.push({
asset,
finalized,
expiryPrice: ethers.utils.formatUnits(expiryPrice, 8),
});
}

return prices;
}
export async function getExpiryPrices(
expiryTimestamp: number
): Promise<PriceResponse[]> {
const chainIds = Object.keys(PROVIDERS).map(Number); // Parse the chain IDs as numbers

const unmergedPromises = chainIds.map((chainId) =>
getExpiryPricesForChainId(chainId, expiryTimestamp)
);

const unmerged = await Promise.all(unmergedPromises);
const prices = unmerged.flat();

return prices;
}

export async function getwstETHRatio(blockNumber: number): Promise<number> {
const provider = PROVIDERS[CHAIN_IDS["ETH_MAINNET"]];
const contract = new ethers.Contract(
ASSETS[CHAIN_IDS["ETH_MAINNET"]]["wstETH"],
wstETH_ABI,
provider
);
const result: string = await contract.callStatic.stEthPerToken({
blockTag: blockNumber,
});
return parseFloat(ethers.utils.formatEther(result));
}

export async function getrETHRatio(blockNumber: number): Promise<number> {
const provider = PROVIDERS[CHAIN_IDS["ETH_MAINNET"]];
const contract = new ethers.Contract(
ASSETS[CHAIN_IDS["ETH_MAINNET"]]["rETH"],
rETH_ABI,
provider
);
const result: string = await contract.callStatic.getExchangeRate({
blockTag: blockNumber,
});
return parseFloat(ethers.utils.formatEther(result));
}

export async function getsAVAXRatio(blockNumber: number): Promise<number> {
const provider = PROVIDERS[CHAIN_IDS["AVAX_MAINNET"]];
const contract = new ethers.Contract(
ASSETS[CHAIN_IDS["AVAX_MAINNET"]]["sAVAX"],
sAVAX_ABI,
provider
);
const result: string = await contract.callStatic.getPooledAvaxByShares(
ethers.utils.parseEther("1"),
{
blockTag: blockNumber,
}
);
return parseFloat(ethers.utils.formatEther(result));
}

export async function getClosestBlock(
timestamp: number,
chainName: string
): Promise<number> {
const url = `https://coins.llama.fi/block/${chainName}/${timestamp.toString()}`;
try {
const response = await axios.get(url);

const { data } = response;
if (data.timestamp >= timestamp) {
return data.height;
} else {
return data.height + 1;
}
} catch (error) {
console.error(error);
throw error;
}
}
60 changes: 60 additions & 0 deletions webapp/api/_utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import moment, { Moment } from "moment";
import { NextApiRequest } from "next";

export const parseExpiryFromRequest = (request: NextApiRequest) => {
const ex = request.query["expiry"] as string;
let expiryTimestamp: number;
if (ex === "latest") {
expiryTimestamp = getLastFriday();
} else {
expiryTimestamp = parseInt(request.query["expiry"] as string);
}
return expiryTimestamp;
};

export const getLastFriday = () => {
const now = moment().utc();
let friday;

switch (now.isoWeekday()) {
case 1:
case 2:
case 3:
case 4:
friday = moment().utc().day(5).subtract(1, "week");
break;
case 5:
// On Fridays, if before 8am UTC return last week. If after, return today
if (now.hours() < 8) {
friday = moment().utc().day(5).subtract(1, "week");
} else {
friday = moment().utc().day(5);
}
break;
case 6:
case 7:
friday = moment().utc().day(5);
break;
}
return (friday as Moment).hours(8).minutes(0).seconds(0).unix();
};

export const getNextFridayTimestamp = () => {
const now = moment().utc();
let friday;

switch (now.isoWeekday()) {
case 1:
case 2:
case 3:
friday = moment().utc().day(5);
break;
case 4:
case 5:
case 6:
case 7:
friday = moment().utc().day(5).add(1, "week");
break;
}
return (friday as Moment).hours(8).minutes(0).seconds(0).unix();
};
Loading

5 comments on commit 75e88dc

@vercel
Copy link

@vercel vercel bot commented on 75e88dc Sep 13, 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:

ribbon-lend – ./lend

ribbon-lend-git-master-ribbon-finance.vercel.app
ribbon-lend-ribbon-finance.vercel.app
lend.ribbon.finance

@vercel
Copy link

@vercel vercel bot commented on 75e88dc Sep 13, 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:

ribbon-frontend – ./webapp

app.ribbon.finance
ribbon-frontend-git-master-ribbon-finance.vercel.app
ribbon-frontend-ribbon-finance.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 75e88dc Sep 13, 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:

ribbon-governance – ./governance

ribbon-governance-git-master-ribbon-finance.vercel.app
ribbon-governance-ribbon-finance.vercel.app
vote.ribbon.finance

@vercel
Copy link

@vercel vercel bot commented on 75e88dc Sep 13, 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 75e88dc Sep 13, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.