Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.

Commit d7b53ea

Browse files
authored
feat: add flashloan hints to the app-data (#89)
feat: Add flashloan hints to the app-data. fixes #88.
1 parent 1955ff4 commit d7b53ea

8 files changed

Lines changed: 535 additions & 3 deletions

File tree

src/api/flashloan.spec.ts

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { APP_DATA_DOC_WITH_FLASHLOAN } from '../mocks'
2+
import { generateAppDataDoc } from './generateAppDataDoc'
3+
import { validateAppDataDoc } from './validateAppDataDoc'
4+
5+
describe('Flashloan metadata', () => {
6+
test('Creates appDataDoc with flashloan metadata', async () => {
7+
// given
8+
const flashloanMetadata = {
9+
lender: '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2',
10+
borrower: '0x2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b',
11+
token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
12+
amount: '1000000000',
13+
}
14+
15+
// when
16+
const appDataDoc = await generateAppDataDoc({
17+
metadata: {
18+
flashloan: flashloanMetadata,
19+
},
20+
})
21+
22+
// then
23+
expect(appDataDoc.metadata.flashloan).toEqual(flashloanMetadata)
24+
expect(appDataDoc.version).toBe('1.6.0')
25+
})
26+
27+
test('Validates valid flashloan metadata', async () => {
28+
// when
29+
const validation = await validateAppDataDoc(APP_DATA_DOC_WITH_FLASHLOAN)
30+
31+
// then
32+
expect(validation.success).toBeTruthy()
33+
expect(validation.errors).toBeUndefined()
34+
})
35+
36+
test('Fails validation with invalid lender address', async () => {
37+
// given
38+
const invalidDoc = {
39+
...APP_DATA_DOC_WITH_FLASHLOAN,
40+
metadata: {
41+
flashloan: {
42+
...APP_DATA_DOC_WITH_FLASHLOAN.metadata.flashloan,
43+
lender: '0xinvalid',
44+
},
45+
},
46+
}
47+
48+
// when
49+
const validation = await validateAppDataDoc(invalidDoc)
50+
51+
// then
52+
expect(validation.success).toBeFalsy()
53+
expect(validation.errors).toContain('data/metadata/flashloan/lender must match pattern "^0x[a-fA-F0-9]{40}$"')
54+
})
55+
56+
test('Fails validation with invalid amount', async () => {
57+
// given
58+
const invalidDoc = {
59+
...APP_DATA_DOC_WITH_FLASHLOAN,
60+
metadata: {
61+
flashloan: {
62+
...APP_DATA_DOC_WITH_FLASHLOAN.metadata.flashloan,
63+
amount: '-100',
64+
},
65+
},
66+
}
67+
68+
// when
69+
const validation = await validateAppDataDoc(invalidDoc)
70+
71+
// then
72+
expect(validation.success).toBeFalsy()
73+
expect(validation.errors).toContain('data/metadata/flashloan/amount must match pattern "^[1-9]\\d*$"')
74+
})
75+
76+
test('Fails validation with zero amount', async () => {
77+
// given
78+
const invalidDoc = {
79+
...APP_DATA_DOC_WITH_FLASHLOAN,
80+
metadata: {
81+
flashloan: {
82+
...APP_DATA_DOC_WITH_FLASHLOAN.metadata.flashloan,
83+
amount: '0',
84+
},
85+
},
86+
}
87+
88+
// when
89+
const validation = await validateAppDataDoc(invalidDoc)
90+
91+
// then
92+
expect(validation.success).toBeFalsy()
93+
expect(validation.errors).toContain('data/metadata/flashloan/amount must match pattern "^[1-9]\\d*$"')
94+
})
95+
96+
test('Fails validation with missing required fields', async () => {
97+
// given
98+
const invalidDoc = {
99+
version: '1.6.0',
100+
appCode: 'CoW Swap',
101+
metadata: {
102+
flashloan: {
103+
lender: '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2',
104+
// missing borrower, token, and amount
105+
},
106+
},
107+
}
108+
109+
// when
110+
const validation = await validateAppDataDoc(invalidDoc)
111+
112+
// then
113+
expect(validation.success).toBeFalsy()
114+
expect(validation.errors).toContain("data/metadata/flashloan must have required property 'borrower'")
115+
})
116+
117+
test('Creates appDataDoc with flashloan and other metadata', async () => {
118+
// given
119+
const metadata = {
120+
flashloan: {
121+
lender: '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2',
122+
borrower: '0x2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b',
123+
token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
124+
amount: '1000000000',
125+
},
126+
quote: {
127+
slippageBips: 50,
128+
version: '1.1.0',
129+
},
130+
}
131+
132+
// when
133+
const appDataDoc = await generateAppDataDoc({ metadata })
134+
135+
// then
136+
expect(appDataDoc.metadata).toEqual(metadata)
137+
expect(appDataDoc.version).toBe('1.6.0')
138+
})
139+
})

src/generatedTypes/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ import * as v1_2_0 from './v1.2.0'
1717
import * as v1_3_0 from './v1.3.0'
1818
import * as v1_4_0 from './v1.4.0'
1919
import * as v1_5_0 from './v1.5.0'
20+
import * as v1_6_0 from './v1.6.0'
2021

2122
export * from './latest'
2223

23-
export const LATEST_APP_DATA_VERSION = '1.5.0'
24+
export const LATEST_APP_DATA_VERSION = '1.6.0'
2425
export const LATEST_QUOTE_METADATA_VERSION = '1.1.0'
2526
export const LATEST_REFERRER_METADATA_VERSION = '0.2.0'
2627
export const LATEST_ORDER_CLASS_METADATA_VERSION = '0.3.0'
@@ -31,8 +32,9 @@ export const LATEST_WIDGET_METADATA_VERSION = '0.1.0'
3132
export const LATEST_PARTNER_FEE_METADATA_VERSION = '1.0.0'
3233
export const LATEST_REPLACED_ORDER_METADATA_VERSION = '0.1.0'
3334

34-
export type LatestAppDataDocVersion = v1_5_0.AppDataRootSchema
35+
export type LatestAppDataDocVersion = v1_6_0.AppDataRootSchema
3536
export type AnyAppDataDocVersion =
37+
| v1_6_0.AppDataRootSchema
3638
| v1_5_0.AppDataRootSchema
3739
| v1_4_0.AppDataRootSchema
3840
| v1_3_0.AppDataRootSchema
@@ -52,6 +54,7 @@ export type AnyAppDataDocVersion =
5254
| v0_1_0.AppDataRootSchema
5355

5456
export {
57+
v1_6_0,
5558
v1_5_0,
5659
v1_4_0,
5760
v1_3_0,

src/generatedTypes/latest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
// generated file, do not edit manually
22

3-
export * as latest from './v1.5.0'
3+
export * as latest from './v1.6.0'

0 commit comments

Comments
 (0)