编译器
0.8.17+commit.8df45f5f
文件 1 的 21:AddressUpgradeable.sol
pragma solidity ^0.8.1;
library AddressUpgradeable {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 21:Constants.sol
pragma solidity ^0.8.13;
address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;
文件 3 的 21:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 21:ERC1155.sol
pragma solidity >=0.8.0;
abstract contract ERC1155 {
event TransferSingle(
address indexed operator,
address indexed from,
address indexed to,
uint256 id,
uint256 amount
);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] amounts
);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
mapping(address => mapping(uint256 => uint256)) public balanceOf;
mapping(address => mapping(address => bool)) public isApprovedForAll;
function uri(uint256 id) public view virtual returns (string memory);
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) public virtual {
require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");
balanceOf[from][id] -= amount;
balanceOf[to][id] += amount;
emit TransferSingle(msg.sender, from, to, id, amount);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) ==
ERC1155TokenReceiver.onERC1155Received.selector,
"UNSAFE_RECIPIENT"
);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) public virtual {
require(ids.length == amounts.length, "LENGTH_MISMATCH");
require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");
uint256 id;
uint256 amount;
for (uint256 i = 0; i < ids.length; ) {
id = ids[i];
amount = amounts[i];
balanceOf[from][id] -= amount;
balanceOf[to][id] += amount;
unchecked {
++i;
}
}
emit TransferBatch(msg.sender, from, to, ids, amounts);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) ==
ERC1155TokenReceiver.onERC1155BatchReceived.selector,
"UNSAFE_RECIPIENT"
);
}
function balanceOfBatch(address[] calldata owners, uint256[] calldata ids)
public
view
virtual
returns (uint256[] memory balances)
{
require(owners.length == ids.length, "LENGTH_MISMATCH");
balances = new uint256[](owners.length);
unchecked {
for (uint256 i = 0; i < owners.length; ++i) {
balances[i] = balanceOf[owners[i]][ids[i]];
}
}
}
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 ||
interfaceId == 0xd9b67a26 ||
interfaceId == 0x0e89341c;
}
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
balanceOf[to][id] += amount;
emit TransferSingle(msg.sender, address(0), to, id, amount);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) ==
ERC1155TokenReceiver.onERC1155Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _batchMint(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
uint256 idsLength = ids.length;
require(idsLength == amounts.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < idsLength; ) {
balanceOf[to][ids[i]] += amounts[i];
unchecked {
++i;
}
}
emit TransferBatch(msg.sender, address(0), to, ids, amounts);
require(
to.code.length == 0
? to != address(0)
: ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) ==
ERC1155TokenReceiver.onERC1155BatchReceived.selector,
"UNSAFE_RECIPIENT"
);
}
function _batchBurn(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
uint256 idsLength = ids.length;
require(idsLength == amounts.length, "LENGTH_MISMATCH");
for (uint256 i = 0; i < idsLength; ) {
balanceOf[from][ids[i]] -= amounts[i];
unchecked {
++i;
}
}
emit TransferBatch(msg.sender, from, address(0), ids, amounts);
}
function _burn(
address from,
uint256 id,
uint256 amount
) internal virtual {
balanceOf[from][id] -= amount;
emit TransferSingle(msg.sender, from, address(0), id, amount);
}
}
abstract contract ERC1155TokenReceiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) external virtual returns (bytes4) {
return ERC1155TokenReceiver.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external virtual returns (bytes4) {
return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
}
文件 5 的 21:ERC1155Holder.sol
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
contract ERC1155Holder is ERC1155Receiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}
文件 6 的 21:ERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
}
文件 7 的 21:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 8 的 21:ERC2981.sol
pragma solidity ^0.8.0;
import "../../interfaces/IERC2981.sol";
import "../../utils/introspection/ERC165.sol";
abstract contract ERC2981 is IERC2981, ERC165 {
struct RoyaltyInfo {
address receiver;
uint96 royaltyFraction;
}
RoyaltyInfo private _defaultRoyaltyInfo;
mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
}
function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {
RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];
if (royalty.receiver == address(0)) {
royalty = _defaultRoyaltyInfo;
}
uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();
return (royalty.receiver, royaltyAmount);
}
function _feeDenominator() internal pure virtual returns (uint96) {
return 10000;
}
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
require(receiver != address(0), "ERC2981: invalid receiver");
_defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
}
function _deleteDefaultRoyalty() internal virtual {
delete _defaultRoyaltyInfo;
}
function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {
require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
require(receiver != address(0), "ERC2981: Invalid parameters");
_tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
}
function _resetTokenRoyalty(uint256 tokenId) internal virtual {
delete _tokenRoyaltyInfo[tokenId];
}
}
文件 9 的 21:FellowshipPrintDeeds.sol
pragma solidity ^0.8.17;
import "./ERC1155.sol";
import "./interfaces/IDeedAuthorizer.sol";
import "./interfaces/IFPD.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/token/common/ERC2981.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "operator-filter-registry/src/upgradeable/RevokableDefaultOperatorFiltererUpgradeable.sol";
contract FellowshipPrintDeeds is
IFPD, RevokableDefaultOperatorFiltererUpgradeable, ERC2981, ERC1155Holder, ERC1155, Pausable, Ownable {
string public constant name = "Fellowship Print Deeds";
string public constant symbol = "FPD";
mapping(address => CollectionInfo) private _collectionInfo;
mapping(address => RoyaltyInfo) public collectionToRoyaltyInfo;
mapping(uint256 => uint256) public deedsClaimed;
address public printFactory = 0x11F32c8d5Ad08f844CA2E95f6ffE66E5Cd74457D;
address public uriDelegate;
function supportsInterface(
bytes4 interfaceId
) public view virtual override(ERC1155, ERC1155Receiver, ERC2981) returns (bool) {
return super.supportsInterface(interfaceId);
}
function addCollection(
address collection,
uint256 collectionStartId,
uint256 collectionSupply,
uint256 editionSize,
address royaltyRecipient,
address authorizer
) external onlyOwner {
require(_collectionInfo[collection].editionSize == 0);
require(editionSize > 0 && royaltyRecipient != address(0) && authorizer != address(0));
uint256[] memory deedIds = new uint256[](collectionSupply);
uint256[] memory amounts = new uint256[](collectionSupply);
uint256 upperLimit = collectionStartId + collectionSupply;
for (uint256 i = collectionStartId; i < upperLimit; ++i) {
deedIds[i] = artTokentoDeedId(collection, i);
amounts[i] = editionSize;
}
_collectionInfo[collection] = CollectionInfo(
authorizer, uint96(collectionStartId), uint96(collectionSupply), uint96(editionSize)
);
updateRoyalties(collection, royaltyRecipient, 500);
emit TransferBatch(msg.sender, address(0), address(this), deedIds, amounts);
}
function extendCollection(
address collection,
uint256 additionalSupply
) external onlyOwner {
CollectionInfo storage cInfo = _collectionInfo[collection];
require(cInfo.editionSize > 0);
uint256[] memory deedIds = new uint256[](additionalSupply);
uint256[] memory amounts = new uint256[](additionalSupply);
uint256 start = cInfo.startId + cInfo.supply;
uint256 upperLimit = start + additionalSupply;
uint256 editionSize = cInfo.editionSize;
for (uint256 i = start; i < upperLimit; ++i) {
deedIds[i] = artTokentoDeedId(collection, i);
amounts[i] = editionSize;
}
cInfo.supply += uint96(additionalSupply);
emit TransferBatch(msg.sender, address(0), address(this), deedIds, amounts);
}
function increaseEditions(
address collection,
uint256 additionalEditions
) external onlyOwner {
CollectionInfo storage cInfo = _collectionInfo[collection];
require(cInfo.editionSize > 0);
uint256 supply = cInfo.supply;
uint256[] memory deedIds = new uint256[](supply);
uint256[] memory amounts = new uint256[](supply);
uint256 start = cInfo.startId;
uint256 upperLimit = start + supply;
for (uint256 i = start; i < upperLimit; ++i) {
deedIds[i] = artTokentoDeedId(collection, i);
amounts[i] = additionalEditions;
}
cInfo.editionSize += uint96(additionalEditions);
emit TransferBatch(msg.sender, address(0), address(this), deedIds, amounts);
}
function pauseClaims() external onlyOwner {
_pause();
}
function resumeClaims() external onlyOwner {
_unpause();
}
function updateCollectionAuth(
address collection,
address authorizer
) external onlyOwner {
_collectionInfo[collection].authorizer = authorizer;
}
function updatePrintFactory(
address factory
) external onlyOwner {
printFactory = factory;
}
function updateRoyalties(
address collection,
address recipient,
uint256 royaltyBps
) public onlyOwner {
collectionToRoyaltyInfo[collection] = RoyaltyInfo(recipient, uint96(royaltyBps));
}
function updateUriDelegate(
address newUriDelegate
) external onlyOwner {
uriDelegate = newUriDelegate;
}
function royaltyInfo(
uint256 tokenId,
uint256 salePrice
) public view virtual override returns (address, uint256) {
address collection = getCollectionFromDeedId(tokenId);
RoyaltyInfo memory royalty = collectionToRoyaltyInfo[collection];
uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();
return (royalty.receiver, royaltyAmount);
}
function claimDeeds(
address[] calldata collections,
uint256[] calldata ids
) external {
_claim(collections, ids, msg.sender);
}
function claimDeedsTo(
address[] calldata collections,
uint256[] calldata ids,
address to
) external {
_claim(collections, ids, to);
}
function claimPrintsDirectly(
address[] calldata collections,
uint256[] calldata ids
) external {
_claim(collections, ids, printFactory);
}
function claimDeedsPartial(
address[] calldata collections,
uint256[] calldata ids,
uint256[] calldata amounts
) external {
_claimPartial(collections, ids, amounts, msg.sender);
}
function claimDeedsPartialTo(
address[] calldata collections,
uint256[] calldata ids,
uint256[] calldata amounts,
address to
) external {
_claimPartial(collections, ids, amounts, to);
}
function claimPrintsDirectlyPartial(
address[] calldata collections,
uint256[] calldata ids,
uint256[] calldata amounts
) external {
_claimPartial(collections, ids, amounts, printFactory);
}
function _claim(
address[] calldata collections,
uint256[] calldata ids,
address target
) internal whenNotPaused {
require(collections.length == ids.length && collections.length > 0);
uint256[] memory deedIds = new uint256[](collections.length);
uint256[] memory amounts = new uint256[](collections.length);
for (uint256 i; i < collections.length; ++i) {
CollectionInfo memory cInfo = _collectionInfo[collections[i]];
require(cInfo.editionSize > 0);
require(ids[i] >= cInfo.startId && ids[i] < cInfo.startId + cInfo.supply);
uint256 deedId = artTokentoDeedId(collections[i], ids[i]);
uint256 deedsLeft = cInfo.editionSize - deedsClaimed[deedId];
require(deedsLeft > 0);
deedIds[i] = deedId;
amounts[i] = deedsLeft;
balanceOf[target][deedId] += deedsLeft;
deedsClaimed[deedId] += deedsLeft;
emit URI("", deedId);
require(IDeedAuthorizer(
cInfo.authorizer
).isAuthedForDeeds(msg.sender, collections[i], ids[i], amounts[i]));
}
emit TransferBatch(msg.sender, address(this), target, deedIds, amounts);
}
function _claimPartial(
address[] calldata collections,
uint256[] calldata ids,
uint256[] calldata amounts,
address target
) internal whenNotPaused {
require(collections.length == ids.length && ids.length == amounts.length && collections.length > 0);
uint256[] memory deedIds = new uint256[](collections.length);
for (uint256 i; i < collections.length; ++i) {
CollectionInfo memory cInfo = _collectionInfo[collections[i]];
require(cInfo.editionSize > 0);
require(ids[i] >= cInfo.startId && ids[i] < cInfo.startId + cInfo.supply);
uint256 deedId = artTokentoDeedId(collections[i], ids[i]);
require(amounts[i] > 0);
require(amounts[i] <= cInfo.editionSize - deedsClaimed[deedId]);
deedIds[i] = deedId;
balanceOf[target][deedId] += amounts[i];
deedsClaimed[deedId] += amounts[i];
emit URI("", deedId);
require(IDeedAuthorizer(
cInfo.authorizer
).isAuthedForDeeds(msg.sender, collections[i], ids[i], amounts[i]));
}
emit TransferBatch(msg.sender, address(this), target, deedIds, amounts);
}
function artTokentoDeedId(
address collection,
uint256 id
) public pure returns (uint256) {
return (uint256(uint160(collection)) << 96) | uint96(id);
}
function collectionInfo(address collection) external view returns (CollectionInfo memory) {
return _collectionInfo[collection];
}
function deedsLeftToClaim(
address collection,
uint256 id
) external view returns (uint256) {
return _collectionInfo[collection].editionSize - deedsClaimed[artTokentoDeedId(collection, id)];
}
function getCollectionFromDeedId(
uint256 deedId
) public pure returns (address) {
return address(uint160(deedId >> 96));
}
function getArtTokenIdFromDeedId(
uint256 deedId
) public pure returns (uint256) {
return uint256(uint96(deedId));
}
function owner() public view virtual override(Ownable, RevokableOperatorFiltererUpgradeable) returns (address) {
return Ownable.owner();
}
function setApprovalForAll(
address operator,
bool approved
) public override onlyAllowedOperatorApproval(operator) {
super.setApprovalForAll(operator, approved);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
uint256 amount,
bytes calldata data
) public override onlyAllowedOperator(from) {
super.safeTransferFrom(from, to, tokenId, amount, data);
if (to == printFactory) {
emit URI("", tokenId);
}
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) public virtual override onlyAllowedOperator(from) {
super.safeBatchTransferFrom(from, to, ids, amounts, data);
if (to == printFactory) {
for (uint256 i; i < ids.length; ++i) {
emit URI("", ids[i]);
}
}
}
function uri(
uint256 id
) public view override returns (string memory) {
return ERC1155(uriDelegate).uri(id);
}
function onERC1155Received(
address,
address from,
uint256 id,
uint256 amount,
bytes memory
) public virtual override returns (bytes4) {
require(msg.sender == address(this));
balanceOf[address(this)][id] = 0;
deedsClaimed[id] -= amount;
emit URI("", id);
address collection = getCollectionFromDeedId(id);
uint256 tokenId = getArtTokenIdFromDeedId(id);
require(IDeedAuthorizer(_collectionInfo[collection].authorizer).deedsMerged(
from,
collection,
tokenId,
amount
));
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address from,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory
) public virtual override returns (bytes4) {
require(msg.sender == address(this));
for (uint256 i; i < ids.length; ++i) {
balanceOf[address(this)][ids[i]] = 0;
deedsClaimed[ids[i]] -= amounts[i];
emit URI("", ids[i]);
address collection = getCollectionFromDeedId(ids[i]);
uint256 tokenId = getArtTokenIdFromDeedId(ids[i]);
require(IDeedAuthorizer(_collectionInfo[collection].authorizer).deedsMerged(
from,
collection,
tokenId,
amounts[i]
));
}
return this.onERC1155BatchReceived.selector;
}
function burnDeeds(
uint256[] calldata ids,
uint256[] calldata amounts
) external {
require(msg.sender == printFactory);
require(ids.length == amounts.length);
for (uint256 i = 0; i < ids.length; ++i) {
balanceOf[msg.sender][ids[i]] -= amounts[i];
balanceOf[address(0)][ids[i]] += amounts[i];
}
emit TransferBatch(msg.sender, msg.sender, address(0), ids, amounts);
}
}
文件 10 的 21:IDeedAuthorizer.sol
pragma solidity ^0.8.17;
interface IDeedAuthorizer {
function isAuthedForDeeds(
address claimant,
address collection,
uint256 tokenId,
uint256 amount
) external returns (bool);
function deedsMerged(
address returnee,
address collection,
uint256 tokenId,
uint256 amount
) external returns (bool);
}
文件 11 的 21:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 12 的 21:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 13 的 21:IERC2981.sol
pragma solidity ^0.8.0;
import "../utils/introspection/IERC165.sol";
interface IERC2981 is IERC165 {
function royaltyInfo(
uint256 tokenId,
uint256 salePrice
) external view returns (address receiver, uint256 royaltyAmount);
}
文件 14 的 21:IFPD.sol
pragma solidity ^0.8.17;
interface IFPD {
struct CollectionInfo {
address authorizer;
uint96 startId;
uint96 supply;
uint96 editionSize;
}
function collectionInfo(address) external view returns (CollectionInfo memory);
function deedsClaimed(uint256) external view returns (uint256);
function getArtTokenIdFromDeedId(uint256) external view returns (uint256);
function getCollectionFromDeedId(uint256) external view returns (address);
function printFactory() external view returns (address);
}
文件 15 的 21:IOperatorFilterRegistry.sol
pragma solidity ^0.8.13;
interface IOperatorFilterRegistry {
function isOperatorAllowed(address registrant, address operator) external view returns (bool);
function register(address registrant) external;
function registerAndSubscribe(address registrant, address subscription) external;
function registerAndCopyEntries(address registrant, address registrantToCopy) external;
function unregister(address addr) external;
function updateOperator(address registrant, address operator, bool filtered) external;
function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
function subscribe(address registrant, address registrantToSubscribe) external;
function unsubscribe(address registrant, bool copyExistingEntries) external;
function subscriptionOf(address addr) external returns (address registrant);
function subscribers(address registrant) external returns (address[] memory);
function subscriberAt(address registrant, uint256 index) external returns (address);
function copyEntriesOf(address registrant, address registrantToCopy) external;
function isOperatorFiltered(address registrant, address operator) external returns (bool);
function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
function filteredOperators(address addr) external returns (address[] memory);
function filteredCodeHashes(address addr) external returns (bytes32[] memory);
function filteredOperatorAt(address registrant, uint256 index) external returns (address);
function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
function isRegistered(address addr) external returns (bool);
function codeHashOf(address addr) external returns (bytes32);
}
文件 16 的 21:Initializable.sol
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
abstract contract Initializable {
uint8 private _initialized;
bool private _initializing;
event Initialized(uint8 version);
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}
文件 17 的 21:OperatorFiltererUpgradeable.sol
pragma solidity ^0.8.13;
import {IOperatorFilterRegistry} from "../IOperatorFilterRegistry.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
abstract contract OperatorFiltererUpgradeable is Initializable {
error OperatorNotAllowed(address operator);
IOperatorFilterRegistry constant OPERATOR_FILTER_REGISTRY =
IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);
function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe)
internal
onlyInitializing
{
if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
if (!OPERATOR_FILTER_REGISTRY.isRegistered(address(this))) {
if (subscribe) {
OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
} else {
if (subscriptionOrRegistrantToCopy != address(0)) {
OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
} else {
OPERATOR_FILTER_REGISTRY.register(address(this));
}
}
}
}
}
modifier onlyAllowedOperator(address from) virtual {
if (from != msg.sender) {
_checkFilterOperator(msg.sender);
}
_;
}
modifier onlyAllowedOperatorApproval(address operator) virtual {
_checkFilterOperator(operator);
_;
}
function _checkFilterOperator(address operator) internal view virtual {
if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
revert OperatorNotAllowed(operator);
}
}
}
}
文件 18 的 21:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 19 的 21:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 20 的 21:RevokableDefaultOperatorFiltererUpgradeable.sol
pragma solidity ^0.8.13;
import {RevokableOperatorFiltererUpgradeable} from "./RevokableOperatorFiltererUpgradeable.sol";
import {CANONICAL_CORI_SUBSCRIPTION} from "../lib/Constants.sol";
abstract contract RevokableDefaultOperatorFiltererUpgradeable is RevokableOperatorFiltererUpgradeable {
function __RevokableDefaultOperatorFilterer_init() internal onlyInitializing {
RevokableOperatorFiltererUpgradeable.__RevokableOperatorFilterer_init(CANONICAL_CORI_SUBSCRIPTION, true);
}
}
文件 21 的 21:RevokableOperatorFiltererUpgradeable.sol
pragma solidity ^0.8.13;
import {OperatorFiltererUpgradeable} from "./OperatorFiltererUpgradeable.sol";
library RevokableOperatorFiltererUpgradeableStorage {
struct Layout {
bool _isOperatorFilterRegistryRevoked;
}
bytes32 internal constant STORAGE_SLOT = keccak256("RevokableOperatorFiltererUpgradeable.contracts.storage");
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}
abstract contract RevokableOperatorFiltererUpgradeable is OperatorFiltererUpgradeable {
using RevokableOperatorFiltererUpgradeableStorage for RevokableOperatorFiltererUpgradeableStorage.Layout;
error OnlyOwner();
error AlreadyRevoked();
event OperatorFilterRegistryRevoked();
function __RevokableOperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal {
OperatorFiltererUpgradeable.__OperatorFilterer_init(subscriptionOrRegistrantToCopy, subscribe);
}
function _checkFilterOperator(address operator) internal view virtual override {
if (
!RevokableOperatorFiltererUpgradeableStorage.layout()._isOperatorFilterRegistryRevoked
&& address(OPERATOR_FILTER_REGISTRY).code.length > 0
) {
if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
revert OperatorNotAllowed(operator);
}
}
}
function revokeOperatorFilterRegistry() external {
if (msg.sender != owner()) {
revert OnlyOwner();
}
if (RevokableOperatorFiltererUpgradeableStorage.layout()._isOperatorFilterRegistryRevoked) {
revert AlreadyRevoked();
}
RevokableOperatorFiltererUpgradeableStorage.layout()._isOperatorFilterRegistryRevoked = true;
emit OperatorFilterRegistryRevoked();
}
function isOperatorFilterRegistryRevoked() public view returns (bool) {
return RevokableOperatorFiltererUpgradeableStorage.layout()._isOperatorFilterRegistryRevoked;
}
function owner() public view virtual returns (address);
}
{
"compilationTarget": {
"FellowshipPrintDeeds.sol": "FellowshipPrintDeeds"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"name":"AlreadyRevoked","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[],"name":"OperatorFilterRegistryRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"collectionStartId","type":"uint256"},{"internalType":"uint256","name":"collectionSupply","type":"uint256"},{"internalType":"uint256","name":"editionSize","type":"uint256"},{"internalType":"address","name":"royaltyRecipient","type":"address"},{"internalType":"address","name":"authorizer","type":"address"}],"name":"addCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"artTokentoDeedId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"burnDeeds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"collections","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"claimDeeds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"collections","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"claimDeedsPartial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"collections","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"claimDeedsPartialTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"collections","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"claimDeedsTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"collections","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"claimPrintsDirectly","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"collections","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"claimPrintsDirectlyPartial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"collectionInfo","outputs":[{"components":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"uint96","name":"startId","type":"uint96"},{"internalType":"uint96","name":"supply","type":"uint96"},{"internalType":"uint96","name":"editionSize","type":"uint96"}],"internalType":"struct IFPD.CollectionInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"collectionToRoyaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"royaltyFraction","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deedsClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"deedsLeftToClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"additionalSupply","type":"uint256"}],"name":"extendCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"deedId","type":"uint256"}],"name":"getArtTokenIdFromDeedId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"deedId","type":"uint256"}],"name":"getCollectionFromDeedId","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"additionalEditions","type":"uint256"}],"name":"increaseEditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOperatorFilterRegistryRevoked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseClaims","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"printFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resumeClaims","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeOperatorFilterRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"authorizer","type":"address"}],"name":"updateCollectionAuth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"factory","type":"address"}],"name":"updatePrintFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"royaltyBps","type":"uint256"}],"name":"updateRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newUriDelegate","type":"address"}],"name":"updateUriDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uriDelegate","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]