Skip to content

Commit

Permalink
I hate gas math. Javascript ints suck
Browse files Browse the repository at this point in the history
  • Loading branch information
lucemans committed Mar 19, 2024
1 parent b299411 commit 4b6041f
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 28 deletions.
78 changes: 72 additions & 6 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useMemo } from 'react';
import { BsFuelPump } from 'react-icons/bs';
import useSWR from 'swr';

import { getTransactions } from './etherscan/getTransactions';
Expand All @@ -8,7 +9,9 @@ import {
AllMultiReturnTypes,
decodeTransaction,
} from './utils/decodeTransaction';
import { useEthUsd } from './utils/ethUsd';
import { formatThousands } from './utils/formatThousands';
import { gasPriceMagic } from './utils/gasMagic';

const contractAddress = '0xFC0a4A934410F34A9bb8b4F28bEd6b960C943a7E';

Expand All @@ -35,6 +38,12 @@ export const App = () => {
return aggregateTotals(decodedTransactions) as Aggregates;
}, [decodedTransactions]);

const { data: currentUSDCPrice } = useEthUsd();

console.log({ currentUSDCPrice });

const gasPrice = 30n;

return (
<div className="w-full h-full min-h-screen bg-light-background-secondary dark:bg-dark-background-secondary px-4">
<div className="mx-auto w-full max-w-3xl space-y-4 py-8">
Expand Down Expand Up @@ -63,8 +72,27 @@ export const App = () => {
<div className="card w-full px-4 py-2">
<div>Commit Fee</div>
{totals?.commitAverage ? (
<div className="text-right font-bold text-lg">
{formatThousands(totals.commitAverage)}
<div>
<div className="text-right font-bold text-lg">
{formatThousands(totals.commitAverage)}
</div>
{currentUSDCPrice ? (
<div className="text-light-text-secondary flex justify-between gap-2 items-center">
<div className="flex items-center gap-1">
<BsFuelPump />
{gasPrice.toString()}
</div>
<div className="text-right flex items-center justify-end">
~{' '}
{gasPriceMagic(
totals.commitAverage,
gasPrice,
currentUSDCPrice
)}{' '}
USD
</div>
</div>
) : undefined}
</div>
) : (
<div>Loading...</div>
Expand All @@ -73,8 +101,27 @@ export const App = () => {
<div className="card w-full px-4 py-2">
<div>Registration Fee</div>
{totals?.registerAverage ? (
<div className="text-right font-bold text-lg">
{formatThousands(totals.registerAverage)}
<div>
<div className="text-right font-bold text-lg">
{formatThousands(totals.registerAverage)}
</div>
{currentUSDCPrice ? (
<div className="text-light-text-secondary flex justify-between gap-2 items-center">
<div className="flex items-center gap-1">
<BsFuelPump />
{gasPrice.toString()}
</div>
<div className="text-right flex items-center justify-end">
~{' '}
{gasPriceMagic(
totals.registerAverage,
gasPrice,
currentUSDCPrice
)}{' '}
USD
</div>
</div>
) : undefined}
</div>
) : (
<div>Loading...</div>
Expand All @@ -83,8 +130,27 @@ export const App = () => {
<div className="card w-full px-4 py-2">
<div>Renewal Fee</div>
{totals?.renewAverage ? (
<div className="text-right font-bold text-lg">
{formatThousands(totals.renewAverage)}
<div>
<div className="text-right font-bold text-lg">
{formatThousands(totals.renewAverage)}
</div>
{currentUSDCPrice ? (
<div className="text-light-text-secondary flex justify-between gap-2 items-center">
<div className="flex items-center gap-1">
<BsFuelPump />
{gasPrice.toString()}
</div>
<div className="text-right flex items-center justify-end">
~{' '}
{gasPriceMagic(
totals.renewAverage,
gasPrice,
currentUSDCPrice
)}{' '}
USD
</div>
</div>
) : undefined}
</div>
) : (
<div>Loading...</div>
Expand Down
24 changes: 23 additions & 1 deletion web/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import './globals.css';

import React from 'react';
import ReactDOM from 'react-dom/client';
import { SWRConfig } from 'swr';

import { App } from './App';

Expand All @@ -10,8 +11,29 @@ BigInt.prototype.toJSON = function () {
return this.toString();
};

function localStorageProvider() {
// When initializing, we restore the data from `localStorage` into a map.
const map = new Map(JSON.parse(localStorage.getItem('app-cache') || '[]'));

// Before unloading the app, we write back all the data into `localStorage`.
window.addEventListener('beforeunload', () => {
const appCache = JSON.stringify(Array.from(map.entries()));

localStorage.setItem('app-cache', appCache);
});

// We still use the map for write & read for performance.
return map;
}

ReactDOM.createRoot(document.querySelector('#root') as HTMLElement).render(
<React.StrictMode>
<App />
<SWRConfig
value={{
provider: localStorageProvider as any,
}}
>
<App />
</SWRConfig>
</React.StrictMode>
);
19 changes: 11 additions & 8 deletions web/src/txHistory/TransactionEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from '../utils/decodeTransaction';
import { useEthUsd } from '../utils/ethUsd';
import { formatThousands } from '../utils/formatThousands';
import { gasToEth } from '../utils/gas';

export const TransactionEntry: FC<{ tx: AllMultiReturnTypes }> = ({ tx }) => {
const actionLabel = deriveLabelFromFunctionName(tx.functionName, tx.tx.to);
Expand Down Expand Up @@ -65,18 +64,22 @@ export const TransactionEntry: FC<{ tx: AllMultiReturnTypes }> = ({ tx }) => {
<BsFuelPump />
<div>{formatThousands(BigInt(tx.tx.gasUsed))}</div>
</div>
{ethUsd.data && (
{ethUsd.data ? (
<div className="text-sm opacity-70">
{(
ethUsd.data *
gasToEth(
BigInt(tx.tx.gasUsed),
BigInt(tx.tx.gasPrice)
{Number(
Number(
(ethUsd.data *
Number(
(BigInt(tx.tx.gasUsed) *
BigInt(tx.tx.gasPrice)) /
1_000_000_000_000_000n
)) /
1_000_000
)
).toFixed(2)}{' '}
USD
</div>
)}
) : undefined}
</div>
<div className="flex justify-center items-center gap-1">
<LuFlame />
Expand Down
15 changes: 12 additions & 3 deletions web/src/utils/ethUsd.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import useSWR from 'swr';

export const useEthUsd = (timestamp: number) => {
const date = new Date(timestamp);
export const useEthUsd = (timestamp?: number) => {
const date = timestamp ? new Date(timestamp) : new Date(Date.now());
const year = date.getUTCFullYear();
const month = date.getUTCMonth() + 1;
const day = date.getUTCDate();
Expand All @@ -10,12 +10,21 @@ export const useEthUsd = (timestamp: number) => {
const dateString = `${day}-${month}-${year}`;

return useSWR(['ethUsd', dateString], async () => {
const x = localStorage.getItem('usdc-eth-' + dateString);

if (x) return Number(x);

const response = await fetch(
`https://api.coingecko.com/api/v3/coins/ethereum/history?date=${dateString}`
);

const data = await response.json();

return data.market_data.current_price.usd as number;
// USDC per 1000 ETH
const value = Number(data.market_data.current_price.usd) * 1000;

localStorage.setItem('usdc-eth-' + dateString, value.toString());

return Number(value);
});
};
10 changes: 0 additions & 10 deletions web/src/utils/gas.ts

This file was deleted.

12 changes: 12 additions & 0 deletions web/src/utils/gasMagic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const gasPriceMagic = (
gas: bigint,
gasPrice: bigint,
ethUSDC: number
) => {
return (
Number(
BigInt(Math.round(Number(gas * gasPrice * 1000n) * ethUSDC)) /
1_000_000n
) / 1_000_000_000
).toPrecision(3);
};

0 comments on commit 4b6041f

Please sign in to comment.