diff --git a/package.json b/package.json index c2864146..d959e32b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@opensea/seaport-js", - "version": "4.0.1", + "version": "4.0.2", "description": "[Seaport](https://github.com/ProjectOpenSea/seaport) is a new marketplace protocol for safely and efficiently buying and selling NFTs. This is a TypeScript library intended to make interfacing with the contract reasonable and easy.", "license": "MIT", "author": "OpenSea Developers", diff --git a/src/seaport.ts b/src/seaport.ts index b34bb6c7..c778cf67 100644 --- a/src/seaport.ts +++ b/src/seaport.ts @@ -52,9 +52,8 @@ import { shouldUseBasicFulfill, validateAndSanitizeFromOrderStatus, } from "./utils/fulfill"; -import { getMaximumSizeForOrder, isCurrencyItem } from "./utils/item"; +import { isCurrencyItem } from "./utils/item"; import { - adjustTipsForPartialFills, areAllCurrenciesSame, deductFees, feeToConsiderationItem, @@ -1049,16 +1048,6 @@ export class Seaport { offererBalancesAndApprovals: offerersBalancesAndApprovals[index], offererOperator: allOffererOperators[index], }; - if (order.tips.length > 0) { - order.tips = adjustTipsForPartialFills( - order.tips, - order.unitsToFill || 1, - // Max total amount to fulfill for scaling - getMaximumSizeForOrder({ - ...order.order, - }), - ); - } return order; }, diff --git a/src/utils/fulfill.ts b/src/utils/fulfill.ts index 81f378ce..c390fb38 100644 --- a/src/utils/fulfill.ts +++ b/src/utils/fulfill.ts @@ -574,6 +574,31 @@ export function fulfillAvailableOrders({ ), })); + const adjustTips = (orderMetadata: { + order: Order; + unitsToFill?: BigNumberish; + orderStatus: OrderStatus; + offerCriteria: InputCriteria[]; + considerationCriteria: InputCriteria[]; + tips: ConsiderationItem[]; + extraData: string; + offererBalancesAndApprovals: BalancesAndApprovals; + offererOperator: string; + }): ConsiderationItem[] => { + if (!orderMetadata.tips || !orderMetadata.tips.length) { + return []; + } + + // Max total amount to fulfill for scaling + const maxUnits = getMaximumSizeForOrder(orderMetadata.order); + + return adjustTipsForPartialFills( + orderMetadata.tips, + orderMetadata.unitsToFill || 1, + maxUnits, + ); + }; + const ordersMetadataWithAdjustedFills = sanitizedOrdersMetadata.map( (orderMetadata) => ({ ...orderMetadata, @@ -589,6 +614,7 @@ export function fulfillAvailableOrders({ totalFilled: orderMetadata.orderStatus.totalFilled, totalSize: orderMetadata.orderStatus.totalSize, }), + tips: adjustTips(orderMetadata), }), ); diff --git a/test/partial-fulfill.spec.ts b/test/partial-fulfill.spec.ts index 462d2cc9..c2f03c97 100644 --- a/test/partial-fulfill.spec.ts +++ b/test/partial-fulfill.spec.ts @@ -13,6 +13,8 @@ import { describeWithFixture } from "./utils/setup"; import { OPENSEA_DOMAIN, OPENSEA_DOMAIN_TAG } from "./utils/constants"; import { SinonSpy } from "sinon"; import { SeaportABI } from "../src/abi/Seaport"; +import { FulfillOrdersMetadata } from "../lib/utils/fulfill"; +import { mapInputItemToOfferItem } from "../src/utils/order"; const sinon = require("sinon"); @@ -24,6 +26,7 @@ describeWithFixture( let fulfiller: Signer; let fulfillStandardOrderSpy: SinonSpy; + let fulfillAvailableOrdersSpy: SinonSpy; let standardCreateOrderInput: CreateOrderInput; let secondTestErc1155: TestERC1155; @@ -33,6 +36,7 @@ describeWithFixture( [offerer, zone, fulfiller] = await ethers.getSigners(); fulfillStandardOrderSpy = sinon.spy(fulfill, "fulfillStandardOrder"); + fulfillAvailableOrdersSpy = sinon.spy(fulfill, "fulfillAvailableOrders"); const TestERC1155 = await ethers.getContractFactory("TestERC1155"); secondTestErc1155 = await TestERC1155.deploy(); @@ -41,6 +45,7 @@ describeWithFixture( afterEach(() => { fulfillStandardOrderSpy.restore(); + fulfillAvailableOrdersSpy.restore(); }); describe("An ERC1155 is partially transferred", () => { @@ -223,7 +228,6 @@ describeWithFixture( }); it("ERC1155 <=> ETH adjust tips correctly using fulfillOrders", async () => { - // same test as above, but instead of fulfillOrder we use fulfillOrders const tips = [ { amount: parseEther("1").toString(), @@ -304,7 +308,46 @@ describeWithFixture( fulfillReceipt: receipt!, }); - expect(fulfillStandardOrderSpy.calledOnce); + const tipConsiderationItems = tips.map((tip) => ({ + ...mapInputItemToOfferItem(tip), + recipient: tip.recipient, + })); + + const expectedArgs = { + ordersMetadata: [ + { + order, + unitsToFill: 2, + tips: tipConsiderationItems, + }, + ], + }; + + expect( + fulfillAvailableOrdersSpy.withArgs( + sinon.match(function ({ + ordersMetadata, + }: { + ordersMetadata: FulfillOrdersMetadata; + }) { + ordersMetadata.every((metadata, index) => { + expect(metadata.order).to.deep.equal( + expectedArgs.ordersMetadata[index].order, + "order doesn't match expected value", + ); + expect(metadata.unitsToFill).to.deep.equal( + expectedArgs.ordersMetadata[index].unitsToFill, + "unitsToFill doesn't match expected value", + ); + expect(metadata.tips).to.deep.equal( + expectedArgs.ordersMetadata[index].tips, + "tips doesn't match expected value", + ); + }); + return true; + }), + ).calledOnce, + ).to.be.true; }); it("ERC1155 <=> ETH adjust tips correctly with low denomination", async () => {