Skip to content

Commit

Permalink
Add hypercerts to marketplace functionality (#1170)
Browse files Browse the repository at this point in the history
* Feat/batch burn (#1051)

* feat(batch_burn): add batch burn function

* fix(docs): update SemiFungible1155 docs

* chore(lint): cleanup lint ignores

* chore(lint): defender lint errors

* chore(deploy): reduce optimizer run for kb limit

* chore(script): update upgrade script

* feat(gha): split graph deploy develop-main

* chore(lint): line length rule to warn from err

* chore(gha): run CI on PR to develop

* chore(gha): run e2e,ci on pr,push to develop

* feat(graph): update graph for burn methods

* chore(turbo): split graph deploys (#1055)

* Fix/workspace label (#1060)

chore(yarn): update workspace label

* 1052 subgraph a claimed token should indicate whether it was claimed from an allowlist (#1058)

* fix(graph): link claim with allowlist

* chore(tweak): yada

* fix(graph): update mapping to claim (#1061)

* nitial trader implementation (#1063)

* feat(iface): draft of trader interface

* feat(trader): simple offer, buy, cancel flow

* feat(db): update allowlist query (#1057)

* feat(test): tweaks and initial tests for Trader

* chore(gha): remove hardcoded foundry nightly

* feat(test): add initial test for trader sales

* feat(test): sales tests

* feat(deploy): deployed to goerli

* chore(ci): updated hh scripts for trader contract

* feat(pause): pausable controls and tests

* feat(trader): init trader graph

* feat(tokens): surface accepted tokens (#1065)

* feat(tokens): surface accepted tokens

* fix(tokens): acceptedTokens test and fix

* Feat/accepted tokens (#1066)

* feat(tokens): surface accepted tokens

* fix(tokens): acceptedTokens test and fix

* chore(address): update trader address graph

* fix(import): add bigint to import

* Feat/accepted tokens (#1067)

* feat(tokens): surface accepted tokens

* fix(tokens): acceptedTokens test and fix

* chore(address): update trader address graph

* fix(import): add bigint to import

* fix(log): add logging to trader mapping

* chore(prep): protocol contracts to protocol dir

* chore(prep): tests to protocol dir and remappings

* chore(license): MIT license

* Feat/init marketplace (#1139)

* chore(prep): protocol contracts to protocol dir

* chore(prep): tests to protocol dir and remappings

* chore(license): MIT license

* feat(marketplace): inject, build, refactor, test

* chore(gha): run gha on push and develop-branches

* fix(build): build and lint errors

* chore(pnpm): refresh lock file

* chore(build): reduce turbo concurrency

* fix(build): whac a mole

* chore(build): restore prettier in solhint

* chore(build): env.template vars

* chore(dist): clean and remap output contracts

* chore(clean): last tests

* fix(build): ignore cors-proxy type errors

* chore(gha): add rpc env vars for fork testing

---------

Co-authored-by: jipstavenuiter <[email protected]>

* chore(lint): cleanup config and affiliate flows (#1140)

* chore(license): dual licensing contracts + repo (#1141)

* [Test] Release marketplace contracts on testnet and add to contracts package (#1150)

* feat(deploy): deploy to testnets

* chore(build): hardhat build

* feat(pack): release, test, bump updated contracts

* chore(gha): updated env vars

* chore(pnpm): updated lock file

* fix(build): build error, replaced util with viem

* fix(pnpm): root dir ethers resolution

* chore(pnpm): updated lockfile

* fix(pnpm): overrides

* chore(build): resolving build issues sdk

* chore(refactor): dep resolution bug - del eth v5

* fix(test): mock ipfs in minting, remove timeout

* Direct Hypercert fraction sale (#1142)

* feat(tranfer): transfer single hypercert fraction

* feat(transfer): batch transfers and across collections

* feat(transfer): reduce cyclomatic complexity

* feat(offers): hypercert offer signatures

* feat(transfer): standard txs tests hypercerts

* chore(gha): only run on every push

* fix(merge): merge artifacts

---------

Co-authored-by: jipstavenuiter <[email protected]>
  • Loading branch information
bitbeckers and Jipperism authored Nov 8, 2023
1 parent ee250ee commit 44baf47
Show file tree
Hide file tree
Showing 36 changed files with 14,687 additions and 2,561 deletions.
1 change: 1 addition & 0 deletions contracts/remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ prb-test/=lib/prb-test/src/
@looksrare/=node_modules/@looksrare/
hardhat/=node_modules/hardhat/
solmate/=node_modules/solmate/
@openzeppelin/=node_modules/@openzeppelin/
2 changes: 1 addition & 1 deletion contracts/src/marketplace/LooksRareProtocol.sol
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ import {QuoteType} from "./enums/QuoteType.sol";
* ~~~ ~~~
* ~~~~ ~~~~
* ~~~~~~
* @author LooksRare protocol team (👀,💎)
* @author LooksRare protocol team (👀,💎); bitbeckers
*/
contract LooksRareProtocol is
ILooksRareProtocol,
Expand Down
75 changes: 56 additions & 19 deletions contracts/src/marketplace/TransferManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -239,26 +239,11 @@ contract TransferManager is ITransferManager, LowLevelERC721Transfer, LowLevelER

CollectionType collectionType = items[i].collectionType;
if (collectionType == CollectionType.ERC721) {
for (uint256 j; j < itemIdsLengthForSingleCollection;) {
if (amounts[j] != 1) {
revert AmountInvalid();
}
_executeERC721TransferFrom(items[i].collection, from, to, itemIds[j]);
unchecked {
++j;
}
}
_processBatch721Collection(items[i], from, to);
} else if (collectionType == CollectionType.ERC1155) {
for (uint256 j; j < itemIdsLengthForSingleCollection;) {
if (amounts[j] == 0) {
revert AmountInvalid();
}

unchecked {
++j;
}
}
_executeERC1155SafeBatchTransferFrom(items[i].collection, from, to, itemIds, amounts);
_processBatch1155Collection(items[i], from, to);
} else if (collectionType == CollectionType.Hypercert) {
_processBatchHypercertCollection(items[i], from, to);
}

unchecked {
Expand Down Expand Up @@ -372,4 +357,56 @@ contract TransferManager is ITransferManager, LowLevelERC721Transfer, LowLevelER

revert TransferCallerInvalid();
}

function _processBatch721Collection(BatchTransferItem calldata batchItems, address from, address to) private {
uint256[] calldata itemIds = batchItems.itemIds;
uint256[] calldata amounts = batchItems.amounts;
uint256 length = itemIds.length;

for (uint256 j; j < length;) {
if (amounts[j] != 1) {
revert AmountInvalid();
}
_executeERC721TransferFrom(batchItems.collection, from, to, itemIds[j]);
unchecked {
++j;
}
}
}

function _processBatch1155Collection(BatchTransferItem calldata batchItems, address from, address to) private {
uint256[] calldata itemIds = batchItems.itemIds;
uint256[] calldata amounts = batchItems.amounts;
uint256 length = itemIds.length;

for (uint256 j; j < length;) {
if (amounts[j] == 0) {
revert AmountInvalid();
}

unchecked {
++j;
}
}
_executeERC1155SafeBatchTransferFrom(batchItems.collection, from, to, itemIds, amounts);
}

function _processBatchHypercertCollection(BatchTransferItem calldata batchItems, address from, address to)
private
{
uint256[] calldata itemIds = batchItems.itemIds;
uint256[] calldata amounts = batchItems.amounts;
uint256 length = itemIds.length;

for (uint256 j; j < length;) {
if (amounts[j] == 0) {
revert AmountInvalid();
}

unchecked {
++j;
}
}
_executeERC1155SafeBatchTransferFrom(batchItems.collection, from, to, itemIds, amounts);
}
}
2 changes: 1 addition & 1 deletion contracts/src/marketplace/TransferSelectorNFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ contract TransferSelectorNFT is ExecutionManager, PackableReentrancyGuard {
} else if (collectionType == CollectionType.ERC1155) {
transferManager.transferItemsERC1155(collection, sender, recipient, itemIds, amounts);
} else if (collectionType == CollectionType.Hypercert) {
transferManager.transferItemsERC1155(collection, sender, recipient, itemIds, amounts);
transferManager.transferItemsHypercert(collection, sender, recipient, itemIds, amounts);
} else if (collectionType == CollectionType.Hyperboard) {
revert UnsupportedCollectionType();
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/marketplace/interfaces/ITransferManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface ITransferManager {
/**
* @notice This struct is only used for transferBatchItemsAcrossCollections.
* @param collection Collection address
* @param collectionType 0 for ERC721, 1 for ERC1155
* @param collectionType 0 for ERC721, 1 for ERC1155, 2 for Hypercert, 3 for Hyperboard
* @param itemIds Array of item ids to transfer
* @param amounts Array of amounts to transfer
*/
Expand Down
4 changes: 4 additions & 0 deletions contracts/src/protocol/interfaces/IHypercertToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ interface IHypercertToken {
/// @notice Operator must be allowed by `creator` and the token must represent the total amount of available units.
function burnFraction(address account, uint256 tokenID) external;

/// @dev Function to burn the tokens at `tokenIDs` for `account`
/// @notice Operator must be allowed by `creator` and the tokens must represent the total amount of available units.
function batchBurnFraction(address account, uint256[] memory tokenIDs) external;

/// @dev Returns the `units` held by a (fractional) token at `claimID`
/// @dev If `tokenID` is a base type, the total amount of `units` for the claim is returned.
/// @dev If `tokenID` is a fractional token, the `units` held by the token is returned
Expand Down
13 changes: 13 additions & 0 deletions contracts/test/foundry/marketplace/ProtocolBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {OrderStructs} from "@hypercerts/marketplace/libraries/OrderStructs.sol";
import {LooksRareProtocol, ILooksRareProtocol} from "@hypercerts/marketplace/LooksRareProtocol.sol";
import {TransferManager} from "@hypercerts/marketplace/TransferManager.sol";
import {ProtocolFeeRecipient} from "@hypercerts/marketplace/ProtocolFeeRecipient.sol";
import {HypercertMinter} from "@hypercerts/protocol/HypercertMinter.sol";
import {IHypercertToken} from "@hypercerts/protocol/interfaces/IHypercertToken.sol";

// Other contracts
import {OrderValidatorV2A} from "@hypercerts/marketplace/helpers/OrderValidatorV2A.sol";
Expand All @@ -21,6 +23,7 @@ import {MockERC721} from "../../mock/MockERC721.sol";
import {MockERC721WithRoyalties} from "../../mock/MockERC721WithRoyalties.sol";
import {MockERC1155} from "../../mock/MockERC1155.sol";
import {MockRoyaltyFeeRegistry} from "../../mock/MockRoyaltyFeeRegistry.sol";
import {MockHypercertMinterUUPS} from "../../mock/MockHypercertMinterUUPS.sol";

// Utils
import {MockOrderGenerator} from "./utils/MockOrderGenerator.sol";
Expand All @@ -32,6 +35,11 @@ contract ProtocolBase is MockOrderGenerator, ILooksRareProtocol {
MockERC721WithRoyalties public mockERC721WithRoyalties;
MockERC721 public mockERC721;
MockERC1155 public mockERC1155;
MockHypercertMinterUUPS public mockHypercertMinterUUPS;
HypercertMinter public mockHypercertMinter;

IHypercertToken.TransferRestrictions public constant FROM_CREATOR_ONLY =
IHypercertToken.TransferRestrictions.FromCreatorOnly;

ProtocolFeeRecipient public protocolFeeRecipient;
LooksRareProtocol public looksRareProtocol;
Expand Down Expand Up @@ -125,6 +133,8 @@ contract ProtocolBase is MockOrderGenerator, ILooksRareProtocol {
mockERC721.setApprovalForAll(address(transferManager), true);
mockERC1155.setApprovalForAll(address(transferManager), true);
mockERC721WithRoyalties.setApprovalForAll(address(transferManager), true);
mockHypercertMinter.setApprovalForAll(address(transferManager), true);

weth.approve(address(looksRareProtocol), type(uint256).max);

// Grant approvals for transfer manager
Expand Down Expand Up @@ -153,6 +163,9 @@ contract ProtocolBase is MockOrderGenerator, ILooksRareProtocol {
looksRareToken = new MockERC20();
mockERC721 = new MockERC721();
mockERC1155 = new MockERC1155();
mockHypercertMinterUUPS = new MockHypercertMinterUUPS();
mockHypercertMinterUUPS.setUp();
mockHypercertMinter = mockHypercertMinterUUPS.minter();

transferManager = new TransferManager(_owner);
royaltyFeeRegistry = new MockRoyaltyFeeRegistry(_owner, 9500);
Expand Down
Loading

0 comments on commit 44baf47

Please sign in to comment.