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,36 @@ 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+ ) ;
106+ console . log ( 'validTo' , validTo , state . expiry ) ;
44107
45108 // Pre-compute instance address
46109 useEffect ( ( ) => {
47110 if ( state . chainId !== 100 ) return ; // TODO: remove this once we have a supported chainId
48- calculateInstanceAddress ( state , user , validTo )
111+ calculateInstanceAddress ( {
112+ user,
113+ validTo,
114+ type : AaveFlashLoanType . CollateralSwap ,
115+ orderCore,
116+ } )
49117 . catch ( ( error ) => {
50118 console . error ( 'calculateInstanceAddress error' , error ) ;
51119 setTxError ( getErrorTextFromError ( error , TxAction . MAIN_ACTION , true ) ) ;
@@ -58,24 +126,23 @@ export const CollateralSwapActionsViaCowAdapters = ({
58126 . then ( ( address ) => {
59127 if ( address ) setPrecalculatedInstanceAddress ( address ) ;
60128 } ) ;
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- ] ) ;
129+ } , [ user , validTo , orderCore , state . chainId ] ) ;
72130
73131 // Approval is aToken ERC20 Approval
132+ const amountToApprove = useMemo (
133+ ( ) =>
134+ calculateSignedAmount (
135+ normalizeBN ( orderCore . sellAmount . toString ( ) , orderCore . sellToken . decimals ) . toString ( ) ,
136+ orderCore . sellToken . decimals
137+ ) ,
138+ [ orderCore . sellAmount , orderCore . sellToken . decimals ]
139+ ) ;
140+
74141 const { requiresApproval, approval, tryPermit, signatureParams } = useSwapTokenApproval ( {
75142 chainId : state . chainId ,
76143 token : state . sourceToken . addressToSwap ,
77144 symbol : state . sourceToken . symbol ,
78- amount : state . inputAmount ,
145+ amount : normalize ( amountToApprove . toString ( ) , orderCore . sellToken . decimals ) ,
79146 decimals : state . sourceToken . decimals ,
80147 spender : precalculatedInstanceAddress ,
81148 setState,
@@ -101,23 +168,13 @@ export const CollateralSwapActionsViaCowAdapters = ({
101168 } ) ;
102169
103170 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
171+ const tradingSdk = await getCowTradingSdkByChainIdAndAppCode (
172+ orderCore . chainId ,
173+ APP_CODE_PER_SWAP_TYPE [ state . swapType ] ,
174+ 'staging'
119175 ) ;
120- const flashLoanSdk = new AaveCollateralSwapSdk ( ) ;
176+ const flashLoanSdk = await getCowFlashLoanSdk ( orderCore . chainId ) ;
177+
121178 const collateralPermit = signatureParams
122179 ? {
123180 amount : signatureParams ?. amount ,
@@ -128,42 +185,41 @@ export const CollateralSwapActionsViaCowAdapters = ({
128185 }
129186 : undefined ;
130187
131- const partnerFee = COW_PARTNER_FEE ( state . sourceToken . symbol , state . destinationToken . symbol ) ;
132-
133188 const { flashLoanFeeAmount, sellAmountToSign } = flashLoanSdk . calculateFlashLoanAmounts ( {
134189 flashLoanFeePercent : FLASH_LOAN_FEE_BPS / 100 ,
135- sellAmount : BigInt ( sellAmount ) ,
190+ sellAmount : BigInt ( orderCore . sellAmount . toString ( ) ) ,
136191 } ) ;
137192
138193 const limitOrder : LimitTradeParameters = {
139- sellToken : state . sourceToken . underlyingAddress ,
140- sellTokenDecimals : state . sourceToken . decimals ,
141- buyToken : state . destinationToken . underlyingAddress ,
142- buyTokenDecimals : state . destinationToken . decimals ,
194+ sellToken : orderCore . sellToken . underlyingAddress ,
195+ sellTokenDecimals : orderCore . sellToken . decimals ,
196+ buyToken : orderCore . buyToken . underlyingAddress ,
197+ buyTokenDecimals : orderCore . buyToken . decimals ,
143198 sellAmount : sellAmountToSign . toString ( ) ,
144- buyAmount : buyAmount . toString ( ) ,
145- kind : state . side === 'buy' ? OrderKind . BUY : OrderKind . SELL ,
199+ buyAmount : orderCore . buyAmount . toString ( ) ,
200+ kind : orderCore . side === 'buy' ? OrderKind . BUY : OrderKind . SELL ,
146201 validTo,
147- slippageBps,
148- partnerFee,
202+ slippageBps : orderCore . slippageBps ,
203+ partnerFee : orderCore . partnerFee ,
149204 } ;
150205
151206 const orderToSign = getOrderToSign (
152- { chainId : state . chainId , from : user , networkCostsAmount : '0' , isEthFlow : false } ,
207+ { chainId : orderCore . chainId , from : user , networkCostsAmount : '0' , isEthFlow : false } ,
153208 limitOrder ,
154209 HASH_ZERO
155210 ) ;
156211
157212 const orderPostParams = await flashLoanSdk . getOrderPostingSettings (
213+ AaveFlashLoanType . CollateralSwap ,
158214 {
159- chainId : state . chainId ,
215+ chainId : orderCore . chainId ,
160216 validTo,
161217 owner : user as `0x${string } `,
162- flashLoanFeeAmount,
218+ flashLoanFeeAmount : flashLoanFeeAmount + BigInt ( 1 ) , // Fix for flashloanfee rounding error
163219 } ,
164220 {
165- sellAmount : BigInt ( sellAmount ) ,
166- buyAmount : BigInt ( buyAmount ) ,
221+ sellAmount : BigInt ( orderCore . sellAmount . toString ( ) ) ,
222+ buyAmount : BigInt ( orderCore . buyAmount . toString ( ) ) ,
167223 orderToSign,
168224 collateralPermit,
169225 }
0 commit comments