@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 +448 -0
- package/dist/index.d.mts +269 -0
- package/dist/index.d.ts +269 -0
- package/dist/index.js +663 -0
- package/dist/index.mjs +629 -0
- package/package.json +52 -0
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)
|