-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop-contracts' of github.com:hypercerts-org/hyperce…
…rts into develop-contracts
- Loading branch information
Showing
128 changed files
with
15,972 additions
and
3,864 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,26 @@ | ||
# Full reference https://github.com/foundry-rs/foundry/tree/master/config | ||
|
||
[profile.default] | ||
auto_detect_solc = false | ||
auto_detect_solc = true | ||
allow_paths = ["../node_modules", "lib"] | ||
bytecode_hash = "none" | ||
force = false | ||
fuzz = { runs = 1025 } | ||
gas_reports = ["*"] | ||
libs = ["lib"] | ||
libraries = [] | ||
libs = ["node_modules", "lib"] | ||
optimizer = true | ||
optimizer_runs = 5_000 | ||
out = "out" | ||
solc = "0.8.16" | ||
src = "src" | ||
test = "test/foundry" | ||
|
||
no_match_test = "testCannotExecuteOrderIfInvalidUserGlobal" | ||
|
||
[profile.ci] | ||
fuzz = { runs = 1024 } | ||
verbosity = 1 | ||
|
||
[rpc_endpoints] | ||
mainnet = "${MAINNET_RPC_URL}" | ||
goerli = "${GOERLI_RPC_URL}" | ||
optimism = "${OPTIMISM_RPC_URL}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.17; | ||
|
||
// Shared errors | ||
import { MerkleProofTooLarge } from "./errors/SharedErrors.sol"; | ||
|
||
/** | ||
* @title BatchOrderTypehashRegistry | ||
* @notice The contract generates the batch order hash that is used to compute the digest for signature verification. | ||
* @author LooksRare protocol team (👀,💎) | ||
*/ | ||
contract BatchOrderTypehashRegistry { | ||
/** | ||
* @notice This function returns the hash of the concatenation of batch order type hash and merkle root. | ||
* @param root Merkle root | ||
* @param proofLength Merkle proof length | ||
* @return batchOrderHash The batch order hash | ||
*/ | ||
function hashBatchOrder(bytes32 root, uint256 proofLength) public pure returns (bytes32 batchOrderHash) { | ||
batchOrderHash = keccak256(abi.encode(_getBatchOrderTypehash(proofLength), root)); | ||
} | ||
|
||
/** | ||
* @dev It looks like this for each height | ||
* height == 1: BatchOrder(Maker[2] tree)Maker(uint8 quoteType,uint256 globalNonce,uint256 subsetNonce,uint256 orderNonce,uint256 strategyId,uint8 collectionType,address collection,address currency,address signer,uint256 startTime,uint256 endTime,uint256 price,uint256[] itemIds,uint256[] amounts,bytes additionalParameters) | ||
* height == 2: BatchOrder(Maker[2][2] tree)Maker(uint8 quoteType,uint256 globalNonce,uint256 subsetNonce,uint256 orderNonce,uint256 strategyId,uint8 collectionType,address collection,address currency,address signer,uint256 startTime,uint256 endTime,uint256 price,uint256[] itemIds,uint256[] amounts,bytes additionalParameters) | ||
* height == n: BatchOrder(Maker[2]...[2] tree)Maker(uint8 quoteType,uint256 globalNonce,uint256 subsetNonce,uint256 orderNonce,uint256 strategyId,uint8 collectionType,address collection,address currency,address signer,uint256 startTime,uint256 endTime,uint256 price,uint256[] itemIds,uint256[] amounts,bytes additionalParameters) | ||
*/ | ||
function _getBatchOrderTypehash(uint256 height) internal pure returns (bytes32 typehash) { | ||
if (height == 1) { | ||
typehash = hex"9661287f7a4aa4867db46a2453ee15bebac4e8fc25667a58718da658f15de643"; | ||
} else if (height == 2) { | ||
typehash = hex"a54ab330ea9e1dfccee2b86f3666989e7fbd479704416c757c8de8e820142a08"; | ||
} else if (height == 3) { | ||
typehash = hex"93390f5d45ede9dea305f16aec86b2472af4f823851637f1b7019ad0775cea49"; | ||
} else if (height == 4) { | ||
typehash = hex"9dda2c8358da895e43d574bb15954ce5727b22e923a2d8f28261f297bce42f0b"; | ||
} else if (height == 5) { | ||
typehash = hex"92dc717124e161262f9d10c7079e7d54dc51271893fba54aa4a0f270fecdcc98"; | ||
} else if (height == 6) { | ||
typehash = hex"ce02aee5a7a35d40d974463c4c6e5534954fb07a7e7bc966fee268a15337bfd8"; | ||
} else if (height == 7) { | ||
typehash = hex"f7a65efd167a18f7091b2bb929d687dd94503cf0a43620487055ed7d6b727559"; | ||
} else if (height == 8) { | ||
typehash = hex"def24acacad1318b664520f7c10e8bc6d1e7f6f6f7c8b031e70624ceb42266a6"; | ||
} else if (height == 9) { | ||
typehash = hex"4cb4080dc4e7bae88b4dc4307ad5117fa4f26195998a1b5f40368809d7f4c7f2"; | ||
} else if (height == 10) { | ||
typehash = hex"f8b1f864164d8d6e0b45f1399bd711223117a4ab0b057a9c2d7779e86a7c88db"; | ||
} else { | ||
revert MerkleProofTooLarge(height); | ||
} | ||
} | ||
} |
94 changes: 94 additions & 0 deletions
94
contracts/src/marketplace/CreatorFeeManagerWithRebates.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.17; | ||
|
||
// LooksRare unopinionated libraries | ||
import { IERC2981 } from "@looksrare/contracts-libs/contracts/interfaces/generic/IERC2981.sol"; | ||
|
||
// Interfaces | ||
import { ICreatorFeeManager } from "./interfaces/ICreatorFeeManager.sol"; | ||
import { IRoyaltyFeeRegistry } from "./interfaces/IRoyaltyFeeRegistry.sol"; | ||
|
||
// Constants | ||
import { ONE_HUNDRED_PERCENT_IN_BP } from "./constants/NumericConstants.sol"; | ||
|
||
/** | ||
* @title CreatorFeeManagerWithRebates | ||
* @notice This contract returns the creator fee address and the creator rebate amount. | ||
* @author LooksRare protocol team (👀,💎) | ||
*/ | ||
contract CreatorFeeManagerWithRebates is ICreatorFeeManager { | ||
/** | ||
* @notice Standard royalty fee (in basis point). | ||
*/ | ||
uint256 public constant STANDARD_ROYALTY_FEE_BP = 50; | ||
|
||
/** | ||
* @notice Royalty fee registry interface. | ||
*/ | ||
IRoyaltyFeeRegistry public immutable royaltyFeeRegistry; | ||
|
||
/** | ||
* @notice Constructor | ||
* @param _royaltyFeeRegistry Royalty fee registry address. | ||
*/ | ||
constructor(address _royaltyFeeRegistry) { | ||
royaltyFeeRegistry = IRoyaltyFeeRegistry(_royaltyFeeRegistry); | ||
} | ||
|
||
/** | ||
* @inheritdoc ICreatorFeeManager | ||
*/ | ||
function viewCreatorFeeInfo( | ||
address collection, | ||
uint256 price, | ||
uint256[] memory itemIds | ||
) external view returns (address creator, uint256 creatorFeeAmount) { | ||
// Check if there is a royalty info in the system | ||
(creator, ) = royaltyFeeRegistry.royaltyInfo(collection, price); | ||
|
||
if (creator == address(0)) { | ||
if (IERC2981(collection).supportsInterface(IERC2981.royaltyInfo.selector)) { | ||
uint256 length = itemIds.length; | ||
|
||
for (uint256 i; i < length; ) { | ||
try IERC2981(collection).royaltyInfo(itemIds[i], price) returns ( | ||
address newCreator, | ||
uint256 /* newCreatorFeeAmount */ | ||
) { | ||
if (i == 0) { | ||
creator = newCreator; | ||
|
||
unchecked { | ||
++i; | ||
} | ||
continue; | ||
} | ||
|
||
if (newCreator != creator) { | ||
revert BundleEIP2981NotAllowed(collection); | ||
} | ||
} catch { | ||
// If creator address is not 0, that means there was at least 1 | ||
// successful call. If all royaltyInfo calls fail, it should assume | ||
// 0 royalty. | ||
// If the first call reverts, even if creator is address(0), subsequent | ||
// successful calls will still revert above with BundleEIP2981NotAllowed | ||
// because newCreator will be different from creator. | ||
if (creator != address(0)) { | ||
revert BundleEIP2981NotAllowed(collection); | ||
} | ||
} | ||
|
||
unchecked { | ||
++i; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// A fixed royalty fee is applied | ||
if (creator != address(0)) { | ||
creatorFeeAmount = (STANDARD_ROYALTY_FEE_BP * price) / ONE_HUNDRED_PERCENT_IN_BP; | ||
} | ||
} | ||
} |
Oops, something went wrong.