Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/swap fees calculation #1338

Open
wants to merge 3 commits into
base: swap-endpoint
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions api/_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import {
TokenNotFoundError,
} from "./_errors";
import { Token } from "./_dexes/types";
import { CoingeckoQueryParams } from "./coingecko";
import { addMarkupToAmount } from "./_dexes/uniswap/utils";

export { InputError, handleErrorCondition } from "./_errors";
Expand Down Expand Up @@ -777,20 +778,16 @@ export const buildDepositForSimulation = (depositArgs: {
* @param date An optional date string in the format of `DD-MM-YYYY` to resolve a historical price
* @returns The price of the `l1Token` token.
*/
export const getCachedTokenPrice = async (
l1Token: string,
baseCurrency: string = "eth",
historicalDateISO?: string,
chainId?: number
): Promise<number> => {
export const getCachedTokenPrice = async ({
baseCurrency = "eth",
...params
}: CoingeckoQueryParams): Promise<number> => {
return Number(
(
await axios(`${resolveVercelEndpoint()}/api/coingecko`, {
params: {
l1Token,
chainId,
baseCurrency,
date: historicalDateISO,
...params,
},
})
).data.price
Expand Down Expand Up @@ -1775,9 +1772,15 @@ export async function fetchStakingPool(

const [acrossTokenAddress, tokenUSDExchangeRate] = await Promise.all([
acceleratingDistributor.rewardToken(),
getCachedTokenPrice(poolUnderlyingTokenAddress, "usd"),
getCachedTokenPrice({
l1Token: poolUnderlyingTokenAddress,
baseCurrency: "usd",
}),
]);
const acxPriceInUSD = await getCachedTokenPrice(acrossTokenAddress, "usd");
const acxPriceInUSD = await getCachedTokenPrice({
l1Token: acrossTokenAddress,
baseCurrency: "usd",
});

const lpTokenERC20 = ERC20__factory.connect(lpTokenAddress, provider);

Expand Down Expand Up @@ -1968,7 +1971,7 @@ export async function getBalancerV2TokenPrice(
tokens.map(async (token: string, i: number): Promise<number> => {
const tokenContract = ERC20__factory.connect(token, provider);
const [price, decimals] = await Promise.all([
getCachedTokenPrice(token, "usd"),
getCachedTokenPrice({ l1Token: token, baseCurrency: "usd" }),
tokenContract.decimals(),
]);
const balance = parseFloat(
Expand Down
35 changes: 20 additions & 15 deletions api/coingecko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
getCachedTokenPrice,
parseQuery,
positiveInt,
boolStr,
} from "./_utils";
import {
CG_CONTRACTS_DEFERRED_TO_ID,
Expand All @@ -35,10 +36,11 @@ const CoingeckoQueryParamsSchema = object({
tokenAddress: optional(validAddress()),
chainId: optional(positiveInt),
baseCurrency: optional(string()),
findById: optional(boolStr()), // Tells CG client to find the token price by ID (more reliable)
date: optional(pattern(string(), /\d{2}-\d{2}-\d{4}/)),
});

type CoingeckoQueryParams = Infer<typeof CoingeckoQueryParamsSchema>;
export type CoingeckoQueryParams = Infer<typeof CoingeckoQueryParamsSchema>;

const handler = async (
{ query }: TypedVercelRequest<CoingeckoQueryParams>,
Expand All @@ -56,6 +58,7 @@ const handler = async (
tokenAddress,
chainId,
baseCurrency,
findById,
date: dateStr,
} = parseQuery(query, CoingeckoQueryParamsSchema);

Expand Down Expand Up @@ -140,16 +143,18 @@ const handler = async (
chainId
);
} else {
[, price] = CG_CONTRACTS_DEFERRED_TO_ID.has(address)
? await coingeckoClient.getCurrentPriceById(
address,
modifiedBaseCurrency
)
: await coingeckoClient.getCurrentPriceByContract(
address,
modifiedBaseCurrency,
chainId
);
[, price] =
CG_CONTRACTS_DEFERRED_TO_ID.has(address) || findById
? await coingeckoClient.getCurrentPriceById(
address,
modifiedBaseCurrency,
chainId
)
: await coingeckoClient.getCurrentPriceByContract(
address,
modifiedBaseCurrency,
chainId
);
}
}

Expand All @@ -162,10 +167,10 @@ const handler = async (
TOKEN_SYMBOLS_MAP[
baseCurrency.toUpperCase() as keyof typeof TOKEN_SYMBOLS_MAP
];
quotePrice = await getCachedTokenPrice(
token.addresses[CHAIN_IDs.MAINNET],
"usd"
);
quotePrice = await getCachedTokenPrice({
l1Token: token.addresses[CHAIN_IDs.MAINNET],
baseCurrency: "usd",
});
quotePrecision = token.decimals;
}
price = Number((price / quotePrice).toFixed(quotePrecision));
Expand Down
12 changes: 7 additions & 5 deletions api/limits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,13 @@ const handler = async (

const [tokenPriceNative, _tokenPriceUsd, latestBlock, gasUnits, gasPrice] =
await Promise.all([
getCachedTokenPrice(
l1Token.address,
sdk.utils.getNativeTokenSymbol(destinationChainId).toLowerCase()
),
getCachedTokenPrice(l1Token.address, "usd"),
getCachedTokenPrice({
l1Token: l1Token.address,
baseCurrency: sdk.utils
.getNativeTokenSymbol(destinationChainId)
.toLowerCase(),
}),
getCachedTokenPrice({ l1Token: l1Token.address, baseCurrency: "usd" }),
getCachedLatestBlock(HUB_POOL_CHAIN_ID),
// Only use cached gas units if message is not defined, i.e. standard for standard bridges
isMessageDefined
Expand Down
2 changes: 1 addition & 1 deletion api/suggested-fees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ const handler = async (
limits,
] = await Promise.all([
callViaMulticall3(provider, multiCalls, { blockTag: quoteBlockNumber }),
getCachedTokenPrice(l1Token.address, "usd"),
getCachedTokenPrice({ l1Token: l1Token.address, baseCurrency: "usd" }),
getCachedLimits(
inputToken.address,
outputToken.address,
Expand Down
34 changes: 17 additions & 17 deletions api/swap/_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ export async function handleBaseSwapQueryParams({
});

// 3. Calculate fees based for full route
// const fees = await calculateCrossSwapFees(crossSwapQuotes);
const fees = await calculateCrossSwapFees(crossSwapQuotes);

return {
crossSwapQuotes: {
...crossSwapQuotes,
// fees,
fees,
},
integratorId,
skipOriginTxEstimation,
Expand Down Expand Up @@ -178,18 +178,18 @@ async function calculateSwapFee(
): Promise<Record<string, number>> {
const { tokenIn, tokenOut, expectedAmountOut, expectedAmountIn } = swapQuote;
const [inputTokenPriceBase, outputTokenPriceBase] = await Promise.all([
getCachedTokenPrice(
tokenIn.address,
getCachedTokenPrice({
tokenAddress: tokenIn.address,
baseCurrency,
undefined,
tokenIn.chainId
),
getCachedTokenPrice(
tokenOut.address,
chainId: tokenIn.chainId,
findById: "true",
}),
getCachedTokenPrice({
tokenAddress: tokenOut.address,
baseCurrency,
undefined,
tokenOut.chainId
),
chainId: tokenOut.chainId,
findById: "true",
}),
]);

const normalizedIn =
Expand All @@ -208,12 +208,12 @@ async function calculateBridgeFee(
baseCurrency: string
): Promise<Record<string, number>> {
const { inputToken, suggestedFees } = bridgeQuote;
const inputTokenPriceBase = await getCachedTokenPrice(
inputToken.address,
const inputTokenPriceBase = await getCachedTokenPrice({
tokenAddress: inputToken.address,
baseCurrency,
undefined,
inputToken.chainId
);
chainId: inputToken.chainId,
findById: "true",
});
const normalizedFee =
parseFloat(
formatUnits(suggestedFees.totalRelayFee.total, inputToken.decimals)
Expand Down
2 changes: 1 addition & 1 deletion api/swap/allowance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const handler = async (
: bridgeQuote.outputToken;

const responseJson = {
// fees: crossSwapQuotes.fees,
fees: crossSwapQuotes.fees,
checks: {
allowance: {
token: inputTokenAddress,
Expand Down
2 changes: 1 addition & 1 deletion scripts/tests/swap-allowance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const MIN_OUTPUT_CASES = [
{
labels: ["B2B", "MIN_OUTPUT", "USDC - USDC"],
params: {
amount: ethers.utils.parseUnits("1", 6).toString(),
amount: ethers.utils.parseUnits("10", 6).toString(),
tradeType: "minOutput",
inputToken: TOKEN_SYMBOLS_MAP.USDC.addresses[originChainId],
originChainId,
Expand Down
Loading