Skip to content

Commit

Permalink
🩹 gas: use l1 gas oracle
Browse files Browse the repository at this point in the history
  • Loading branch information
jgalat committed Oct 27, 2023
1 parent f737d6d commit 5cabf4c
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 18 deletions.
66 changes: 66 additions & 0 deletions abi/GasPriceOracle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
[
{ "inputs": [], "stateMutability": "nonpayable", "type": "constructor" },
{
"inputs": [],
"name": "baseFee",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "gasPrice",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "bytes", "name": "_data", "type": "bytes" }],
"name": "getL1Fee",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "bytes", "name": "_data", "type": "bytes" }],
"name": "getL1GasUsed",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "l1BaseFee",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "overhead",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "scalar",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
}
]
24 changes: 12 additions & 12 deletions components/OperationsModal/ModalTxCost/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React, { useMemo } from 'react';
import React from 'react';
import { Typography, Skeleton, Box } from '@mui/material';
import { useTranslation } from 'react-i18next';
import { formatUnits } from 'viem';
import { WEI_PER_ETHER } from 'utils/const';

import ModalInfo from 'components/common/modal/ModalInfo';
import useAccountData from 'hooks/useAccountData';
import useEstimateGas from 'hooks/useEstimateGas';
import useAsyncLoad from 'hooks/useAsyncLoad';

type Props = {
gasCost?: bigint;
Expand All @@ -14,24 +16,22 @@ type Props = {
function ModalTxCost({ gasCost }: Props) {
const { t } = useTranslation();
const { marketAccount } = useAccountData('WETH');
const estimate = useEstimateGas();
const { data: fallback } = useAsyncLoad(estimate);

const renderGas = useMemo(() => {
if (!gasCost || !marketAccount) return <Skeleton width={100} />;
const gas = gasCost || fallback;

const eth = parseFloat(formatUnits(gasCost, 18)).toFixed(6);
const usd = parseFloat(formatUnits((gasCost * marketAccount.usdPrice) / WEI_PER_ETHER, 18)).toFixed(2);
if (!gas || !marketAccount) return <Skeleton width={100} />;

return (
const eth = parseFloat(formatUnits(gas, 18)).toFixed(6);
const usd = parseFloat(formatUnits((gas * marketAccount.usdPrice) / WEI_PER_ETHER, 18)).toFixed(2);

return (
<ModalInfo label={t('TX Cost')} variant="row">
<Box display="flex" gap={0.5}>
<Typography variant="modalRow">{`~$${usd}`}</Typography>
<Typography variant="modalRow" color="figma.grey.600">{`(${eth} ETH)`}</Typography>
</Box>
);
}, [gasCost, marketAccount]);

return (
<ModalInfo label={t('TX Cost')} variant="row">
{renderGas}
</ModalInfo>
);
}
Expand Down
4 changes: 2 additions & 2 deletions hooks/useApprove.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useState } from 'react';
import { parseUnits, type Address, type EstimateGasParameters, type Hex } from 'viem';
import { parseUnits, type Address, type EstimateContractGasParameters, type Hex } from 'viem';
import { ERC20, Market } from 'types/contracts';
import { useWeb3 } from './useWeb3';
import { useOperationContext } from 'contexts/OperationContext';
Expand Down Expand Up @@ -37,7 +37,7 @@ function useApprove({
const estimateGas = useCallback(async () => {
if (!contract || !spender || !walletAddress || !opts) return;

let params: EstimateGasParameters;
let params: EstimateContractGasParameters;
switch (operation) {
case 'deposit':
case 'depositAtMaturity':
Expand Down
26 changes: 22 additions & 4 deletions hooks/useEstimateGas.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,40 @@
import { useCallback, useMemo } from 'react';
import { encodeFunctionData, type EstimateContractGasParameters } from 'viem';
import { usePublicClient } from 'wagmi';
import { optimism } from 'wagmi/chains';
import { useWeb3 } from './useWeb3';
import { isE2E } from 'utils/client';
import { getAlchemyProvider } from 'utils/providers';
import { EstimateGasParameters } from 'viem';
import { l1GasPriceOracleABI } from 'types/abi';

export default function useEstimateGas() {
const { chain } = useWeb3();
const e2ePublicClient = usePublicClient();
const publicClient = useMemo(() => (isE2E ? e2ePublicClient : getAlchemyProvider(chain)), [chain, e2ePublicClient]);

return useCallback(
async (request: EstimateGasParameters) => {
async (request?: EstimateContractGasParameters) => {
if (!publicClient) return;

let l1Gas = 0n;
if (chain.id === optimism.id) {
if (request) {
const data = encodeFunctionData(request);
l1Gas = await publicClient.readContract({
abi: l1GasPriceOracleABI,
address: '0x420000000000000000000000000000000000000F',
functionName: 'getL1Fee',
args: [data],
});
} else {
l1Gas = 5_555_555_555_55n;
}
}
const gasPrice = await publicClient.getGasPrice();
return gasPrice * (await publicClient.estimateGas(request));
const gasUsed = request ? await publicClient.estimateContractGas(request) : 500_000n;

return gasPrice * gasUsed + l1Gas;
},
[publicClient],
[publicClient, chain],
);
}
2 changes: 2 additions & 0 deletions wagmi.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import SablierV2LockupLinear from '@exactly/protocol/deployments/goerli/SablierV
import SablierV2NFTDescriptor from '@exactly/protocol/deployments/goerli/SablierV2NFTDescriptor.json' assert { type: 'json' };
import ExtraFinanceLendingABI from './abi/extraFinanceLending.json' assert { type: 'json' };
import DelegateRegistryABI from './abi/DelegateRegistry.json' assert { type: 'json' };
import GasPriceOracle from './abi/GasPriceOracle.json' assert { type: 'json' };
import EscrowedEXA from '@exactly/protocol/deployments/goerli/esEXA.json' assert { type: 'json' };

import { Abi } from 'viem';
Expand Down Expand Up @@ -51,6 +52,7 @@ export default defineConfig({
{ name: 'ExtraFinanceLending', abi: ExtraFinanceLendingABI as Abi },
{ name: 'DelegateRegistry', abi: DelegateRegistryABI as Abi },
{ name: 'EscrowedEXA', abi: EscrowedEXA.abi as Abi },
{ name: 'L1GasPriceOracle', abi: GasPriceOracle as Abi },
],
plugins: [
react({
Expand Down

0 comments on commit 5cabf4c

Please sign in to comment.