Skip to content

Commit

Permalink
chore: Simplify usage for collection orders (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xShisui authored Mar 20, 2023
1 parent 0f6144a commit 72cf905
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 36 deletions.
30 changes: 27 additions & 3 deletions doc/classes/LooksRare.LooksRare.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,30 @@ the maker object and isCurrencyApproved

___

### createMakerCollectionOffer

**createMakerCollectionOffer**(`orderInputs`): `Promise`<[`CreateMakerBidOutput`](../interfaces/types.CreateMakerBidOutput.md)\>

Create a maker bid for collection offer.

**`See`**

this.createMakerBid

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `orderInputs` | [`CreateMakerCollectionOfferInput`](../modules/types.md#createmakercollectionofferinput) | Order data |

#### Returns

`Promise`<[`CreateMakerBidOutput`](../interfaces/types.CreateMakerBidOutput.md)\>

CreateMakerBidOutput

___

### createTaker

**createTaker**(`maker`, `recipient?`, `additionalParameters?`): [`Taker`](../interfaces/types.Taker.md)
Expand All @@ -237,11 +261,11 @@ Taker object

___

### createTakerForCollectionOrder
### createTakerCollectionOffer

**createTakerForCollectionOrder**(`maker`, `itemId`, `recipient?`): [`Taker`](../interfaces/types.Taker.md)
**createTakerCollectionOffer**(`maker`, `itemId`, `recipient?`): [`Taker`](../interfaces/types.Taker.md)

Wrapper of createTaker to facilitate taker creation for collection orders
Create a taker ask order for collection order.

**`See`**

Expand Down
6 changes: 6 additions & 0 deletions doc/modules/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@

## Type Aliases

### CreateMakerCollectionOfferInput

Ƭ **CreateMakerCollectionOfferInput**: `Omit`<[`CreateMakerInput`](../interfaces/types.CreateMakerInput.md), ``"strategyId"`` \| ``"itemIds"``\>

___

### EIP712TypedData

Ƭ **EIP712TypedData**: `Record`<`string`, `TypedDataField`[]\>
Expand Down
6 changes: 2 additions & 4 deletions guides/collectionOrder.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
:warning: These code snippets are just examples and the data should never be used as is :warning:

# How to create a collection order (maker bid with collection strategy)
# How to create a collection offer (maker bid with collection strategy)

A collection order is just a maker bid order using the `collection strategy`.

Expand All @@ -10,15 +10,13 @@ import { LooksRare, SupportedChainId, CollectionType, StrategyType } from "@look

const lr = new LooksRare(SupportedChainId.MAINNET, provider, signer);

const { makerAsk, isCurrencyApproved } = await lr.createMakerBid({
const { makerAsk, isCurrencyApproved } = await lr.createMakerCollectionOffer({
collection: "0x0000000000000000000000000000000000000000", // Collection address
collectionType: CollectionType.ERC721,
strategyId: StrategyType.collection,
subsetNonce: 0, // keep 0 if you don't know what it is used for
orderNonce: 0, // You need to retrieve this value from the API
endTime: Math.floor(Date.now() / 1000), // If you use a timestamp in ms, the function will revert
price: ethers.utils.parseEther("1"), // Be careful to use a price in wei, this example is for 1 ETH
itemIds: [0], // Token id of the NFT(s) you want to sell, add several ids to create a bundle
amounts: [1], // Use it for listing multiple ERC-1155 (Optional, Default to [1])
startTime: Math.floor(Date.now() / 1000), // Use it to create an order that will be valid in the future (Optional, Default to now)
});
Expand Down
15 changes: 13 additions & 2 deletions src/LooksRare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
CreateMakerInput,
CreateMakerAskOutput,
CreateMakerBidOutput,
CreateMakerCollectionOfferInput,
MerkleTree,
ContractMethods,
OrderValidatorCode,
Expand Down Expand Up @@ -249,14 +250,24 @@ export class LooksRare {
}

/**
* Wrapper of createTaker to facilitate taker creation for collection orders
* Create a maker bid for collection offer.
* @see this.createMakerBid
* @param orderInputs Order data
* @returns CreateMakerBidOutput
*/
public createMakerCollectionOffer(orderInputs: CreateMakerCollectionOfferInput): Promise<CreateMakerBidOutput> {
return this.createMakerBid({ ...orderInputs, strategyId: StrategyType.collection, itemIds: [] });
}

/**
* Create a taker ask order for collection order.
* @see this.createTaker
* @param makerBid Maker bid that will be used as counterparty for the taker
* @param itemId Token id to use as a counterparty for the collection order
* @param recipient Recipient address of the taker (if none, it will use the sender)
* @returns Taker object
*/
public createTakerForCollectionOrder(maker: Maker, itemId: BigNumberish, recipient?: string): Taker {
public createTakerCollectionOffer(maker: Maker, itemId: BigNumberish, recipient?: string): Taker {
if (maker.quoteType !== QuoteType.Bid) {
throw new ErrorQuoteType();
}
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/helpers/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { ERC721 } from "../../typechain/solmate/src/tokens/ERC721.sol/ERC721";
import abiIERC721 from "../../abis/IERC721.json";
import { Signer } from "../../types";

export const balanceOf = async (signer: Signer, collection: string, owner?: string, overrides?: Overrides) => {
const contract = new Contract(collection, abiIERC721, signer) as ERC721;
export const balanceOf = async (signer: Signer, contractAddress: string, owner?: string, overrides?: Overrides) => {
const contract = new Contract(contractAddress, abiIERC721, signer) as ERC721;
return contract.balanceOf(owner ?? (await signer.getAddress()), { ...overrides });
};

Expand Down
8 changes: 4 additions & 4 deletions src/__tests__/looksrare/createTaker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe("Create takers", () => {
expect(taker.additionalParameters).to.be.equal("0x");
});
});
describe("createTakerForCollectionOrder", async () => {
describe("createTakerCollectionOffer", async () => {
it("create taker for collection order", async () => {
const baseMakerAskInput: CreateMakerInput = {
...baseInput,
Expand All @@ -63,7 +63,7 @@ describe("Create takers", () => {
};
const lr = new LooksRare(SupportedChainId.HARDHAT, ethers.provider, signers.user1, mocks.addresses);
const { maker } = await lr.createMakerBid(baseMakerAskInput);
const taker = lr.createTakerForCollectionOrder(maker, 1, signers.user2.address);
const taker = lr.createTakerCollectionOffer(maker, 1, signers.user2.address);

const [itemId] = utils.defaultAbiCoder.decode(getTakerParamsTypes(maker.strategyId), taker.additionalParameters);
expect(taker.recipient).to.be.equal(signers.user2.address);
Expand All @@ -79,7 +79,7 @@ describe("Create takers", () => {
const lr = new LooksRare(SupportedChainId.HARDHAT, ethers.provider, signers.user1, mocks.addresses);
const { maker } = await lr.createMakerAsk(baseMakerAskInput);

expect(() => lr.createTakerForCollectionOrder(maker, 1, signers.user2.address)).to.throw(ErrorQuoteType);
expect(() => lr.createTakerCollectionOffer(maker, 1, signers.user2.address)).to.throw(ErrorQuoteType);
});
it("throw when strategy type is wrong", async () => {
const baseMakerAskInput: CreateMakerInput = {
Expand All @@ -91,7 +91,7 @@ describe("Create takers", () => {
const lr = new LooksRare(SupportedChainId.HARDHAT, ethers.provider, signers.user1, mocks.addresses);
const { maker } = await lr.createMakerBid(baseMakerAskInput);

expect(() => lr.createTakerForCollectionOrder(maker, 1, signers.user2.address)).to.throw(ErrorStrategyType);
expect(() => lr.createTakerCollectionOffer(maker, 1, signers.user2.address)).to.throw(ErrorStrategyType);
});
});
});
62 changes: 41 additions & 21 deletions src/__tests__/looksrare/executeCollectionOrder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,70 @@ import { expect } from "chai";
import { utils } from "ethers";
import { ethers } from "hardhat";
import { setUpContracts, SetupMocks, getSigners, Signers } from "../helpers/setup";
import { ownerOf, balanceOf } from "../helpers/tokens";
import { LooksRare } from "../../LooksRare";
import { SupportedChainId, CollectionType, StrategyType, CreateMakerInput } from "../../types";
import { SupportedChainId, CollectionType, CreateMakerCollectionOfferInput } from "../../types";

describe("execute collection order", () => {
let mocks: SetupMocks;
let lrUser1: LooksRare;
let signers: Signers;
let baseMakerBidInput: CreateMakerInput;
let lrUser2: LooksRare;
let collectionOfferInput: CreateMakerCollectionOfferInput;

beforeEach(async () => {
mocks = await setUpContracts();
signers = await getSigners();
lrUser1 = new LooksRare(SupportedChainId.HARDHAT, ethers.provider, signers.user1, mocks.addresses);
lrUser2 = new LooksRare(SupportedChainId.HARDHAT, ethers.provider, signers.user2, mocks.addresses);

const tx = await mocks.contracts.transferManager
.connect(signers.user1)
.grantApprovals([mocks.addresses.EXCHANGE_V2]);
await tx.wait();

baseMakerBidInput = {
collectionOfferInput = {
collection: mocks.contracts.collectionERC721.address,
collectionType: CollectionType.ERC721,
strategyId: StrategyType.collection,
subsetNonce: 0,
orderNonce: 0,
startTime: Math.floor(Date.now() / 1000),
endTime: Math.floor(Date.now() / 1000) + 3600,
price: utils.parseEther("1"),
itemIds: [1],
};
});
it("execute collection order", async () => {
const lrUser1 = new LooksRare(SupportedChainId.HARDHAT, ethers.provider, signers.user1, mocks.addresses);
const lrUser2 = new LooksRare(SupportedChainId.HARDHAT, ethers.provider, signers.user2, mocks.addresses);
const { maker } = await lrUser2.createMakerBid(baseMakerBidInput);
let tx = await lrUser2.approveErc20(lrUser2.addresses.WETH);

let tx = await lrUser1.grantTransferManagerApproval().call();
await tx.wait();
const signature = await lrUser2.signMakerOrder(maker);

tx = await lrUser1.approveAllCollectionItems(maker.collection);
tx = await lrUser2.approveErc20(mocks.addresses.WETH);
await tx.wait();
const taker = lrUser1.createTakerForCollectionOrder(maker, 0);

tx = await lrUser1.approveAllCollectionItems(mocks.contracts.collectionERC721.address);
await tx.wait();
});

it("execute estimatedGas and callStatic", async () => {
const { maker } = await lrUser2.createMakerCollectionOffer(collectionOfferInput);
const signature = await lrUser2.signMakerOrder(maker);
const taker = lrUser1.createTakerCollectionOffer(maker, 0);
const contractMethods = lrUser1.executeOrder(maker, taker, signature);

const estimatedGas = await contractMethods.estimateGas();
expect(estimatedGas.toNumber()).to.be.greaterThan(0);
await expect(contractMethods.callStatic()).to.eventually.be.fulfilled;
});

it("execute collection order", async () => {
const itemId = 0;
const { maker } = await lrUser2.createMakerCollectionOffer(collectionOfferInput);
const signature = await lrUser2.signMakerOrder(maker);
const taker = lrUser1.createTakerCollectionOffer(maker, itemId);

const user1InitialBalance = await balanceOf(signers.user1, mocks.addresses.WETH);
const contractMethods = lrUser1.executeOrder(maker, taker, signature);

tx = await contractMethods.call();
const receipt = await tx.wait();
const receipt = await (await contractMethods.call()).wait();
expect(receipt.status).to.be.equal(1);

const owner = await ownerOf(signers.user2, collectionOfferInput.collection, itemId);
expect(owner).to.be.equal(signers.user2.address);

const user1UpdatedBalance = await balanceOf(signers.user1, mocks.addresses.WETH);
expect(user1UpdatedBalance.gt(user1InitialBalance)).to.be.true;
});
});
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ export interface CreateMakerInput {
additionalParameters?: any[];
}

export type CreateMakerCollectionOfferInput = Omit<CreateMakerInput, "strategyId" | "itemIds">;

/** Maker object to be used in execute functions */
export interface Maker {
/** Ask or bid */
Expand Down

0 comments on commit 72cf905

Please sign in to comment.