Skip to content

Commit a282085

Browse files
committed
fix: optimize swap amounts by accounting flashloan fees
1 parent f2e3618 commit a282085

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

src/components/transactions/Swap/hooks/useSwapOrderAmounts.ts

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { normalize, normalizeBN, valueToBigNumber } from '@aave/math-utils';
22
import { OrderKind } from '@cowprotocol/cow-sdk';
33
import { Dispatch, useEffect } from 'react';
44

5-
import { COW_PARTNER_FEE } from '../constants/cow.constants';
5+
import { COW_PARTNER_FEE, FLASH_LOAN_FEE_BPS } from '../constants/cow.constants';
6+
import { PARASWAP_FLASH_LOAN_FEE_BPS } from '../constants/paraswap.constants';
67
import {
78
isCowProtocolRates,
89
OrderType,
@@ -21,6 +22,14 @@ const marketOrderKindPerSwapType: Record<SwapType, OrderKind> = {
2122
[SwapType.WithdrawAndSwap]: OrderKind.SELL,
2223
};
2324

25+
const isPositionSwap = (swapType: SwapType) => {
26+
return swapType != SwapType.Swap;
27+
};
28+
29+
const getFlashLoanFeeBps = (provider: SwapProvider) => {
30+
return provider === SwapProvider.COW_PROTOCOL ? FLASH_LOAN_FEE_BPS : PARASWAP_FLASH_LOAN_FEE_BPS;
31+
};
32+
2433
/**
2534
* Computes normalized sell/buy amounts used to build transactions.
2635
*
@@ -78,6 +87,15 @@ export const useSwapOrderAmounts = ({
7887
: valueToBigNumber(state.inputAmount).multipliedBy(partnetFeeBps).dividedBy(10000);
7988
// const partnerFeeToken = state.side === 'sell' ? state.destinationToken : state.sourceToken;
8089

90+
const flashLoanFeeBps = isPositionSwap(state.swapType) ? getFlashLoanFeeBps(state.provider) : 0;
91+
const flashLoanFeeAmount =
92+
state.processedSide == 'sell'
93+
? valueToBigNumber(state.outputAmount).multipliedBy(flashLoanFeeBps).dividedBy(10000)
94+
: valueToBigNumber(state.inputAmount).multipliedBy(flashLoanFeeBps).dividedBy(10000);
95+
96+
console.info('partnerFeeAmount', partnerFeeAmount.toString());
97+
console.info('flashLoanFeeAmount', flashLoanFeeAmount.toString());
98+
8199
if (!isInvertedSwap) {
82100
// on classic swaps, minimum is calculated from the output token and sent amount is from the input token
83101
sellAmountToken = state.sourceToken;
@@ -130,8 +148,11 @@ export const useSwapOrderAmounts = ({
130148
const outputAmountAfterPartnerFees = valueToBigNumber(outputAmountAfterNetworkFees).minus(
131149
partnerFeeAmount
132150
);
133-
const outputAmountAfterSlippage = valueToBigNumber(
151+
const outputAmountAfterFlashLoanFees = valueToBigNumber(
134152
outputAmountAfterPartnerFees
153+
).minus(flashLoanFeeAmount);
154+
const outputAmountAfterSlippage = valueToBigNumber(
155+
outputAmountAfterFlashLoanFees
135156
).multipliedBy(1 - Number(state.slippage) / 100);
136157
buyAmountFormatted = outputAmountAfterSlippage.toFixed();
137158
} else {
@@ -144,9 +165,12 @@ export const useSwapOrderAmounts = ({
144165
const sellAmountAfterPartnerFees = valueToBigNumber(sellAmountAfterNetworkFees).plus(
145166
partnerFeeAmount
146167
);
147-
const sellAmountAfterSlippage = valueToBigNumber(sellAmountAfterPartnerFees).multipliedBy(
148-
1 + Number(state.slippage) / 100
168+
const sellAmountAfterFlashLoanFees = valueToBigNumber(sellAmountAfterPartnerFees).plus(
169+
flashLoanFeeAmount
149170
);
171+
const sellAmountAfterSlippage = valueToBigNumber(
172+
sellAmountAfterFlashLoanFees
173+
).multipliedBy(1 + Number(state.slippage) / 100);
150174
sellAmountFormatted = sellAmountAfterSlippage.toFixed();
151175
}
152176
} else if (state.orderType === OrderType.LIMIT) {
@@ -157,12 +181,14 @@ export const useSwapOrderAmounts = ({
157181
// Do not apply network costs on limit orders
158182
buyAmountFormatted = valueToBigNumber(state.outputAmount)
159183
.minus(partnerFeeAmount)
184+
.minus(flashLoanFeeAmount)
160185
.toFixed();
161186
} else {
162187
// on a buy limit order, we receive exactly the output amount and send the input amount after partner fees (no slippage applied)
163188
// Do not apply network costs on limit orders
164189
sellAmountFormatted = valueToBigNumber(state.inputAmount)
165190
.plus(partnerFeeAmount)
191+
.plus(flashLoanFeeAmount)
166192
.toFixed();
167193

168194
buyAmountFormatted = state.outputAmount;
@@ -226,7 +252,10 @@ export const useSwapOrderAmounts = ({
226252
const inputAmountAfterPartnerFees = valueToBigNumber(inputAmountAfterNetworkFees)
227253
.minus(partnerFeeAmount)
228254
.toFixed();
229-
const inputAmountAfterSlippage = valueToBigNumber(inputAmountAfterPartnerFees)
255+
const inputAmountAfterFlashLoanFees = valueToBigNumber(inputAmountAfterPartnerFees).minus(
256+
flashLoanFeeAmount
257+
);
258+
const inputAmountAfterSlippage = valueToBigNumber(inputAmountAfterFlashLoanFees)
230259
.multipliedBy(1 + Number(state.slippage) / 100)
231260
.toFixed();
232261
buyAmountFormatted = inputAmountAfterSlippage;
@@ -239,9 +268,12 @@ export const useSwapOrderAmounts = ({
239268
const sellAmountAfterPartnerFees = valueToBigNumber(sellAmountAfterNetworkFees).plus(
240269
partnerFeeAmount
241270
);
242-
const sellAmountAfterSlippage = valueToBigNumber(sellAmountAfterPartnerFees).multipliedBy(
243-
1 + Number(state.slippage) / 100
271+
const sellAmountAfterFlashLoanFees = valueToBigNumber(sellAmountAfterPartnerFees).plus(
272+
flashLoanFeeAmount
244273
);
274+
const sellAmountAfterSlippage = valueToBigNumber(
275+
sellAmountAfterFlashLoanFees
276+
).multipliedBy(1 + Number(state.slippage) / 100);
245277
sellAmountFormatted = sellAmountAfterSlippage.toFixed();
246278
}
247279
} else {
@@ -252,6 +284,7 @@ export const useSwapOrderAmounts = ({
252284
// Do not apply network costs on limit orders
253285
sellAmountFormatted = valueToBigNumber(state.outputAmount)
254286
.plus(partnerFeeAmount)
287+
.plus(flashLoanFeeAmount)
255288
.toFixed();
256289
} else {
257290
// on an inverted sell limit order, we sell the output amount and buy the input amount after partner fees (no slippage applied)
@@ -260,6 +293,7 @@ export const useSwapOrderAmounts = ({
260293
// Do not apply network costs on limit orders
261294
buyAmountFormatted = valueToBigNumber(state.inputAmount)
262295
.minus(partnerFeeAmount)
296+
.minus(flashLoanFeeAmount)
263297
.toFixed();
264298
}
265299
}
@@ -312,6 +346,7 @@ export const useSwapOrderAmounts = ({
312346
networkFeeAmountInSellFormatted,
313347
networkFeeAmountInBuyFormatted,
314348
partnerFeeAmountFormatted: partnerFeeAmount.toFixed(),
349+
flashLoanFeeAmountFormatted: flashLoanFeeAmount.toFixed(),
315350
partnerFeeBps: partnetFeeBps,
316351
});
317352
}, [

src/components/transactions/Swap/types/state.types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ export type TokensSwapState = {
9494
networkFeeAmountInBuyFormatted?: string;
9595
/** Partner fee amount applied to this order, normalized to the fee token units (depends on side). */
9696
partnerFeeAmountFormatted?: string;
97+
/** Flash loan fee amount applied to this order, normalized to the fee token units (depends on side). */
98+
flashLoanFeeAmountFormatted?: string;
9799
/** Partner fee in basis points used to compute partnerFeeAmountFormatted. */
98100
partnerFeeBps?: number;
99101

@@ -279,8 +281,8 @@ export const swapDefaultState: SwapState = {
279281
networkFeeAmountInSellFormatted: '0',
280282
networkFeeAmountInBuyFormatted: '0',
281283
partnerFeeAmountFormatted: '0',
284+
flashLoanFeeAmountFormatted: '0',
282285
partnerFeeBps: 0,
283-
284286
limitsOrderButtonBlocked: false,
285287
showSlippageWarning: false,
286288
showChangeNetworkWarning: false,

0 commit comments

Comments
 (0)