Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x050525cC...f71d0944a The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
RoyaltyModule
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 20000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import { Governable } from "../../governance/Governable.sol";
import { IRoyaltyModule } from "../../interfaces/modules/royalty/IRoyaltyModule.sol";
import { IRoyaltyPolicy } from "../../interfaces/modules/royalty/policies/IRoyaltyPolicy.sol";
import { Errors } from "../../lib/Errors.sol";
import { ROYALTY_MODULE_KEY } from "../../lib/modules/Module.sol";
/// @title Story Protocol Royalty Module
/// @notice The Story Protocol royalty module allows to set royalty policies an ipId
/// and pay royalties as a derivative ip.
contract RoyaltyModule is IRoyaltyModule, Governable, ReentrancyGuard {
string public constant override name = ROYALTY_MODULE_KEY;
/// @notice Licensing module address
address public LICENSING_MODULE;
/// @notice Indicates if a royalty policy is whitelisted
mapping(address royaltyPolicy => bool allowed) public isWhitelistedRoyaltyPolicy;
/// @notice Indicates if a royalty token is whitelisted
mapping(address token => bool) public isWhitelistedRoyaltyToken;
/// @notice Indicates the royalty policy for a given ipId
mapping(address ipId => address royaltyPolicy) public royaltyPolicies;
/// @notice Indicates if a royalty policy is immutable
mapping(address ipId => bool) public isRoyaltyPolicyImmutable;
/// @notice Constructor
/// @param _governance The address of the governance contract
constructor(address _governance) Governable(_governance) {}
modifier onlyLicensingModule() {
if (msg.sender != LICENSING_MODULE) revert Errors.RoyaltyModule__NotAllowedCaller();
_;
}
/// @notice Sets the license registry
/// @param _licensingModule The address of the license registry
function setLicensingModule(address _licensingModule) external onlyProtocolAdmin {
if (_licensingModule == address(0)) revert Errors.RoyaltyModule__ZeroLicensingModule();
LICENSING_MODULE = _licensingModule;
}
/// @notice Whitelist a royalty policy
/// @param _royaltyPolicy The address of the royalty policy
/// @param _allowed Indicates if the royalty policy is whitelisted or not
function whitelistRoyaltyPolicy(address _royaltyPolicy, bool _allowed) external onlyProtocolAdmin {
if (_royaltyPolicy == address(0)) revert Errors.RoyaltyModule__ZeroRoyaltyPolicy();
isWhitelistedRoyaltyPolicy[_royaltyPolicy] = _allowed;
emit RoyaltyPolicyWhitelistUpdated(_royaltyPolicy, _allowed);
}
/// @notice Whitelist a royalty token
/// @param _token The token address
/// @param _allowed Indicates if the token is whitelisted or not
function whitelistRoyaltyToken(address _token, bool _allowed) external onlyProtocolAdmin {
if (_token == address(0)) revert Errors.RoyaltyModule__ZeroRoyaltyToken();
isWhitelistedRoyaltyToken[_token] = _allowed;
emit RoyaltyTokenWhitelistUpdated(_token, _allowed);
}
// TODO: Ensure that the ipId that is passed in from license cannot be manipulated - given ipId addresses are deterministic
/// @notice Sets the royalty policy for an ipId
/// @param _ipId The ipId
/// @param _royaltyPolicy The address of the royalty policy
/// @param _parentIpIds The parent ipIds
/// @param _data The data to initialize the policy
function setRoyaltyPolicy(
address _ipId,
address _royaltyPolicy,
address[] calldata _parentIpIds,
bytes calldata _data
) external nonReentrant onlyLicensingModule {
if (isRoyaltyPolicyImmutable[_ipId]) revert Errors.RoyaltyModule__AlreadySetRoyaltyPolicy();
if (!isWhitelistedRoyaltyPolicy[_royaltyPolicy]) revert Errors.RoyaltyModule__NotWhitelistedRoyaltyPolicy();
if (_parentIpIds.length > 0) isRoyaltyPolicyImmutable[_ipId] = true;
// the loop below is limited to 100 iterations
for (uint32 i = 0; i < _parentIpIds.length; i++) {
if (royaltyPolicies[_parentIpIds[i]] != _royaltyPolicy) revert Errors.RoyaltyModule__IncompatibleRoyaltyPolicy();
isRoyaltyPolicyImmutable[_parentIpIds[i]] = true;
}
royaltyPolicies[_ipId] = _royaltyPolicy;
IRoyaltyPolicy(_royaltyPolicy).initPolicy(_ipId, _parentIpIds, _data);
emit RoyaltyPolicySet(_ipId, _royaltyPolicy, _data);
}
function setRoyaltyPolicyImmutable(address _ipId) external onlyLicensingModule {
isRoyaltyPolicyImmutable[_ipId] = true;
}
function minRoyaltyFromDescendants(address _ipId) external view returns (uint256) {
address royaltyPolicy = royaltyPolicies[_ipId];
if (royaltyPolicy == address(0)) revert Errors.RoyaltyModule__NoRoyaltyPolicySet();
return IRoyaltyPolicy(royaltyPolicy).minRoyaltyFromDescendants(_ipId);
}
/// @notice Allows a sender to to pay royalties on behalf of an ipId
/// @param _receiverIpId The ipId that receives the royalties
/// @param _payerIpId The ipId that pays the royalties
/// @param _token The token to use to pay the royalties
/// @param _amount The amount to pay
function payRoyaltyOnBehalf(address _receiverIpId, address _payerIpId, address _token, uint256 _amount) external nonReentrant {
address royaltyPolicy = royaltyPolicies[_receiverIpId];
if (royaltyPolicy == address(0)) revert Errors.RoyaltyModule__NoRoyaltyPolicySet();
if (!isWhitelistedRoyaltyToken[_token]) revert Errors.RoyaltyModule__NotWhitelistedRoyaltyToken();
if (!isWhitelistedRoyaltyPolicy[royaltyPolicy]) revert Errors.RoyaltyModule__NotWhitelistedRoyaltyPolicy();
IRoyaltyPolicy(royaltyPolicy).onRoyaltyPayment(msg.sender, _receiverIpId, _token, _amount);
emit RoyaltyPaid(_receiverIpId, _payerIpId, msg.sender, _token, _amount);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}// SPDX-License-Identifier: UNLICENSED
// See https://github.com/storyprotocol/protocol-contracts/blob/main/StoryProtocol-AlphaTestingAgreement-17942166.3.pdf
pragma solidity ^0.8.23;
import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import { Errors } from "../lib/Errors.sol";
import { IGovernance } from "../interfaces/governance/IGovernance.sol";
import { IGovernable } from "../interfaces/governance/IGovernable.sol";
import { GovernanceLib } from "../lib/GovernanceLib.sol";
/// @title Governable
/// @dev All contracts managed by governance should inherit from this contract.
abstract contract Governable is IGovernable {
/// @notice The address of the governance.
address public governance;
/// @dev Ensures that the function is called by the protocol admin.
modifier onlyProtocolAdmin() {
if (!IGovernance(governance).hasRole(GovernanceLib.PROTOCOL_ADMIN, msg.sender)) {
revert Errors.Governance__OnlyProtocolAdmin();
}
_;
}
modifier whenNotPaused() {
if (IGovernance(governance).getState() == GovernanceLib.ProtocolState.Paused) {
revert Errors.Governance__ProtocolPaused();
}
_;
}
/// @notice Constructs a new Governable contract.
/// @param governance_ The address of the governance.
constructor(address governance_) {
if (governance_ == address(0)) revert Errors.Governance__ZeroAddress();
governance = governance_;
emit GovernanceUpdated(governance);
}
/// @notice Sets a new governance address.
/// @param newGovernance The address of the new governance.
function setGovernance(address newGovernance) external onlyProtocolAdmin {
if (newGovernance == address(0)) revert Errors.Governance__ZeroAddress();
if (!ERC165Checker.supportsInterface(newGovernance, type(IGovernance).interfaceId))
revert Errors.Governance__UnsupportedInterface("IGovernance");
if (IGovernance(newGovernance).getState() != IGovernance(governance).getState())
revert Errors.Governance__InconsistentState();
governance = newGovernance;
emit GovernanceUpdated(newGovernance);
}
/// @notice Returns the current governance address.
/// @return The address of the current governance.
function getGovernance() external view returns (address) {
return governance;
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
import { IModule } from "../../modules/base/IModule.sol";
/// @title RoyaltyModule interface
interface IRoyaltyModule is IModule {
/// @notice Event emitted when a royalty policy is whitelisted
/// @param royaltyPolicy The address of the royalty policy
/// @param allowed Indicates if the royalty policy is whitelisted or not
event RoyaltyPolicyWhitelistUpdated(address royaltyPolicy, bool allowed);
/// @notice Event emitted when a royalty token is whitelisted
/// @param token The address of the royalty token
/// @param allowed Indicates if the royalty token is whitelisted or not
event RoyaltyTokenWhitelistUpdated(address token, bool allowed);
/// @notice Event emitted when a royalty policy is set
/// @param ipId The ipId
/// @param royaltyPolicy The address of the royalty policy
/// @param data The data to initialize the policy
event RoyaltyPolicySet(address ipId, address royaltyPolicy, bytes data);
/// @notice Event emitted when royalties are paid
/// @param receiverIpId The ipId that receives the royalties
/// @param payerIpId The ipId that pays the royalties
/// @param sender The address that pays the royalties on behalf of the payer ipId
/// @param token The token that is used to pay the royalties
/// @param amount The amount that is paid
event RoyaltyPaid(address receiverIpId, address payerIpId, address sender, address token, uint256 amount);
/// @notice Sets the licensing module
/// @param licensingModule The address of the licensing module
function setLicensingModule(address licensingModule) external;
/// @notice Whitelist a royalty policy
/// @param royaltyPolicy The address of the royalty policy
/// @param allowed Indicates if the royalty policy is whitelisted or not
function whitelistRoyaltyPolicy(address royaltyPolicy, bool allowed) external;
/// @notice Whitelist a royalty token
/// @param token The token address
/// @param allowed Indicates if the token is whitelisted or not
function whitelistRoyaltyToken(address token, bool allowed) external;
/// @notice Sets the royalty policy for an ipId
/// @param ipId The ipId
/// @param royaltyPolicy The address of the royalty policy
/// @param parentIpIds The parent ipIds
/// @param data The data to initialize the policy
function setRoyaltyPolicy(address ipId, address royaltyPolicy, address[] calldata parentIpIds, bytes calldata data) external;
/// @notice Allows a sender to to pay royalties on behalf of an ipId
/// @param receiverIpId The ipId that receives the royalties
/// @param payerIpId The ipId that pays the royalties
/// @param token The token to use to pay the royalties
/// @param amount The amount to pay
function payRoyaltyOnBehalf(address receiverIpId, address payerIpId, address token, uint256 amount) external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
/// @title RoyaltyPolicy interface
interface IRoyaltyPolicy {
/// @notice Initializes the royalty policy
/// @param ipId The ipId
/// @param parentsIpIds The parent ipIds
/// @param data The data to initialize the policy
function initPolicy(address ipId, address[] calldata parentsIpIds, bytes calldata data) external;
/// @notice Allows to pay a royalty
/// @param caller The caller
/// @param ipId The ipId
/// @param token The token to pay
/// @param amount The amount to pay
function onRoyaltyPayment(address caller, address ipId, address token, uint256 amount) external;
/// @notice Returns the minimum royalty the IPAccount expects from descendants
/// @param ipId The ipId
function minRoyaltyFromDescendants(address ipId) external view returns (uint32);
}// SPDX-License-Identifier: UNLICENSED
// See https://github.com/storyprotocol/protocol-contracts/blob/main/StoryProtocol-AlphaTestingAgreement-17942166.3.pdf
pragma solidity ^0.8.19;
/// @title Errors Library
/// @notice Library for all Story Protocol contract errors.
library Errors {
////////////////////////////////////////////////////////////////////////////
// Governance //
////////////////////////////////////////////////////////////////////////////
error Governance__OnlyProtocolAdmin();
error Governance__ZeroAddress();
error Governance__ProtocolPaused();
error Governance__InconsistentState();
error Governance__NewStateIsTheSameWithOldState();
error Governance__UnsupportedInterface(string interfaceName);
////////////////////////////////////////////////////////////////////////////
// IPAccount //
////////////////////////////////////////////////////////////////////////////
error IPAccount__InvalidSigner();
error IPAccount__InvalidSignature();
error IPAccount__ExpiredSignature();
error IPAccount__InvalidCalldata();
////////////////////////////////////////////////////////////////////////////
// Module //
////////////////////////////////////////////////////////////////////////////
/// @notice The caller is not allowed to call the provided module.
error Module_Unauthorized();
////////////////////////////////////////////////////////////////////////////
// IPAccountRegistry //
////////////////////////////////////////////////////////////////////////////
error IPAccountRegistry_InvalidIpAccountImpl();
////////////////////////////////////////////////////////////////////////////
// IPAssetRegistry //
////////////////////////////////////////////////////////////////////////////
/// @notice The IP asset has already been registered.
error IPAssetRegistry__AlreadyRegistered();
/// @notice The IP account has already been created.
error IPAssetRegistry__IPAccountAlreadyCreated();
/// @notice The IP asset has not yet been registered.
error IPAssetRegistry__NotYetRegistered();
/// @notice The specified IP resolver is not valid.
error IPAssetRegistry__ResolverInvalid();
/// @notice Caller not authorized to perform the IP registry function call.
error IPAssetRegistry__Unauthorized();
/// @notice The deployed address of account doesn't match with IP ID.
error IPAssetRegistry__InvalidAccount();
/// @notice The metadata provider is not valid.
error IPAssetRegistry__InvalidMetadataProvider();
////////////////////////////////////////////////////////////////////////////
// IPResolver ///
////////////////////////////////////////////////////////////////////////////
/// @notice The targeted IP does not yet have an IP account.
error IPResolver_InvalidIP();
/// @notice Caller not authorized to perform the IP resolver function call.
error IPResolver_Unauthorized();
////////////////////////////////////////////////////////////////////////////
// Metadata Provider ///
////////////////////////////////////////////////////////////////////////////
/// @notice Provided hash metadata is not valid.
error MetadataProvider__HashInvalid();
/// @notice The caller is not the authorized IP asset owner.
error MetadataProvider__IPAssetOwnerInvalid();
/// @notice Provided hash metadata is not valid.
error MetadataProvider__NameInvalid();
/// @notice The new metadata provider is not compatible with the old provider.
error MetadataProvider__MetadataNotCompatible();
/// @notice Provided registrant metadata is not valid.
error MetadataProvider__RegistrantInvalid();
/// @notice Provided registration date is not valid.
error MetadataProvider__RegistrationDateInvalid();
/// @notice Caller does not access to set metadata storage for the provider.
error MetadataProvider__Unauthorized();
/// @notice A metadata provider upgrade is not currently available.
error MetadataProvider__UpgradeUnavailable();
/// @notice The upgrade provider is not valid.
error MetadataProvider__UpgradeProviderInvalid();
/// @notice Provided metadata URI is not valid.
error MetadataProvider__URIInvalid();
////////////////////////////////////////////////////////////////////////////
// LicenseRegistry //
////////////////////////////////////////////////////////////////////////////
error LicenseRegistry__CallerNotLicensingModule();
error LicenseRegistry__ZeroLicensingModule();
error LicensingModule__CallerNotLicenseRegistry();
/// @notice emitted when trying to transfer a license that is not transferable (by policy)
error LicenseRegistry__NotTransferable();
////////////////////////////////////////////////////////////////////////////
// LicensingModule //
////////////////////////////////////////////////////////////////////////////
error LicensingModule__PolicyAlreadySetForIpId();
error LicensingModule__FrameworkNotFound();
error LicensingModule__EmptyLicenseUrl();
error LicensingModule__InvalidPolicyFramework();
error LicensingModule__PolicyAlreadyAdded();
error LicensingModule__ParamVerifierLengthMismatch();
error LicensingModule__PolicyNotFound();
error LicensingModule__NotLicensee();
error LicensingModule__ParentIdEqualThanChild();
error LicensingModule__LicensorDoesntHaveThisPolicy();
error LicensingModule__MintLicenseParamFailed();
error LicensingModule__LinkParentParamFailed();
error LicensingModule__TransferParamFailed();
error LicensingModule__InvalidLicensor();
error LicensingModule__ParamVerifierAlreadySet();
error LicensingModule__CommercialTermInNonCommercialPolicy();
error LicensingModule__EmptyParamName();
error LicensingModule__UnregisteredFrameworkAddingPolicy();
error LicensingModule__UnauthorizedAccess();
error LicensingModule__LicensorNotRegistered();
error LicensingModule__CallerNotLicensorAndPolicyNotSet();
error LicensingModule__DerivativesCannotAddPolicy();
error LicensingModule__IncompatibleRoyaltyPolicyAddress();
error LicensingModule__IncompatibleRoyaltyPolicyDerivativeRevShare();
error LicensingModule__IncompatibleLicensorCommercialPolicy();
error LicensingModule__IncompatibleLicensorRoyaltyDerivativeRevShare();
error LicensingModule__DerivativeRevShareSumExceedsMaxRNFTSupply();
error LicensingModule__MismatchBetweenCommercialRevenueShareAndMinRoyalty();
error LicensingModule__MismatchBetweenRoyaltyPolicy();
////////////////////////////////////////////////////////////////////////////
// LicensingModuleAware //
////////////////////////////////////////////////////////////////////////////
error LicensingModuleAware__CallerNotLicensingModule();
////////////////////////////////////////////////////////////////////////////
// PolicyFrameworkManager //
////////////////////////////////////////////////////////////////////////////
error PolicyFrameworkManager__GettingPolicyWrongFramework();
////////////////////////////////////////////////////////////////////////////
// LicensorApprovalChecker //
////////////////////////////////////////////////////////////////////////////
error LicensorApprovalChecker__Unauthorized();
////////////////////////////////////////////////////////////////////////////
// Dispute Module //
////////////////////////////////////////////////////////////////////////////
error DisputeModule__ZeroArbitrationPolicy();
error DisputeModule__ZeroArbitrationRelayer();
error DisputeModule__ZeroDisputeTag();
error DisputeModule__ZeroLinkToDisputeEvidence();
error DisputeModule__NotWhitelistedArbitrationPolicy();
error DisputeModule__NotWhitelistedDisputeTag();
error DisputeModule__NotWhitelistedArbitrationRelayer();
error DisputeModule__NotDisputeInitiator();
error DisputeModule__NotInDisputeState();
error DisputeModule__NotAbleToResolve();
error DisputeModule__NotRegisteredIpId();
error DisputeModule__UnauthorizedAccess();
error ArbitrationPolicySP__ZeroDisputeModule();
error ArbitrationPolicySP__ZeroPaymentToken();
error ArbitrationPolicySP__NotDisputeModule();
////////////////////////////////////////////////////////////////////////////
// Royalty Module //
////////////////////////////////////////////////////////////////////////////
error RoyaltyModule__ZeroRoyaltyPolicy();
error RoyaltyModule__NotWhitelistedRoyaltyPolicy();
error RoyaltyModule__AlreadySetRoyaltyPolicy();
error RoyaltyModule__ZeroRoyaltyToken();
error RoyaltyModule__NotWhitelistedRoyaltyToken();
error RoyaltyModule__NoRoyaltyPolicySet();
error RoyaltyModule__IncompatibleRoyaltyPolicy();
error RoyaltyModule__NotAllowedCaller();
error RoyaltyModule__ZeroLicensingModule();
error RoyaltyPolicyLS__ZeroRoyaltyModule();
error RoyaltyPolicyLS__ZeroLiquidSplitFactory();
error RoyaltyPolicyLS__ZeroLiquidSplitMain();
error RoyaltyPolicyLS__NotRoyaltyModule();
error RoyaltyPolicyLS__TransferFailed();
error RoyaltyPolicyLS__InvalidMinRoyalty();
error RoyaltyPolicyLS__InvalidRoyaltyStack();
error RoyaltyPolicyLS__ZeroMinRoyalty();
error RoyaltyPolicyLS__ZeroLicensingModule();
error LSClaimer__InvalidPath();
error LSClaimer__InvalidPathFirstPosition();
error LSClaimer__InvalidPathLastPosition();
error LSClaimer__AlreadyClaimed();
error LSClaimer__ETHBalanceNotZero();
error LSClaimer__ERC20BalanceNotZero();
error LSClaimer__ZeroIpId();
error LSClaimer__ZeroLicensingModule();
error LSClaimer__ZeroRoyaltyPolicyLS();
////////////////////////////////////////////////////////////////////////////
// ModuleRegistry //
////////////////////////////////////////////////////////////////////////////
error ModuleRegistry__ModuleAddressZeroAddress();
error ModuleRegistry__ModuleAddressNotContract();
error ModuleRegistry__ModuleAlreadyRegistered();
error ModuleRegistry__NameEmptyString();
error ModuleRegistry__NameAlreadyRegistered();
error ModuleRegistry__NameDoesNotMatch();
error ModuleRegistry__ModuleNotRegistered();
////////////////////////////////////////////////////////////////////////////
// RegistrationModule //
////////////////////////////////////////////////////////////////////////////
/// @notice The caller is not the owner of the root IP NFT.
error RegistrationModule__InvalidOwner();
////////////////////////////////////////////////////////////////////////////
// AccessController //
////////////////////////////////////////////////////////////////////////////
error AccessController__IPAccountIsZeroAddress();
error AccessController__IPAccountIsNotValid(address ipAccount);
error AccessController__SignerIsZeroAddress();
error AccessController__CallerIsNotIPAccount();
error AccessController__PermissionIsNotValid();
error AccessController__RecipientIsNotRegisteredModule(address to);
error AccessController__PermissionDenied(address ipAccount, address signer, address to, bytes4 func);
////////////////////////////////////////////////////////////////////////////
// AccessControlled //
////////////////////////////////////////////////////////////////////////////
error AccessControlled__ZeroAddress();
error AccessControlled__NotIpAccount(address ipAccount);
error AccessControlled__CallerIsNotIpAccount(address caller);
////////////////////////////////////////////////////////////////////////////
// TaggingModule //
////////////////////////////////////////////////////////////////////////////
error TaggingModule__InvalidRelationTypeName();
error TaggingModule__RelationTypeAlreadyExists();
error TaggingModule__SrcIpIdDoesNotHaveSrcTag();
error TaggingModule__DstIpIdDoesNotHaveDstTag();
error TaggingModule__RelationTypeDoesNotExist();
}// SPDX-License-Identifier: UNLICENSED // See https://github.com/storyprotocol/protocol-contracts/blob/main/StoryProtocol-AlphaTestingAgreement-17942166.3.pdf pragma solidity ^0.8.23; // String values for core protocol modules. string constant IP_RESOLVER_MODULE_KEY = "IP_RESOLVER_MODULE"; // String values for core protocol modules. string constant REGISTRATION_MODULE_KEY = "REGISTRATION_MODULE"; // String values for core protocol modules. string constant DISPUTE_MODULE_KEY = "DISPUTE_MODULE"; string constant TAGGING_MODULE_KEY = "TAGGING_MODULE"; string constant ROYALTY_MODULE_KEY = "ROYALTY_MODULE"; string constant LICENSING_MODULE_KEY = "LICENSING_MODULE";
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165Checker.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Library used to query support of an interface declared via {IERC165}.
*
* Note that these functions return the actual result of the query: they do not
* `revert` if an interface is not supported. It is up to the caller to decide
* what to do in these cases.
*/
library ERC165Checker {
// As per the EIP-165 spec, no interface should ever match 0xffffffff
bytes4 private constant INTERFACE_ID_INVALID = 0xffffffff;
/**
* @dev Returns true if `account` supports the {IERC165} interface.
*/
function supportsERC165(address account) internal view returns (bool) {
// Any contract that implements ERC165 must explicitly indicate support of
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
return
supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&
!supportsERC165InterfaceUnchecked(account, INTERFACE_ID_INVALID);
}
/**
* @dev Returns true if `account` supports the interface defined by
* `interfaceId`. Support for {IERC165} itself is queried automatically.
*
* See {IERC165-supportsInterface}.
*/
function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
// query support of both ERC165 as per the spec and support of _interfaceId
return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);
}
/**
* @dev Returns a boolean array where each value corresponds to the
* interfaces passed in and whether they're supported or not. This allows
* you to batch check interfaces for a contract where your expectation
* is that some interfaces may not be supported.
*
* See {IERC165-supportsInterface}.
*/
function getSupportedInterfaces(
address account,
bytes4[] memory interfaceIds
) internal view returns (bool[] memory) {
// an array of booleans corresponding to interfaceIds and whether they're supported or not
bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);
// query support of ERC165 itself
if (supportsERC165(account)) {
// query support of each interface in interfaceIds
for (uint256 i = 0; i < interfaceIds.length; i++) {
interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);
}
}
return interfaceIdsSupported;
}
/**
* @dev Returns true if `account` supports all the interfaces defined in
* `interfaceIds`. Support for {IERC165} itself is queried automatically.
*
* Batch-querying can lead to gas savings by skipping repeated checks for
* {IERC165} support.
*
* See {IERC165-supportsInterface}.
*/
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
// query support of ERC165 itself
if (!supportsERC165(account)) {
return false;
}
// query support of each interface in interfaceIds
for (uint256 i = 0; i < interfaceIds.length; i++) {
if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {
return false;
}
}
// all interfaces supported
return true;
}
/**
* @notice Query if a contract implements an interface, does not check ERC165 support
* @param account The address of the contract to query for support of an interface
* @param interfaceId The interface identifier, as specified in ERC-165
* @return true if the contract at account indicates support of the interface with
* identifier interfaceId, false otherwise
* @dev Assumes that account contains a contract that supports ERC165, otherwise
* the behavior of this method is undefined. This precondition can be checked
* with {supportsERC165}.
*
* Some precompiled contracts will falsely indicate support for a given interface, so caution
* should be exercised when using this function.
*
* Interface identification is specified in ERC-165.
*/
function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {
// prepare call
bytes memory encodedParams = abi.encodeCall(IERC165.supportsInterface, (interfaceId));
// perform static call
bool success;
uint256 returnSize;
uint256 returnValue;
assembly {
success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)
returnSize := returndatasize()
returnValue := mload(0x00)
}
return success && returnSize >= 0x20 && returnValue > 0;
}
}// SPDX-License-Identifier: UNLICENSED
// See https://github.com/storyprotocol/protocol-contracts/blob/main/StoryProtocol-AlphaTestingAgreement-17942166.3.pdf
pragma solidity ^0.8.23;
import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol";
import { GovernanceLib } from "../../lib/GovernanceLib.sol";
/// @title IGovernance
/// @dev This interface defines the governance functionality for the protocol.
interface IGovernance is IAccessControl {
/// @notice Emitted when the protocol state is set
/// @param account The address that triggered the state change
/// @param prevState The previous state of the protocol
/// @param newState The new state of the protocol
/// @param timestamp The time when the state change occurred
event StateSet(
address indexed account,
GovernanceLib.ProtocolState prevState,
GovernanceLib.ProtocolState newState,
uint256 timestamp
);
/// @notice Sets the state of the protocol
/// @dev This function can only be called by an account with the appropriate role
/// @param newState The new state to set for the protocol
function setState(GovernanceLib.ProtocolState newState) external;
/// @notice Returns the current state of the protocol
/// @return The current state of the protocol
function getState() external view returns (GovernanceLib.ProtocolState);
}// SPDX-License-Identifier: UNLICENSED
// See https://github.com/storyprotocol/protocol-contracts/blob/main/StoryProtocol-AlphaTestingAgreement-17942166.3.pdf
pragma solidity ^0.8.23;
/// @title IGovernable
/// @notice This is the interface for the Lens Protocol main governance functions.
interface IGovernable {
/// @notice Emitted when the governance is updated
/// @param newGovernance The address of the new governance
event GovernanceUpdated(address indexed newGovernance);
/// @notice Sets the governance address
/// @param newGovernance The address of the new governance
function setGovernance(address newGovernance) external;
/// @notice Returns the current governance address
/// @return The address of the current governance
function getGovernance() external view returns (address);
}// SPDX-License-Identifier: UNLICENSED
// See https://github.com/storyprotocol/protocol-contracts/blob/main/StoryProtocol-AlphaTestingAgreement-17942166.3.pdf
pragma solidity ^0.8.23;
/// @title Governance
/// @dev This library provides types for Story Protocol Governance.
library GovernanceLib {
bytes32 public constant PROTOCOL_ADMIN = bytes32(0);
/// @notice An enum containing the different states the protocol can be in.
/// @param Unpaused The unpaused state.
/// @param Paused The paused state.
enum ProtocolState {
Unpaused,
Paused
}
}// SPDX-License-Identifier: UNLICENSED
// See https://github.com/storyprotocol/protocol-contracts/blob/main/StoryProtocol-AlphaTestingAgreement-17942166.3.pdf
pragma solidity ^0.8.23;
/// @notice Module Interface
interface IModule {
/// @notice Returns the string identifier associated with the module.
function name() external returns (string memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}{
"remappings": [
"@ethereum-waffle/=node_modules/@ethereum-waffle/",
"@openzeppelin/=node_modules/@openzeppelin/",
"base64-sol/=node_modules/base64-sol/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"eth-gas-reporter/=node_modules/eth-gas-reporter/",
"forge-std/=lib/forge-std/src/",
"hardhat-deploy/=node_modules/hardhat-deploy/",
"hardhat/=node_modules/hardhat/",
"openzeppelin-contracts/=lib/reference/lib/openzeppelin-contracts/",
"@reference/=lib/reference/",
"reference/=lib/reference/"
],
"optimizer": {
"enabled": true,
"runs": 20000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"libraries": {
"contracts/lib/registries/IPAccountChecker.sol": {
"IPAccountChecker": "0x3d9f7264c34b3db04cdabf5745d38b12f12f1007"
}
}
}Contract ABI
API[{"inputs":[{"internalType":"address","name":"_governance","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Governance__InconsistentState","type":"error"},{"inputs":[],"name":"Governance__OnlyProtocolAdmin","type":"error"},{"inputs":[{"internalType":"string","name":"interfaceName","type":"string"}],"name":"Governance__UnsupportedInterface","type":"error"},{"inputs":[],"name":"Governance__ZeroAddress","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"RoyaltyModule__AlreadySetRoyaltyPolicy","type":"error"},{"inputs":[],"name":"RoyaltyModule__IncompatibleRoyaltyPolicy","type":"error"},{"inputs":[],"name":"RoyaltyModule__NoRoyaltyPolicySet","type":"error"},{"inputs":[],"name":"RoyaltyModule__NotAllowedCaller","type":"error"},{"inputs":[],"name":"RoyaltyModule__NotWhitelistedRoyaltyPolicy","type":"error"},{"inputs":[],"name":"RoyaltyModule__NotWhitelistedRoyaltyToken","type":"error"},{"inputs":[],"name":"RoyaltyModule__ZeroLicensingModule","type":"error"},{"inputs":[],"name":"RoyaltyModule__ZeroRoyaltyPolicy","type":"error"},{"inputs":[],"name":"RoyaltyModule__ZeroRoyaltyToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newGovernance","type":"address"}],"name":"GovernanceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"receiverIpId","type":"address"},{"indexed":false,"internalType":"address","name":"payerIpId","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RoyaltyPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"ipId","type":"address"},{"indexed":false,"internalType":"address","name":"royaltyPolicy","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"RoyaltyPolicySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"royaltyPolicy","type":"address"},{"indexed":false,"internalType":"bool","name":"allowed","type":"bool"}],"name":"RoyaltyPolicyWhitelistUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bool","name":"allowed","type":"bool"}],"name":"RoyaltyTokenWhitelistUpdated","type":"event"},{"inputs":[],"name":"LICENSING_MODULE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"ipId","type":"address"}],"name":"isRoyaltyPolicyImmutable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"royaltyPolicy","type":"address"}],"name":"isWhitelistedRoyaltyPolicy","outputs":[{"internalType":"bool","name":"allowed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"isWhitelistedRoyaltyToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_ipId","type":"address"}],"name":"minRoyaltyFromDescendants","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_receiverIpId","type":"address"},{"internalType":"address","name":"_payerIpId","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"payRoyaltyOnBehalf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"ipId","type":"address"}],"name":"royaltyPolicies","outputs":[{"internalType":"address","name":"royaltyPolicy","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newGovernance","type":"address"}],"name":"setGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_licensingModule","type":"address"}],"name":"setLicensingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ipId","type":"address"},{"internalType":"address","name":"_royaltyPolicy","type":"address"},{"internalType":"address[]","name":"_parentIpIds","type":"address[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"setRoyaltyPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ipId","type":"address"}],"name":"setRoyaltyPolicyImmutable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_royaltyPolicy","type":"address"},{"internalType":"bool","name":"_allowed","type":"bool"}],"name":"whitelistRoyaltyPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"bool","name":"_allowed","type":"bool"}],"name":"whitelistRoyaltyToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
0x608060405234801561001057600080fd5b50604051611a2e380380611a2e83398101604081905261002f916100a7565b806001600160a01b0381166100575760405163239261b360e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b038316908117825560405190917f9d3e522e1e47a2f6009739342b9cc7b252a1888154e843ab55ee1c81745795ab91a25050600180556100d7565b6000602082840312156100b957600080fd5b81516001600160a01b03811681146100d057600080fd5b9392505050565b611948806100e66000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638296ad1c11610097578063cc5b608411610066578063cc5b6084146102d1578063d2577f3b146102e4578063e06b635c146102f7578063f5f76ca81461031a57600080fd5b80638296ad1c14610247578063926e04fd14610268578063964678141461029b578063ab033ea9146102be57600080fd5b806349fb4615116100d357806349fb4615146101e1578063520cbac6146101f45780635aa6e6751461020757806365165aa51461022757600080fd5b806306fdde0314610105578063289b3c0d146101575780632930af8b1461019657806340ff6bd2146101cc575b600080fd5b6101416040518060400160405280600e81526020017f524f59414c54595f4d4f44554c4500000000000000000000000000000000000081525081565b60405161014e91906114ad565b60405180910390f35b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014e565b6101716101a4366004611543565b60056020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6101df6101da366004611543565b61032d565b005b6101df6101ef36600461156f565b6103cd565b6101df61020236600461156f565b610578565b6000546101719073ffffffffffffffffffffffffffffffffffffffff1681565b6002546101719073ffffffffffffffffffffffffffffffffffffffff1681565b61025a610255366004611543565b61071b565b60405190815260200161014e565b61028b610276366004611543565b60046020526000908152604090205460ff1681565b604051901515815260200161014e565b61028b6102a9366004611543565b60036020526000908152604090205460ff1681565b6101df6102cc366004611543565b610819565b6101df6102df366004611543565b610b8c565b6101df6102f23660046115a6565b610cef565b61028b610305366004611543565b60066020526000908152604090205460ff1681565b6101df61032836600461163a565b610f20565b60025473ffffffffffffffffffffffffffffffffffffffff16331461037e576040517f6f34205e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600080546040517f91d14854000000000000000000000000000000000000000000000000000000008152600481019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906391d1485490604401602060405180830381865afa158015610442573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046691906116fc565b61049c576040517f59a8f42a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166104e9576040517fb3c4f5c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558251938452908301527f1f584640e1aae6441a6deba8d18148f5c9fb11a0bd7640e4b2808383a966269091015b60405180910390a15050565b600080546040517f91d14854000000000000000000000000000000000000000000000000000000008152600481019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906391d1485490604401602060405180830381865afa1580156105ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061191906116fc565b610647576040517f59a8f42a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216610694576040517f6bed9b9600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558251938452908301527fb40e5b8c4310e269d81608ec0e28372febb69a03ed8ace904c86459366cc3627910161056c565b73ffffffffffffffffffffffffffffffffffffffff8082166000908152600560205260408120549091168061077c576040517fd5c3d2f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f8296ad1c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152821690638296ad1c90602401602060405180830381865afa1580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c9190611719565b63ffffffff169392505050565b600080546040517f91d14854000000000000000000000000000000000000000000000000000000008152600481019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906391d1485490604401602060405180830381865afa15801561088e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b291906116fc565b6108e8576040517f59a8f42a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610935576040517f4724c36600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61095f817f4ebb53a6000000000000000000000000000000000000000000000000000000006112f4565b6109c8576040517ea73c8d00000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f49476f7665726e616e6365000000000000000000000000000000000000000000604482015260640160405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631865c57d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a57919061173f565b6001811115610a6857610a68611760565b8173ffffffffffffffffffffffffffffffffffffffff16631865c57d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ab3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad7919061173f565b6001811115610ae857610ae8611760565b14610b1f576040517f649cdd9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f9d3e522e1e47a2f6009739342b9cc7b252a1888154e843ab55ee1c81745795ab91a250565b600080546040517f91d14854000000000000000000000000000000000000000000000000000000008152600481019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906391d1485490604401602060405180830381865afa158015610c01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2591906116fc565b610c5b576040517f59a8f42a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610ca8576040517f7c5eee2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610cf7611317565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600560205260409020541680610d56576040517fd5c3d2f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526004602052604090205460ff16610db5576040517f7227c77800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090205460ff16610e14576040517f06b627fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5be8968b00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8681166024830152848116604483015260648201849052821690635be8968b90608401600060405180830381600087803b158015610e9257600080fd5b505af1158015610ea6573d6000803e3d6000fd5b50506040805173ffffffffffffffffffffffffffffffffffffffff898116825288811660208301523382840152871660608201526080810186905290517fe0ee75d70c5bcafc95db3e81961af1375efcd0e19fbfd7cae8a85f41c68e2d2d93509081900360a0019150a150610f1a60018055565b50505050565b610f28611317565b60025473ffffffffffffffffffffffffffffffffffffffff163314610f79576040517f6f34205e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861660009081526006602052604090205460ff1615610fd9576040517f16f86d6f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff851660009081526003602052604090205460ff16611038576040517f06b627fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b821561108d5773ffffffffffffffffffffffffffffffffffffffff8616600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b60005b63ffffffff81168411156111df578573ffffffffffffffffffffffffffffffffffffffff166005600087878563ffffffff168181106110d1576110d161178f565b90506020020160208101906110e69190611543565b73ffffffffffffffffffffffffffffffffffffffff90811682526020820192909252604001600020541614611147576040517f9739ce9100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016006600087878563ffffffff168181106111655761116561178f565b905060200201602081019061117a9190611543565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806111d7816117be565b915050611090565b5073ffffffffffffffffffffffffffffffffffffffff8681166000908152600560205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169288169283179055517f2fd0a9bf000000000000000000000000000000000000000000000000000000008152632fd0a9bf906112749089908890889088908890600401611851565b600060405180830381600087803b15801561128e57600080fd5b505af11580156112a2573d6000803e3d6000fd5b505050507fcbe100c36abd13680863f25364d62ee301a90dc5683227134a30e9b60e2161a7868684846040516112db94939291906118ce565b60405180910390a16112ec60018055565b505050505050565b60006112ff8361135a565b8015611310575061131083836113bf565b9392505050565b600260015403611353576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600155565b6000611386827f01ffc9a7000000000000000000000000000000000000000000000000000000006113bf565b80156113b957506113b7827fffffffff000000000000000000000000000000000000000000000000000000006113bf565b155b92915050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000821660248201526000908190604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015611496575060208210155b80156114a25750600081115b979650505050505050565b60006020808352835180602085015260005b818110156114db578581018301518582016040015282016114bf565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461153e57600080fd5b919050565b60006020828403121561155557600080fd5b6113108261151a565b801515811461156c57600080fd5b50565b6000806040838503121561158257600080fd5b61158b8361151a565b9150602083013561159b8161155e565b809150509250929050565b600080600080608085870312156115bc57600080fd5b6115c58561151a565b93506115d36020860161151a565b92506115e16040860161151a565b9396929550929360600135925050565b60008083601f84011261160357600080fd5b50813567ffffffffffffffff81111561161b57600080fd5b60208301915083602082850101111561163357600080fd5b9250929050565b6000806000806000806080878903121561165357600080fd5b61165c8761151a565b955061166a6020880161151a565b9450604087013567ffffffffffffffff8082111561168757600080fd5b818901915089601f83011261169b57600080fd5b8135818111156116aa57600080fd5b8a60208260051b85010111156116bf57600080fd5b6020830196508095505060608901359150808211156116dd57600080fd5b506116ea89828a016115f1565b979a9699509497509295939492505050565b60006020828403121561170e57600080fd5b81516113108161155e565b60006020828403121561172b57600080fd5b815163ffffffff8116811461131057600080fd5b60006020828403121561175157600080fd5b81516002811061131057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036117fe577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff868116825260606020808401829052908301869052600091879160808501845b898110156118ab57836118988661151a565b1682529382019390820190600101611886565b5085810360408701526118bf81888a611808565b9b9a5050505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060606040830152611908606083018486611808565b969550505050505056fea264697066735822122036a66777b5a864fbfc9dcab7fb7483b42341941e2d78a2813f730a2cb5e9fc9564736f6c63430008170033000000000000000000000000d46a8c1cd01dd7bdc4fa8c928e9b1df28efc6e43
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101005760003560e01c80638296ad1c11610097578063cc5b608411610066578063cc5b6084146102d1578063d2577f3b146102e4578063e06b635c146102f7578063f5f76ca81461031a57600080fd5b80638296ad1c14610247578063926e04fd14610268578063964678141461029b578063ab033ea9146102be57600080fd5b806349fb4615116100d357806349fb4615146101e1578063520cbac6146101f45780635aa6e6751461020757806365165aa51461022757600080fd5b806306fdde0314610105578063289b3c0d146101575780632930af8b1461019657806340ff6bd2146101cc575b600080fd5b6101416040518060400160405280600e81526020017f524f59414c54595f4d4f44554c4500000000000000000000000000000000000081525081565b60405161014e91906114ad565b60405180910390f35b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014e565b6101716101a4366004611543565b60056020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b6101df6101da366004611543565b61032d565b005b6101df6101ef36600461156f565b6103cd565b6101df61020236600461156f565b610578565b6000546101719073ffffffffffffffffffffffffffffffffffffffff1681565b6002546101719073ffffffffffffffffffffffffffffffffffffffff1681565b61025a610255366004611543565b61071b565b60405190815260200161014e565b61028b610276366004611543565b60046020526000908152604090205460ff1681565b604051901515815260200161014e565b61028b6102a9366004611543565b60036020526000908152604090205460ff1681565b6101df6102cc366004611543565b610819565b6101df6102df366004611543565b610b8c565b6101df6102f23660046115a6565b610cef565b61028b610305366004611543565b60066020526000908152604090205460ff1681565b6101df61032836600461163a565b610f20565b60025473ffffffffffffffffffffffffffffffffffffffff16331461037e576040517f6f34205e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600080546040517f91d14854000000000000000000000000000000000000000000000000000000008152600481019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906391d1485490604401602060405180830381865afa158015610442573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046691906116fc565b61049c576040517f59a8f42a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166104e9576040517fb3c4f5c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558251938452908301527f1f584640e1aae6441a6deba8d18148f5c9fb11a0bd7640e4b2808383a966269091015b60405180910390a15050565b600080546040517f91d14854000000000000000000000000000000000000000000000000000000008152600481019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906391d1485490604401602060405180830381865afa1580156105ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061191906116fc565b610647576040517f59a8f42a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216610694576040517f6bed9b9600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558251938452908301527fb40e5b8c4310e269d81608ec0e28372febb69a03ed8ace904c86459366cc3627910161056c565b73ffffffffffffffffffffffffffffffffffffffff8082166000908152600560205260408120549091168061077c576040517fd5c3d2f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f8296ad1c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152821690638296ad1c90602401602060405180830381865afa1580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c9190611719565b63ffffffff169392505050565b600080546040517f91d14854000000000000000000000000000000000000000000000000000000008152600481019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906391d1485490604401602060405180830381865afa15801561088e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b291906116fc565b6108e8576040517f59a8f42a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610935576040517f4724c36600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61095f817f4ebb53a6000000000000000000000000000000000000000000000000000000006112f4565b6109c8576040517ea73c8d00000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f49476f7665726e616e6365000000000000000000000000000000000000000000604482015260640160405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631865c57d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a57919061173f565b6001811115610a6857610a68611760565b8173ffffffffffffffffffffffffffffffffffffffff16631865c57d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ab3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad7919061173f565b6001811115610ae857610ae8611760565b14610b1f576040517f649cdd9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f9d3e522e1e47a2f6009739342b9cc7b252a1888154e843ab55ee1c81745795ab91a250565b600080546040517f91d14854000000000000000000000000000000000000000000000000000000008152600481019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906391d1485490604401602060405180830381865afa158015610c01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2591906116fc565b610c5b576040517f59a8f42a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610ca8576040517f7c5eee2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610cf7611317565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600560205260409020541680610d56576040517fd5c3d2f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526004602052604090205460ff16610db5576040517f7227c77800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090205460ff16610e14576040517f06b627fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f5be8968b00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8681166024830152848116604483015260648201849052821690635be8968b90608401600060405180830381600087803b158015610e9257600080fd5b505af1158015610ea6573d6000803e3d6000fd5b50506040805173ffffffffffffffffffffffffffffffffffffffff898116825288811660208301523382840152871660608201526080810186905290517fe0ee75d70c5bcafc95db3e81961af1375efcd0e19fbfd7cae8a85f41c68e2d2d93509081900360a0019150a150610f1a60018055565b50505050565b610f28611317565b60025473ffffffffffffffffffffffffffffffffffffffff163314610f79576040517f6f34205e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861660009081526006602052604090205460ff1615610fd9576040517f16f86d6f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff851660009081526003602052604090205460ff16611038576040517f06b627fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b821561108d5773ffffffffffffffffffffffffffffffffffffffff8616600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b60005b63ffffffff81168411156111df578573ffffffffffffffffffffffffffffffffffffffff166005600087878563ffffffff168181106110d1576110d161178f565b90506020020160208101906110e69190611543565b73ffffffffffffffffffffffffffffffffffffffff90811682526020820192909252604001600020541614611147576040517f9739ce9100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016006600087878563ffffffff168181106111655761116561178f565b905060200201602081019061117a9190611543565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806111d7816117be565b915050611090565b5073ffffffffffffffffffffffffffffffffffffffff8681166000908152600560205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169288169283179055517f2fd0a9bf000000000000000000000000000000000000000000000000000000008152632fd0a9bf906112749089908890889088908890600401611851565b600060405180830381600087803b15801561128e57600080fd5b505af11580156112a2573d6000803e3d6000fd5b505050507fcbe100c36abd13680863f25364d62ee301a90dc5683227134a30e9b60e2161a7868684846040516112db94939291906118ce565b60405180910390a16112ec60018055565b505050505050565b60006112ff8361135a565b8015611310575061131083836113bf565b9392505050565b600260015403611353576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600155565b6000611386827f01ffc9a7000000000000000000000000000000000000000000000000000000006113bf565b80156113b957506113b7827fffffffff000000000000000000000000000000000000000000000000000000006113bf565b155b92915050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000821660248201526000908190604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825192935060009283928392909183918a617530fa92503d91506000519050828015611496575060208210155b80156114a25750600081115b979650505050505050565b60006020808352835180602085015260005b818110156114db578581018301518582016040015282016114bf565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461153e57600080fd5b919050565b60006020828403121561155557600080fd5b6113108261151a565b801515811461156c57600080fd5b50565b6000806040838503121561158257600080fd5b61158b8361151a565b9150602083013561159b8161155e565b809150509250929050565b600080600080608085870312156115bc57600080fd5b6115c58561151a565b93506115d36020860161151a565b92506115e16040860161151a565b9396929550929360600135925050565b60008083601f84011261160357600080fd5b50813567ffffffffffffffff81111561161b57600080fd5b60208301915083602082850101111561163357600080fd5b9250929050565b6000806000806000806080878903121561165357600080fd5b61165c8761151a565b955061166a6020880161151a565b9450604087013567ffffffffffffffff8082111561168757600080fd5b818901915089601f83011261169b57600080fd5b8135818111156116aa57600080fd5b8a60208260051b85010111156116bf57600080fd5b6020830196508095505060608901359150808211156116dd57600080fd5b506116ea89828a016115f1565b979a9699509497509295939492505050565b60006020828403121561170e57600080fd5b81516113108161155e565b60006020828403121561172b57600080fd5b815163ffffffff8116811461131057600080fd5b60006020828403121561175157600080fd5b81516002811061131057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600063ffffffff8083168181036117fe577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001019392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff868116825260606020808401829052908301869052600091879160808501845b898110156118ab57836118988661151a565b1682529382019390820190600101611886565b5085810360408701526118bf81888a611808565b9b9a5050505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060606040830152611908606083018486611808565b969550505050505056fea264697066735822122036a66777b5a864fbfc9dcab7fb7483b42341941e2d78a2813f730a2cb5e9fc9564736f6c63430008170033
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.