Skip to content

Commit ccaa021

Browse files
vbrvkCI/CD Bot
and
CI/CD Bot
authored
fix: whitelist for get[Taking/Making]Amount (#126)
Co-authored-by: CI/CD Bot <[email protected]>
1 parent 954e816 commit ccaa021

8 files changed

+191
-20
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@1inch/fusion-sdk",
3-
"version": "2.1.10",
3+
"version": "2.1.11-rc.1",
44
"description": "1inch Fusion SDK",
55
"author": "@1inch",
66
"private": false,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import {
2+
FeeCalculator,
3+
Fees,
4+
IntegratorFee
5+
} from '@1inch/limit-order-sdk/extensions/fee-taker'
6+
import {Address, Bps} from '@1inch/limit-order-sdk'
7+
import {AmountCalculator} from './amount-calculator'
8+
import {AuctionCalculator} from './auction-calculator'
9+
import {Whitelist} from '../fusion-order'
10+
import {now} from '../utils/time'
11+
12+
describe('AmountCalculator', () => {
13+
it('should correct extract fee', () => {
14+
const integratorFeeBps = new Bps(6n) // 60% from 10bps
15+
const calculator = new AmountCalculator(
16+
new AuctionCalculator(
17+
1738650250n,
18+
180n,
19+
1218519n,
20+
[{coefficient: 609353, delay: 180}],
21+
{gasBumpEstimate: 609353n, gasPriceEstimate: 1526n}
22+
),
23+
new FeeCalculator(
24+
Fees.integratorFee(
25+
new IntegratorFee(
26+
new Address(
27+
'0x8e097e5e0493de033270a01b324caf31f464dc67'
28+
),
29+
new Address(
30+
'0x90cbe4bdd538d6e9b379bff5fe72c3d67a521de5'
31+
),
32+
new Bps(10n),
33+
new Bps(6000n)
34+
)
35+
),
36+
Whitelist.new(1738650226n, [
37+
{address: Address.fromBigInt(1n), allowFrom: 0n}
38+
])
39+
)
40+
)
41+
const takingAmount = 100000n
42+
const requiredTakingAmount = calculator.getRequiredTakingAmount(
43+
Address.ZERO_ADDRESS,
44+
takingAmount,
45+
now(),
46+
10n
47+
)
48+
49+
const integratorFee = calculator.getIntegratorFee(
50+
Address.ZERO_ADDRESS,
51+
takingAmount,
52+
now(),
53+
10n
54+
)
55+
56+
expect(
57+
AmountCalculator.extractFeeAmount(
58+
requiredTakingAmount,
59+
integratorFeeBps
60+
)
61+
).toEqual(integratorFee)
62+
})
63+
})

src/amount-calculator/amount-calculator.ts

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import {Address, Bps, FeeTakerExt} from '@1inch/limit-order-sdk'
1+
import {
2+
Address,
3+
Bps,
4+
FeeTakerExt,
5+
mulDiv,
6+
Rounding
7+
} from '@1inch/limit-order-sdk'
28
import {FeeCalculator, Fees} from '@1inch/limit-order-sdk/extensions/fee-taker'
39
import {AuctionCalculator} from './auction-calculator'
410
import {FusionExtension} from '../fusion-order'
@@ -51,6 +57,27 @@ export class AmountCalculator {
5157
return (withoutFee * numerator) / Fees.BASE_1E5
5258
}
5359

60+
/**
61+
* Return fee amount in taker asset which is included in `requiredTakingAmount`
62+
*
63+
* @param requiredTakingAmount must already contain fee
64+
* @param fee to extract
65+
*/
66+
public static extractFeeAmount(
67+
requiredTakingAmount: bigint,
68+
fee: Bps
69+
): bigint {
70+
return (
71+
requiredTakingAmount -
72+
mulDiv(
73+
requiredTakingAmount,
74+
Fees.BASE_1E5,
75+
Fees.BASE_1E5 + BigInt(fee.toFraction(Fees.BASE_1E5)),
76+
Rounding.Ceil
77+
)
78+
)
79+
}
80+
5481
/**
5582
* Returns adjusted taking amount with included fees and auction bump
5683
*

src/fusion-order/fusion-extension.ts

+38-13
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {BN, BytesBuilder, BytesIter} from '@1inch/byte-utils'
1313
import assert from 'assert'
1414
import {AuctionDetails} from './auction-details'
1515
import {Whitelist} from './whitelist/whitelist'
16+
import {add0x} from '../utils'
1617

1718
export class FusionExtension {
1819
/**
@@ -82,6 +83,8 @@ export class FusionExtension {
8283
: undefined
8384

8485
const interactionData = parseAmountData(interactionBytes)
86+
const whitelist = Whitelist.decodeFrom(interactionBytes)
87+
8588
//endregion Parse postInteraction data
8689

8790
//region Parse amount data
@@ -90,6 +93,20 @@ export class FusionExtension {
9093

9194
const auctionDetails = AuctionDetails.decodeFrom(amountBytes)
9295
const amountData = parseAmountData(amountBytes)
96+
const whitelistAddressLength = Number(amountBytes.nextUint8())
97+
98+
assert(
99+
whitelist.length === whitelistAddressLength,
100+
'whitelist addresses must be same in interaction data and in amount data'
101+
)
102+
103+
const whitelistAddressesFromAmount: string[] = []
104+
105+
for (let i = 0; i < whitelistAddressLength; i++) {
106+
whitelistAddressesFromAmount.push(
107+
BigInt(amountBytes.nextBytes(10)).toString(16).padStart(20, '0')
108+
)
109+
}
93110

94111
//endregion Parse amount data
95112

@@ -122,8 +139,11 @@ export class FusionExtension {
122139
)
123140

124141
assert(
125-
interactionData.whitelist.equal(amountData.whitelist),
126-
'whitelist must be same in interaction data and in amount data'
142+
whitelist.whitelist.every(
143+
({addressHalf}, i) =>
144+
whitelistAddressesFromAmount[i] === addressHalf
145+
),
146+
'whitelist addresses must be same in interaction data and in amount data'
127147
)
128148

129149
const hasFees =
@@ -133,10 +153,11 @@ export class FusionExtension {
133153
return new FusionExtension(
134154
settlementContract,
135155
auctionDetails,
136-
interactionData.whitelist,
156+
whitelist,
137157
{
138158
makerPermit,
139-
customReceiver
159+
customReceiver,
160+
fees: undefined
140161
}
141162
)
142163
}
@@ -162,7 +183,7 @@ export class FusionExtension {
162183
return new FusionExtension(
163184
settlementContract,
164185
auctionDetails,
165-
interactionData.whitelist,
186+
whitelist,
166187
{
167188
makerPermit,
168189
fees,
@@ -244,10 +265,10 @@ export class FusionExtension {
244265
*
245266
* @see https://github.com/1inch/limit-order-settlement/blob/82f0a25c969170f710825ce6aa6920062adbde88/contracts/SimpleSettlement.sol#L34
246267
*/
247-
private buildAmountGetterData(withAuction: boolean): string {
268+
private buildAmountGetterData(forAmountGetters: boolean): string {
248269
const builder = new BytesBuilder()
249270

250-
if (withAuction) {
271+
if (forAmountGetters) {
251272
// auction data required only for `getMakingAmount/getTakingAmount` and not for `postInteraction`
252273
this.auctionDetails.encodeInto(builder)
253274
}
@@ -282,7 +303,15 @@ export class FusionExtension {
282303
)
283304
)
284305

285-
this.whitelist.encodeInto(builder)
306+
if (forAmountGetters) {
307+
// amount getters need only addresses, without delays
308+
builder.addUint8(BigInt(this.whitelist.whitelist.length))
309+
this.whitelist.whitelist.forEach((i) => {
310+
builder.addBytes(add0x(i.addressHalf))
311+
})
312+
} else {
313+
this.whitelist.encodeInto(builder)
314+
}
286315

287316
return builder.asHex()
288317
}
@@ -348,7 +377,6 @@ function parseAmountData(iter: BytesIter<string>): {
348377
resolverFee: Bps
349378
whitelistDiscount: Bps
350379
}
351-
whitelist: Whitelist
352380
} {
353381
const fees = {
354382
integratorFee: Bps.fromFraction(
@@ -369,10 +397,7 @@ function parseAmountData(iter: BytesIter<string>): {
369397
)
370398
}
371399

372-
const whitelist = Whitelist.decodeFrom(iter)
373-
374400
return {
375-
fees,
376-
whitelist
401+
fees
377402
}
378403
}

src/fusion-order/fusion-order.spec.ts

+55-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import {Address, Bps, MakerTraits, FeeTakerExt} from '@1inch/limit-order-sdk'
1+
import {
2+
Address,
3+
Bps,
4+
MakerTraits,
5+
FeeTakerExt,
6+
Extension
7+
} from '@1inch/limit-order-sdk'
28
import {parseUnits} from 'ethers'
39
import {FusionOrder} from './fusion-order'
410
import {AuctionDetails} from './auction-details'
@@ -59,7 +65,7 @@ describe('Fusion Order', () => {
5965
takingAmount: '1420000000',
6066
makerTraits:
6167
'33471150795161712739625987854073848363835856965607525350783622537007396290560',
62-
salt: '15150891855335877009553113668813008135841821470374'
68+
salt: '15154917212229274031775300768002549554250257257796'
6369
})
6470

6571
const makerTraits = new MakerTraits(BigInt(builtOrder.makerTraits))
@@ -131,7 +137,7 @@ describe('Fusion Order', () => {
131137
takingAmount: '1420000000',
132138
makerTraits:
133139
'33471150795161712739625987854073848363835856965607525350783622537007396290560',
134-
salt: '15927625895819333064650069072431807310373701948678'
140+
salt: '14784889872407883648102551457165962490230021209460'
135141
})
136142

137143
const makerTraits = new MakerTraits(BigInt(builtOrder.makerTraits))
@@ -286,4 +292,50 @@ describe('Fusion Order', () => {
286292
2n * order.takingAmount // because init rate bump is 100%
287293
)
288294
})
295+
296+
it.skip('Should calculate total fee', () => {
297+
// https://etherscan.io/tx/0x8f95dc0e6e836ca0abdad88e20cf61b0caf7c5463d67b577740f3084d428e56e
298+
const data = [
299+
{
300+
order: '{"salt": "88244613754032523633323406132962387804442696513566413874801304436628426636029", "maker": "0x6edc317f3208b10c46f4ff97faa04dd632487408", "receiver": "0xabd4e5fb590aa132749bbf2a04ea57efbaac399e", "makerAsset": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "takerAsset": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "makerTraits": "62419173104490761595518734106935910747442209877250655105498008304728645042176", "makingAmount": "7340000000000000", "takingAmount": "17733698"}',
301+
extension:
302+
'0x000000ec0000008c0000008c0000008c0000008c000000460000000000000000abd4e5fb590aa132749bbf2a04ea57efbaac399e094c49000005f667a1b28a0000b41297d701094c4900b400643c00006402d1a23c3abeed63c51b86b5636af8f99b8e85dc9fabd4e5fb590aa132749bbf2a04ea57efbaac399e094c49000005f667a1b28a0000b41297d701094c4900b400643c00006402d1a23c3abeed63c51b86b5636af8f99b8e85dc9fabd4e5fb590aa132749bbf2a04ea57efbaac399e008e097e5e0493de033270a01b324caf31f464dc6790cbe4bdd538d6e9b379bff5fe72c3d67a521de500643c00006467a1b27202d1a23c3abeed63c51b860000b5636af8f99b8e85dc9f0000'
303+
}
304+
]
305+
306+
const order = FusionOrder.fromDataAndExtension(
307+
JSON.parse(data[0].order),
308+
Extension.decode(data[0].extension)
309+
)
310+
311+
const userAmount = order
312+
.getAmountCalculator()
313+
.getUserTakingAmountAmount(
314+
Address.ZERO_ADDRESS,
315+
order.takingAmount,
316+
1738650311n,
317+
1533984564n
318+
)
319+
320+
const integratorFee = order
321+
.getAmountCalculator()
322+
.getIntegratorFee(
323+
Address.ZERO_ADDRESS,
324+
order.takingAmount,
325+
1738650311n,
326+
1533984564n
327+
)
328+
const protocolFee = order
329+
.getAmountCalculator()
330+
.getProtocolFee(
331+
Address.ZERO_ADDRESS,
332+
order.takingAmount,
333+
1738650311n,
334+
1533984564n
335+
)
336+
337+
expect(userAmount).toEqual(18442228n)
338+
expect(integratorFee).toEqual(11065n)
339+
expect(protocolFee).toEqual(7377n)
340+
})
289341
})

src/fusion-order/whitelist/whitelist.ts

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export class Whitelist {
1919
})
2020
}
2121

22+
public get length(): number {
23+
return this.whitelist.length
24+
}
25+
2226
/**
2327
* Construct `Whitelist` from BytesIter
2428
*

0 commit comments

Comments
 (0)