@cowprotocol/sdk-flash-loans 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,448 @@
1
+ <p align="center">
2
+ <img width="400" src="https://github.com/cowprotocol/cow-sdk/raw/main/docs/images/CoW.png" />
3
+ </p>
4
+
5
+ # Flash Loans SDK
6
+
7
+ Execute flash loan-based collateral swaps using Aave Protocol V3 integrated with CoW Protocol for optimal trading execution.
8
+
9
+ This SDK facilitates complex flash loan operations where you can:
10
+ - Borrow assets via Aave flash loans
11
+ - Swap collateral using CoW Protocol's intent-based trading
12
+ - Repay flash loans automatically with optimized execution
13
+ - Use CoW Protocol hooks to manage the entire flow
14
+
15
+ ## How It Works
16
+
17
+ 1. 💸 Borrow tokens via Aave flash loan
18
+ 2. 🔄 Execute a CoW Protocol swap to desired collateral
19
+ 3. ⚙️ Use CoW hooks to deploy adapter contracts and manage the swap
20
+ 4. ✅ Automatically repay the flash loan with fees
21
+
22
+ The order is signed using EIP-1271 with a deterministically generated smart contract address as the signer.
23
+
24
+ ## Why Use Flash Loans?
25
+
26
+ - **Capital Efficiency** - No upfront capital required to swap collateral
27
+ - **Atomic Execution** - The entire operation succeeds or reverts atomically
28
+ - **Gas Optimization** - Single transaction for complex multi-step operations
29
+ - **Aave Integration** - Leverage Aave V3's flash loan infrastructure
30
+ - **CoW Protocol Benefits** - MEV protection and optimal execution via batch auctions
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ npm install @cowprotocol/sdk-flash-loans
36
+ # or
37
+ pnpm add @cowprotocol/sdk-flash-loans
38
+ # or
39
+ yarn add @cowprotocol/sdk-flash-loans
40
+ ```
41
+
42
+ You'll also need the trading SDK:
43
+ ```bash
44
+ npm install @cowprotocol/sdk-trading
45
+ ```
46
+
47
+ ## Setup
48
+
49
+ You need:
50
+ - `chainId` - Supported chain ID (see [SDK config](https://docs.cow.fi/cow-protocol/reference/sdks/core-utilities/sdk-config))
51
+ - `appCode` - Unique app identifier for tracking orders
52
+ - `signer` - Private key, ethers signer, or `Eip1193` provider
53
+ - `TradingSdk` instance - For getting quotes and posting orders
54
+
55
+ ## Usage
56
+
57
+ ### Basic Collateral Swap
58
+
59
+ ```typescript
60
+ import { AaveCollateralSwapSdk } from '@cowprotocol/sdk-flash-loans'
61
+ import { TradingSdk } from '@cowprotocol/sdk-trading'
62
+ import { SupportedChainId } from '@cowprotocol/sdk-config'
63
+ import { OrderKind } from '@cowprotocol/sdk-order-book'
64
+ import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
65
+ import { createPublicClient, http, privateKeyToAccount } from 'viem'
66
+ import { gnosis } from 'viem/chains'
67
+
68
+ // Set up adapter
69
+ const adapter = new ViemAdapter({
70
+ provider: createPublicClient({
71
+ chain: gnosis,
72
+ transport: http('YOUR_RPC_URL')
73
+ }),
74
+ signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
75
+ })
76
+
77
+ // Initialize the Trading SDK
78
+ const tradingSdk = new TradingSdk(
79
+ {
80
+ chainId: SupportedChainId.GNOSIS_CHAIN,
81
+ appCode: 'aave-v3-flashloan',
82
+ },
83
+ {},
84
+ adapter
85
+ )
86
+
87
+ // Initialize the Flash Loan SDK
88
+ const flashLoanSdk = new AaveCollateralSwapSdk()
89
+
90
+ // Execute collateral swap
91
+ const result = await flashLoanSdk.collateralSwap(
92
+ {
93
+ chainId: SupportedChainId.GNOSIS_CHAIN,
94
+ tradeParameters: {
95
+ sellToken: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', // WXDAI
96
+ sellTokenDecimals: 18,
97
+ buyToken: '0x2a22f9c3b484c3629090FeED35F17Ff8F88f76F0', // USDC.e
98
+ buyTokenDecimals: 6,
99
+ amount: '20000000000000000000', // 20 WXDAI
100
+ kind: OrderKind.SELL,
101
+ validFor: 600, // 10 minutes
102
+ slippageBps: 50, // 0.5% slippage
103
+ },
104
+ collateralToken: '0xd0Dd6cEF72143E22cCED4867eb0d5F2328715533', // aGnoWXDAI (Aave interest-bearing WXDAI)
105
+ flashLoanFeePercent: 0.05, // 0.05% flash loan fee
106
+ },
107
+ tradingSdk
108
+ )
109
+
110
+ console.log('Flash loan order created:', result.orderId)
111
+ ```
112
+
113
+ ### Advanced Usage with Quote Review
114
+
115
+ For maximum control over the process, including manual approval management:
116
+
117
+ ```typescript
118
+ import { AaveCollateralSwapSdk } from '@cowprotocol/sdk-flash-loans'
119
+ import { TradingSdk } from '@cowprotocol/sdk-trading'
120
+ import { SupportedChainId } from '@cowprotocol/sdk-config'
121
+ import { OrderKind } from '@cowprotocol/sdk-order-book'
122
+
123
+ const flashLoanSdk = new AaveCollateralSwapSdk()
124
+
125
+ const collateralToken = '0xd0Dd6cEF72143E22cCED4867eb0d5F2328715533' // aGnoWXDAI
126
+
127
+ // Step 1: Prepare quote parameters
128
+ const params = {
129
+ chainId: SupportedChainId.GNOSIS_CHAIN,
130
+ tradeParameters: {
131
+ sellToken: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d',
132
+ sellTokenDecimals: 18,
133
+ buyToken: '0x2a22f9c3b484c3629090FeED35F17Ff8F88f76F0',
134
+ buyTokenDecimals: 6,
135
+ amount: '20000000000000000000',
136
+ kind: OrderKind.SELL,
137
+ },
138
+ collateralToken,
139
+ flashLoanFeePercent: 0.05,
140
+ }
141
+
142
+ const quoteParams = await flashLoanSdk.getSwapQuoteParams(params)
143
+
144
+ // Step 2: Get quote
145
+ const quoteAndPost = await tradingSdk.getQuote(quoteParams)
146
+ const { quoteResults } = quoteAndPost
147
+
148
+ // Step 3: Review the quote
149
+ const buyAmount = quoteResults.amountsAndCosts.afterSlippage.buyAmount
150
+ console.log(`You will receive at least: ${buyAmount} tokens`)
151
+
152
+ // Step 4: Generate order settings and get instance address
153
+ const { swapSettings, instanceAddress } = await flashLoanSdk.getOrderPostingSettings(
154
+ params,
155
+ quoteParams,
156
+ quoteResults
157
+ )
158
+
159
+ // Step 5: Check collateral allowance
160
+ const sellAmount = BigInt(params.tradeParameters.amount)
161
+ const allowance = await flashLoanSdk.getCollateralAllowance({
162
+ trader: quoteParams.owner,
163
+ collateralToken,
164
+ amount: sellAmount,
165
+ instanceAddress,
166
+ })
167
+
168
+ console.log(`Current allowance: ${allowance.toString()}`)
169
+ console.log(`Required amount: ${sellAmount.toString()}`)
170
+
171
+ // Step 6: Approve collateral if needed
172
+ if (allowance < sellAmount) {
173
+ console.log('Insufficient allowance, approving...')
174
+ const txResponse = await flashLoanSdk.approveCollateral({
175
+ trader: quoteParams.owner,
176
+ collateralToken,
177
+ amount: sellAmount,
178
+ instanceAddress,
179
+ })
180
+ console.log('Approval transaction:', txResponse.hash)
181
+ // Optionally wait for confirmation here
182
+ } else {
183
+ console.log('Sufficient allowance already exists')
184
+ }
185
+
186
+ // Step 7: Post the order
187
+ const result = await quoteAndPost.postSwapOrderFromQuote(swapSettings)
188
+ console.log('Order posted:', result.orderId)
189
+ ```
190
+
191
+ ## Flash Loan Fee
192
+
193
+ Aave flash loans typically charge a fee (currently 0.05% on most assets). This fee is:
194
+ - Deducted from the sell amount before getting the quote
195
+ - Ensures the swap proceeds cover both the desired output and flash loan repayment
196
+ - Configurable via `flashLoanFeePercent` parameter
197
+
198
+ **Example:**
199
+ ```typescript
200
+ // With 0.05% flash loan fee on 20 WXDAI:
201
+ // - Flash loan: 20 WXDAI
202
+ // - Fee: 0.01 WXDAI (0.05% of 20)
203
+ // - Actual swap amount: 19.99 WXDAI
204
+ {
205
+ amount: '20000000000000000000',
206
+ flashLoanFeePercent: 0.05, // 0.05%
207
+ }
208
+ ```
209
+
210
+ ## Collateral Token Parameter
211
+
212
+ The `collateralToken` parameter specifies which Aave interest-bearing token (aToken) will be used as collateral for the flash loan operation.
213
+
214
+ ### What are aTokens?
215
+
216
+ When you deposit assets into Aave, you receive aTokens (e.g., aWXDAI, aUSDC) that:
217
+ - Represent your deposited collateral
218
+ - Accrue interest automatically
219
+ - Can be used for flash loan collateral swaps
220
+ - Need approval for the flash loan adapter to spend
221
+
222
+ ### Common aTokens on Gnosis Chain
223
+
224
+ ```typescript
225
+ const AAVE_TOKENS = {
226
+ aGnoWXDAI: '0xd0Dd6cEF72143E22cCED4867eb0d5F2328715533', // Aave WXDAI
227
+ aGnoUSDC: '0xc6B7AcA6DE8a6044E0e32d0c841a89244A10D284', // Aave USDC
228
+ // Add more as needed
229
+ }
230
+ ```
231
+
232
+ ### Usage Example
233
+
234
+ ```typescript
235
+ const result = await flashLoanSdk.collateralSwap(
236
+ {
237
+ chainId: SupportedChainId.GNOSIS_CHAIN,
238
+ tradeParameters: {
239
+ sellToken: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', // WXDAI (what we're swapping)
240
+ buyToken: '0x2a22f9c3b484c3629090FeED35F17Ff8F88f76F0', // USDC.e (what we want)
241
+ amount: '20000000000000000000',
242
+ kind: OrderKind.SELL,
243
+ },
244
+ collateralToken: '0xd0Dd6cEF72143E22cCED4867eb0d5F2328715533', // aGnoWXDAI (our Aave collateral)
245
+ flashLoanFeePercent: 0.05,
246
+ },
247
+ tradingSdk
248
+ )
249
+ ```
250
+
251
+ **Important Notes:**
252
+ - The `collateralToken` must be an Aave aToken address
253
+ - You must have sufficient aToken balance for collateral
254
+ - The SDK automatically handles approval of this token
255
+ - This is different from `sellToken` (which is the underlying asset being swapped)
256
+
257
+ ## Collateral Token Approval
258
+
259
+ Before executing a collateral swap, the flash loan adapter needs approval to spend your collateral tokens. The SDK handles this automatically but also provides methods for manual control.
260
+
261
+ ### Automatic Approval
262
+
263
+ By default, `collateralSwap()` automatically checks and approves collateral if needed:
264
+
265
+ ```typescript
266
+ // Automatic approval happens here
267
+ const result = await flashLoanSdk.collateralSwap(
268
+ {
269
+ chainId: SupportedChainId.GNOSIS_CHAIN,
270
+ tradeParameters: { /* ... */ },
271
+ collateralToken: '0xd0Dd6cEF72143E22cCED4867eb0d5F2328715533', // aGnoWXDAI
272
+ },
273
+ tradingSdk
274
+ )
275
+ ```
276
+
277
+ ### Manual Approval with getCollateralAllowance and approveCollateral
278
+
279
+ For more control over the approval process:
280
+
281
+ ```typescript
282
+ // Step 1: Get the adapter instance address
283
+ const quoteParams = await flashLoanSdk.getSwapQuoteParams(params)
284
+ const quoteAndPost = await tradingSdk.getQuote(quoteParams)
285
+ const { swapSettings, instanceAddress } = await flashLoanSdk.getOrderPostingSettings(
286
+ params,
287
+ quoteParams,
288
+ quoteAndPost.quoteResults
289
+ )
290
+ const sellAmount = BigInt(params.tradeParameters.amount)
291
+
292
+ // Step 2: Check current allowance
293
+ const allowance = await flashLoanSdk.getCollateralAllowance({
294
+ trader: quoteParams.owner,
295
+ collateralToken: '0xd0Dd6cEF72143E22cCED4867eb0d5F2328715533',
296
+ amount: sellAmount,
297
+ instanceAddress,
298
+ })
299
+
300
+ console.log('Current allowance:', allowance.toString())
301
+
302
+ // Step 3: Approve if needed
303
+ if (allowance < sellAmount) {
304
+ const txResponse = await flashLoanSdk.approveCollateral({
305
+ trader: quoteParams.owner,
306
+ collateralToken: '0xd0Dd6cEF72143E22cCED4867eb0d5F2328715533',
307
+ amount: sellAmount,
308
+ instanceAddress,
309
+ })
310
+ console.log('Approval transaction:', txResponse.hash)
311
+ // Wait for confirmation...
312
+ }
313
+
314
+ // Step 4: Execute swap with approval prevention
315
+ const result = await flashLoanSdk.collateralSwap(
316
+ {
317
+ chainId: SupportedChainId.GNOSIS_CHAIN,
318
+ tradeParameters: { /* ... */ },
319
+ collateralToken: '0xd0Dd6cEF72143E22cCED4867eb0d5F2328715533',
320
+ settings: {
321
+ preventApproval: true, // Skip automatic approval
322
+ },
323
+ },
324
+ tradingSdk
325
+ )
326
+ ```
327
+
328
+ ### Gasless Approval with EIP-2612 Permit
329
+
330
+ For tokens that support EIP-2612, you can use permit for gasless approval:
331
+
332
+ ```typescript
333
+ // Generate permit signature (implementation varies by wallet)
334
+ const collateralPermit = {
335
+ amount: 0,
336
+ deadline: Math.floor(Date.now() / 1000) + 3600, // 1 hour
337
+ v: 27,
338
+ r: '0x...',
339
+ s: '0x...',
340
+ }
341
+
342
+ const result = await flashLoanSdk.collateralSwap(
343
+ {
344
+ chainId: SupportedChainId.GNOSIS_CHAIN,
345
+ tradeParameters: { /* ... */ },
346
+ collateralToken: '0xd0Dd6cEF72143E22cCED4867eb0d5F2328715533',
347
+ settings: {
348
+ collateralPermit, // Use permit instead of approve
349
+ },
350
+ },
351
+ tradingSdk
352
+ )
353
+ ```
354
+
355
+ ## How Hooks Work
356
+
357
+ The SDK uses CoW Protocol hooks to orchestrate the flash loan:
358
+
359
+ ### Pre-Hook
360
+ - Deploys the Aave adapter contract deterministically
361
+ - Transfers the flash loan to the adapter
362
+ - Sets up the swap parameters
363
+
364
+ ### Post-Hook
365
+ - Executes the collateral swap via the adapter
366
+ - Repays the Aave flash loan with fees
367
+ - Transfers remaining tokens to the owner
368
+
369
+ All hooks are automatically configured and gas estimated by the SDK.
370
+
371
+ ## Error Handling
372
+
373
+ Common errors and solutions:
374
+
375
+ **Insufficient flash loan amount**
376
+ ```typescript
377
+ // Error: Flash loan amount doesn't cover fee + swap
378
+ // Solution: Increase amount or adjust flash loan fee
379
+ {
380
+ amount: '20000000000000000000', // Increase this
381
+ flashLoanFeePercent: 0.05,
382
+ }
383
+ ```
384
+
385
+ **Slippage too tight**
386
+ ```typescript
387
+ // Error: Slippage tolerance too low for current market conditions
388
+ // Solution: Increase slippageBps
389
+ {
390
+ slippageBps: 100, // Increase from 50 to 100 (1%)
391
+ }
392
+ ```
393
+
394
+ **Order expired**
395
+ ```typescript
396
+ // Error: Order validity period too short
397
+ // Solution: Increase validFor
398
+ {
399
+ validFor: 1200, // 20 minutes instead of 10
400
+ }
401
+ ```
402
+
403
+ ## Advanced Topics
404
+
405
+ ### EIP-1271 Signatures
406
+
407
+ Flash loan orders use EIP-1271 signature verification with a deterministically generated smart contract address. This enables:
408
+ - Gasless order creation
409
+ - Deterministic contract deployment
410
+ - Secure flash loan execution
411
+
412
+ ### Gas Optimization
413
+
414
+ The SDK automatically:
415
+ - Estimates gas for hook execution
416
+ - Uses fallback gas limits if estimation fails
417
+ - Optimizes hook call data encoding
418
+
419
+ ### Adapter Contracts
420
+
421
+ Adapter contracts are:
422
+ - Deployed deterministically using CREATE2
423
+ - Reusable across multiple flash loan operations
424
+ - Managed automatically by the SDK
425
+
426
+ ## Limitations
427
+
428
+ - Only supports Aave V3 flash loans
429
+ - Requires sufficient liquidity in Aave pools
430
+ - Flash loan fees apply (typically 0.05%)
431
+ - Subject to CoW Protocol order limits
432
+ - Network-specific contract deployments required
433
+
434
+ ## Security Considerations
435
+
436
+ - Always review quotes before execution
437
+ - Set appropriate slippage tolerances
438
+ - Verify token addresses and decimals
439
+ - Test with small amounts first
440
+ - Monitor transaction execution
441
+ - Be aware of flash loan fees and costs
442
+
443
+ ## Resources
444
+
445
+ - [Aave Flash Loans Documentation](https://docs.aave.com/developers/guides/flash-loans)
446
+ - [CoW Protocol Documentation](https://docs.cow.fi/)
447
+ - [CoW Protocol Hooks](https://docs.cow.fi/cow-protocol/reference/core/intents/hooks)
448
+ - [EIP-1271 Specification](https://eips.ethereum.org/EIPS/eip-1271)