diff --git a/package.json b/package.json index 10307be..9641223 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@1inch/fusion-sdk", - "version": "2.4.1", + "version": "2.4.2-rc.0", "description": "1inch Fusion SDK", "author": "@1inch", "files": [ diff --git a/src/fusion-order/fusion-extension.spec.ts b/src/fusion-order/fusion-extension.spec.ts index ef51a43..44cc459 100644 --- a/src/fusion-order/fusion-extension.spec.ts +++ b/src/fusion-order/fusion-extension.spec.ts @@ -1,4 +1,4 @@ -import {Address} from '@1inch/limit-order-sdk' +import {Address, Interaction} from '@1inch/limit-order-sdk' import {FusionOrder} from './fusion-order.js' import {AuctionDetails} from './auction-details/index.js' import {FusionExtension} from './fusion-extension.js' @@ -104,4 +104,63 @@ describe('FusionExtension', () => { const fusionExtension = FusionExtension.decode(order.extension.encode()) expect(fusionExtension).toStrictEqual(order.fusionExtension) }) + + it('should decode with pre/post interaction hooks', () => { + const extensionContract = new Address( + '0x8273f37417da37c4a6c3995e82cf442f87a25d9c' + ) + + const order = FusionOrder.new( + extensionContract, + { + makerAsset: new Address( + '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ), + takerAsset: new Address( + '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' + ), + makingAmount: 1000000000000000000n, + takingAmount: 1420000000n, + maker: new Address( + '0x00000000219ab540356cbb839cbe05303d7705fa' + ), + salt: 10n + }, + { + auction: new AuctionDetails({ + duration: 180n, + startTime: 1673548149n, + initialRateBump: 50000, + points: [ + { + coefficient: 20000, + delay: 12 + } + ] + }), + whitelist: Whitelist.new(1673548139n, [ + { + address: new Address( + '0x00000000219ab540356cbb839cbe05303d7705fa' + ), + allowFrom: 0n + } + ]), + surplus: SurplusParams.NO_FEE + }, + { + permit: '0xdeadbeef', + preInteraction: new Interaction( + Address.fromBigInt(1n), + '0xbeef' + ), + postInteraction: new Interaction( + Address.fromBigInt(2n), + '0xdead' + ) + } + ) + const fusionExtension = FusionExtension.decode(order.extension.encode()) + expect(fusionExtension).toStrictEqual(order.fusionExtension) + }) }) diff --git a/src/fusion-order/fusion-extension.ts b/src/fusion-order/fusion-extension.ts index 6beb42d..b5ba581 100644 --- a/src/fusion-order/fusion-extension.ts +++ b/src/fusion-order/fusion-extension.ts @@ -5,7 +5,8 @@ import { Interaction, Bps, mulDiv, - Rounding + Rounding, + ZX } from '@1inch/limit-order-sdk' import {BN, BytesBuilder, BytesIter} from '@1inch/byte-utils' @@ -32,6 +33,8 @@ export class FusionExtension { makerPermit?: Interaction customReceiver?: Address fees?: Fees + preInteraction?: Interaction + postInteraction?: Interaction } ) {} @@ -152,6 +155,15 @@ export class FusionExtension { const hasFees = !integratorFeeRecipient.isZero() || !protocolFeeRecipient.isZero() + const preInteraction = + extension.preInteraction == ZX + ? undefined + : Interaction.decode(extension.preInteraction) + + const postInteraction = interactionBytes.isEmpty() + ? undefined + : Interaction.decode(interactionBytes.rest()) + if (!hasFees) { return new FusionExtension( settlementContract, @@ -161,7 +173,9 @@ export class FusionExtension { { makerPermit, customReceiver, - fees: undefined + fees: undefined, + preInteraction, + postInteraction } ) } @@ -190,7 +204,9 @@ export class FusionExtension { { makerPermit, fees, - customReceiver + customReceiver, + preInteraction, + postInteraction } ) } @@ -202,9 +218,16 @@ export class FusionExtension { .withMakingAmountData(this.address, amountData) .withTakingAmountData(this.address, amountData) .withPostInteraction( - new Interaction(this.address, this.buildInteractionData()) + new Interaction( + this.address, + this.buildInteractionData(this.extra?.postInteraction) + ) ) + if (this.extra?.preInteraction) { + builder.withPreInteraction(this.extra.preInteraction) + } + if (this.extra?.makerPermit) { builder.withMakerPermit( this.extra?.makerPermit.target, @@ -215,6 +238,26 @@ export class FusionExtension { return builder.build() } + /** + * Returns takingAmount with fee, but without auction bump + * @param taker + * @param orderTakingAmount + * @private + */ + public getTakingAmountWithFee( + taker: Address, + orderTakingAmount: bigint + ): bigint { + const fees = this.getFeesForTaker(taker) + + return mulDiv( + orderTakingAmount, + Fees.BASE_1E5 + fees.resolverFee + fees.integratorFee, + Fees.BASE_1E5, + Rounding.Ceil + ) + } + /** * Build data for `FeeTaker.postInteraction` * @@ -230,7 +273,7 @@ export class FusionExtension { * @see buildAmountGetterData * @see https://github.com/1inch/limit-order-protocol/blob/22a18f7f20acfec69d4f50ce1880e8e662477710/contracts/extensions/FeeTaker.sol#L114 */ - private buildInteractionData(): string { + private buildInteractionData(customPostInteraction?: Interaction): string { const customReceiver = this.extra?.customReceiver || Address.ZERO_ADDRESS @@ -259,6 +302,10 @@ export class FusionExtension { builder.addUint256(this.surplus.estimatedTakerAmount) builder.addUint8(BigInt(this.surplus.protocolFee.toPercent())) + if (customPostInteraction) { + builder.addBytes(customPostInteraction.encode()) + } + return builder.asHex() } @@ -348,26 +395,6 @@ export class FusionExtension { integratorFee: integratorFeeBN } } - - /** - * Returns takingAmount with fee, but without auction bump - * @param taker - * @param orderTakingAmount - * @private - */ - private getTakingAmountWithFee( - taker: Address, - orderTakingAmount: bigint - ): bigint { - const fees = this.getFeesForTaker(taker) - - return mulDiv( - orderTakingAmount, - Fees.BASE_1E5 + fees.resolverFee + fees.integratorFee, - Fees.BASE_1E5, - Rounding.Ceil - ) - } } function parseAmountData(iter: BytesIter): { diff --git a/src/fusion-order/fusion-order.ts b/src/fusion-order/fusion-order.ts index 7c3d2d6..1971e65 100644 --- a/src/fusion-order/fusion-order.ts +++ b/src/fusion-order/fusion-order.ts @@ -58,7 +58,9 @@ export class FusionOrder { ? new Interaction(orderInfo.makerAsset, extra.permit) : undefined, customReceiver: orderInfo.receiver, - fees: extra?.fees + fees: extra?.fees, + preInteraction: extra.preInteraction, + postInteraction: extra.postInteraction } ) ) { diff --git a/src/fusion-order/types.ts b/src/fusion-order/types.ts index 8ff95bd..0b7bd87 100644 --- a/src/fusion-order/types.ts +++ b/src/fusion-order/types.ts @@ -1,3 +1,4 @@ +import {Interaction} from '@1inch/limit-order-sdk' import {AuctionDetails} from './auction-details/auction-details.js' import {Fees} from './fees/index.js' import {SurplusParams} from './surplus-params.js' @@ -35,6 +36,18 @@ export type Extra = { * By default: enabled */ optimizeReceiverAddress?: boolean + + /** + * Allows maker to execute custom code before order executed + * @see https://github.com/1inch/limit-order-protocol/blob/master/docs/interfaces/IPreInteraction.md + */ + preInteraction?: Interaction + + /** + * Allows maker to execute custom code after order executed + * @see https://github.com/1inch/limit-order-protocol/blob/master/docs/interfaces/IPostInteraction.md + */ + postInteraction?: Interaction } export type Details = {