1- import { normalize } from '@aave/math-utils' ;
2- import { getOrderToSign , LimitTradeParameters , OrderKind , TradingSdk } from '@cowprotocol/cow-sdk' ;
3- import { AaveCollateralSwapSdk , HASH_ZERO } from '@cowprotocol/sdk-flash-loans' ;
1+ import { normalize , normalizeBN } from '@aave/math-utils' ;
2+ import { getOrderToSign , LimitTradeParameters , OrderKind } from '@cowprotocol/cow-sdk' ;
3+ import { AaveFlashLoanType , HASH_ZERO } from '@cowprotocol/sdk-flash-loans' ;
44import { Trans } from '@lingui/macro' ;
5- import { Dispatch , useEffect , useState } from 'react' ;
5+ import { Dispatch , useEffect , useMemo , useState } from 'react' ;
66import { TxActionsWrapper } from 'src/components/transactions/TxActionsWrapper' ;
7+ import { calculateSignedAmount } from 'src/hooks/paraswap/common' ;
78import { useModalContext } from 'src/hooks/useModal' ;
89import { useRootStore } from 'src/store/root' ;
910import { getErrorTextFromError , TxAction } from 'src/ui-config/errorMapping' ;
1011import { useShallow } from 'zustand/react/shallow' ;
1112
1213import { TrackAnalyticsHandlers } from '../../analytics/useTrackAnalytics' ;
13- import { COW_PARTNER_FEE , FLASH_LOAN_FEE_BPS } from '../../constants/cow.constants' ;
14+ import { FLASH_LOAN_FEE_BPS } from '../../constants/cow.constants' ;
1415import { APP_CODE_PER_SWAP_TYPE } from '../../constants/shared.constants' ;
15- import { getCowAdapter } from '../../helpers/cow' ;
16- import { calculateInstanceAddress } from '../../helpers/cow/adapters.helpers' ;
16+ import { getCowFlashLoanSdk , getCowTradingSdkByChainIdAndAppCode } from '../../helpers/cow' ;
17+ import { calculateInstanceAddress , OrderCore } from '../../helpers/cow/adapters.helpers' ;
1718import { useSwapGasEstimation } from '../../hooks/useSwapGasEstimation' ;
18- import { OrderType , SwapParams , SwapState } from '../../types' ;
19+ import { ExpiryToSecondsMap , OrderType , SwapParams , SwapState } from '../../types' ;
1920import { useSwapTokenApproval } from '../approval/useSwapTokenApproval' ;
2021
22+ export const getCollateralSwapOrderCore = ( state : SwapState ) : OrderCore => {
23+ // In limit orders, slippage is zero.
24+ const slippageInPercentage =
25+ state . orderType === OrderType . LIMIT ? 0 : Number ( state . slippage ) / 100 ;
26+
27+ const sellToken = state . sourceToken ;
28+ const buyToken = state . destinationToken ;
29+ const side = state . side ;
30+
31+ // If side is sell, we allow less buy amount to ensure sell amount
32+ // If side is buy, we allow more sell amount to ensure buy amount
33+ const sellAmount =
34+ side === 'sell'
35+ ? normalizeBN ( state . inputAmount , - sellToken . decimals )
36+ : normalizeBN ( state . inputAmount , - sellToken . decimals )
37+ . multipliedBy ( 1 + slippageInPercentage )
38+ . decimalPlaces ( 0 ) ;
39+ const buyAmount =
40+ side === 'sell'
41+ ? normalizeBN ( state . outputAmount , - buyToken . decimals )
42+ . dividedBy ( 1 + slippageInPercentage )
43+ . decimalPlaces ( 0 )
44+ : normalizeBN ( state . outputAmount , - buyToken . decimals ) . decimalPlaces ( 0 ) ;
45+
46+ // TODO: REQUIRES FIX IN COW SDK
47+ // slippageBps = slippageInPercentage * 10000
48+ // const partnerFee = COW_PARTNER_FEE(state.sourceToken.symbol, state.destinationToken.symbol);
49+
50+ const partnerFee = {
51+ volumeBps : 0 ,
52+ recipient : '0x0000000000000000000000000000000000000000' ,
53+ } ;
54+ const slippageBps = 0 ;
55+
56+ return {
57+ chainId : state . chainId ,
58+ sellAmount,
59+ buyAmount,
60+ sellToken,
61+ buyToken,
62+ side,
63+ slippageBps,
64+ partnerFee,
65+ } ;
66+ } ;
67+
2168export const CollateralSwapActionsViaCowAdapters = ( {
2269 params,
2370 state,
@@ -37,15 +84,35 @@ export const CollateralSwapActionsViaCowAdapters = ({
3784 const [ precalculatedInstanceAddress , setPrecalculatedInstanceAddress ] = useState <
3885 string | undefined
3986 > ( ) ;
40- const validTo = state . expiry || Math . floor ( Date . now ( ) / 1000 ) + 10 * 60 ; // 10 minutes
4187
42- const slippageBps =
43- state . orderType === OrderType . LIMIT ? 0 : Math . round ( Number ( state . slippage ) * 100 ) ; // percent to bps
88+ const validTo = useMemo (
89+ ( ) => Math . floor ( Date . now ( ) / 1000 ) + ExpiryToSecondsMap [ state . expiry ] ,
90+ [ state . expiry ]
91+ ) ;
92+
93+ const orderCore = useMemo (
94+ ( ) => getCollateralSwapOrderCore ( state ) ,
95+ [
96+ state . inputAmount ,
97+ state . outputAmount ,
98+ state . sourceToken ,
99+ state . destinationToken ,
100+ state . side ,
101+ state . slippage ,
102+ state . orderType ,
103+ state . chainId ,
104+ ]
105+ ) ;
44106
45107 // Pre-compute instance address
46108 useEffect ( ( ) => {
47109 if ( state . chainId !== 100 ) return ; // TODO: remove this once we have a supported chainId
48- calculateInstanceAddress ( state , user , validTo )
110+ calculateInstanceAddress ( {
111+ user,
112+ validTo,
113+ type : AaveFlashLoanType . CollateralSwap ,
114+ orderCore,
115+ } )
49116 . catch ( ( error ) => {
50117 console . error ( 'calculateInstanceAddress error' , error ) ;
51118 setTxError ( getErrorTextFromError ( error , TxAction . MAIN_ACTION , true ) ) ;
@@ -58,24 +125,23 @@ export const CollateralSwapActionsViaCowAdapters = ({
58125 . then ( ( address ) => {
59126 if ( address ) setPrecalculatedInstanceAddress ( address ) ;
60127 } ) ;
61- } , [
62- user ,
63- state . inputAmount ,
64- state . minimumReceived ,
65- state . destinationToken . underlyingAddress ,
66- state . sourceToken . symbol ,
67- state . destinationToken . symbol ,
68- state . slippage ,
69- state . autoSlippage ,
70- APP_CODE_PER_SWAP_TYPE [ state . swapType ] ,
71- ] ) ;
128+ } , [ user , validTo , orderCore , state . chainId ] ) ;
72129
73130 // Approval is aToken ERC20 Approval
131+ const amountToApprove = useMemo (
132+ ( ) =>
133+ calculateSignedAmount (
134+ normalizeBN ( orderCore . sellAmount . toString ( ) , orderCore . sellToken . decimals ) . toString ( ) ,
135+ orderCore . sellToken . decimals
136+ ) ,
137+ [ orderCore . sellAmount , orderCore . sellToken . decimals ]
138+ ) ;
139+
74140 const { requiresApproval, approval, tryPermit, signatureParams } = useSwapTokenApproval ( {
75141 chainId : state . chainId ,
76142 token : state . sourceToken . addressToSwap ,
77143 symbol : state . sourceToken . symbol ,
78- amount : state . inputAmount ,
144+ amount : normalize ( amountToApprove . toString ( ) , orderCore . sellToken . decimals ) ,
79145 decimals : state . sourceToken . decimals ,
80146 spender : precalculatedInstanceAddress ,
81147 setState,
@@ -101,23 +167,13 @@ export const CollateralSwapActionsViaCowAdapters = ({
101167 } ) ;
102168
103169 try {
104- if ( ! state . minimumReceived ) return ;
105-
106- const sellAmount = normalize ( state . inputAmount , - state . sourceToken . decimals ) ;
107- const buyAmount = normalize ( state . minimumReceived , - state . destinationToken . decimals ) ;
108-
109- const adapter = await getCowAdapter ( state . chainId ) ;
110- const tradingSdk = new TradingSdk (
111- {
112- chainId : state . chainId ,
113- appCode : APP_CODE_PER_SWAP_TYPE [ state . swapType ] ,
114- env : 'staging' ,
115- signer : adapter . signer ,
116- } ,
117- { } ,
118- adapter
170+ const tradingSdk = await getCowTradingSdkByChainIdAndAppCode (
171+ orderCore . chainId ,
172+ APP_CODE_PER_SWAP_TYPE [ state . swapType ] ,
173+ 'staging'
119174 ) ;
120- const flashLoanSdk = new AaveCollateralSwapSdk ( ) ;
175+ const flashLoanSdk = await getCowFlashLoanSdk ( orderCore . chainId ) ;
176+
121177 const collateralPermit = signatureParams
122178 ? {
123179 amount : signatureParams ?. amount ,
@@ -128,42 +184,41 @@ export const CollateralSwapActionsViaCowAdapters = ({
128184 }
129185 : undefined ;
130186
131- const partnerFee = COW_PARTNER_FEE ( state . sourceToken . symbol , state . destinationToken . symbol ) ;
132-
133187 const { flashLoanFeeAmount, sellAmountToSign } = flashLoanSdk . calculateFlashLoanAmounts ( {
134- flashLoanFeePercent : FLASH_LOAN_FEE_BPS / 100 ,
135- sellAmount : BigInt ( sellAmount ) ,
188+ flashLoanFeeBps : FLASH_LOAN_FEE_BPS ,
189+ sellAmount : BigInt ( orderCore . sellAmount . toString ( ) ) ,
136190 } ) ;
137191
138192 const limitOrder : LimitTradeParameters = {
139- sellToken : state . sourceToken . underlyingAddress ,
140- sellTokenDecimals : state . sourceToken . decimals ,
141- buyToken : state . destinationToken . underlyingAddress ,
142- buyTokenDecimals : state . destinationToken . decimals ,
193+ sellToken : orderCore . sellToken . underlyingAddress ,
194+ sellTokenDecimals : orderCore . sellToken . decimals ,
195+ buyToken : orderCore . buyToken . underlyingAddress ,
196+ buyTokenDecimals : orderCore . buyToken . decimals ,
143197 sellAmount : sellAmountToSign . toString ( ) ,
144- buyAmount : buyAmount . toString ( ) ,
145- kind : state . side === 'buy' ? OrderKind . BUY : OrderKind . SELL ,
198+ buyAmount : orderCore . buyAmount . toString ( ) ,
199+ kind : orderCore . side === 'buy' ? OrderKind . BUY : OrderKind . SELL ,
146200 validTo,
147- slippageBps,
148- partnerFee,
201+ slippageBps : orderCore . slippageBps ,
202+ partnerFee : orderCore . partnerFee ,
149203 } ;
150204
151205 const orderToSign = getOrderToSign (
152- { chainId : state . chainId , from : user , networkCostsAmount : '0' , isEthFlow : false } ,
206+ { chainId : orderCore . chainId , from : user , networkCostsAmount : '0' , isEthFlow : false } ,
153207 limitOrder ,
154208 HASH_ZERO
155209 ) ;
156210
157211 const orderPostParams = await flashLoanSdk . getOrderPostingSettings (
212+ AaveFlashLoanType . CollateralSwap ,
158213 {
159- chainId : state . chainId ,
214+ chainId : orderCore . chainId ,
160215 validTo,
161216 owner : user as `0x${string } `,
162217 flashLoanFeeAmount,
163218 } ,
164219 {
165- sellAmount : BigInt ( sellAmount ) ,
166- buyAmount : BigInt ( buyAmount ) ,
220+ sellAmount : BigInt ( orderCore . sellAmount . toString ( ) ) ,
221+ buyAmount : BigInt ( orderCore . buyAmount . toString ( ) ) ,
167222 orderToSign,
168223 collateralPermit,
169224 }
0 commit comments