编译器
0.8.23+commit.f704f362
文件 1 的 19:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 2 的 19:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 3 的 19:IERC5192.sol
pragma solidity ^0.8.23;
interface IERC5192 {
event Locked(uint256 indexed tokenId);
event Unlocked(uint256 indexed tokenId);
function locked(uint256 tokenId) external view returns (bool);
}
文件 4 的 19:IERC721.sol
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 5 的 19:IPatchwork1155Patch.sol
pragma solidity ^0.8.23;
import "./IPatchworkScoped.sol";
interface IPatchwork1155Patch is IPatchworkScoped {
struct PatchTarget {
address addr;
uint256 tokenId;
address account;
}
function mintPatch(address to, PatchTarget memory target) external payable returns (uint256 tokenId);
}
interface IPatchworkReversible1155Patch is IPatchwork1155Patch {
function getTokenIdByTarget(PatchTarget memory target) external returns (uint256 tokenId);
}
文件 6 的 19:IPatchwork721.sol
pragma solidity ^0.8.23;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./IERC5192.sol";
import "./IPatchworkScoped.sol";
interface IPatchworkMetadata {
enum FieldType {
BOOLEAN,
INT8,
INT16,
INT32,
INT64,
INT128,
INT256,
UINT8,
UINT16,
UINT32,
UINT64,
UINT128,
UINT256,
CHAR8,
CHAR16,
CHAR32,
CHAR64,
LITEREF
}
struct MetadataSchema {
uint256 version;
MetadataSchemaEntry[] entries;
}
struct MetadataSchemaEntry {
uint256 id;
uint256 permissionId;
FieldType fieldType;
uint256 fieldCount;
FieldVisibility visibility;
uint256 slot;
uint256 offset;
string key;
}
enum FieldVisibility {
PUBLIC,
PRIVATE
}
}
interface IPatchwork721 is IPatchworkScoped, IPatchworkMetadata, IERC5192, IERC721 {
event Frozen(uint256 indexed tokenId);
event Thawed(uint256 indexed tokenId);
event PermissionChange(address indexed to, uint256 permissions);
event SchemaChange(address indexed addr);
function schemaURI() external view returns (string memory);
function schema() external view returns (MetadataSchema memory);
function imageURI(uint256 tokenId) external view returns (string memory);
function setPermissions(address to, uint256 permissions) external;
function storePackedMetadataSlot(uint256 tokenId, uint256 slot, uint256 data) external;
function storePackedMetadata(uint256 tokenId, uint256[] memory data) external;
function loadPackedMetadataSlot(uint256 tokenId, uint256 slot) external view returns (uint256);
function loadPackedMetadata(uint256 tokenId) external view returns (uint256[] memory);
function getFreezeNonce(uint256 tokenId) external view returns (uint256 nonce);
function setFrozen(uint256 tokenId, bool frozen) external;
function frozen(uint256 tokenId) external view returns (bool);
function setLocked(uint256 tokenId, bool locked) external;
}
文件 7 的 19:IPatchworkAccountPatch.sol
pragma solidity ^0.8.23;
import "./IPatchworkScoped.sol";
interface IPatchworkAccountPatch is IPatchworkScoped {
function mintPatch(address owner, address target) external payable returns (uint256 tokenId);
}
interface IPatchworkReversibleAccountPatch is IPatchworkAccountPatch {
function getTokenIdByTarget(address target) external returns (uint256 tokenId);
}
文件 8 的 19:IPatchworkAssignable.sol
pragma solidity ^0.8.23;
import "./IPatchworkScoped.sol";
interface IPatchworkAssignable is IPatchworkScoped {
struct Assignment {
address tokenAddr;
uint256 tokenId;
}
function assign(uint256 ourTokenId, address to, uint256 tokenId) external;
function allowAssignment(uint256 ourTokenId, address target, uint256 targetTokenId, address targetOwner, address by, string memory scopeName) external view returns (bool);
}
文件 9 的 19:IPatchworkLiteRef.sol
pragma solidity ^0.8.23;
interface IPatchworkLiteRef {
event Redact(address indexed target, address indexed fragment);
event Unredact(address indexed target, address indexed fragment);
event Register(address indexed target, address indexed fragment, uint8 idx);
function registerReferenceAddress(address addr) external returns (uint8 id);
function getReferenceId(address addr) external view returns (uint8 id, bool redacted);
function getReferenceAddress(uint8 id) external view returns (address addr, bool redacted);
function redactReferenceAddress(uint8 id) external;
function unredactReferenceAddress(uint8 id) external;
function getLiteReference(address addr, uint256 tokenId) external view returns (uint64 liteRef, bool redacted);
function getReferenceAddressAndTokenId(uint64 liteRef) external view returns (address addr, uint256 tokenId);
function addReference(uint256 tokenId, uint64 liteRef) external;
function addReference(uint256 tokenId, uint64 liteRef, uint256 targetMetadataId) external;
function addReferenceBatch(uint256 tokenId, uint64[] calldata liteRefs) external;
function addReferenceBatch(uint256 tokenId, uint64[] calldata liteRefs, uint256 targetMetadataId) external;
function removeReference(uint256 tokenId, uint64 liteRef) external;
function removeReference(uint256 tokenId, uint64 liteRef, uint256 targetMetadataId) external;
function loadReferenceAddressAndTokenId(uint256 ourTokenId, uint256 idx) external view returns (address addr, uint256 tokenId);
function loadAllStaticReferences(uint256 tokenId) external view returns (address[] memory addresses, uint256[] memory tokenIds);
function getDynamicReferenceCount(uint256 tokenId) external view returns (uint256 count);
function loadDynamicReferencePage(uint256 tokenId, uint256 offset, uint256 count) external view returns (address[] memory addresses, uint256[] memory tokenIds);
}
文件 10 的 19:IPatchworkMintable.sol
pragma solidity ^0.8.23;
import "./IPatchworkScoped.sol";
interface IPatchworkMintable is IPatchworkScoped {
function mint(address to, bytes calldata data) external payable returns (uint256 tokenId);
function mintBatch(address to, bytes calldata data, uint256 quantity) external payable returns (uint256[] memory tokenIds);
}
文件 11 的 19:IPatchworkMultiAssignable.sol
pragma solidity ^0.8.23;
import "./IPatchworkAssignable.sol";
interface IPatchworkMultiAssignable is IPatchworkAssignable {
function isAssignedTo(uint256 ourTokenId, address target, uint256 targetTokenId) external view returns (bool);
function unassign(uint256 ourTokenId, address target, uint256 targetTokenId) external;
function getAssignmentCount(uint256 tokenId) external view returns (uint256);
function getAssignments(uint256 tokenId, uint256 offset, uint256 count) external view returns (Assignment[] memory);
}
文件 12 的 19:IPatchworkPatch.sol
pragma solidity ^0.8.23;
import "./IPatchworkScoped.sol";
interface IPatchworkPatch is IPatchworkScoped {
struct PatchTarget {
address addr;
uint256 tokenId;
}
function mintPatch(address owner, PatchTarget memory target) external payable returns (uint256 tokenId);
function updateOwnership(uint256 tokenId) external;
function ownerOfPatch(uint256 tokenId) external view returns (address);
}
interface IPatchworkReversiblePatch is IPatchworkPatch {
function getTokenIdByTarget(PatchTarget memory target) external view returns (uint256 tokenId);
}
文件 13 的 19:IPatchworkProtocol.sol
pragma solidity ^0.8.23;
interface IPatchworkProtocol {
error NotAuthorized(address addr);
error ScopeExists(string scopeName);
error ScopeDoesNotExist(string scopeName);
error ScopeTransferNotAllowed(address to);
error Frozen(address addr, uint256 tokenId);
error Locked(address addr, uint256 tokenId);
error NotWhitelisted(string scopeName, address addr);
error AccountAlreadyPatched(address addr, address patchAddress);
error AlreadyPatched(address addr, uint256 tokenId, address patchAddress);
error ERC1155AlreadyPatched(address addr, uint256 tokenId, address account, address patchAddress);
error BadInputLengths();
error FragmentUnregistered(address addr);
error FragmentRedacted(address addr);
error FragmentAlreadyAssigned(address addr, uint256 tokenId);
error RefNotFound(address target, address fragment, uint256 tokenId);
error FragmentNotAssigned(address addr, uint256 tokenId);
error FragmentNotAssignedToTarget(address addr, uint256 tokenId, address targetAddress, uint256 targetTokenId);
error FragmentAlreadyRegistered(address addr);
error OutOfIDs();
error UnsupportedTokenId(uint256 tokenId);
error CannotLockSoulboundPatch(address addr);
error NotFrozen(address addr, uint256 tokenId);
error IncorrectNonce(address addr, uint256 tokenId, uint256 nonce);
error SelfAssignmentNotAllowed(address addr, uint256 tokenId);
error TransferNotAllowed(address addr, uint256 tokenId);
error TransferBlockedByAssignment(address addr, uint256 tokenId);
error MintNotAllowed(address addr);
error NotPatchworkAssignable(address addr);
error DataIntegrityError(address addr, uint256 tokenId, address addr2, uint256 tokenId2);
error InsufficientFunds();
error IncorrectFeeAmount();
error MintNotActive();
error FailedToSend();
error UnsupportedContract();
error UnsupportedOperation();
error NoProposedFeeSet();
error TimelockNotElapsed();
error InvalidFeeValue();
error NoDelegateProposed();
struct FeeConfig {
uint256 mintBp;
uint256 patchBp;
uint256 assignBp;
}
struct FeeConfigOverride {
uint256 mintBp;
uint256 patchBp;
uint256 assignBp;
bool active;
}
struct ProposedFeeConfig {
FeeConfig config;
uint256 timestamp;
bool active;
}
struct MintConfig {
uint256 flatFee;
bool active;
}
struct ProposedAssignerDelegate {
uint256 timestamp;
address addr;
}
struct Scope {
address owner;
address ownerElect;
bool allowUserPatch;
bool allowUserAssign;
bool requireWhitelist;
mapping(address => bool) operators;
mapping(address => bool) whitelist;
mapping(address => MintConfig) mintConfigurations;
mapping(address => uint256) patchFees;
mapping(address => uint256) assignFees;
uint256 balance;
mapping(address => bool) bankers;
}
event Assign(address indexed owner, address fragmentAddress, uint256 fragmentTokenId, address indexed targetAddress, uint256 indexed targetTokenId, uint256 scopeFee, uint256 protocolFee);
event Unassign(address indexed owner, address fragmentAddress, uint256 fragmentTokenId, address indexed targetAddress, uint256 indexed targetTokenId);
event Patch(address indexed owner, address originalAddress, uint256 originalTokenId, address indexed patchAddress, uint256 indexed patchTokenId, uint256 scopeFee, uint256 protocolFee);
event ERC1155Patch(address indexed owner, address originalAddress, uint256 originalTokenId, address originalAccount, address indexed patchAddress, uint256 indexed patchTokenId, uint256 scopeFee, uint256 protocolFee);
event AccountPatch(address indexed owner, address originalAddress, address indexed patchAddress, uint256 indexed patchTokenId, uint256 scopeFee, uint256 protocolFee);
event ScopeClaim(string scopeName, address indexed owner);
event ScopeTransferElect(string scopeName, address indexed from, address indexed to);
event ScopeTransferCancel(string scopeName, address indexed from, address indexed to);
event ScopeTransfer(string scopeName, address indexed from, address indexed to);
event ScopeAddOperator(string scopeName, address indexed actor, address indexed operator);
event ScopeRemoveOperator(string scopeName, address indexed actor, address indexed operator);
event ScopeRuleChange(string scopeName, address indexed actor, bool allowUserPatch, bool allowUserAssign, bool requireWhitelist);
event ScopeWhitelistAdd(string scopeName, address indexed actor, address indexed addr);
event ScopeWhitelistRemove(string scopeName, address indexed actor, address indexed addr);
event MintConfigure(string scopeName, address indexed actor, address indexed mintable, MintConfig config);
event ScopeBankerAdd(string scopeName, address indexed actor, address indexed banker);
event ScopeBankerRemove(string scopeName, address indexed actor, address indexed banker);
event ScopeWithdraw(string scopeName, address indexed actor, uint256 amount);
event ProtocolBankerAdd(address indexed actor, address indexed banker);
event ProtocolBankerRemove(address indexed actor, address indexed banker);
event ProtocolWithdraw(address indexed actor, uint256 amount);
event Mint(address indexed actor, string scopeName, address indexed to, address indexed mintable, bytes data, uint256 scopeFee, uint256 protocolFee);
event MintBatch(address indexed actor, string scopeName, address indexed to, address indexed mintable, bytes data, uint256 quantity, uint256 scopeFee, uint256 protocolFee);
event ProtocolFeeConfigPropose(FeeConfig config);
event ProtocolFeeConfigCommit(FeeConfig config);
event ScopeFeeOverridePropose(string scopeName, FeeConfigOverride config);
event ScopeFeeOverrideCommit(string scopeName, FeeConfigOverride config);
event PatchFeeChange(string scopeName, address indexed addr, uint256 fee);
event AssignFeeChange(string scopeName, address indexed addr, uint256 fee);
event AssignerDelegatePropose(address indexed addr);
event AssignerDelegateCommit(address indexed addr);
function claimScope(string calldata scopeName) external;
function transferScopeOwnership(string calldata scopeName, address newOwner) external;
function cancelScopeTransfer(string calldata scopeName) external;
function acceptScopeTransfer(string calldata scopeName) external;
function getScopeOwnerElect(string calldata scopeName) external view returns (address ownerElect);
function getScopeOwner(string calldata scopeName) external view returns (address owner);
function addOperator(string calldata scopeName, address op) external;
function removeOperator(string calldata scopeName, address op) external;
function setScopeRules(string calldata scopeName, bool allowUserPatch, bool allowUserAssign, bool requireWhitelist) external;
function addWhitelist(string calldata scopeName, address addr) external;
function removeWhitelist(string calldata scopeName, address addr) external;
function setMintConfiguration(address addr, MintConfig memory config) external;
function getMintConfiguration(address addr) external view returns (MintConfig memory config);
function setPatchFee(address addr, uint256 baseFee) external;
function getPatchFee(address addr) external view returns (uint256 baseFee);
function setAssignFee(address fragmentAddress, uint256 baseFee) external;
function getAssignFee(address fragmentAddress) external view returns (uint256 baseFee);
function addBanker(string memory scopeName, address addr) external;
function removeBanker(string memory scopeName, address addr) external;
function withdraw(string memory scopeName, uint256 amount) external;
function balanceOf(string memory scopeName) external view returns (uint256 balance);
function mint(address to, address mintable, bytes calldata data) external payable returns (uint256 tokenId);
function mintBatch(address to, address mintable, bytes calldata data, uint256 quantity) external payable returns (uint256[] memory tokenIds);
function proposeProtocolFeeConfig(FeeConfig memory config) external;
function commitProtocolFeeConfig() external;
function getProtocolFeeConfig() external view returns (FeeConfig memory config);
function proposeScopeFeeOverride(string memory scopeName, FeeConfigOverride memory config) external;
function commitScopeFeeOverride(string memory scopeName) external;
function getScopeFeeOverride(string memory scopeName) external view returns (FeeConfigOverride memory config);
function addProtocolBanker(address addr) external;
function removeProtocolBanker(address addr) external;
function withdrawFromProtocol(uint256 balance) external;
function balanceOfProtocol() external view returns (uint256 balance);
function patch(address owner, address originalAddress, uint originalTokenId, address patchAddress) external payable returns (uint256 tokenId);
function patchBurned(address originalAddress, uint originalTokenId, address patchAddress) external;
function patch1155(address to, address originalAddress, uint originalTokenId, address originalAccount, address patchAddress) external payable returns (uint256 tokenId);
function patchBurned1155(address originalAddress, uint originalTokenId, address originalAccount, address patchAddress) external;
function patchAccount(address owner, address originalAddress, address patchAddress) external payable returns (uint256 tokenId);
function patchBurnedAccount(address originalAddress, address patchAddress) external;
function assign(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId) external payable;
function assign(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId, uint256 targetMetadataId) external payable;
function assignBatch(address[] calldata fragments, uint256[] calldata tokenIds, address target, uint256 targetTokenId) external payable;
function assignBatch(address[] calldata fragments, uint256[] calldata tokenIds, address target, uint256 targetTokenId, uint256 targetMetadataId) external payable;
function unassignSingle(address fragment, uint256 fragmentTokenId) external;
function unassignSingle(address fragment, uint256 fragmentTokenId, uint256 targetMetadataId) external;
function unassignMulti(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId) external;
function unassignMulti(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId, uint256 targetMetadataId) external;
function unassign(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId) external;
function unassign(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId, uint256 targetMetadataId) external;
function applyTransfer(address from, address to, uint256 tokenId) external;
function updateOwnershipTree(address addr, uint256 tokenId) external;
function proposeAssignerDelegate(address addr) external;
function commitAssignerDelegate() external;
}
文件 14 的 19:IPatchworkScoped.sol
pragma solidity ^0.8.23;
interface IPatchworkScoped {
function getScopeName() external view returns (string memory);
}
文件 15 的 19:IPatchworkSingleAssignable.sol
pragma solidity ^0.8.23;
import "./IPatchworkAssignable.sol";
interface IPatchworkSingleAssignable is IPatchworkAssignable {
function unassign(uint256 ourTokenId) external;
function getAssignedTo(uint256 ourTokenId) external view returns (address, uint256);
function unassignedOwnerOf(uint256 ourTokenId) external view returns (address);
function onAssignedTransfer(address from, address to, uint256 tokenId) external;
function updateOwnership(uint256 tokenId) external;
}
文件 16 的 19:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 17 的 19:PatchworkProtocol.sol
pragma solidity ^0.8.23;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./PatchworkProtocolCommon.sol";
import "./interfaces/IPatchwork721.sol";
import "./interfaces/IPatchworkSingleAssignable.sol";
import "./interfaces/IPatchworkMultiAssignable.sol";
import "./interfaces/IPatchworkLiteRef.sol";
import "./interfaces/IPatchworkPatch.sol";
import "./interfaces/IPatchwork1155Patch.sol";
import "./interfaces/IPatchworkAccountPatch.sol";
import "./interfaces/IPatchworkProtocol.sol";
import "./interfaces/IPatchworkMintable.sol";
import "./interfaces/IPatchworkScoped.sol";
contract PatchworkProtocol is IPatchworkProtocol, PatchworkProtocolCommon {
uint256 public constant FEE_CHANGE_TIMELOCK = 1209600;
uint256 public constant CONTRACT_UPGRADE_TIMELOCK = 1209600;
uint256 private constant _FEE_BASIS_DENOM = 10000;
uint256 private constant _PROTOCOL_FEE_CEILING = 3000;
constructor(address owner_, address assignerDelegate_) PatchworkProtocolCommon(owner_) {
_assignerDelegate = assignerDelegate_;
}
function claimScope(string calldata scopeName) public {
if (bytes(scopeName).length == 0) {
revert NotAuthorized(msg.sender);
}
Scope storage s = _scopes[scopeName];
if (s.owner != address(0)) {
revert ScopeExists(scopeName);
}
s.owner = msg.sender;
s.requireWhitelist = true;
emit ScopeClaim(scopeName, msg.sender);
}
function transferScopeOwnership(string calldata scopeName, address newOwner) public {
Scope storage s = _mustHaveScope(scopeName);
_mustBeOwner(s);
if (newOwner == address(0)) {
revert ScopeTransferNotAllowed(address(0));
}
s.ownerElect = newOwner;
emit ScopeTransferElect(scopeName, s.owner, s.ownerElect);
}
function cancelScopeTransfer(string calldata scopeName) public {
Scope storage s = _mustHaveScope(scopeName);
_mustBeOwner(s);
emit ScopeTransferCancel(scopeName, s.owner, s.ownerElect);
s.ownerElect = address(0);
}
function acceptScopeTransfer(string calldata scopeName) public {
Scope storage s = _mustHaveScope(scopeName);
if (s.ownerElect == msg.sender) {
address oldOwner = s.owner;
s.owner = msg.sender;
s.ownerElect = address(0);
emit ScopeTransfer(scopeName, oldOwner, msg.sender);
} else {
revert NotAuthorized(msg.sender);
}
}
function getScopeOwnerElect(string calldata scopeName) public view returns (address ownerElect) {
return _scopes[scopeName].ownerElect;
}
function getScopeOwner(string calldata scopeName) public view returns (address owner) {
return _scopes[scopeName].owner;
}
function addOperator(string calldata scopeName, address op) public {
Scope storage s = _mustHaveScope(scopeName);
_mustBeOwner(s);
s.operators[op] = true;
emit ScopeAddOperator(scopeName, msg.sender, op);
}
function removeOperator(string calldata scopeName, address op) public {
Scope storage s = _mustHaveScope(scopeName);
_mustBeOwner(s);
s.operators[op] = false;
emit ScopeRemoveOperator(scopeName, msg.sender, op);
}
function setScopeRules(string calldata scopeName, bool allowUserPatch, bool allowUserAssign, bool requireWhitelist) public {
Scope storage s = _mustHaveScope(scopeName);
_mustBeOwner(s);
s.allowUserPatch = allowUserPatch;
s.allowUserAssign = allowUserAssign;
s.requireWhitelist = requireWhitelist;
emit ScopeRuleChange(scopeName, msg.sender, allowUserPatch, allowUserAssign, requireWhitelist);
}
function setMintConfiguration(address addr, MintConfig memory config) public {
if (!IERC165(addr).supportsInterface(type(IPatchworkMintable).interfaceId)) {
revert UnsupportedContract();
}
string memory scopeName = _getScopeName(addr);
Scope storage scope = _mustHaveScope(scopeName);
_mustBeWhitelisted(scopeName, scope, addr);
_mustBeOwnerOrOperator(scope);
scope.mintConfigurations[addr] = config;
emit MintConfigure(scopeName, msg.sender, addr, config);
}
function getMintConfiguration(address addr) public view returns (MintConfig memory config) {
if (!IERC165(addr).supportsInterface(type(IPatchworkMintable).interfaceId)) {
revert UnsupportedContract();
}
Scope storage scope = _mustHaveScope(_getScopeNameViewOnly(addr));
return scope.mintConfigurations[addr];
}
function setPatchFee(address addr, uint256 baseFee) public {
if (!IERC165(addr).supportsInterface(type(IPatchworkScoped).interfaceId)) {
revert UnsupportedContract();
}
string memory scopeName = _getScopeName(addr);
Scope storage scope = _mustHaveScope(scopeName);
_mustBeWhitelisted(scopeName, scope, addr);
_mustBeOwnerOrOperator(scope);
scope.patchFees[addr] = baseFee;
emit PatchFeeChange(scopeName, addr, baseFee);
}
function getPatchFee(address addr) public view returns (uint256 baseFee) {
if (!IERC165(addr).supportsInterface(type(IPatchworkScoped).interfaceId)) {
revert UnsupportedContract();
}
Scope storage scope = _mustHaveScope(_getScopeNameViewOnly(addr));
return scope.patchFees[addr];
}
function setAssignFee(address fragmentAddress, uint256 baseFee) public {
if (!IERC165(fragmentAddress).supportsInterface(type(IPatchworkScoped).interfaceId)) {
revert UnsupportedContract();
}
string memory scopeName = _getScopeName(fragmentAddress);
Scope storage scope = _mustHaveScope(scopeName);
_mustBeWhitelisted(scopeName, scope, fragmentAddress);
_mustBeOwnerOrOperator(scope);
scope.assignFees[fragmentAddress] = baseFee;
emit AssignFeeChange(scopeName, fragmentAddress, baseFee);
}
function getAssignFee(address fragmentAddress) public view returns (uint256 baseFee) {
if (!IERC165(fragmentAddress).supportsInterface(type(IPatchworkScoped).interfaceId)) {
revert UnsupportedContract();
}
Scope storage scope = _mustHaveScope(_getScopeNameViewOnly(fragmentAddress));
return scope.assignFees[fragmentAddress];
}
function addBanker(string memory scopeName, address addr) public {
Scope storage scope = _mustHaveScope(scopeName);
_mustBeOwnerOrOperator(scope);
scope.bankers[addr] = true;
emit ScopeBankerAdd(scopeName, msg.sender, addr);
}
function removeBanker(string memory scopeName, address addr) public {
Scope storage scope = _mustHaveScope(scopeName);
_mustBeOwnerOrOperator(scope);
delete scope.bankers[addr];
emit ScopeBankerRemove(scopeName, msg.sender, addr);
}
function withdraw(string memory scopeName, uint256 amount) public nonReentrant {
Scope storage scope = _mustHaveScope(scopeName);
if (msg.sender != scope.owner && !scope.bankers[msg.sender]) {
revert NotAuthorized(msg.sender);
}
if (amount > scope.balance) {
revert InsufficientFunds();
}
scope.balance -= amount;
(bool sent,) = msg.sender.call{value: amount}("");
if (!sent) {
revert FailedToSend();
}
emit ScopeWithdraw(scopeName, msg.sender, amount);
}
function balanceOf(string memory scopeName) public view returns (uint256 balance) {
Scope storage scope = _mustHaveScope(scopeName);
return scope.balance;
}
function mint(address to, address mintable, bytes calldata data) external payable returns (uint256 tokenId) {
(MintConfig memory config, string memory scopeName, Scope storage scope) = _setupMint(mintable);
if (msg.value != config.flatFee) {
revert IncorrectFeeAmount();
}
(uint256 scopeFee, uint256 protocolFee) = _handleMintFee(scopeName, scope);
tokenId = IPatchworkMintable(mintable).mint(to, data);
emit Mint(msg.sender, scopeName, to, mintable, data, scopeFee, protocolFee);
}
function mintBatch(address to, address mintable, bytes calldata data, uint256 quantity) external payable returns (uint256[] memory tokenIds) {
(MintConfig memory config, string memory scopeName, Scope storage scope) = _setupMint(mintable);
uint256 totalFee = config.flatFee * quantity;
if (msg.value != totalFee) {
revert IncorrectFeeAmount();
}
(uint256 scopeFee, uint256 protocolFee) = _handleMintFee(scopeName, scope);
tokenIds = IPatchworkMintable(mintable).mintBatch(to, data, quantity);
emit MintBatch(msg.sender, scopeName, to, mintable, data, quantity, scopeFee, protocolFee);
}
function _setupMint(address mintable) internal view returns (MintConfig memory config, string memory scopeName, Scope storage scope) {
if (!IERC165(mintable).supportsInterface(type(IPatchworkMintable).interfaceId)) {
revert UnsupportedContract();
}
scopeName = _getScopeNameViewOnly(mintable);
scope = _mustHaveScope(scopeName);
_mustBeWhitelisted(scopeName, scope, mintable);
config = scope.mintConfigurations[mintable];
if (!config.active) {
revert MintNotActive();
}
}
function _handleMintFee(string memory scopeName, Scope storage scope) internal returns (uint256 scopeFee, uint256 protocolFee) {
if (msg.value != 0) {
uint256 mintBp;
FeeConfigOverride storage feeOverride = _scopeFeeOverrides[scopeName];
if (feeOverride.active) {
mintBp = feeOverride.mintBp;
} else {
mintBp = _protocolFeeConfig.mintBp;
}
protocolFee = msg.value * mintBp / _FEE_BASIS_DENOM;
scopeFee = msg.value - protocolFee;
_protocolBalance += protocolFee;
scope.balance += scopeFee;
}
}
function proposeProtocolFeeConfig(FeeConfig memory config) public onlyProtoOwnerBanker {
if (config.assignBp > _PROTOCOL_FEE_CEILING || config.mintBp > _PROTOCOL_FEE_CEILING || config.patchBp > _PROTOCOL_FEE_CEILING) {
revert InvalidFeeValue();
}
_proposedFeeConfigs[""] = ProposedFeeConfig(config, block.timestamp, true);
emit ProtocolFeeConfigPropose(config);
}
function commitProtocolFeeConfig() public onlyProtoOwnerBanker {
(FeeConfig memory config, ) = _preCommitFeeChange("");
_protocolFeeConfig = config;
emit ProtocolFeeConfigCommit(_protocolFeeConfig);
}
function getProtocolFeeConfig() public view returns (FeeConfig memory config) {
return _protocolFeeConfig;
}
function proposeScopeFeeOverride(string memory scopeName, FeeConfigOverride memory config) public onlyProtoOwnerBanker {
if (config.assignBp > _PROTOCOL_FEE_CEILING || config.mintBp > _PROTOCOL_FEE_CEILING || config.patchBp > _PROTOCOL_FEE_CEILING) {
revert InvalidFeeValue();
}
_proposedFeeConfigs[scopeName] = ProposedFeeConfig(
FeeConfig(config.mintBp, config.patchBp, config.assignBp), block.timestamp, config.active);
emit ScopeFeeOverridePropose(scopeName, config);
}
function commitScopeFeeOverride(string memory scopeName) public onlyProtoOwnerBanker {
(FeeConfig memory config, bool active) = _preCommitFeeChange(scopeName);
FeeConfigOverride memory feeOverride = FeeConfigOverride(config.mintBp, config.patchBp, config.assignBp, active);
if (!active) {
delete _scopeFeeOverrides[scopeName];
} else {
_scopeFeeOverrides[scopeName] = feeOverride;
}
emit ScopeFeeOverrideCommit(scopeName, feeOverride);
}
function _preCommitFeeChange(string memory scopeName) private returns (FeeConfig memory config, bool active) {
ProposedFeeConfig storage proposal = _proposedFeeConfigs[scopeName];
if (proposal.timestamp == 0) {
revert NoProposedFeeSet();
}
if (block.timestamp < proposal.timestamp + FEE_CHANGE_TIMELOCK) {
revert TimelockNotElapsed();
}
config = proposal.config;
active = proposal.active;
delete _proposedFeeConfigs[scopeName];
}
function getScopeFeeOverride(string memory scopeName) public view returns (FeeConfigOverride memory config) {
return _scopeFeeOverrides[scopeName];
}
function addProtocolBanker(address addr) external onlyOwner {
_protocolBankers[addr] = true;
emit ProtocolBankerAdd(msg.sender, addr);
}
function removeProtocolBanker(address addr) external onlyOwner {
delete _protocolBankers[addr];
emit ProtocolBankerRemove(msg.sender, addr);
}
function withdrawFromProtocol(uint256 amount) external nonReentrant onlyProtoOwnerBanker {
if (amount > _protocolBalance) {
revert InsufficientFunds();
}
_protocolBalance -= amount;
(bool sent,) = msg.sender.call{value: amount}("");
if (!sent) {
revert FailedToSend();
}
emit ProtocolWithdraw(msg.sender, amount);
}
function balanceOfProtocol() public view returns (uint256 balance) {
return _protocolBalance;
}
function addWhitelist(string calldata scopeName, address addr) public {
Scope storage s = _mustHaveScope(scopeName);
_mustBeOwnerOrOperator(s);
s.whitelist[addr] = true;
emit ScopeWhitelistAdd(scopeName, msg.sender, addr);
}
function removeWhitelist(string calldata scopeName, address addr) public {
Scope storage s = _mustHaveScope(scopeName);
_mustBeOwnerOrOperator(s);
s.whitelist[addr] = false;
emit ScopeWhitelistRemove(scopeName, msg.sender, addr);
}
function patch(address owner, address originalAddress, uint originalTokenId, address patchAddress) external payable returns (uint256 tokenId) {
if (!IERC165(patchAddress).supportsInterface(type(IPatchworkPatch).interfaceId)) {
revert UnsupportedContract();
}
IPatchworkPatch patch_ = IPatchworkPatch(patchAddress);
string memory scopeName = _getScopeName(patchAddress);
Scope storage scope = _mustHaveScope(scopeName);
_mustBeWhitelisted(scopeName, scope, patchAddress);
if (scope.owner == msg.sender || scope.operators[msg.sender]) {
} else if (scope.allowUserPatch) {
} else {
revert NotAuthorized(msg.sender);
}
(uint256 scopeFee, uint256 protocolFee) = _handlePatchFee(scopeName, scope, patchAddress);
bytes32 _hash = keccak256(abi.encodePacked(originalAddress, originalTokenId, patchAddress));
if (_uniquePatches[_hash]) {
revert AlreadyPatched(originalAddress, originalTokenId, patchAddress);
}
_uniquePatches[_hash] = true;
tokenId = patch_.mintPatch(owner, IPatchworkPatch.PatchTarget(originalAddress, originalTokenId));
emit Patch(owner, originalAddress, originalTokenId, patchAddress, tokenId, scopeFee, protocolFee);
return tokenId;
}
function patchBurned(address originalAddress, uint originalTokenId, address patchAddress) external onlyFrom(patchAddress) {
bytes32 _hash = keccak256(abi.encodePacked(originalAddress, originalTokenId, patchAddress));
delete _uniquePatches[_hash];
}
function patch1155(address to, address originalAddress, uint originalTokenId, address originalAccount, address patchAddress) external payable returns (uint256 tokenId) {
if (!IERC165(patchAddress).supportsInterface(type(IPatchwork1155Patch).interfaceId)) {
revert UnsupportedContract();
}
IPatchwork1155Patch patch_ = IPatchwork1155Patch(patchAddress);
string memory scopeName = _getScopeName(patchAddress);
Scope storage scope = _mustHaveScope(scopeName);
_mustBeWhitelisted(scopeName, scope, patchAddress);
if (scope.owner == msg.sender || scope.operators[msg.sender]) {
} else if (scope.allowUserPatch) {
} else {
revert NotAuthorized(msg.sender);
}
(uint256 scopeFee, uint256 protocolFee) = _handlePatchFee(scopeName, scope, patchAddress);
bytes32 _hash = keccak256(abi.encodePacked(originalAddress, originalTokenId, originalAccount, patchAddress));
if (_uniquePatches[_hash]) {
revert ERC1155AlreadyPatched(originalAddress, originalTokenId, originalAccount, patchAddress);
}
_uniquePatches[_hash] = true;
tokenId = patch_.mintPatch(to, IPatchwork1155Patch.PatchTarget(originalAddress, originalTokenId, originalAccount));
emit ERC1155Patch(to, originalAddress, originalTokenId, originalAccount, patchAddress, tokenId, scopeFee, protocolFee);
return tokenId;
}
function patchBurned1155(address originalAddress, uint originalTokenId, address originalAccount, address patchAddress) external onlyFrom(patchAddress) {
bytes32 _hash = keccak256(abi.encodePacked(originalAddress, originalTokenId, originalAccount, patchAddress));
delete _uniquePatches[_hash];
}
function patchAccount(address owner, address originalAddress, address patchAddress) external payable returns (uint256 tokenId) {
if (!IERC165(patchAddress).supportsInterface(type(IPatchworkAccountPatch).interfaceId)) {
revert UnsupportedContract();
}
IPatchworkAccountPatch patch_ = IPatchworkAccountPatch(patchAddress);
string memory scopeName = _getScopeName(patchAddress);
Scope storage scope = _mustHaveScope(scopeName);
_mustBeWhitelisted(scopeName, scope, patchAddress);
if (scope.owner == msg.sender || scope.operators[msg.sender]) {
} else if (scope.allowUserPatch) {
} else {
revert NotAuthorized(msg.sender);
}
(uint256 scopeFee, uint256 protocolFee) = _handlePatchFee(scopeName, scope, patchAddress);
bytes32 _hash = keccak256(abi.encodePacked(originalAddress, patchAddress));
if (_uniquePatches[_hash]) {
revert AccountAlreadyPatched(originalAddress, patchAddress);
}
_uniquePatches[_hash] = true;
tokenId = patch_.mintPatch(owner, originalAddress);
emit AccountPatch(owner, originalAddress, patchAddress, tokenId, scopeFee, protocolFee);
return tokenId;
}
function patchBurnedAccount(address originalAddress, address patchAddress) external onlyFrom(patchAddress) {
bytes32 _hash = keccak256(abi.encodePacked(originalAddress, patchAddress));
delete _uniquePatches[_hash];
}
function _handlePatchFee(string memory scopeName, Scope storage scope, address patchAddress) private returns (uint256 scopeFee, uint256 protocolFee) {
uint256 patchFee = scope.patchFees[patchAddress];
if (msg.value != patchFee) {
revert IncorrectFeeAmount();
}
if (msg.value > 0) {
uint256 patchBp;
FeeConfigOverride storage feeOverride = _scopeFeeOverrides[scopeName];
if (feeOverride.active) {
patchBp = feeOverride.patchBp;
} else {
patchBp = _protocolFeeConfig.patchBp;
}
protocolFee = msg.value * patchBp / _FEE_BASIS_DENOM;
scopeFee = msg.value - protocolFee;
_protocolBalance += protocolFee;
scope.balance += scopeFee;
}
}
function _delegatecall(address delegate, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = delegate.delegatecall(data);
if (!success) {
if (returndata.length == 0) revert();
assembly {
revert(add(32, returndata), mload(returndata))
}
}
return returndata;
}
function assign(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId) public payable {
_delegatecall(_assignerDelegate, abi.encodeWithSignature("assign(address,uint256,address,uint256)", fragment, fragmentTokenId, target, targetTokenId));
}
function assign(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId, uint256 targetMetadataId) public payable {
_delegatecall(_assignerDelegate, abi.encodeWithSignature("assign(address,uint256,address,uint256,uint256)", fragment, fragmentTokenId, target, targetTokenId, targetMetadataId));
}
function assignBatch(address[] calldata fragments, uint256[] calldata tokenIds, address target, uint256 targetTokenId) public payable {
_delegatecall(_assignerDelegate, abi.encodeWithSignature("assignBatch(address[],uint256[],address,uint256)", fragments, tokenIds, target, targetTokenId));
}
function assignBatch(address[] calldata fragments, uint256[] calldata tokenIds, address target, uint256 targetTokenId, uint256 targetMetadataId) public payable {
_delegatecall(_assignerDelegate, abi.encodeWithSignature("assignBatch(address[],uint256[],address,uint256,uint256)", fragments, tokenIds, target, targetTokenId, targetMetadataId));
}
function unassign(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId) public {
_delegatecall(_assignerDelegate, abi.encodeWithSignature("unassign(address,uint256,address,uint256)", fragment, fragmentTokenId, target, targetTokenId));
}
function unassign(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId, uint256 targetMetadataId) public {
_delegatecall(_assignerDelegate, abi.encodeWithSignature("unassign(address,uint256,address,uint256,uint256)", fragment, fragmentTokenId, target, targetTokenId, targetMetadataId));
}
function unassignMulti(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId) public {
_delegatecall(_assignerDelegate, abi.encodeWithSignature("unassignMulti(address,uint256,address,uint256)", fragment, fragmentTokenId, target, targetTokenId));
}
function unassignMulti(address fragment, uint256 fragmentTokenId, address target, uint256 targetTokenId, uint256 targetMetadataId) public {
_delegatecall(_assignerDelegate, abi.encodeWithSignature("unassignMulti(address,uint256,address,uint256,uint256)", fragment, fragmentTokenId, target, targetTokenId, targetMetadataId));
}
function unassignSingle(address fragment, uint256 fragmentTokenId) public {
_delegatecall(_assignerDelegate, abi.encodeWithSignature("unassignSingle(address,uint256)", fragment, fragmentTokenId));
}
function unassignSingle(address fragment, uint256 fragmentTokenId, uint256 targetMetadataId) public {
_delegatecall(_assignerDelegate, abi.encodeWithSignature("unassignSingle(address,uint256,uint256)", fragment, fragmentTokenId, targetMetadataId));
}
function applyTransfer(address from, address to, uint256 tokenId) public {
address nft = msg.sender;
if (IERC165(nft).supportsInterface(type(IPatchworkSingleAssignable).interfaceId)) {
IPatchworkSingleAssignable assignable = IPatchworkSingleAssignable(nft);
(address addr,) = assignable.getAssignedTo(tokenId);
if (addr != address(0)) {
revert TransferBlockedByAssignment(nft, tokenId);
}
}
if (IERC165(nft).supportsInterface(type(IPatchworkPatch).interfaceId)) {
revert TransferNotAllowed(nft, tokenId);
}
if (IERC165(nft).supportsInterface(type(IPatchwork721).interfaceId)) {
if (IPatchwork721(nft).locked(tokenId)) {
revert Locked(nft, tokenId);
}
}
if (IERC165(nft).supportsInterface(type(IPatchworkLiteRef).interfaceId)) {
(address[] memory addresses, uint256[] memory tokenIds) = IPatchworkLiteRef(nft).loadAllStaticReferences(tokenId);
for (uint i = 0; i < addresses.length; i++) {
if (addresses[i] != address(0)) {
_applyAssignedTransfer(addresses[i], from, to, tokenIds[i], nft, tokenId);
}
}
}
}
function _applyAssignedTransfer(address nft, address from, address to, uint256 tokenId, address assignedTo_, uint256 assignedToTokenId_) private {
if (!IERC165(nft).supportsInterface(type(IPatchworkSingleAssignable).interfaceId)) {
revert NotPatchworkAssignable(nft);
}
(address assignedTo, uint256 assignedToTokenId) = IPatchworkSingleAssignable(nft).getAssignedTo(tokenId);
if (assignedTo_ != assignedTo || assignedToTokenId_ != assignedToTokenId) {
revert DataIntegrityError(assignedTo_, assignedToTokenId_, assignedTo, assignedToTokenId);
}
IPatchworkSingleAssignable(nft).onAssignedTransfer(from, to, tokenId);
if (IERC165(nft).supportsInterface(type(IPatchworkLiteRef).interfaceId)) {
address nft_ = nft;
(address[] memory addresses, uint256[] memory tokenIds) = IPatchworkLiteRef(nft).loadAllStaticReferences(tokenId);
for (uint i = 0; i < addresses.length; i++) {
if (addresses[i] != address(0)) {
_applyAssignedTransfer(addresses[i], from, to, tokenIds[i], nft_, tokenId);
}
}
}
}
function updateOwnershipTree(address addr, uint256 tokenId) public {
if (IERC165(addr).supportsInterface(type(IPatchworkLiteRef).interfaceId)) {
(address[] memory addresses, uint256[] memory tokenIds) = IPatchworkLiteRef(addr).loadAllStaticReferences(tokenId);
for (uint i = 0; i < addresses.length; i++) {
if (addresses[i] != address(0)) {
updateOwnershipTree(addresses[i], tokenIds[i]);
}
}
}
if (IERC165(addr).supportsInterface(type(IPatchworkSingleAssignable).interfaceId)) {
IPatchworkSingleAssignable(addr).updateOwnership(tokenId);
} else if (IERC165(addr).supportsInterface(type(IPatchworkPatch).interfaceId)) {
IPatchworkPatch(addr).updateOwnership(tokenId);
}
}
function proposeAssignerDelegate(address addr) public onlyOwner {
if (addr == address(0)) {
_proposedAssignerDelegate = ProposedAssignerDelegate(0, address(0));
} else {
_proposedAssignerDelegate = ProposedAssignerDelegate(block.timestamp, addr);
}
emit AssignerDelegatePropose(addr);
}
function commitAssignerDelegate() public onlyOwner {
if (_proposedAssignerDelegate.timestamp == 0) {
revert NoDelegateProposed();
}
if (block.timestamp < _proposedAssignerDelegate.timestamp + CONTRACT_UPGRADE_TIMELOCK) {
revert TimelockNotElapsed();
}
_assignerDelegate = _proposedAssignerDelegate.addr;
_proposedAssignerDelegate = ProposedAssignerDelegate(0, address(0));
emit AssignerDelegateCommit(_assignerDelegate);
}
function _mustBeOwner(Scope storage scope) private view {
if (msg.sender != scope.owner) {
revert NotAuthorized(msg.sender);
}
}
function _mustBeOwnerOrOperator(Scope storage scope) private view {
if (msg.sender != scope.owner && !scope.operators[msg.sender]) {
revert NotAuthorized(msg.sender);
}
}
function _getScopeNameViewOnly(address addr) private view returns (string memory scopeName) {
scopeName = _scopeNameCache[addr];
if (bytes(scopeName).length == 0) {
scopeName = IPatchworkScoped(addr).getScopeName();
}
}
modifier onlyProtoOwnerBanker() {
if (msg.sender != owner() && _protocolBankers[msg.sender] == false) {
revert NotAuthorized(msg.sender);
}
_;
}
modifier onlyFrom(address addr) {
if (msg.sender != addr) {
revert NotAuthorized(msg.sender);
}
_;
}
}
文件 18 的 19:PatchworkProtocolCommon.sol
pragma solidity ^0.8.23;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "./interfaces/IPatchworkProtocol.sol";
import "./interfaces/IPatchworkScoped.sol";
contract PatchworkProtocolCommon is Ownable, ReentrancyGuard{
constructor(address owner_) Ownable(owner_) {}
mapping(string => IPatchworkProtocol.Scope) internal _scopes;
mapping(bytes32 => bool) internal _liteRefs;
mapping(bytes32 => bool) internal _uniquePatches;
uint256 internal _protocolBalance;
mapping(address => bool) internal _protocolBankers;
IPatchworkProtocol.FeeConfig internal _protocolFeeConfig;
mapping(string => IPatchworkProtocol.ProposedFeeConfig) internal _proposedFeeConfigs;
mapping(string => IPatchworkProtocol.FeeConfigOverride) internal _scopeFeeOverrides;
mapping(address => string) internal _scopeNameCache;
IPatchworkProtocol.ProposedAssignerDelegate internal _proposedAssignerDelegate;
address internal _assignerDelegate;
function _getScopeName(address addr) internal returns (string memory scopeName) {
scopeName = _scopeNameCache[addr];
if (bytes(scopeName).length == 0) {
scopeName = IPatchworkScoped(addr).getScopeName();
_scopeNameCache[addr] = scopeName;
}
}
function _mustHaveScope(string memory scopeName) internal view returns (IPatchworkProtocol.Scope storage scope) {
scope = _scopes[scopeName];
if (scope.owner == address(0)) {
revert IPatchworkProtocol.ScopeDoesNotExist(scopeName);
}
}
function _mustBeWhitelisted(string memory scopeName, IPatchworkProtocol.Scope storage scope, address addr) internal view {
if (scope.requireWhitelist && !scope.whitelist[addr]) {
revert IPatchworkProtocol.NotWhitelisted(scopeName, addr);
}
}
}
文件 19 的 19:ReentrancyGuard.sol
pragma solidity ^0.8.20;
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
_status = ENTERED;
}
function _nonReentrantAfter() private {
_status = NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
{
"compilationTarget": {
"src/PatchworkProtocol.sol": "PatchworkProtocol"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@openzeppelin/=lib/openzeppelin-contracts/",
":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/"
]
}
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"assignerDelegate_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"address","name":"patchAddress","type":"address"}],"name":"AccountAlreadyPatched","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"patchAddress","type":"address"}],"name":"AlreadyPatched","type":"error"},{"inputs":[],"name":"BadInputLengths","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"CannotLockSoulboundPatch","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"addr2","type":"address"},{"internalType":"uint256","name":"tokenId2","type":"uint256"}],"name":"DataIntegrityError","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"patchAddress","type":"address"}],"name":"ERC1155AlreadyPatched","type":"error"},{"inputs":[],"name":"FailedToSend","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"FragmentAlreadyAssigned","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"FragmentAlreadyRegistered","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"FragmentNotAssigned","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"uint256","name":"targetTokenId","type":"uint256"}],"name":"FragmentNotAssignedToTarget","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"FragmentRedacted","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"FragmentUnregistered","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Frozen","type":"error"},{"inputs":[],"name":"IncorrectFeeAmount","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"IncorrectNonce","type":"error"},{"inputs":[],"name":"InsufficientFunds","type":"error"},{"inputs":[],"name":"InvalidFeeValue","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Locked","type":"error"},{"inputs":[],"name":"MintNotActive","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"MintNotAllowed","type":"error"},{"inputs":[],"name":"NoDelegateProposed","type":"error"},{"inputs":[],"name":"NoProposedFeeSet","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"NotAuthorized","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NotFrozen","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"NotPatchworkAssignable","type":"error"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"NotWhitelisted","type":"error"},{"inputs":[],"name":"OutOfIDs","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"fragment","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"RefNotFound","type":"error"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"}],"name":"ScopeDoesNotExist","type":"error"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"}],"name":"ScopeExists","type":"error"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"ScopeTransferNotAllowed","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"SelfAssignmentNotAllowed","type":"error"},{"inputs":[],"name":"TimelockNotElapsed","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TransferBlockedByAssignment","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TransferNotAllowed","type":"error"},{"inputs":[],"name":"UnsupportedContract","type":"error"},{"inputs":[],"name":"UnsupportedOperation","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"UnsupportedTokenId","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"originalAddress","type":"address"},{"indexed":true,"internalType":"address","name":"patchAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"patchTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scopeFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolFee","type":"uint256"}],"name":"AccountPatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"fragmentAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"fragmentTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"targetAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"targetTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scopeFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolFee","type":"uint256"}],"name":"Assign","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"AssignFeeChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"AssignerDelegateCommit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"AssignerDelegatePropose","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"originalAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"originalTokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"originalAccount","type":"address"},{"indexed":true,"internalType":"address","name":"patchAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"patchTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scopeFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolFee","type":"uint256"}],"name":"ERC1155Patch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"mintable","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"scopeFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolFee","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"mintable","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scopeFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolFee","type":"uint256"}],"name":"MintBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":true,"internalType":"address","name":"mintable","type":"address"},{"components":[{"internalType":"uint256","name":"flatFee","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"indexed":false,"internalType":"struct IPatchworkProtocol.MintConfig","name":"config","type":"tuple"}],"name":"MintConfigure","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":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"originalAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"originalTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"patchAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"patchTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"scopeFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolFee","type":"uint256"}],"name":"Patch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"PatchFeeChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":true,"internalType":"address","name":"banker","type":"address"}],"name":"ProtocolBankerAdd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":true,"internalType":"address","name":"banker","type":"address"}],"name":"ProtocolBankerRemove","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"mintBp","type":"uint256"},{"internalType":"uint256","name":"patchBp","type":"uint256"},{"internalType":"uint256","name":"assignBp","type":"uint256"}],"indexed":false,"internalType":"struct IPatchworkProtocol.FeeConfig","name":"config","type":"tuple"}],"name":"ProtocolFeeConfigCommit","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"mintBp","type":"uint256"},{"internalType":"uint256","name":"patchBp","type":"uint256"},{"internalType":"uint256","name":"assignBp","type":"uint256"}],"indexed":false,"internalType":"struct IPatchworkProtocol.FeeConfig","name":"config","type":"tuple"}],"name":"ProtocolFeeConfigPropose","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ProtocolWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"}],"name":"ScopeAddOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":true,"internalType":"address","name":"banker","type":"address"}],"name":"ScopeBankerAdd","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":true,"internalType":"address","name":"banker","type":"address"}],"name":"ScopeBankerRemove","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"ScopeClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"components":[{"internalType":"uint256","name":"mintBp","type":"uint256"},{"internalType":"uint256","name":"patchBp","type":"uint256"},{"internalType":"uint256","name":"assignBp","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"indexed":false,"internalType":"struct IPatchworkProtocol.FeeConfigOverride","name":"config","type":"tuple"}],"name":"ScopeFeeOverrideCommit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"components":[{"internalType":"uint256","name":"mintBp","type":"uint256"},{"internalType":"uint256","name":"patchBp","type":"uint256"},{"internalType":"uint256","name":"assignBp","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"indexed":false,"internalType":"struct IPatchworkProtocol.FeeConfigOverride","name":"config","type":"tuple"}],"name":"ScopeFeeOverridePropose","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"}],"name":"ScopeRemoveOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":false,"internalType":"bool","name":"allowUserPatch","type":"bool"},{"indexed":false,"internalType":"bool","name":"allowUserAssign","type":"bool"},{"indexed":false,"internalType":"bool","name":"requireWhitelist","type":"bool"}],"name":"ScopeRuleChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ScopeTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ScopeTransferCancel","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ScopeTransferElect","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"ScopeWhitelistAdd","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"ScopeWhitelistRemove","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"scopeName","type":"string"},{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ScopeWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"fragmentAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"fragmentTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"targetAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"targetTokenId","type":"uint256"}],"name":"Unassign","type":"event"},{"inputs":[],"name":"CONTRACT_UPGRADE_TIMELOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_CHANGE_TIMELOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"}],"name":"acceptScopeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"addBanker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"internalType":"address","name":"op","type":"address"}],"name":"addOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addProtocolBanker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"addWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"applyTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fragment","type":"address"},{"internalType":"uint256","name":"fragmentTokenId","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"targetTokenId","type":"uint256"}],"name":"assign","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"fragment","type":"address"},{"internalType":"uint256","name":"fragmentTokenId","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"targetTokenId","type":"uint256"},{"internalType":"uint256","name":"targetMetadataId","type":"uint256"}],"name":"assign","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"fragments","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"targetTokenId","type":"uint256"}],"name":"assignBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"fragments","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"targetTokenId","type":"uint256"},{"internalType":"uint256","name":"targetMetadataId","type":"uint256"}],"name":"assignBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOfProtocol","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"}],"name":"cancelScopeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"}],"name":"claimScope","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"commitAssignerDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"commitProtocolFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"}],"name":"commitScopeFeeOverride","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fragmentAddress","type":"address"}],"name":"getAssignFee","outputs":[{"internalType":"uint256","name":"baseFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getMintConfiguration","outputs":[{"components":[{"internalType":"uint256","name":"flatFee","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct IPatchworkProtocol.MintConfig","name":"config","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getPatchFee","outputs":[{"internalType":"uint256","name":"baseFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProtocolFeeConfig","outputs":[{"components":[{"internalType":"uint256","name":"mintBp","type":"uint256"},{"internalType":"uint256","name":"patchBp","type":"uint256"},{"internalType":"uint256","name":"assignBp","type":"uint256"}],"internalType":"struct IPatchworkProtocol.FeeConfig","name":"config","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"}],"name":"getScopeFeeOverride","outputs":[{"components":[{"internalType":"uint256","name":"mintBp","type":"uint256"},{"internalType":"uint256","name":"patchBp","type":"uint256"},{"internalType":"uint256","name":"assignBp","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct IPatchworkProtocol.FeeConfigOverride","name":"config","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"}],"name":"getScopeOwner","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"}],"name":"getScopeOwnerElect","outputs":[{"internalType":"address","name":"ownerElect","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"mintable","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"mintable","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mintBatch","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"originalAddress","type":"address"},{"internalType":"uint256","name":"originalTokenId","type":"uint256"},{"internalType":"address","name":"patchAddress","type":"address"}],"name":"patch","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"originalAddress","type":"address"},{"internalType":"uint256","name":"originalTokenId","type":"uint256"},{"internalType":"address","name":"originalAccount","type":"address"},{"internalType":"address","name":"patchAddress","type":"address"}],"name":"patch1155","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"originalAddress","type":"address"},{"internalType":"address","name":"patchAddress","type":"address"}],"name":"patchAccount","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"originalAddress","type":"address"},{"internalType":"uint256","name":"originalTokenId","type":"uint256"},{"internalType":"address","name":"patchAddress","type":"address"}],"name":"patchBurned","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"originalAddress","type":"address"},{"internalType":"uint256","name":"originalTokenId","type":"uint256"},{"internalType":"address","name":"originalAccount","type":"address"},{"internalType":"address","name":"patchAddress","type":"address"}],"name":"patchBurned1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"originalAddress","type":"address"},{"internalType":"address","name":"patchAddress","type":"address"}],"name":"patchBurnedAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"proposeAssignerDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"mintBp","type":"uint256"},{"internalType":"uint256","name":"patchBp","type":"uint256"},{"internalType":"uint256","name":"assignBp","type":"uint256"}],"internalType":"struct IPatchworkProtocol.FeeConfig","name":"config","type":"tuple"}],"name":"proposeProtocolFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"components":[{"internalType":"uint256","name":"mintBp","type":"uint256"},{"internalType":"uint256","name":"patchBp","type":"uint256"},{"internalType":"uint256","name":"assignBp","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct IPatchworkProtocol.FeeConfigOverride","name":"config","type":"tuple"}],"name":"proposeScopeFeeOverride","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"removeBanker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"internalType":"address","name":"op","type":"address"}],"name":"removeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"removeProtocolBanker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"removeWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fragmentAddress","type":"address"},{"internalType":"uint256","name":"baseFee","type":"uint256"}],"name":"setAssignFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"components":[{"internalType":"uint256","name":"flatFee","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct IPatchworkProtocol.MintConfig","name":"config","type":"tuple"}],"name":"setMintConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"baseFee","type":"uint256"}],"name":"setPatchFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"internalType":"bool","name":"allowUserPatch","type":"bool"},{"internalType":"bool","name":"allowUserAssign","type":"bool"},{"internalType":"bool","name":"requireWhitelist","type":"bool"}],"name":"setScopeRules","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferScopeOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fragment","type":"address"},{"internalType":"uint256","name":"fragmentTokenId","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"targetTokenId","type":"uint256"},{"internalType":"uint256","name":"targetMetadataId","type":"uint256"}],"name":"unassign","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fragment","type":"address"},{"internalType":"uint256","name":"fragmentTokenId","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"targetTokenId","type":"uint256"}],"name":"unassign","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fragment","type":"address"},{"internalType":"uint256","name":"fragmentTokenId","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"targetTokenId","type":"uint256"},{"internalType":"uint256","name":"targetMetadataId","type":"uint256"}],"name":"unassignMulti","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fragment","type":"address"},{"internalType":"uint256","name":"fragmentTokenId","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"targetTokenId","type":"uint256"}],"name":"unassignMulti","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fragment","type":"address"},{"internalType":"uint256","name":"fragmentTokenId","type":"uint256"},{"internalType":"uint256","name":"targetMetadataId","type":"uint256"}],"name":"unassignSingle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fragment","type":"address"},{"internalType":"uint256","name":"fragmentTokenId","type":"uint256"}],"name":"unassignSingle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"updateOwnershipTree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"scopeName","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawFromProtocol","outputs":[],"stateMutability":"nonpayable","type":"function"}]