Skip to content

Commit

Permalink
Direct Hypercert fraction sale (#1142)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
bitbeckers authored Nov 3, 2023
1 parent d01c7b0 commit 32c2e3f
Show file tree
Hide file tree
Showing 15 changed files with 1,386 additions and 46 deletions.
5 changes: 0 additions & 5 deletions .github/workflows/ci-default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ env:
on:
# A push occurs to one of the matched branches.
push:
pull_request:
branches:
- main
- develop
- develop-contracts
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

Expand Down
2 changes: 1 addition & 1 deletion contracts/.solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"no-console": "off",
"no-empty-blocks": "off",
"not-rely-on-time": "off",
"private-vars-leading-underscore": "warn",
"private-vars-leading-underscore": ["off", { "strict": false }],
"reason-string": ["warn", { "maxLength": 64 }],
"one-contract-per-file": "off"
}
Expand Down
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
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 32c2e3f

Please sign in to comment.