Last active
April 2, 2024 03:06
-
-
Save Turupawn/ae0e56622bfae810ec94e882335a07fe to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Fees are calculated as follows (https://community.optimism.io/docs/developers/l2/new-fees.html): | |
Total transaction fee is a combination of an "L2 execution fee" and an "L1 security fee": | |
total_fee = (l2_gas_price * l2_gas_used) + (l1_gas_price * l1_gas_used) | |
Where: | |
- `l2_gas_price` corresponds to the cost of execution on L2 | |
- `l2_gas_used` corresponds to the amount of gas used on L2 | |
- `l1_gas_price` corresponds to the cost of publishing the transaction data on L1 | |
- `l1_gas_used` corresponds to the amount of transaction data published on L1 | |
*/ | |
export const name = 'Scroll Transaction Fees'; | |
export const version = '0.3.3'; | |
export const license = 'MIT'; | |
const SEC_IN_DAY = 86400; | |
export function setup(sdk: Context) { | |
const OP_GAS_PREDEPLOY = '0x5300000000000000000000000000000000000002'; | |
const OP_GAS_ABI = [ | |
{ | |
inputs: [ | |
{ | |
internalType: 'bytes', | |
name: '_data', | |
type: 'bytes', | |
}, | |
], | |
name: 'getL1Fee', | |
outputs: [ | |
{ | |
internalType: 'uint256', | |
name: '', | |
type: 'uint256', | |
}, | |
], | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
]; | |
sdk.ethers.addProvider("scroll", "https://sepolia-rpc.scroll.io/"); | |
const provider = sdk.ethers.getProvider("scroll"); | |
const gasPredeployContract = sdk.ethers.getContract(OP_GAS_PREDEPLOY, OP_GAS_ABI, "scroll"); | |
const getTransferEthCost = async () => { | |
const l2GasPrice = await provider.getGasPrice(); | |
const l2GasEstimate = await provider.estimateGas({ | |
from: '0xb6F5414bAb8d5ad8F33E37591C02f7284E974FcB', // Address has enough ETH that this won't fail | |
to: '0xcafebeefcafebeefcafebeefcafebeefcafebeef', | |
value: '0x38d7ea4c68000', // 0.001 ETH | |
}); | |
const l1GasCost = await gasPredeployContract.getL1Fee( | |
sdk.ethers.utils.serializeTransaction({ | |
nonce: 1234, | |
value: '0x38d7ea4c68000', // 0.001 ETH | |
gasPrice: l2GasPrice, | |
gasLimit: l2GasEstimate, | |
to: '0xcafebeefcafebeefcafebeefcafebeefcafebeef', | |
data: '0x', | |
}) | |
); | |
const totalGasCostWei = l2GasPrice.mul(l2GasEstimate).add(l1GasCost).toNumber(); | |
const ethPrice = await sdk.defiLlama.getCurrentPrice('coingecko', 'ethereum'); | |
return (totalGasCostWei * ethPrice) / 1e18; | |
}; | |
const getTransferTokenCost = async () => { | |
const l2GasPrice = await provider.getGasPrice(); | |
const l2GasEstimate = await provider.estimateGas({ | |
from: '0xb6F5414bAb8d5ad8F33E37591C02f7284E974FcB', // Random account with USDT | |
to: '0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4', // USDT Contract | |
data: | |
'0xa9059cbb00000000000000000000000023e7039c34c7aa47a0d4e975fbc789e0f763fa640000000000000000000000000000000000000000000000000000000000000001', | |
}); | |
const l1GasCost = await gasPredeployContract.getL1Fee( | |
sdk.ethers.utils.serializeTransaction({ | |
nonce: 1234, | |
value: '0x', | |
gasPrice: l2GasPrice, | |
gasLimit: l2GasEstimate, | |
to: '0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4', | |
data: | |
'0xa9059cbb00000000000000000000000023e7039c34c7aa47a0d4e975fbc789e0f763fa640000000000000000000000000000000000000000000000000000000000000001', | |
}) | |
); | |
const totalGasCostWei = l2GasPrice.mul(l2GasEstimate).add(l1GasCost).toNumber(); | |
const ethPrice = await sdk.defiLlama.getCurrentPrice('coingecko', 'ethereum'); | |
return (totalGasCostWei * ethPrice) / 1e18; | |
}; | |
const getSwapCost = async () => { | |
const l2GasPrice = await provider.getGasPrice(); | |
const l2GasEstimate = await provider.estimateGas({ | |
from: '0xb6F5414bAb8d5ad8F33E37591C02f7284E974FcB', // Random account with USDT | |
to: '0xfc30937f5cDe93Df8d48aCAF7e6f5D8D8A31F636', // Uniswap Router | |
data: | |
'0x414bf38900000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000c9499bd14493f6d9006d6a13aca3098c786fe6b100000000000000000000000000000000000000000000000000000000912e6519000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', | |
}); | |
const l1GasCost = await gasPredeployContract.getL1Fee( | |
sdk.ethers.utils.serializeTransaction({ | |
nonce: 1234, | |
value: '0x', | |
gasPrice: l2GasPrice, | |
gasLimit: l2GasEstimate, | |
to: '0xfc30937f5cDe93Df8d48aCAF7e6f5D8D8A31F636', | |
data: | |
'0x414bf38900000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da100000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000c9499bd14493f6d9006d6a13aca3098c786fe6b100000000000000000000000000000000000000000000000000000000912e6519000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', | |
}) | |
); | |
const totalGasCostWei = l2GasPrice.mul(l2GasEstimate).add(l1GasCost).toNumber(); | |
const ethPrice = await sdk.defiLlama.getCurrentPrice('coingecko', 'ethereum'); | |
return (totalGasCostWei * ethPrice) / 1e18; | |
}; | |
const getAverageSwapFee = async (date: string) => { | |
const dayId = Math.floor(sdk.date.dateToTimestamp(date) / SEC_IN_DAY); | |
const query = `{ | |
dayStat(id: "${dayId}") { | |
averageCostUSD | |
} | |
nextDay: dayStat(id: "${dayId + 1}") { | |
averageCostUSD | |
} | |
}`; | |
const result = await sdk.graph.query('40579/scroll-average-fees', query); | |
if (!result.dayStat) { | |
throw new Error('Data unavailable'); | |
} | |
if (!result.nextDay) { | |
throw new Error('Day incomplete'); | |
} | |
return parseFloat(result.dayStat.averageCostUSD); | |
}; | |
sdk.register({ | |
id: 'scroll', | |
queries: { | |
feeTransferEth: getTransferEthCost, | |
feeTransferERC20: getTransferTokenCost, | |
feeSwap: getSwapCost, | |
oneDayAverageFeeSwap: getAverageSwapFee, | |
}, | |
metadata: { | |
icon: sdk.ipfs.getDataURILoader( | |
'QmS1mBxRRDjuVPAPkjrmrnVgzYwyfchjvRZTH11vgjqabG', | |
'image/svg+xml' | |
), | |
category: 'l2', | |
name: 'Scroll', | |
description: | |
'Scroll is an zkEVM.', | |
l2BeatSlug: 'scroll', | |
website: 'https://scroll.io', | |
flags: { | |
throtle: | |
'Scroll is throttled while in beta. Fees will decrease as this throttle is lifted.', | |
}, | |
}, | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment