Source Code
Overview
S Balance
0 S
More Info
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
5592392 | 4 days ago | 0 S |
Loading...
Loading
Contract Name:
CultBearsV2
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import '@layerzerolabs/onft-evm/contracts/onft721/ONFT721.sol'; import '@openzeppelin/contracts/utils/Strings.sol'; import '@openzeppelin/contracts/token/common/ERC2981.sol'; import '@openzeppelin/contracts/utils/Pausable.sol'; contract CultBearsV2 is ONFT721, ERC2981, Pausable { using Strings for uint256; enum TokenRarityType { COMMON, RARE, ULTRA_RARE, LEGENDARY, MYTHIC } string public baseURI; string public fileExtension = '.json'; uint256 public constant maxSupply = 2000; event URIUpdated(string newBaseURI); event FileExtensionUpdated(string newExtension); event RoyaltySet(address indexed receiver, uint96 feeNumerator); constructor( string memory _name, string memory _symbol, address _lzEndpoint, address _delegate, string memory initialBaseURI ) ONFT721(_name, _symbol, _lzEndpoint, _delegate) { baseURI = initialBaseURI; _setDefaultRoyalty(msg.sender, 500); // 5% default royalty } function setFileExtension(string memory extension) external onlyOwner whenNotPaused { require(bytes(extension).length > 0, "File extension cannot be empty"); fileExtension = extension; emit FileExtensionUpdated(extension); } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_existsToken(tokenId), "ERC721Metadata: URI query for nonexistent token"); return string(abi.encodePacked(baseURI, "cult-bear-", tokenId.toString(), fileExtension)); } function _existsToken(uint256 tokenId) internal view returns (bool) { try this.ownerOf(tokenId) returns (address owner) { return owner != address(0); } catch { return false; } } function getRarity(uint256 tokenId) public pure returns (TokenRarityType) { require(tokenId > 0 && tokenId <= 2000, "Token ID out of range"); if (tokenId <= 2 || (tokenId >= 1001 && tokenId <= 1002)) return TokenRarityType.MYTHIC; if ((tokenId >= 3 && tokenId <= 15) || (tokenId >= 1003 && tokenId <= 1015)) return TokenRarityType.LEGENDARY; if ((tokenId >= 16 && tokenId <= 40) || (tokenId >= 1016 && tokenId <= 1040)) return TokenRarityType.ULTRA_RARE; if ((tokenId >= 41 && tokenId <= 90) || (tokenId >= 1041 && tokenId <= 1090)) return TokenRarityType.RARE; return TokenRarityType.COMMON; } function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) external onlyOwner whenNotPaused { _setTokenRoyalty(tokenId, receiver, feeNumerator); emit RoyaltySet(receiver, feeNumerator); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { IMessageLibManager } from "./IMessageLibManager.sol"; import { IMessagingComposer } from "./IMessagingComposer.sol"; import { IMessagingChannel } from "./IMessagingChannel.sol"; import { IMessagingContext } from "./IMessagingContext.sol"; struct MessagingParams { uint32 dstEid; bytes32 receiver; bytes message; bytes options; bool payInLzToken; } struct MessagingReceipt { bytes32 guid; uint64 nonce; MessagingFee fee; } struct MessagingFee { uint256 nativeFee; uint256 lzTokenFee; } struct Origin { uint32 srcEid; bytes32 sender; uint64 nonce; } interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext { event PacketSent(bytes encodedPayload, bytes options, address sendLibrary); event PacketVerified(Origin origin, address receiver, bytes32 payloadHash); event PacketDelivered(Origin origin, address receiver); event LzReceiveAlert( address indexed receiver, address indexed executor, Origin origin, bytes32 guid, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); event LzTokenSet(address token); event DelegateSet(address sender, address delegate); function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory); function send( MessagingParams calldata _params, address _refundAddress ) external payable returns (MessagingReceipt memory); function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external; function verifiable(Origin calldata _origin, address _receiver) external view returns (bool); function initializable(Origin calldata _origin, address _receiver) external view returns (bool); function lzReceive( Origin calldata _origin, address _receiver, bytes32 _guid, bytes calldata _message, bytes calldata _extraData ) external payable; // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external; function setLzToken(address _lzToken) external; function lzToken() external view returns (address); function nativeToken() external view returns (address); function setDelegate(address _delegate) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { Origin } from "./ILayerZeroEndpointV2.sol"; interface ILayerZeroReceiver { function allowInitializePath(Origin calldata _origin) external view returns (bool); function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64); function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { SetConfigParam } from "./IMessageLibManager.sol"; enum MessageLibType { Send, Receive, SendAndReceive } interface IMessageLib is IERC165 { function setConfig(address _oapp, SetConfigParam[] calldata _config) external; function getConfig(uint32 _eid, address _oapp, uint32 _configType) external view returns (bytes memory config); function isSupportedEid(uint32 _eid) external view returns (bool); // message libs of same major version are compatible function version() external view returns (uint64 major, uint8 minor, uint8 endpointVersion); function messageLibType() external view returns (MessageLibType); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; struct SetConfigParam { uint32 eid; uint32 configType; bytes config; } interface IMessageLibManager { struct Timeout { address lib; uint256 expiry; } event LibraryRegistered(address newLib); event DefaultSendLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry); event SendLibrarySet(address sender, uint32 eid, address newLib); event ReceiveLibrarySet(address receiver, uint32 eid, address newLib); event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout); function registerLibrary(address _lib) external; function isRegisteredLibrary(address _lib) external view returns (bool); function getRegisteredLibraries() external view returns (address[] memory); function setDefaultSendLibrary(uint32 _eid, address _newLib) external; function defaultSendLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external; function defaultReceiveLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external; function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry); function isSupportedEid(uint32 _eid) external view returns (bool); function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool); /// ------------------- OApp interfaces ------------------- function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external; function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib); function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool); function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external; function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault); function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external; function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry); function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external; function getConfig( address _oapp, address _lib, uint32 _eid, uint32 _configType ) external view returns (bytes memory config); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingChannel { event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce); event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); function eid() external view returns (uint32); // this is an emergency function if a message cannot be verified for some reasons // required to provide _nextNonce to avoid race condition function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external; function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32); function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64); function inboundPayloadHash( address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce ) external view returns (bytes32); function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingComposer { event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message); event ComposeDelivered(address from, address to, bytes32 guid, uint16 index); event LzComposeAlert( address indexed from, address indexed to, address indexed executor, bytes32 guid, uint16 index, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); function composeQueue( address _from, address _to, bytes32 _guid, uint16 _index ) external view returns (bytes32 messageHash); function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external; function lzCompose( address _from, address _to, bytes32 _guid, uint16 _index, bytes calldata _message, bytes calldata _extraData ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingContext { function isSendingMessage() external view returns (bool); function getSendContext() external view returns (uint32 dstEid, address sender); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { MessagingFee } from "./ILayerZeroEndpointV2.sol"; import { IMessageLib } from "./IMessageLib.sol"; struct Packet { uint64 nonce; uint32 srcEid; address sender; uint32 dstEid; bytes32 receiver; bytes32 guid; bytes message; } interface ISendLib is IMessageLib { function send( Packet calldata _packet, bytes calldata _options, bool _payInLzToken ) external returns (MessagingFee memory, bytes memory encodedPacket); function quote( Packet calldata _packet, bytes calldata _options, bool _payInLzToken ) external view returns (MessagingFee memory); function setTreasury(address _treasury) external; function withdrawFee(address _to, uint256 _amount) external; function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external; }
// SPDX-License-Identifier: LZBL-1.2 pragma solidity ^0.8.20; library AddressCast { error AddressCast_InvalidSizeForAddress(); error AddressCast_InvalidAddress(); function toBytes32(bytes calldata _addressBytes) internal pure returns (bytes32 result) { if (_addressBytes.length > 32) revert AddressCast_InvalidAddress(); result = bytes32(_addressBytes); unchecked { uint256 offset = 32 - _addressBytes.length; result = result >> (offset * 8); } } function toBytes32(address _address) internal pure returns (bytes32 result) { result = bytes32(uint256(uint160(_address))); } function toBytes(bytes32 _addressBytes32, uint256 _size) internal pure returns (bytes memory result) { if (_size == 0 || _size > 32) revert AddressCast_InvalidSizeForAddress(); result = new bytes(_size); unchecked { uint256 offset = 256 - _size * 8; assembly { mstore(add(result, 32), shl(offset, _addressBytes32)) } } } function toAddress(bytes32 _addressBytes32) internal pure returns (address result) { result = address(uint160(uint256(_addressBytes32))); } function toAddress(bytes calldata _addressBytes) internal pure returns (address result) { if (_addressBytes.length != 20) revert AddressCast_InvalidAddress(); result = address(bytes20(_addressBytes)); } }
// SPDX-License-Identifier: LZBL-1.2 pragma solidity ^0.8.20; import { Packet } from "../../interfaces/ISendLib.sol"; import { AddressCast } from "../../libs/AddressCast.sol"; library PacketV1Codec { using AddressCast for address; using AddressCast for bytes32; uint8 internal constant PACKET_VERSION = 1; // header (version + nonce + path) // version uint256 private constant PACKET_VERSION_OFFSET = 0; // nonce uint256 private constant NONCE_OFFSET = 1; // path uint256 private constant SRC_EID_OFFSET = 9; uint256 private constant SENDER_OFFSET = 13; uint256 private constant DST_EID_OFFSET = 45; uint256 private constant RECEIVER_OFFSET = 49; // payload (guid + message) uint256 private constant GUID_OFFSET = 81; // keccak256(nonce + path) uint256 private constant MESSAGE_OFFSET = 113; function encode(Packet memory _packet) internal pure returns (bytes memory encodedPacket) { encodedPacket = abi.encodePacked( PACKET_VERSION, _packet.nonce, _packet.srcEid, _packet.sender.toBytes32(), _packet.dstEid, _packet.receiver, _packet.guid, _packet.message ); } function encodePacketHeader(Packet memory _packet) internal pure returns (bytes memory) { return abi.encodePacked( PACKET_VERSION, _packet.nonce, _packet.srcEid, _packet.sender.toBytes32(), _packet.dstEid, _packet.receiver ); } function encodePayload(Packet memory _packet) internal pure returns (bytes memory) { return abi.encodePacked(_packet.guid, _packet.message); } function header(bytes calldata _packet) internal pure returns (bytes calldata) { return _packet[0:GUID_OFFSET]; } function version(bytes calldata _packet) internal pure returns (uint8) { return uint8(bytes1(_packet[PACKET_VERSION_OFFSET:NONCE_OFFSET])); } function nonce(bytes calldata _packet) internal pure returns (uint64) { return uint64(bytes8(_packet[NONCE_OFFSET:SRC_EID_OFFSET])); } function srcEid(bytes calldata _packet) internal pure returns (uint32) { return uint32(bytes4(_packet[SRC_EID_OFFSET:SENDER_OFFSET])); } function sender(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[SENDER_OFFSET:DST_EID_OFFSET]); } function senderAddressB20(bytes calldata _packet) internal pure returns (address) { return sender(_packet).toAddress(); } function dstEid(bytes calldata _packet) internal pure returns (uint32) { return uint32(bytes4(_packet[DST_EID_OFFSET:RECEIVER_OFFSET])); } function receiver(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[RECEIVER_OFFSET:GUID_OFFSET]); } function receiverB20(bytes calldata _packet) internal pure returns (address) { return receiver(_packet).toAddress(); } function guid(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[GUID_OFFSET:MESSAGE_OFFSET]); } function message(bytes calldata _packet) internal pure returns (bytes calldata) { return bytes(_packet[MESSAGE_OFFSET:]); } function payload(bytes calldata _packet) internal pure returns (bytes calldata) { return bytes(_packet[GUID_OFFSET:]); } function payloadHash(bytes calldata _packet) internal pure returns (bytes32) { return keccak256(payload(_packet)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { ILayerZeroEndpointV2 } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; /** * @title IOAppCore */ interface IOAppCore { // Custom error messages error OnlyPeer(uint32 eid, bytes32 sender); error NoPeer(uint32 eid); error InvalidEndpointCall(); error InvalidDelegate(); // Event emitted when a peer (OApp) is set for a corresponding endpoint event PeerSet(uint32 eid, bytes32 peer); /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. */ function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion); /** * @notice Retrieves the LayerZero endpoint associated with the OApp. * @return iEndpoint The LayerZero endpoint as an interface. */ function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint); /** * @notice Retrieves the peer (OApp) associated with a corresponding endpoint. * @param _eid The endpoint ID. * @return peer The peer address (OApp instance) associated with the corresponding endpoint. */ function peers(uint32 _eid) external view returns (bytes32 peer); /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. */ function setPeer(uint32 _eid, bytes32 _peer) external; /** * @notice Sets the delegate address for the OApp Core. * @param _delegate The address of the delegate to be set. */ function setDelegate(address _delegate) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title IOAppMsgInspector * @dev Interface for the OApp Message Inspector, allowing examination of message and options contents. */ interface IOAppMsgInspector { // Custom error message for inspection failure error InspectionFailed(bytes message, bytes options); /** * @notice Allows the inspector to examine LayerZero message contents and optionally throw a revert if invalid. * @param _message The message payload to be inspected. * @param _options Additional options or parameters for inspection. * @return valid A boolean indicating whether the inspection passed (true) or failed (false). * * @dev Optionally done as a revert, OR use the boolean provided to handle the failure. */ function inspect(bytes calldata _message, bytes calldata _options) external view returns (bool valid); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Struct representing enforced option parameters. */ struct EnforcedOptionParam { uint32 eid; // Endpoint ID uint16 msgType; // Message Type bytes options; // Additional options } /** * @title IOAppOptionsType3 * @dev Interface for the OApp with Type 3 Options, allowing the setting and combining of enforced options. */ interface IOAppOptionsType3 { // Custom error message for invalid options error InvalidOptions(bytes options); // Event emitted when enforced options are set event EnforcedOptionSet(EnforcedOptionParam[] _enforcedOptions); /** * @notice Sets enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) external; /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OApp message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) external view returns (bytes memory options); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { ILayerZeroReceiver, Origin } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol"; interface IOAppReceiver is ILayerZeroReceiver { /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata _origin, bytes calldata _message, address _sender ) external view returns (bool isSender); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IOAppOptionsType3, EnforcedOptionParam } from "../interfaces/IOAppOptionsType3.sol"; /** * @title OAppOptionsType3 * @dev Abstract contract implementing the IOAppOptionsType3 interface with type 3 options. */ abstract contract OAppOptionsType3 is IOAppOptionsType3, Ownable { uint16 internal constant OPTION_TYPE_3 = 3; // @dev The "msgType" should be defined in the child contract. mapping(uint32 eid => mapping(uint16 msgType => bytes enforcedOption)) public enforcedOptions; /** * @dev Sets the enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc. * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType. * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose(). */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) public virtual onlyOwner { _setEnforcedOptions(_enforcedOptions); } /** * @dev Sets the enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. * * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc. * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType. * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose(). */ function _setEnforcedOptions(EnforcedOptionParam[] memory _enforcedOptions) internal virtual { for (uint256 i = 0; i < _enforcedOptions.length; i++) { // @dev Enforced options are only available for optionType 3, as type 1 and 2 dont support combining. _assertOptionsType3(_enforcedOptions[i].options); enforcedOptions[_enforcedOptions[i].eid][_enforcedOptions[i].msgType] = _enforcedOptions[i].options; } emit EnforcedOptionSet(_enforcedOptions); } /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OAPP message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. * * @dev If there is an enforced lzReceive option: * - {gasLimit: 200k, msg.value: 1 ether} AND a caller supplies a lzReceive option: {gasLimit: 100k, msg.value: 0.5 ether} * - The resulting options will be {gasLimit: 300k, msg.value: 1.5 ether} when the message is executed on the remote lzReceive() function. * @dev This presence of duplicated options is handled off-chain in the verifier/executor. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) public view virtual returns (bytes memory) { bytes memory enforced = enforcedOptions[_eid][_msgType]; // No enforced options, pass whatever the caller supplied, even if it's empty or legacy type 1/2 options. if (enforced.length == 0) return _extraOptions; // No caller options, return enforced if (_extraOptions.length == 0) return enforced; // @dev If caller provided _extraOptions, must be type 3 as its the ONLY type that can be combined. if (_extraOptions.length >= 2) { _assertOptionsType3(_extraOptions); // @dev Remove the first 2 bytes containing the type from the _extraOptions and combine with enforced. return bytes.concat(enforced, _extraOptions[2:]); } // No valid set of options was found. revert InvalidOptions(_extraOptions); } /** * @dev Internal function to assert that options are of type 3. * @param _options The options to be checked. */ function _assertOptionsType3(bytes memory _options) internal pure virtual { uint16 optionsType; assembly { optionsType := mload(add(_options, 2)) } if (optionsType != OPTION_TYPE_3) revert InvalidOptions(_options); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; // @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import import { OAppSender, MessagingFee, MessagingReceipt } from "./OAppSender.sol"; // @dev Import the 'Origin' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import import { OAppReceiver, Origin } from "./OAppReceiver.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OApp * @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver functionality. */ abstract contract OApp is OAppSender, OAppReceiver { /** * @dev Constructor to initialize the OApp with the provided endpoint and owner. * @param _endpoint The address of the LOCAL LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(address _endpoint, address _delegate) OAppCore(_endpoint, _delegate) {} /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol implementation. * @return receiverVersion The version of the OAppReceiver.sol implementation. */ function oAppVersion() public pure virtual override(OAppSender, OAppReceiver) returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, RECEIVER_VERSION); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IOAppCore, ILayerZeroEndpointV2 } from "./interfaces/IOAppCore.sol"; /** * @title OAppCore * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations. */ abstract contract OAppCore is IOAppCore, Ownable { // The LayerZero endpoint associated with the given OApp ILayerZeroEndpointV2 public immutable endpoint; // Mapping to store peers associated with corresponding endpoints mapping(uint32 eid => bytes32 peer) public peers; /** * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate. * @param _endpoint The address of the LOCAL Layer Zero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. * * @dev The delegate typically should be set as the owner of the contract. */ constructor(address _endpoint, address _delegate) { endpoint = ILayerZeroEndpointV2(_endpoint); if (_delegate == address(0)) revert InvalidDelegate(); endpoint.setDelegate(_delegate); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Only the owner/admin of the OApp can call this function. * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner { _setPeer(_eid, _peer); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function _setPeer(uint32 _eid, bytes32 _peer) internal virtual { peers[_eid] = _peer; emit PeerSet(_eid, _peer); } /** * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set. * ie. the peer is set to bytes32(0). * @param _eid The endpoint ID. * @return peer The address of the peer associated with the specified endpoint. */ function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) { bytes32 peer = peers[_eid]; if (peer == bytes32(0)) revert NoPeer(_eid); return peer; } /** * @notice Sets the delegate address for the OApp. * @param _delegate The address of the delegate to be set. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract. */ function setDelegate(address _delegate) public onlyOwner { endpoint.setDelegate(_delegate); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { IOAppReceiver, Origin } from "./interfaces/IOAppReceiver.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OAppReceiver * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers. */ abstract contract OAppReceiver is IOAppReceiver, OAppCore { // Custom error message for when the caller is not the registered endpoint/ error OnlyEndpoint(address addr); // @dev The version of the OAppReceiver implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant RECEIVER_VERSION = 2; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented. * ie. this is a RECEIVE only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions. */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (0, RECEIVER_VERSION); } /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @dev _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @dev _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement separate composeMsg senders that are NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata /*_origin*/, bytes calldata /*_message*/, address _sender ) public view virtual returns (bool) { return _sender == address(this); } /** * @notice Checks if the path initialization is allowed based on the provided origin. * @param origin The origin information containing the source endpoint and sender address. * @return Whether the path has been initialized. * * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received. * @dev This defaults to assuming if a peer has been set, its initialized. * Can be overridden by the OApp if there is other logic to determine this. */ function allowInitializePath(Origin calldata origin) public view virtual returns (bool) { return peers[origin.srcEid] == origin.sender; } /** * @notice Retrieves the next nonce for a given source endpoint and sender address. * @dev _srcEid The source endpoint ID. * @dev _sender The sender address. * @return nonce The next nonce. * * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement. * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered. * @dev This is also enforced by the OApp. * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0. */ function nextNonce(uint32 /*_srcEid*/, bytes32 /*_sender*/) public view virtual returns (uint64 nonce) { return 0; } /** * @dev Entry point for receiving messages or packets from the endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The payload of the received message. * @param _executor The address of the executor for the received message. * @param _extraData Additional arbitrary data provided by the corresponding executor. * * @dev Entry point for receiving msg/packet from the LayerZero endpoint. */ function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) public payable virtual { // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp. if (address(endpoint) != msg.sender) revert OnlyEndpoint(msg.sender); // Ensure that the sender matches the expected peer for the source endpoint. if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) revert OnlyPeer(_origin.srcEid, _origin.sender); // Call the internal OApp implementation of lzReceive. _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { MessagingParams, MessagingFee, MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OAppSender * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint. */ abstract contract OAppSender is OAppCore { using SafeERC20 for IERC20; // Custom error messages error NotEnoughNative(uint256 msgValue); error LzTokenUnavailable(); // @dev The version of the OAppSender implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant SENDER_VERSION = 1; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented. * ie. this is a SEND only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, 0); } /** * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens. * @return fee The calculated MessagingFee for the message. * - nativeFee: The native fee for the message. * - lzTokenFee: The LZ token fee for the message. */ function _quote( uint32 _dstEid, bytes memory _message, bytes memory _options, bool _payInLzToken ) internal view virtual returns (MessagingFee memory fee) { return endpoint.quote( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), address(this) ); } /** * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _fee The calculated LayerZero fee for the message. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess fee values sent to the endpoint. * @return receipt The receipt for the sent message. * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function _lzSend( uint32 _dstEid, bytes memory _message, bytes memory _options, MessagingFee memory _fee, address _refundAddress ) internal virtual returns (MessagingReceipt memory receipt) { // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint. uint256 messageValue = _payNative(_fee.nativeFee); if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee); return // solhint-disable-next-line check-send-result endpoint.send{ value: messageValue }( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0), _refundAddress ); } /** * @dev Internal function to pay the native fee associated with the message. * @param _nativeFee The native fee to be paid. * @return nativeFee The amount of native currency paid. * * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction, * this will need to be overridden because msg.value would contain multiple lzFees. * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency. * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees. * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time. */ function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) { if (msg.value != _nativeFee) revert NotEnoughNative(msg.value); return _nativeFee; } /** * @dev Internal function to pay the LZ token fee associated with the message. * @param _lzTokenFee The LZ token fee to be paid. * * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint. * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend(). */ function _payLzToken(uint256 _lzTokenFee) internal virtual { // @dev Cannot cache the token because it is not immutable in the endpoint. address lzToken = endpoint.lzToken(); if (lzToken == address(0)) revert LzTokenUnavailable(); // Pay LZ token fee by sending tokens to the endpoint. IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; // @dev Import the Origin so it's exposed to OAppPreCrimeSimulator implementers. // solhint-disable-next-line no-unused-import import { InboundPacket, Origin } from "../libs/Packet.sol"; /** * @title IOAppPreCrimeSimulator Interface * @dev Interface for the preCrime simulation functionality in an OApp. */ interface IOAppPreCrimeSimulator { // @dev simulation result used in PreCrime implementation error SimulationResult(bytes result); error OnlySelf(); /** * @dev Emitted when the preCrime contract address is set. * @param preCrimeAddress The address of the preCrime contract. */ event PreCrimeSet(address preCrimeAddress); /** * @dev Retrieves the address of the preCrime contract implementation. * @return The address of the preCrime contract. */ function preCrime() external view returns (address); /** * @dev Retrieves the address of the OApp contract. * @return The address of the OApp contract. */ function oApp() external view returns (address); /** * @dev Sets the preCrime contract address. * @param _preCrime The address of the preCrime contract. */ function setPreCrime(address _preCrime) external; /** * @dev Mocks receiving a packet, then reverts with a series of data to infer the state/result. * @param _packets An array of LayerZero InboundPacket objects representing received packets. */ function lzReceiveAndRevert(InboundPacket[] calldata _packets) external payable; /** * @dev checks if the specified peer is considered 'trusted' by the OApp. * @param _eid The endpoint Id to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. */ function isPeer(uint32 _eid, bytes32 _peer) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; struct PreCrimePeer { uint32 eid; bytes32 preCrime; bytes32 oApp; } // TODO not done yet interface IPreCrime { error OnlyOffChain(); // for simulate() error PacketOversize(uint256 max, uint256 actual); error PacketUnsorted(); error SimulationFailed(bytes reason); // for preCrime() error SimulationResultNotFound(uint32 eid); error InvalidSimulationResult(uint32 eid, bytes reason); error CrimeFound(bytes crime); function getConfig(bytes[] calldata _packets, uint256[] calldata _packetMsgValues) external returns (bytes memory); function simulate( bytes[] calldata _packets, uint256[] calldata _packetMsgValues ) external payable returns (bytes memory); function buildSimulationResult() external view returns (bytes memory); function preCrime( bytes[] calldata _packets, uint256[] calldata _packetMsgValues, bytes[] calldata _simulations ) external; function version() external view returns (uint64 major, uint8 minor); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Origin } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { PacketV1Codec } from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.sol"; /** * @title InboundPacket * @dev Structure representing an inbound packet received by the contract. */ struct InboundPacket { Origin origin; // Origin information of the packet. uint32 dstEid; // Destination endpointId of the packet. address receiver; // Receiver address for the packet. bytes32 guid; // Unique identifier of the packet. uint256 value; // msg.value of the packet. address executor; // Executor address for the packet. bytes message; // Message payload of the packet. bytes extraData; // Additional arbitrary data for the packet. } /** * @title PacketDecoder * @dev Library for decoding LayerZero packets. */ library PacketDecoder { using PacketV1Codec for bytes; /** * @dev Decode an inbound packet from the given packet data. * @param _packet The packet data to decode. * @return packet An InboundPacket struct representing the decoded packet. */ function decode(bytes calldata _packet) internal pure returns (InboundPacket memory packet) { packet.origin = Origin(_packet.srcEid(), _packet.sender(), _packet.nonce()); packet.dstEid = _packet.dstEid(); packet.receiver = _packet.receiverB20(); packet.guid = _packet.guid(); packet.message = _packet.message(); } /** * @dev Decode multiple inbound packets from the given packet data and associated message values. * @param _packets An array of packet data to decode. * @param _packetMsgValues An array of associated message values for each packet. * @return packets An array of InboundPacket structs representing the decoded packets. */ function decode( bytes[] calldata _packets, uint256[] memory _packetMsgValues ) internal pure returns (InboundPacket[] memory packets) { packets = new InboundPacket[](_packets.length); for (uint256 i = 0; i < _packets.length; i++) { bytes calldata packet = _packets[i]; packets[i] = PacketDecoder.decode(packet); // @dev Allows the verifier to specify the msg.value that gets passed in lzReceive. packets[i].value = _packetMsgValues[i]; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IPreCrime } from "./interfaces/IPreCrime.sol"; import { IOAppPreCrimeSimulator, InboundPacket, Origin } from "./interfaces/IOAppPreCrimeSimulator.sol"; /** * @title OAppPreCrimeSimulator * @dev Abstract contract serving as the base for preCrime simulation functionality in an OApp. */ abstract contract OAppPreCrimeSimulator is IOAppPreCrimeSimulator, Ownable { // The address of the preCrime implementation. address public preCrime; /** * @dev Retrieves the address of the OApp contract. * @return The address of the OApp contract. * * @dev The simulator contract is the base contract for the OApp by default. * @dev If the simulator is a separate contract, override this function. */ function oApp() external view virtual returns (address) { return address(this); } /** * @dev Sets the preCrime contract address. * @param _preCrime The address of the preCrime contract. */ function setPreCrime(address _preCrime) public virtual onlyOwner { preCrime = _preCrime; emit PreCrimeSet(_preCrime); } /** * @dev Interface for pre-crime simulations. Always reverts at the end with the simulation results. * @param _packets An array of InboundPacket objects representing received packets to be delivered. * * @dev WARNING: MUST revert at the end with the simulation results. * @dev Gives the preCrime implementation the ability to mock sending packets to the lzReceive function, * WITHOUT actually executing them. */ function lzReceiveAndRevert(InboundPacket[] calldata _packets) public payable virtual { for (uint256 i = 0; i < _packets.length; i++) { InboundPacket calldata packet = _packets[i]; // Ignore packets that are not from trusted peers. if (!isPeer(packet.origin.srcEid, packet.origin.sender)) continue; // @dev Because a verifier is calling this function, it doesnt have access to executor params: // - address _executor // - bytes calldata _extraData // preCrime will NOT work for OApps that rely on these two parameters inside of their _lzReceive(). // They are instead stubbed to default values, address(0) and bytes("") // @dev Calling this.lzReceiveSimulate removes ability for assembly return 0 callstack exit, // which would cause the revert to be ignored. this.lzReceiveSimulate{ value: packet.value }( packet.origin, packet.guid, packet.message, packet.executor, packet.extraData ); } // @dev Revert with the simulation results. msg.sender must implement IPreCrime.buildSimulationResult(). revert SimulationResult(IPreCrime(msg.sender).buildSimulationResult()); } /** * @dev Is effectively an internal function because msg.sender must be address(this). * Allows resetting the call stack for 'internal' calls. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier of the packet. * @param _message The message payload of the packet. * @param _executor The executor address for the packet. * @param _extraData Additional data for the packet. */ function lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable virtual { // @dev Ensure ONLY can be called 'internally'. if (msg.sender != address(this)) revert OnlySelf(); _lzReceiveSimulate(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to handle the OAppPreCrimeSimulator simulated receive. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The GUID of the LayerZero message. * @param _message The LayerZero message. * @param _executor The address of the off-chain executor. * @param _extraData Arbitrary data passed by the msg executor. * * @dev Enables the preCrime simulator to mock sending lzReceive() messages, * routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver. */ function _lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; /** * @dev checks if the specified peer is considered 'trusted' by the OApp. * @param _eid The endpoint Id to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. */ function isPeer(uint32 _eid, bytes32 _peer) public view virtual returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; /** * @title ONFT Composed Message Codec * @notice Library for encoding and decoding ONFT composed messages. */ library ONFTComposeMsgCodec { // Offset constants for decoding composed messages uint8 private constant NONCE_OFFSET = 8; uint8 private constant SRC_EID_OFFSET = 12; uint8 private constant COMPOSE_FROM_OFFSET = 44; /** * @dev Encodes a ONFT721 composed message. * @param _nonce The nonce value. * @param _srcEid The source LayerZero endpoint ID. * @param _composeMsg The composed message. * @return The encoded payload, including the composed message. */ function encode( uint64 _nonce, uint32 _srcEid, bytes memory _composeMsg // 0x[composeFrom][composeMsg] ) internal pure returns (bytes memory) { return abi.encodePacked(_nonce, _srcEid, _composeMsg); } /** * @dev Retrieves the nonce for the composed message. * @param _msg The message. * @return The nonce value. */ function nonce(bytes calldata _msg) internal pure returns (uint64) { return uint64(bytes8(_msg[:NONCE_OFFSET])); } /** * @dev Retrieves the source LayerZero endpoint ID for the composed message. * @param _msg The message. * @return The source LayerZero endpoint ID. */ function srcEid(bytes calldata _msg) internal pure returns (uint32) { return uint32(bytes4(_msg[NONCE_OFFSET:SRC_EID_OFFSET])); } /** * @dev Retrieves the composeFrom value from the composed message. * @param _msg The message. * @return The composeFrom value as bytes32. */ function composeFrom(bytes calldata _msg) internal pure returns (bytes32) { return bytes32(_msg[SRC_EID_OFFSET:COMPOSE_FROM_OFFSET]); } /** * @dev Retrieves the composed message. * @param _msg The message. * @return The composed message. */ function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) { return _msg[COMPOSE_FROM_OFFSET:]; } /** * @dev Converts an address to bytes32. * @param _addr The address to convert. * @return The bytes32 representation of the address. */ function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } /** * @dev Converts bytes32 to an address. * @param _b The bytes32 value to convert. * @return The address representation of bytes32. */ function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import { MessagingFee, MessagingReceipt } from "@layerzerolabs/oapp-evm/contracts/oapp/OAppSender.sol"; /** * @dev Struct representing token parameters for the ONFT send() operation. */ struct SendParam { uint32 dstEid; // Destination LayerZero EndpointV2 ID. bytes32 to; // Recipient address. uint256 tokenId; bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message. bytes composeMsg; // The composed message for the send() operation. bytes onftCmd; // The ONFT command to be executed, unused in default ONFT implementations. } /** * @title IONFT * @dev Interface for the ONFT721 token. * @dev Does not inherit ERC721 to accommodate usage by OFT721Adapter. */ interface IONFT721 { // Custom error messages error InvalidReceiver(); error OnlyNFTOwner(address caller, address owner); // Events event ONFTSent( bytes32 indexed guid, // GUID of the ONFT message. uint32 dstEid, // Destination Endpoint ID. address indexed fromAddress, // Address of the sender on the src chain. uint256 tokenId // ONFT ID sent. ); event ONFTReceived( bytes32 indexed guid, // GUID of the ONFT message. uint32 srcEid, // Source Endpoint ID. address indexed toAddress, // Address of the recipient on the dst chain. uint256 tokenId // ONFT ID received. ); /** * @notice Retrieves interfaceID and the version of the ONFT. * @return interfaceId The interface ID. * @return version The version. * @dev interfaceId: This specific interface ID is '0x94642228'. * @dev version: Indicates a cross-chain compatible msg encoding with other ONFTs. * @dev If a new feature is added to the ONFT cross-chain msg encoding, the version will be incremented. * ie. localONFT version(x,1) CAN send messages to remoteONFT version(x,1) */ function onftVersion() external view returns (bytes4 interfaceId, uint64 version); /** * @notice Retrieves the address of the token associated with the ONFT. * @return token The address of the ERC721 token implementation. */ function token() external view returns (address); /** * @notice Indicates whether the ONFT contract requires approval of the 'token()' to send. * @return requiresApproval Needs approval of the underlying token implementation. * @dev Allows things like wallet implementers to determine integration requirements, * without understanding the underlying token implementation. */ function approvalRequired() external view returns (bool); /** * @notice Provides a quote for the send() operation. * @param _sendParam The parameters for the send() operation. * @param _payInLzToken Flag indicating whether the caller is paying in the LZ token. * @return fee The calculated LayerZero messaging fee from the send() operation. * @dev MessagingFee: LayerZero msg fee * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. */ function quoteSend(SendParam calldata _sendParam, bool _payInLzToken) external view returns (MessagingFee memory); /** * @notice Executes the send() operation. * @param _sendParam The parameters for the send operation. * @param _fee The fee information supplied by the caller. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds from fees etc. on the src. * @return receipt The LayerZero messaging receipt from the send() operation. * @dev MessagingReceipt: LayerZero msg receipt * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) external payable returns (MessagingReceipt memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; /** * @title ONFT721MsgCodec * @notice Library for encoding and decoding ONFT721 LayerZero messages. */ library ONFT721MsgCodec { uint8 private constant SEND_TO_OFFSET = 32; uint8 private constant TOKEN_ID_OFFSET = 64; /** * @dev Encodes an ONFT721 LayerZero message payload. * @param _sendTo The recipient address. * @param _tokenId The ID of the token to transfer. * @param _composeMsg The composed payload. * @return payload The encoded message payload. * @return hasCompose A boolean indicating whether the message payload contains a composed payload. */ function encode( bytes32 _sendTo, uint256 _tokenId, bytes memory _composeMsg ) internal view returns (bytes memory payload, bool hasCompose) { hasCompose = _composeMsg.length > 0; payload = hasCompose ? abi.encodePacked(_sendTo, _tokenId, addressToBytes32(msg.sender), _composeMsg) : abi.encodePacked(_sendTo, _tokenId); } /** * @dev Decodes sendTo from the ONFT LayerZero message. * @param _msg The message. * @return The recipient address in bytes32 format. */ function sendTo(bytes calldata _msg) internal pure returns (bytes32) { return bytes32(_msg[:SEND_TO_OFFSET]); } /** * @dev Decodes tokenId from the ONFT LayerZero message. * @param _msg The message. * @return The ID of the tokens to transfer. */ function tokenId(bytes calldata _msg) internal pure returns (uint256) { return uint256(bytes32(_msg[SEND_TO_OFFSET:TOKEN_ID_OFFSET])); } /** * @dev Decodes whether there is a composed payload. * @param _msg The message. * @return A boolean indicating whether the message has a composed payload. */ function isComposed(bytes calldata _msg) internal pure returns (bool) { return _msg.length > TOKEN_ID_OFFSET; } /** * @dev Decodes the composed message. * @param _msg The message. * @return The composed message. */ function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) { return _msg[TOKEN_ID_OFFSET:]; } /** * @dev Converts an address to bytes32. * @param _addr The address to convert. * @return The bytes32 representation of the address. */ function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } /** * @dev Converts bytes32 to an address. * @param _b The bytes32 value to convert. * @return The address representation of bytes32. */ function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { ONFT721Core } from "./ONFT721Core.sol"; /** * @title ONFT721 Contract * @dev ONFT721 is an ERC-721 token that extends the functionality of the ONFT721Core contract. */ abstract contract ONFT721 is ONFT721Core, ERC721 { string internal baseTokenURI; event BaseURISet(string baseURI); /** * @dev Constructor for the ONFT721 contract. * @param _name The name of the ONFT. * @param _symbol The symbol of the ONFT. * @param _lzEndpoint The LayerZero endpoint address. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor( string memory _name, string memory _symbol, address _lzEndpoint, address _delegate ) ERC721(_name, _symbol) ONFT721Core(_lzEndpoint, _delegate) {} /** * @notice Retrieves the address of the underlying ERC721 implementation (ie. this contract). */ function token() external view returns (address) { return address(this); } function setBaseURI(string calldata _baseTokenURI) external onlyOwner { baseTokenURI = _baseTokenURI; emit BaseURISet(baseTokenURI); } function _baseURI() internal view override returns (string memory) { return baseTokenURI; } /** * @notice Indicates whether the ONFT721 contract requires approval of the 'token()' to send. * @dev In the case of ONFT where the contract IS the token, approval is NOT required. * @return requiresApproval Needs approval of the underlying token implementation. */ function approvalRequired() external pure virtual returns (bool) { return false; } function _debit(address _from, uint256 _tokenId, uint32 /*_dstEid*/) internal virtual override { if (_from != ERC721.ownerOf(_tokenId)) revert OnlyNFTOwner(_from, ERC721.ownerOf(_tokenId)); _burn(_tokenId); } function _credit(address _to, uint256 _tokenId, uint32 /*_srcEid*/) internal virtual override { _mint(_to, _tokenId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { OApp, Origin } from "@layerzerolabs/oapp-evm/contracts/oapp/OApp.sol"; import { OAppOptionsType3 } from "@layerzerolabs/oapp-evm/contracts/oapp/libs/OAppOptionsType3.sol"; import { IOAppMsgInspector } from "@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppMsgInspector.sol"; import { OAppPreCrimeSimulator } from "@layerzerolabs/oapp-evm/contracts/precrime/OAppPreCrimeSimulator.sol"; import { IONFT721, MessagingFee, MessagingReceipt, SendParam } from "./interfaces/IONFT721.sol"; import { ONFT721MsgCodec } from "./libs/ONFT721MsgCodec.sol"; import { ONFTComposeMsgCodec } from "../libs/ONFTComposeMsgCodec.sol"; /** * @title ONFT721Core * @dev Abstract contract for an ONFT721 token. */ abstract contract ONFT721Core is IONFT721, OApp, OAppPreCrimeSimulator, OAppOptionsType3 { using ONFT721MsgCodec for bytes; using ONFT721MsgCodec for bytes32; // @notice Msg types that are used to identify the various OFT operations. // @dev This can be extended in child contracts for non-default oft operations // @dev These values are used in things like combineOptions() in OAppOptionsType3.sol. uint16 public constant SEND = 1; uint16 public constant SEND_AND_COMPOSE = 2; // Address of an optional contract to inspect both 'message' and 'options' address public msgInspector; event MsgInspectorSet(address inspector); /** * @dev Constructor. * @param _lzEndpoint The address of the LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(address _lzEndpoint, address _delegate) Ownable(_delegate) OApp(_lzEndpoint, _delegate) {} /** * @notice Retrieves interfaceID and the version of the ONFT. * @return interfaceId The interface ID (0x23e18da6). * @return version The version. * @dev version: Indicates a cross-chain compatible msg encoding with other ONFTs. * @dev If a new feature is added to the ONFT cross-chain msg encoding, the version will be incremented. * @dev ie. localONFT version(x,1) CAN send messages to remoteONFT version(x,1) */ function onftVersion() external pure virtual returns (bytes4 interfaceId, uint64 version) { return (type(IONFT721).interfaceId, 1); } /** * @notice Sets the message inspector address for the OFT. * @param _msgInspector The address of the message inspector. * @dev This is an optional contract that can be used to inspect both 'message' and 'options'. * @dev Set it to address(0) to disable it, or set it to a contract address to enable it. */ function setMsgInspector(address _msgInspector) public virtual onlyOwner { msgInspector = _msgInspector; emit MsgInspectorSet(_msgInspector); } function quoteSend( SendParam calldata _sendParam, bool _payInLzToken ) external view virtual returns (MessagingFee memory msgFee) { (bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam); return _quote(_sendParam.dstEid, message, options, _payInLzToken); } function send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) external payable virtual returns (MessagingReceipt memory msgReceipt) { _debit(msg.sender, _sendParam.tokenId, _sendParam.dstEid); (bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam); // @dev Sends the message to the LayerZero Endpoint, returning the MessagingReceipt. msgReceipt = _lzSend(_sendParam.dstEid, message, options, _fee, _refundAddress); emit ONFTSent(msgReceipt.guid, _sendParam.dstEid, msg.sender, _sendParam.tokenId); } /** * @dev Internal function to build the message and options. * @param _sendParam The parameters for the send() operation. * @return message The encoded message. * @return options The encoded options. */ function _buildMsgAndOptions( SendParam calldata _sendParam ) internal view virtual returns (bytes memory message, bytes memory options) { if (_sendParam.to == bytes32(0)) revert InvalidReceiver(); bool hasCompose; (message, hasCompose) = ONFT721MsgCodec.encode(_sendParam.to, _sendParam.tokenId, _sendParam.composeMsg); uint16 msgType = hasCompose ? SEND_AND_COMPOSE : SEND; options = combineOptions(_sendParam.dstEid, msgType, _sendParam.extraOptions); // @dev Optionally inspect the message and options depending if the OApp owner has set a msg inspector. // @dev If it fails inspection, needs to revert in the implementation. ie. does not rely on return boolean address inspector = msgInspector; // caches the msgInspector to avoid potential double storage read if (inspector != address(0)) IOAppMsgInspector(inspector).inspect(message, options); } /** * @dev Internal function to handle the receive on the LayerZero endpoint. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The encoded message. * @dev _executor The address of the executor. * @dev _extraData Additional data. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address /*_executor*/, // @dev unused in the default implementation. bytes calldata /*_extraData*/ // @dev unused in the default implementation. ) internal virtual override { address toAddress = _message.sendTo().bytes32ToAddress(); uint256 tokenId = _message.tokenId(); _credit(toAddress, tokenId, _origin.srcEid); if (_message.isComposed()) { bytes memory composeMsg = ONFTComposeMsgCodec.encode(_origin.nonce, _origin.srcEid, _message.composeMsg()); // @dev As batching is not implemented, the compose index is always 0. // @dev If batching is added, the index will need to be tracked. endpoint.sendCompose(toAddress, _guid, 0 /* the index of composed message*/, composeMsg); } emit ONFTReceived(_guid, _origin.srcEid, toAddress, tokenId); } /* * @dev Internal function to handle the OAppPreCrimeSimulator simulated receive. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The LayerZero message. * @param _executor The address of the off-chain executor. * @param _extraData Arbitrary data passed by the msg executor. * @dev Enables the preCrime simulator to mock sending lzReceive() messages, * routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver. */ function _lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual override { _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Check if the peer is considered 'trusted' by the OApp. * @param _eid The endpoint ID to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. * @dev Enables OAppPreCrimeSimulator to check whether a potential Inbound Packet is from a trusted source. */ function isPeer(uint32 _eid, bytes32 _peer) public view virtual override returns (bool) { return peers[_eid] == _peer; } function _debit(address /*_from*/, uint256 /*_tokenId*/, uint32 /*_dstEid*/) internal virtual; function _credit(address /*_to*/, uint256 /*_tokenId*/, uint32 /*_srcEid*/) internal virtual; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC-20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC-721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC-1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC165} from "./IERC165.sol"; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. * * NOTE: ERC-2981 allows setting the royalty to 100% of the price. In that case all the price would be sent to the * royalty receiver and 0 tokens to the seller. Contracts dealing with royalty should consider empty transfers. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/common/ERC2981.sol) pragma solidity ^0.8.20; import {IERC2981} from "../../interfaces/IERC2981.sol"; import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the ERC. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator); /** * @dev The default royalty receiver is invalid. */ error ERC2981InvalidDefaultRoyaltyReceiver(address receiver); /** * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator); /** * @dev The royalty receiver for `tokenId` is invalid. */ error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver); /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) public view virtual returns (address receiver, uint256 amount) { RoyaltyInfo storage _royaltyInfo = _tokenRoyaltyInfo[tokenId]; address royaltyReceiver = _royaltyInfo.receiver; uint96 royaltyFraction = _royaltyInfo.royaltyFraction; if (royaltyReceiver == address(0)) { royaltyReceiver = _defaultRoyaltyInfo.receiver; royaltyFraction = _defaultRoyaltyInfo.royaltyFraction; } uint256 royaltyAmount = (salePrice * royaltyFraction) / _feeDenominator(); return (royaltyReceiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidDefaultRoyaltyReceiver(address(0)); } _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0)); } _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC1363} from "../../../interfaces/IERC1363.sol"; import {Address} from "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.20; import {IERC721} from "./IERC721.sol"; import {IERC721Metadata} from "./extensions/IERC721Metadata.sol"; import {ERC721Utils} from "./utils/ERC721Utils.sol"; import {Context} from "../../utils/Context.sol"; import {Strings} from "../../utils/Strings.sol"; import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol"; import {IERC721Errors} from "../../interfaces/draft-IERC6093.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC-721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors { using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; mapping(uint256 tokenId => address) private _owners; mapping(address owner => uint256) private _balances; mapping(uint256 tokenId => address) private _tokenApprovals; mapping(address owner => mapping(address operator => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual returns (uint256) { if (owner == address(0)) { revert ERC721InvalidOwner(address(0)); } return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual returns (address) { return _requireOwned(tokenId); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual returns (string memory) { _requireOwned(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual { _approve(to, tokenId, _msgSender()); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual returns (address) { _requireOwned(tokenId); return _getApproved(tokenId); } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. address previousOwner = _update(to, tokenId, _msgSender()); if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { transferFrom(from, to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist * * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the * core ERC-721 logic MUST be matched with the use of {_increaseBalance} to keep balances * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`. */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted. */ function _getApproved(uint256 tokenId) internal view virtual returns (address) { return _tokenApprovals[tokenId]; } /** * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in * particular (ignoring whether it is owned by `owner`). * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { return spender != address(0) && (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); } /** * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner. * Reverts if: * - `spender` does not have approval from `owner` for `tokenId`. * - `spender` does not have approval to manage all of `owner`'s assets. * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { if (!_isAuthorized(owner, spender, tokenId)) { if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } else { revert ERC721InsufficientApproval(spender, tokenId); } } } /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that * a uint256 would ever overflow from increments when these increments are bounded to uint128 values. * * WARNING: Increasing an account's balance using this function tends to be paired with an override of the * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership * remain consistent with one another. */ function _increaseBalance(address account, uint128 value) internal virtual { unchecked { _balances[account] += value; } } /** * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update. * * The `auth` argument is optional. If the value passed is non 0, then this function will check that * `auth` is either the owner of the token, or approved to operate on the token (by the owner). * * Emits a {Transfer} event. * * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}. */ function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { address from = _ownerOf(tokenId); // Perform (optional) operator check if (auth != address(0)) { _checkAuthorized(from, auth, tokenId); } // Execute the update if (from != address(0)) { // Clear approval. No need to re-authorize or emit the Approval event _approve(address(0), tokenId, address(0), false); unchecked { _balances[from] -= 1; } } if (to != address(0)) { unchecked { _balances[to] += 1; } } _owners[tokenId] = to; emit Transfer(from, to, tokenId); return from; } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner != address(0)) { revert ERC721InvalidSender(address(0)); } } /** * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), address(0), to, tokenId, data); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal { address previousOwner = _update(address(0), tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } else if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients * are aware of the ERC-721 standard to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is like {safeTransferFrom} in the sense that it invokes * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `tokenId` token must exist and be owned by `from`. * - `to` cannot be the zero address. * - `from` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId) internal { _safeTransfer(from, to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data); } /** * @dev Approve `to` to operate on `tokenId` * * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is * either the owner of the token, or approved to operate on all tokens held by this owner. * * Emits an {Approval} event. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address to, uint256 tokenId, address auth) internal { _approve(to, tokenId, auth, true); } /** * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not * emitted in the context of transfers. */ function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { // Avoid reading the owner unless necessary if (emitEvent || auth != address(0)) { address owner = _requireOwned(tokenId); // We do not use _isAuthorized because single-token approvals should not be able to call approve if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { revert ERC721InvalidApprover(auth); } if (emitEvent) { emit Approval(owner, to, tokenId); } } _tokenApprovals[tokenId] = to; } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Requirements: * - operator can't be the address zero. * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { if (operator == address(0)) { revert ERC721InvalidOperator(operator); } _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned). * Returns the owner. * * Overrides to ownership logic should be done to {_ownerOf}. */ function _requireOwned(uint256 tokenId) internal view returns (address) { address owner = _ownerOf(tokenId); if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } return owner; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.20; import {IERC721} from "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC-721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC-721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or * {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the address zero. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @title ERC-721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC-721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be * reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/utils/ERC721Utils.sol) pragma solidity ^0.8.20; import {IERC721Receiver} from "../IERC721Receiver.sol"; import {IERC721Errors} from "../../../interfaces/draft-IERC6093.sol"; /** * @dev Library that provide common ERC-721 utility functions. * * See https://eips.ethereum.org/EIPS/eip-721[ERC-721]. * * _Available since v5.1._ */ library ERC721Utils { /** * @dev Performs an acceptance check for the provided `operator` by calling {IERC721-onERC721Received} * on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`). * * The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA). * Otherwise, the recipient must implement {IERC721Receiver-onERC721Received} and return the acceptance magic value to accept * the transfer. */ function checkOnERC721Received( address operator, address from, address to, uint256 tokenId, bytes memory data ) internal { if (to.code.length > 0) { try IERC721Receiver(to).onERC721Received(operator, from, tokenId, data) returns (bytes4 retval) { if (retval != IERC721Receiver.onERC721Received.selector) { // Token rejected revert IERC721Errors.ERC721InvalidReceiver(to); } } catch (bytes memory reason) { if (reason.length == 0) { // non-IERC721Receiver implementer revert IERC721Errors.ERC721InvalidReceiver(to); } else { assembly ("memory-safe") { revert(add(32, reason), mload(reason)) } } } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol) pragma solidity ^0.8.20; import {Errors} from "./Errors.sol"; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert Errors.InsufficientBalance(address(this).balance, amount); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert Errors.FailedCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {Errors.FailedCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case * of an unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {Errors.FailedCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert Errors.FailedCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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.1.0) (utils/math/Math.sol) pragma solidity ^0.8.20; import {Panic} from "../Panic.sol"; import {SafeCast} from "./SafeCast.sol"; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * SafeCast.toUint(condition)); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. Panic.panic(Panic.DIVISION_BY_ZERO); } // The following calculation ensures accurate ceiling division without overflow. // Since a is non-zero, (a - 1) / b will not overflow. // The largest possible result occurs when (a - 1) / b is type(uint256).max, // but the largest value we can obtain is type(uint256).max - 1, which happens // when a = type(uint256).max and b = 1. unchecked { return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2²⁵⁶ + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0. if (denominator <= prod1) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv ≡ 1 mod 2⁴. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2⁸ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ inverse *= 2 - denominator * inverse; // inverse mod 2³² inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @dev Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0. * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. * * If the input value is not inversible, 0 is returned. * * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. */ function invMod(uint256 a, uint256 n) internal pure returns (uint256) { unchecked { if (n == 0) return 0; // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) // Used to compute integers x and y such that: ax + ny = gcd(a, n). // When the gcd is 1, then the inverse of a modulo n exists and it's x. // ax + ny = 1 // ax = 1 + (-y)n // ax ≡ 1 (mod n) # x is the inverse of a modulo n // If the remainder is 0 the gcd is n right away. uint256 remainder = a % n; uint256 gcd = n; // Therefore the initial coefficients are: // ax + ny = gcd(a, n) = n // 0a + 1n = n int256 x = 0; int256 y = 1; while (remainder != 0) { uint256 quotient = gcd / remainder; (gcd, remainder) = ( // The old remainder is the next gcd to try. remainder, // Compute the next remainder. // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd // where gcd is at most n (capped to type(uint256).max) gcd - remainder * quotient ); (x, y) = ( // Increment the coefficient of a. y, // Decrement the coefficient of n. // Can overflow, but the result is casted to uint256 so that the // next value of y is "wrapped around" to a value between 0 and n - 1. x - y * int256(quotient) ); } if (gcd != 1) return 0; // No inverse exists. return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. } } /** * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. * * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that * `a**(p-2)` is the modular multiplicative inverse of a in Fp. * * NOTE: this function does NOT check that `p` is a prime greater than `2`. */ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { unchecked { return Math.modExp(a, p - 2, p); } } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) * * Requirements: * - modulus can't be zero * - underlying staticcall to precompile must succeed * * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make * sure the chain you're using it on supports the precompiled contract for modular exponentiation * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, * the underlying function will succeed given the lack of a revert, but the result may be incorrectly * interpreted as 0. */ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { (bool success, uint256 result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying * to operate modulo 0 or if the underlying precompile reverted. * * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack * of a revert, but the result may be incorrectly interpreted as 0. */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x60:0x7f | value of b | 0x<.............................................................b> | // | 0x80:0x9f | value of e | 0x<.............................................................e> | // | 0xa0:0xbf | value of m | 0x<.............................................................m> | mstore(ptr, 0x20) mstore(add(ptr, 0x20), 0x20) mstore(add(ptr, 0x40), 0x20) mstore(add(ptr, 0x60), b) mstore(add(ptr, 0x80), e) mstore(add(ptr, 0xa0), m) // Given the result < m, it's guaranteed to fit in 32 bytes, // so we can use the memory scratch space located at offset 0. success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) result := mload(0x00) } } /** * @dev Variant of {modExp} that supports inputs of arbitrary length. */ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { (bool success, bytes memory result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Variant of {tryModExp} that supports inputs of arbitrary length. */ function tryModExp( bytes memory b, bytes memory e, bytes memory m ) internal view returns (bool success, bytes memory result) { if (_zeroBytes(m)) return (false, new bytes(0)); uint256 mLen = m.length; // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) // Overwrite the length. // result.length > returndatasize() is guaranteed because returndatasize() == m.length mstore(result, mLen) // Set the memory pointer after the returned data. mstore(0x40, add(dataPtr, mLen)) } } /** * @dev Returns whether the provided byte array is zero. */ function _zeroBytes(bytes memory byteArray) private pure returns (bool) { for (uint256 i = 0; i < byteArray.length; ++i) { if (byteArray[i] != 0) { return false; } } return true; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * This method is based on Newton's method for computing square roots; the algorithm is restricted to only * using integer operations. */ function sqrt(uint256 a) internal pure returns (uint256) { unchecked { // Take care of easy edge cases when a == 0 or a == 1 if (a <= 1) { return a; } // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between // the current value as `ε_n = | x_n - sqrt(a) |`. // // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is // bigger than any uint256. // // By noticing that // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar // to the msb function. uint256 aa = a; uint256 xn = 1; if (aa >= (1 << 128)) { aa >>= 128; xn <<= 64; } if (aa >= (1 << 64)) { aa >>= 64; xn <<= 32; } if (aa >= (1 << 32)) { aa >>= 32; xn <<= 16; } if (aa >= (1 << 16)) { aa >>= 16; xn <<= 8; } if (aa >= (1 << 8)) { aa >>= 8; xn <<= 4; } if (aa >= (1 << 4)) { aa >>= 4; xn <<= 2; } if (aa >= (1 << 2)) { xn <<= 1; } // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). // // We can refine our estimation by noticing that the middle of that interval minimizes the error. // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). // This is going to be our x_0 (and ε_0) xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) // From here, Newton's method give us: // x_{n+1} = (x_n + a / x_n) / 2 // // One should note that: // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a // = ((x_n² + a) / (2 * x_n))² - a // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) // = (x_n² - a)² / (2 * x_n)² // = ((x_n² - a) / (2 * x_n))² // ≥ 0 // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n // // This gives us the proof of quadratic convergence of the sequence: // ε_{n+1} = | x_{n+1} - sqrt(a) | // = | (x_n + a / x_n) / 2 - sqrt(a) | // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | // = | (x_n - sqrt(a))² / (2 * x_n) | // = | ε_n² / (2 * x_n) | // = ε_n² / | (2 * x_n) | // // For the first iteration, we have a special case where x_0 is known: // ε_1 = ε_0² / | (2 * x_0) | // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) // ≤ 2**(2*e-4) / (3 * 2**(e-1)) // ≤ 2**(e-3) / 3 // ≤ 2**(e-3-log2(3)) // ≤ 2**(e-4.5) // // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: // ε_{n+1} = ε_n² / | (2 * x_n) | // ≤ (2**(e-k))² / (2 * 2**(e-1)) // ≤ 2**(2*e-2*k) / 2**e // ≤ 2**(e-2*k) xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either // sqrt(a) or sqrt(a) + 1. return xn - SafeCast.toUint(xn > a / xn); } } /** * @dev Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 exp; unchecked { exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); value >>= exp; result += exp; exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); value >>= exp; result += exp; exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); value >>= exp; result += exp; exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); value >>= exp; result += exp; exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); value >>= exp; result += exp; exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); value >>= exp; result += exp; exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); value >>= exp; result += exp; result += SafeCast.toUint(value > 1); } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 isGt; unchecked { isGt = SafeCast.toUint(value > (1 << 128) - 1); value >>= isGt * 128; result += isGt * 16; isGt = SafeCast.toUint(value > (1 << 64) - 1); value >>= isGt * 64; result += isGt * 8; isGt = SafeCast.toUint(value > (1 << 32) - 1); value >>= isGt * 32; result += isGt * 4; isGt = SafeCast.toUint(value > (1 << 16) - 1); value >>= isGt * 16; result += isGt * 2; result += SafeCast.toUint(value > (1 << 8) - 1); } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; import {SafeCast} from "./SafeCast.sol"; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); } } /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, // taking advantage of the most significant (or "sign" bit) in two's complement representation. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol) pragma solidity ^0.8.20; /** * @dev Helper library for emitting standardized panic codes. * * ```solidity * contract Example { * using Panic for uint256; * * // Use any of the declared internal constants * function foo() { Panic.GENERIC.panic(); } * * // Alternatively * function foo() { Panic.panic(Panic.GENERIC); } * } * ``` * * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. * * _Available since v5.1._ */ // slither-disable-next-line unused-state library Panic { /// @dev generic / unspecified error uint256 internal constant GENERIC = 0x00; /// @dev used by the assert() builtin uint256 internal constant ASSERT = 0x01; /// @dev arithmetic underflow or overflow uint256 internal constant UNDER_OVERFLOW = 0x11; /// @dev division or modulo by zero uint256 internal constant DIVISION_BY_ZERO = 0x12; /// @dev enum conversion error uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; /// @dev invalid encoding in storage uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; /// @dev empty array pop uint256 internal constant EMPTY_ARRAY_POP = 0x31; /// @dev array out of bounds access uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; /// @dev resource error (too large allocation or too large array) uint256 internal constant RESOURCE_ERROR = 0x41; /// @dev calling invalid internal function uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { bool private _paused; /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); /** * @dev The operation failed because the contract is paused. */ error EnforcedPause(); /** * @dev The operation failed because the contract is not paused. */ error ExpectedPause(); /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { if (paused()) { revert EnforcedPause(); } } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) { revert ExpectedPause(); } } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.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 EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * 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: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Strings.sol) pragma solidity ^0.8.20; import {Math} from "./math/Math.sol"; import {SignedMath} from "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; assembly ("memory-safe") { ptr := add(buffer, add(32, length)) } while (true) { ptr--; assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal * representation, according to EIP-55. */ function toChecksumHexString(address addr) internal pure returns (string memory) { bytes memory buffer = bytes(toHexString(addr)); // hash the hex part of buffer (skip length + 2 bytes, length 40) uint256 hashValue; assembly ("memory-safe") { hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) } for (uint256 i = 41; i > 1; --i) { // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { // case shift by xoring with 0x20 buffer[i] ^= 0x20; } hashValue >>= 4; } return string(buffer); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import '@layerzerolabs/onft-evm/contracts/onft721/ONFT721.sol'; import '@openzeppelin/contracts/utils/Strings.sol'; import '@openzeppelin/contracts/utils/ReentrancyGuard.sol'; import '@openzeppelin/contracts/token/common/ERC2981.sol'; import '@openzeppelin/contracts/utils/Pausable.sol'; contract CultBearsV2Avalanche is ONFT721, ReentrancyGuard, ERC2981, Pausable { using Strings for uint256; enum TokenRarityType { COMMON, RARE, ULTRA_RARE, LEGENDARY, MYTHIC } struct TokenIDRange { uint256 start; uint256 amount; } string public baseURI; string public fileExtension = '.json'; uint256 public constant maxSupply = 2000; address public treasuryWallet; bool public isPublicMintAllowed = false; mapping(TokenRarityType => uint256) private privateSalePrice; mapping(TokenRarityType => uint256) public publicSalePrice; mapping(TokenRarityType => TokenIDRange) public tokenIDRange; mapping(TokenRarityType => uint16) public tokenIDCounter; mapping(address => bool) public ogWhitelist; mapping(address => bool) public bearlistedWhitelist; mapping(uint256 => bool) private airdropped; mapping(uint256 => bool) private mintedTokens; uint256 private totalMintedTokens; event Minted(address indexed to, uint256 tokenId); event TreasuryWalletChanged(address indexed oldWallet, address indexed newWallet); event PublicMintToggled(bool isPublicMintAllowed); event URIUpdated(string newBaseURI); event FileExtensionUpdated(string newExtension); event RoyaltySet(address indexed receiver, uint96 feeNumerator); event PrivateMintPriceUpdated(TokenRarityType rarity, uint256 newPrice); event PublicMintPriceUpdated(TokenRarityType rarity, uint256 newPrice); event OGWhitelistAdded(address indexed whitelistee); event OGWhitelistRemoved(address indexed whitelistee); event BearlistedWhitelistAdded(address indexed whitelistee); event BearlistedWhitelistRemoved(address indexed whitelistee); constructor( string memory _name, string memory _symbol, address _lzEndpoint, address _delegate, string memory initialBaseURI, address _initialTreasuryWallet ) ONFT721(_name, _symbol, _lzEndpoint, _delegate) { require(_initialTreasuryWallet != address(0), "Treasury wallet cannot be zero address"); baseURI = initialBaseURI; treasuryWallet = _initialTreasuryWallet; _setDefaultRoyalty(treasuryWallet, 500); // 5% royalty privateSalePrice[TokenRarityType.COMMON] = 78e18; privateSalePrice[TokenRarityType.RARE] = 155e18; privateSalePrice[TokenRarityType.ULTRA_RARE] = 310e18; privateSalePrice[TokenRarityType.LEGENDARY] = 620e18; privateSalePrice[TokenRarityType.MYTHIC] = 1240e18; publicSalePrice[TokenRarityType.COMMON] = 89e18; publicSalePrice[TokenRarityType.RARE] = 177e18; publicSalePrice[TokenRarityType.ULTRA_RARE] = 354e18; publicSalePrice[TokenRarityType.LEGENDARY] = 709e18; publicSalePrice[TokenRarityType.MYTHIC] = 1417e18; tokenIDRange[TokenRarityType.MYTHIC] = TokenIDRange(1, 2); tokenIDRange[TokenRarityType.LEGENDARY] = TokenIDRange(3, 13); tokenIDRange[TokenRarityType.ULTRA_RARE] = TokenIDRange(16, 25); tokenIDRange[TokenRarityType.RARE] = TokenIDRange(41, 50); tokenIDRange[TokenRarityType.COMMON] = TokenIDRange(91, 910); } fallback() external payable {} receive() external payable {} function _exists(uint256 tokenId) internal view virtual returns (bool) { return mintedTokens[tokenId] || (tokenId > 1000); } function tokenURI(uint256 tokenId) public view override returns (string memory) { require(tokenId > 0 && tokenId <= 2000, "Token ID out of range"); return string(abi.encodePacked(baseURI, "cult-bear-", tokenId.toString(), fileExtension)); } function getRarity(uint256 tokenId) public pure returns (TokenRarityType) { require(tokenId > 0 && tokenId <= 2000, "Token ID out of range"); if (tokenId <= 2 || (tokenId >= 1001 && tokenId <= 1002)) return TokenRarityType.MYTHIC; if ((tokenId >= 3 && tokenId <= 15) || (tokenId >= 1003 && tokenId <= 1015)) return TokenRarityType.LEGENDARY; if ((tokenId >= 16 && tokenId <= 40) || (tokenId >= 1016 && tokenId <= 1040)) return TokenRarityType.ULTRA_RARE; if ((tokenId >= 41 && tokenId <= 90) || (tokenId >= 1041 && tokenId <= 1090)) return TokenRarityType.RARE; return TokenRarityType.COMMON; } function setFileExtension(string memory extension) external onlyOwner whenNotPaused { require(bytes(extension).length > 0, "File extension cannot be empty"); fileExtension = extension; emit FileExtensionUpdated(extension); } function togglePublicMint() external onlyOwner whenNotPaused { isPublicMintAllowed = !isPublicMintAllowed; emit PublicMintToggled(isPublicMintAllowed); } function setPrivateMintPrice(TokenRarityType rarity, uint256 price) external onlyOwner whenNotPaused { privateSalePrice[rarity] = price; emit PrivateMintPriceUpdated(rarity, price); } function setPublicMintPrice(TokenRarityType rarity, uint256 price) external onlyOwner whenNotPaused { publicSalePrice[rarity] = price; emit PublicMintPriceUpdated(rarity, price); } function getPrice(TokenRarityType rarityType) external view returns (uint256) { return isPublicMintAllowed ? publicSalePrice[rarityType] : privateSalePrice[rarityType]; } function addToOGWhitelist(address whitelistee) public onlyOwner { require(!bearlistedWhitelist[whitelistee], 'Whitelistee is already present in the bearlisted whitelist'); ogWhitelist[whitelistee] = true; emit OGWhitelistAdded(whitelistee); } function addToBearlistedWhitelist(address whitelistee) public onlyOwner { require(!ogWhitelist[whitelistee], 'Whitelistee is already present in the OG whitelist'); bearlistedWhitelist[whitelistee] = true; emit BearlistedWhitelistAdded(whitelistee); } function removeFromOGWhitelist(address whitelistee) public onlyOwner { ogWhitelist[whitelistee] = false; emit OGWhitelistRemoved(whitelistee); } function removeFromBearlistedWhitelist(address whitelistee) public onlyOwner { bearlistedWhitelist[whitelistee] = false; emit BearlistedWhitelistRemoved(whitelistee); } function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) external onlyOwner whenNotPaused { _setTokenRoyalty(tokenId, receiver, feeNumerator); emit RoyaltySet(receiver, feeNumerator); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } function mintMultiple(uint256 mintAmount, TokenRarityType rarity) external payable nonReentrant whenNotPaused { require(mintAmount > 0 && mintAmount <= 20, "Invalid mint amount"); if (!isPublicMintAllowed) { require(mintAmount == 1, "Private sale can only mint one token at a time"); require(ogWhitelist[msg.sender] || bearlistedWhitelist[msg.sender], "Not whitelisted for private sale"); } uint256 pricePerToken = isPublicMintAllowed ? publicSalePrice[rarity] : privateSalePrice[rarity]; uint256 totalPrice = pricePerToken * mintAmount; require(msg.value >= totalPrice, "Insufficient payment"); uint256 mintedCount = 0; uint256 tokenIDToBeMinted = tokenIDRange[rarity].start + tokenIDCounter[rarity]; uint256 rarityEnd = tokenIDRange[rarity].start + tokenIDRange[rarity].amount; while (mintedCount < mintAmount && tokenIDToBeMinted < rarityEnd) { while (airdropped[tokenIDToBeMinted] || mintedTokens[tokenIDToBeMinted]) { tokenIDToBeMinted++; if (tokenIDToBeMinted >= rarityEnd) break; } if (tokenIDToBeMinted >= rarityEnd) { break; } _safeMint(msg.sender, tokenIDToBeMinted); mintedTokens[tokenIDToBeMinted] = true; emit Minted(msg.sender, tokenIDToBeMinted); mintedCount++; unchecked { tokenIDCounter[rarity]++; totalMintedTokens++; } require(totalMintedTokens <= (maxSupply / 2), "Exceeds chain's max initial supply"); } require(mintedCount == mintAmount, "Minting could not be completed for the requested amount"); } function airdrop(address to, uint256 tokenID) external onlyOwner whenNotPaused { require(!mintedTokens[tokenID], "Token ID already minted"); require(totalMintedTokens + 1 <= (maxSupply / 2), "Exceeds chain's max initial supply"); require(_isValidTokenID(tokenID), "Invalid token ID"); _safeMint(to, tokenID); airdropped[tokenID] = true; mintedTokens[tokenID] = true; totalMintedTokens++; emit Minted(to, tokenID); } function airdropMultiple(address to, uint256[] memory tokenIDs) external onlyOwner whenNotPaused { uint256 length = tokenIDs.length; require(totalMintedTokens + length <= (maxSupply / 2), "Exceeds chain's max initial supply"); for (uint256 i = 0; i < length; i++) { uint256 tokenID = tokenIDs[i]; require(!mintedTokens[tokenID], "Token ID already minted"); require(_isValidTokenID(tokenID), "Invalid token ID"); _safeMint(to, tokenID); airdropped[tokenID] = true; mintedTokens[tokenID] = true; totalMintedTokens++; emit Minted(to, tokenID); } } function withdraw() public onlyOwner nonReentrant whenNotPaused { uint256 balance = address(this).balance; require(balance > 0, "No balance to withdraw"); uint256 ownerShare = (balance * 30) / 100; uint256 treasuryShare = balance - ownerShare; payable(treasuryWallet).transfer(treasuryShare); payable(owner()).transfer(ownerShare); } function changeTreasuryWallet(address _treasuryWallet) public onlyOwner whenNotPaused { require(_treasuryWallet != address(0), "New treasury wallet cannot be zero address"); emit TreasuryWalletChanged(treasuryWallet, _treasuryWallet); treasuryWallet = _treasuryWallet; } function _isValidTokenID(uint256 tokenID) internal view returns (bool) { for (uint8 i = 0; i <= uint8(TokenRarityType.MYTHIC); i++) { TokenIDRange memory range = tokenIDRange[TokenRarityType(i)]; if (tokenID >= range.start && tokenID < range.start + range.amount) { return true; } } return false; } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import '@layerzerolabs/onft-evm/contracts/onft721/ONFT721.sol'; import '@openzeppelin/contracts/utils/Strings.sol'; import '@openzeppelin/contracts/utils/ReentrancyGuard.sol'; import '@openzeppelin/contracts/token/common/ERC2981.sol'; import '@openzeppelin/contracts/utils/Pausable.sol'; contract CultBearsV2Base is ONFT721, ReentrancyGuard, ERC2981, Pausable { using Strings for uint256; enum TokenRarityType { COMMON, RARE, ULTRA_RARE, LEGENDARY, MYTHIC } struct TokenIDRange { uint256 start; uint256 amount; } string public baseURI; string public fileExtension = '.json'; uint256 public constant maxSupply = 2000; address public treasuryWallet; bool public isPublicMintAllowed = false; mapping(TokenRarityType => uint256) private privateSalePrice; mapping(TokenRarityType => uint256) public publicSalePrice; mapping(TokenRarityType => TokenIDRange) public tokenIDRange; mapping(TokenRarityType => uint16) public tokenIDCounter; mapping(address => bool) public ogWhitelist; mapping(address => bool) public bearlistedWhitelist; mapping(uint256 => bool) private airdropped; mapping(uint256 => bool) private mintedTokens; uint256 private totalMintedTokens; event Minted(address indexed to, uint256 tokenId); event TreasuryWalletChanged(address indexed oldWallet, address indexed newWallet); event PublicMintToggled(bool isPublicMintAllowed); event URIUpdated(string newBaseURI); event FileExtensionUpdated(string newExtension); event RoyaltySet(address indexed receiver, uint96 feeNumerator); event PrivateMintPriceUpdated(TokenRarityType rarity, uint256 newPrice); event PublicMintPriceUpdated(TokenRarityType rarity, uint256 newPrice); event OGWhitelistAdded(address indexed whitelistee); event OGWhitelistRemoved(address indexed whitelistee); event BearlistedWhitelistAdded(address indexed whitelistee); event BearlistedWhitelistRemoved(address indexed whitelistee); constructor( string memory _name, string memory _symbol, address _lzEndpoint, address _delegate, string memory initialBaseURI, address _initialTreasuryWallet ) ONFT721(_name, _symbol, _lzEndpoint, _delegate) { require(_initialTreasuryWallet != address(0), "Treasury wallet cannot be zero address"); baseURI = initialBaseURI; treasuryWallet = _initialTreasuryWallet; _setDefaultRoyalty(treasuryWallet, 500); // 5% royalty privateSalePrice[TokenRarityType.COMMON] = 78e18; privateSalePrice[TokenRarityType.RARE] = 155e18; privateSalePrice[TokenRarityType.ULTRA_RARE] = 310e18; privateSalePrice[TokenRarityType.LEGENDARY] = 620e18; privateSalePrice[TokenRarityType.MYTHIC] = 1240e18; publicSalePrice[TokenRarityType.COMMON] = 89e18; publicSalePrice[TokenRarityType.RARE] = 177e18; publicSalePrice[TokenRarityType.ULTRA_RARE] = 354e18; publicSalePrice[TokenRarityType.LEGENDARY] = 709e18; publicSalePrice[TokenRarityType.MYTHIC] = 1417e18; tokenIDRange[TokenRarityType.MYTHIC] = TokenIDRange(1001, 2); tokenIDRange[TokenRarityType.LEGENDARY] = TokenIDRange(1003, 13); tokenIDRange[TokenRarityType.ULTRA_RARE] = TokenIDRange(1016, 25); tokenIDRange[TokenRarityType.RARE] = TokenIDRange(1041, 50); tokenIDRange[TokenRarityType.COMMON] = TokenIDRange(1091, 910); } fallback() external payable {} receive() external payable {} function _exists(uint256 tokenId) internal view virtual returns (bool) { return mintedTokens[tokenId] || (tokenId <= 1000); } function tokenURI(uint256 tokenId) public view override returns (string memory) { require(tokenId > 0 && tokenId <= 2000, "Token ID out of range"); return string(abi.encodePacked(baseURI, "cult-bear-", tokenId.toString(), fileExtension)); } function getRarity(uint256 tokenId) public pure returns (TokenRarityType) { require(tokenId > 0 && tokenId <= 2000, "Token ID out of range"); if (tokenId <= 2 || (tokenId >= 1001 && tokenId <= 1002)) return TokenRarityType.MYTHIC; if ((tokenId >= 3 && tokenId <= 15) || (tokenId >= 1003 && tokenId <= 1015)) return TokenRarityType.LEGENDARY; if ((tokenId >= 16 && tokenId <= 40) || (tokenId >= 1016 && tokenId <= 1040)) return TokenRarityType.ULTRA_RARE; if ((tokenId >= 41 && tokenId <= 90) || (tokenId >= 1041 && tokenId <= 1090)) return TokenRarityType.RARE; return TokenRarityType.COMMON; } function setFileExtension(string memory extension) external onlyOwner whenNotPaused { require(bytes(extension).length > 0, "File extension cannot be empty"); fileExtension = extension; emit FileExtensionUpdated(extension); } function togglePublicMint() external onlyOwner whenNotPaused { isPublicMintAllowed = !isPublicMintAllowed; emit PublicMintToggled(isPublicMintAllowed); } function setPrivateMintPrice(TokenRarityType rarity, uint256 price) external onlyOwner whenNotPaused { privateSalePrice[rarity] = price; emit PrivateMintPriceUpdated(rarity, price); } function setPublicMintPrice(TokenRarityType rarity, uint256 price) external onlyOwner whenNotPaused { publicSalePrice[rarity] = price; emit PublicMintPriceUpdated(rarity, price); } function getPrice(TokenRarityType rarityType) external view returns (uint256) { return isPublicMintAllowed ? publicSalePrice[rarityType] : privateSalePrice[rarityType]; } function addToOGWhitelist(address whitelistee) public onlyOwner { require(!bearlistedWhitelist[whitelistee], 'Whitelistee is already present in the bearlisted whitelist'); ogWhitelist[whitelistee] = true; emit OGWhitelistAdded(whitelistee); } function addToBearlistedWhitelist(address whitelistee) public onlyOwner { require(!ogWhitelist[whitelistee], 'Whitelistee is already present in the OG whitelist'); bearlistedWhitelist[whitelistee] = true; emit BearlistedWhitelistAdded(whitelistee); } function removeFromOGWhitelist(address whitelistee) public onlyOwner { ogWhitelist[whitelistee] = false; emit OGWhitelistRemoved(whitelistee); } function removeFromBearlistedWhitelist(address whitelistee) public onlyOwner { bearlistedWhitelist[whitelistee] = false; emit BearlistedWhitelistRemoved(whitelistee); } function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) external onlyOwner whenNotPaused { _setTokenRoyalty(tokenId, receiver, feeNumerator); emit RoyaltySet(receiver, feeNumerator); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } function mintMultiple(uint256 mintAmount, TokenRarityType rarity) external payable nonReentrant whenNotPaused { require(mintAmount > 0 && mintAmount <= 20, "Invalid mint amount"); if (!isPublicMintAllowed) { require(mintAmount == 1, "Private sale can only mint one token at a time"); require(ogWhitelist[msg.sender] || bearlistedWhitelist[msg.sender], "Not whitelisted for private sale"); } uint256 pricePerToken = isPublicMintAllowed ? publicSalePrice[rarity] : privateSalePrice[rarity]; uint256 totalPrice = pricePerToken * mintAmount; require(msg.value >= totalPrice, "Insufficient payment"); uint256 mintedCount = 0; uint256 tokenIDToBeMinted = tokenIDRange[rarity].start + tokenIDCounter[rarity]; uint256 rarityEnd = tokenIDRange[rarity].start + tokenIDRange[rarity].amount; while (mintedCount < mintAmount && tokenIDToBeMinted < rarityEnd) { while (airdropped[tokenIDToBeMinted] || mintedTokens[tokenIDToBeMinted]) { tokenIDToBeMinted++; if (tokenIDToBeMinted >= rarityEnd) break; } if (tokenIDToBeMinted >= rarityEnd) { break; } _safeMint(msg.sender, tokenIDToBeMinted); mintedTokens[tokenIDToBeMinted] = true; emit Minted(msg.sender, tokenIDToBeMinted); mintedCount++; unchecked { tokenIDCounter[rarity]++; totalMintedTokens++; } require(totalMintedTokens <= (maxSupply / 2), "Exceeds chain's max initial supply"); } require(mintedCount == mintAmount, "Minting could not be completed for the requested amount"); } function airdrop(address to, uint256 tokenID) external onlyOwner whenNotPaused { require(!mintedTokens[tokenID], "Token ID already minted"); require(totalMintedTokens + 1 <= (maxSupply / 2), "Exceeds chain's max initial supply"); require(_isValidTokenID(tokenID), "Invalid token ID"); _safeMint(to, tokenID); airdropped[tokenID] = true; mintedTokens[tokenID] = true; totalMintedTokens++; emit Minted(to, tokenID); } function airdropMultiple(address to, uint256[] memory tokenIDs) external onlyOwner whenNotPaused { uint256 length = tokenIDs.length; require(totalMintedTokens + length <= (maxSupply / 2), "Exceeds chain's max initial supply"); for (uint256 i = 0; i < length; i++) { uint256 tokenID = tokenIDs[i]; require(!mintedTokens[tokenID], "Token ID already minted"); require(_isValidTokenID(tokenID), "Invalid token ID"); _safeMint(to, tokenID); airdropped[tokenID] = true; mintedTokens[tokenID] = true; totalMintedTokens++; emit Minted(to, tokenID); } } function withdraw() public onlyOwner nonReentrant whenNotPaused { uint256 balance = address(this).balance; require(balance > 0, "No balance to withdraw"); uint256 ownerShare = (balance * 30) / 100; uint256 treasuryShare = balance - ownerShare; payable(treasuryWallet).transfer(treasuryShare); payable(owner()).transfer(ownerShare); } function changeTreasuryWallet(address _treasuryWallet) public onlyOwner whenNotPaused { require(_treasuryWallet != address(0), "New treasury wallet cannot be zero address"); emit TreasuryWalletChanged(treasuryWallet, _treasuryWallet); treasuryWallet = _treasuryWallet; } function _isValidTokenID(uint256 tokenID) internal view returns (bool) { for (uint8 i = 0; i <= uint8(TokenRarityType.MYTHIC); i++) { TokenIDRange memory range = tokenIDRange[TokenRarityType(i)]; if (tokenID >= range.start && tokenID < range.start + range.amount) { return true; } } return false; } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true } }
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_lzEndpoint","type":"address"},{"internalType":"address","name":"_delegate","type":"address"},{"internalType":"string","name":"initialBaseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[{"internalType":"bytes","name":"options","type":"bytes"}],"name":"InvalidOptions","type":"error"},{"inputs":[],"name":"InvalidReceiver","type":"error"},{"inputs":[],"name":"LzTokenUnavailable","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"NotEnoughNative","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"OnlyEndpoint","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"OnlyNFTOwner","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"}],"name":"OnlyPeer","type":"error"},{"inputs":[],"name":"OnlySelf","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":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"name":"SimulationResult","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseURI","type":"string"}],"name":"BaseURISet","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"indexed":false,"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"EnforcedOptionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"newExtension","type":"string"}],"name":"FileExtensionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"inspector","type":"address"}],"name":"MsgInspectorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"srcEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ONFTReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"dstEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ONFTSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"peer","type":"bytes32"}],"name":"PeerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"preCrimeAddress","type":"address"}],"name":"PreCrimeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"RoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"newBaseURI","type":"string"}],"name":"URIUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND_AND_COMPOSE","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"}],"name":"allowInitializePath","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvalRequired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"uint16","name":"_msgType","type":"uint16"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"}],"name":"combineOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"}],"name":"enforcedOptions","outputs":[{"internalType":"bytes","name":"enforcedOption","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fileExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRarity","outputs":[{"internalType":"enum CultBearsV2.TokenRarityType","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"_sender","type":"address"}],"name":"isComposeMsgSender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"isPeer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"},{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct InboundPacket[]","name":"_packets","type":"tuple[]"}],"name":"lzReceiveAndRevert","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceiveSimulate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"msgInspector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nextNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oApp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oAppVersion","outputs":[{"internalType":"uint64","name":"senderVersion","type":"uint64"},{"internalType":"uint64","name":"receiverVersion","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"onftVersion","outputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"},{"internalType":"uint64","name":"version","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"peer","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"preCrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"onftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"internalType":"bool","name":"_payInLzToken","type":"bool"}],"name":"quoteSend","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"msgFee","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"onftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"_fee","type":"tuple"},{"internalType":"address","name":"_refundAddress","type":"address"}],"name":"send","outputs":[{"components":[{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt","name":"msgReceipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseTokenURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"setEnforcedOptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"extension","type":"string"}],"name":"setFileExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_msgInspector","type":"address"}],"name":"setMsgInspector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_preCrime","type":"address"}],"name":"setPreCrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e0604052600560a090815264173539b7b760d91b60c05260109062000026908262000330565b503480156200003457600080fd5b50604051620043f8380380620043f88339810160408190526200005791620004cb565b848484848383838381818181806001600160a01b0381166200009457604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200009f8162000192565b506001600160a01b038083166080528116620000ce57604051632d618d8160e21b815260040160405180910390fd5b60805160405163ca5eb5e160e01b81526001600160a01b0383811660048301529091169063ca5eb5e190602401600060405180830381600087803b1580156200011657600080fd5b505af11580156200012b573d6000803e3d6000fd5b50505050505050505050816005908162000146919062000330565b50600662000155828262000330565b5050600e805460ff1916905550600f935062000178925084915083905062000330565b5062000187336101f4620001e2565b505050505062000582565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6127106001600160601b0382168110156200022357604051636f483d0960e01b81526001600160601b0383166004820152602481018290526044016200008b565b6001600160a01b0383166200024f57604051635b6cc80560e11b8152600060048201526024016200008b565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600c55565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620002b457607f821691505b602082108103620002d557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200032b576000816000526020600020601f850160051c81016020861015620003065750805b601f850160051c820191505b81811015620003275782815560010162000312565b5050505b505050565b81516001600160401b038111156200034c576200034c62000289565b62000364816200035d84546200029f565b84620002db565b602080601f8311600181146200039c5760008415620003835750858301515b600019600386901b1c1916600185901b17855562000327565b600085815260208120601f198616915b82811015620003cd57888601518255948401946001909101908401620003ac565b5085821015620003ec5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082601f8301126200040e57600080fd5b81516001600160401b03808211156200042b576200042b62000289565b604051601f8301601f19908116603f0116810190828211818310171562000456576200045662000289565b81604052838152602092508660208588010111156200047457600080fd5b600091505b8382101562000498578582018301518183018401529082019062000479565b6000602085830101528094505050505092915050565b80516001600160a01b0381168114620004c657600080fd5b919050565b600080600080600060a08688031215620004e457600080fd5b85516001600160401b0380821115620004fc57600080fd5b6200050a89838a01620003fc565b965060208801519150808211156200052157600080fd5b6200052f89838a01620003fc565b95506200053f60408901620004ae565b94506200054f60608901620004ae565b935060808801519150808211156200056657600080fd5b506200057588828901620003fc565b9150509295509295909350565b608051613e29620005cf6000396000818161063d01528181610af3015281816115e40152818161193b01528181611bdf01528181612302015281816127a801526128610152613e296000f3fe6080604052600436106103355760003560e01c80637d25a05e116101ab578063bb0b6a53116100f7578063d424388511610095578063f2fde38b1161006f578063f2fde38b146109b6578063f87cafb0146109d6578063fc0c546a14610569578063ff7bd03d146109f657600080fd5b8063d424388514610960578063d5abeb0114610980578063e985e9c51461099657600080fd5b8063c6414e7b116100d1578063c6414e7b146108e0578063c87b56dd1461090d578063ca5eb5e11461092d578063d045a0dc1461094d57600080fd5b8063bb0b6a5314610880578063bc70b354146108ad578063bd815db0146108cd57600080fd5b80639f68b96411610164578063b21a33e41161013e578063b21a33e41461080b578063b731ea0a14610820578063b88d4fde14610840578063b98bd0701461086057600080fd5b80639f68b964146107af578063a22cb465146107c3578063a72f5dd8146107e357600080fd5b80637d25a05e146106f757806382413eac146107325780638456cb59146107525780638da5cb5b146107675780638dc91ac21461078557806395d89b411461079a57600080fd5b806342842e0e116102855780635c975abb116102235780636c0360eb116101fd5780636c0360eb1461067f5780636fc1b31e1461069457806370a08231146106b4578063715018a6146106e257600080fd5b80635c975abb146106135780635e280f111461062b5780636352211e1461065f57600080fd5b80635535d4611161025f5780635535d4611461057c57806355f804b31461059c5780635944c753146105bc5780635a0dfe4d146105dc57600080fd5b806342842e0e1461051c578063487586971461053c57806352ae28791461056957600080fd5b806317442b70116102f257806323b872dd116102cc57806323b872dd146104885780632a55205a146104a85780633400288b146104e75780633f4ba83a1461050757600080fd5b806317442b701461041e5780631f5e13341461044057806321eb730b1461046857600080fd5b806301ffc9a71461033a57806306fdde031461036f578063081812fc14610391578063095ea7b3146103c9578063111ecdad146103eb57806313137d651461040b575b600080fd5b34801561034657600080fd5b5061035a610355366004612bd5565b610a16565b60405190151581526020015b60405180910390f35b34801561037b57600080fd5b50610384610a27565b6040516103669190612c42565b34801561039d57600080fd5b506103b16103ac366004612c55565b610ab9565b6040516001600160a01b039091168152602001610366565b3480156103d557600080fd5b506103e96103e4366004612c83565b610ae2565b005b3480156103f757600080fd5b506004546103b1906001600160a01b031681565b6103e9610419366004612d08565b610af1565b34801561042a57600080fd5b5060408051600181526002602082015201610366565b34801561044c57600080fd5b50610455600181565b60405161ffff9091168152602001610366565b61047b610476366004612db9565b610bb1565b6040516103669190612e26565b34801561049457600080fd5b506103e96104a3366004612e68565b610c6a565b3480156104b457600080fd5b506104c86104c3366004612ea9565b610cf5565b604080516001600160a01b039093168352602083019190915201610366565b3480156104f357600080fd5b506103e9610502366004612edf565b610d7c565b34801561051357600080fd5b506103e9610d8e565b34801561052857600080fd5b506103e9610537366004612e68565b610da0565b34801561054857600080fd5b5061055c610557366004612c55565b610dc0565b6040516103669190612efb565b34801561057557600080fd5b50306103b1565b34801561058857600080fd5b50610384610597366004612f35565b610ef6565b3480156105a857600080fd5b506103e96105b7366004612f68565b610f9b565b3480156105c857600080fd5b506103e96105d7366004612fa9565b610fed565b3480156105e857600080fd5b5061035a6105f7366004612edf565b63ffffffff919091166000908152600160205260409020541490565b34801561061f57600080fd5b50600e5460ff1661035a565b34801561063757600080fd5b506103b17f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b57600080fd5b506103b161067a366004612c55565b611054565b34801561068b57600080fd5b5061038461105f565b3480156106a057600080fd5b506103e96106af366004612fec565b61106c565b3480156106c057600080fd5b506106d46106cf366004612fec565b6110c9565b604051908152602001610366565b3480156106ee57600080fd5b506103e9611111565b34801561070357600080fd5b5061071a610712366004612edf565b600092915050565b6040516001600160401b039091168152602001610366565b34801561073e57600080fd5b5061035a61074d366004613009565b611123565b34801561075e57600080fd5b506103e9611138565b34801561077357600080fd5b506000546001600160a01b03166103b1565b34801561079157600080fd5b50610384611148565b3480156107a657600080fd5b50610384611155565b3480156107bb57600080fd5b50600061035a565b3480156107cf57600080fd5b506103e96107de36600461307d565b611164565b3480156107ef57600080fd5b50604080516311f0c6d360e11b81526001602082015201610366565b34801561081757600080fd5b50610455600281565b34801561082c57600080fd5b506002546103b1906001600160a01b031681565b34801561084c57600080fd5b506103e961085b3660046131cb565b61116f565b34801561086c57600080fd5b506103e961087b36600461327a565b611187565b34801561088c57600080fd5b506106d461089b3660046132af565b60016020526000908152604090205481565b3480156108b957600080fd5b506103846108c83660046132ca565b6111a1565b6103e96108db36600461327a565b611349565b3480156108ec57600080fd5b506109006108fb36600461332a565b6114d3565b6040516103669190613370565b34801561091957600080fd5b50610384610928366004612c55565b611519565b34801561093957600080fd5b506103e9610948366004612fec565b6115bd565b6103e961095b366004612d08565b611643565b34801561096c57600080fd5b506103e961097b366004612fec565b611672565b34801561098c57600080fd5b506106d46107d081565b3480156109a257600080fd5b5061035a6109b1366004613387565b6116c8565b3480156109c257600080fd5b506103e96109d1366004612fec565b6116f6565b3480156109e257600080fd5b506103e96109f13660046133b5565b611734565b348015610a0257600080fd5b5061035a610a113660046133fd565b6117d1565b6000610a2182611807565b92915050565b606060058054610a3690613419565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6290613419565b8015610aaf5780601f10610a8457610100808354040283529160200191610aaf565b820191906000526020600020905b815481529060010190602001808311610a9257829003601f168201915b5050505050905090565b6000610ac48261182c565b506000828152600960205260409020546001600160a01b0316610a21565b610aed828233611865565b5050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314610b41576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b60208701803590610b5b90610b56908a6132af565b611872565b14610b9957610b6d60208801886132af565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610b38565b610ba8878787878787876118ae565b50505050505050565b610bb9612b78565b610bd4336040860135610bcf60208801886132af565b611a0d565b600080610be086611a6d565b9092509050610c0c610bf560208801886132af565b8383610c06368a90038a018a61344d565b88611bac565b805190935033907f986156872b2ee0022b9585231dbbfde457f87f8a16b6c45e1a81c54c4ad8351f610c4160208a018a6132af565b6040805163ffffffff9092168252808b013560208301520160405180910390a350509392505050565b6001600160a01b038216610c9457604051633250574960e11b815260006004820152602401610b38565b6000610ca1838333611cb7565b9050836001600160a01b0316816001600160a01b031614610cef576040516364283d7b60e01b81526001600160a01b0380861660048301526024820184905282166044820152606401610b38565b50505050565b6000828152600d6020526040812080548291906001600160a01b03811690600160a01b90046001600160601b031681610d49575050600c546001600160a01b03811690600160a01b90046001600160601b03165b6000612710610d616001600160601b0384168961347f565b610d6b91906134a4565b9295509193505050505b9250929050565b610d84611db0565b610aed8282611ddd565b610d96611db0565b610d9e611e2b565b565b610dbb8383836040518060200160405280600081525061116f565b505050565b60008082118015610dd357506107d08211155b610e175760405162461bcd60e51b8152602060048201526015602482015274546f6b656e204944206f7574206f662072616e676560581b6044820152606401610b38565b600282111580610e3657506103e98210158015610e3657506103ea8211155b15610e4357506004919050565b60038210158015610e555750600f8211155b80610e6f57506103eb8210158015610e6f57506103f78211155b15610e7c57506003919050565b60108210158015610e8e575060288211155b80610ea857506103f88210158015610ea857506104108211155b15610eb557506002919050565b60298210158015610ec75750605a8211155b80610ee157506104118210158015610ee157506104428211155b15610eee57506001919050565b506000919050565b600360209081526000928352604080842090915290825290208054610f1a90613419565b80601f0160208091040260200160405190810160405280929190818152602001828054610f4690613419565b8015610f935780601f10610f6857610100808354040283529160200191610f93565b820191906000526020600020905b815481529060010190602001808311610f7657829003601f168201915b505050505081565b610fa3611db0565b600b610fb082848361350e565b507ff9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f6600b604051610fe191906135cd565b60405180910390a15050565b610ff5611db0565b610ffd611e7d565b611008838383611ea1565b6040516001600160601b03821681526001600160a01b038316907f23813f5ad446622633cb58c75ceef768a2111751b0f30477a63e06fcaedcff609060200160405180910390a2505050565b6000610a218261182c565b600f8054610f1a90613419565b611074611db0565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b60006001600160a01b0382166110f5576040516322718ad960e21b815260006004820152602401610b38565b506001600160a01b031660009081526008602052604090205490565b611119611db0565b610d9e6000611f63565b6001600160a01b03811630145b949350505050565b611140611db0565b610d9e611fb3565b60108054610f1a90613419565b606060068054610a3690613419565b610aed338383611ff0565b61117a848484610c6a565b610cef338585858561208f565b61118f611db0565b610aed61119c828461365d565b6121b9565b63ffffffff8416600090815260036020908152604080832061ffff871684529091528120805460609291906111d590613419565b80601f016020809104026020016040519081016040528092919081815260200182805461120190613419565b801561124e5780601f106112235761010080835404028352916020019161124e565b820191906000526020600020905b81548152906001019060200180831161123157829003601f168201915b50505050509050805160000361129e5783838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294506111309350505050565b60008390036112ae579050611130565b6002831061132c576112f584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122c092505050565b806113038460028188613732565b6040516020016113159392919061375c565b604051602081830303815290604052915050611130565b8383604051639a6d49cd60e01b8152600401610b389291906137ad565b60005b818110156114525736838383818110611367576113676137c1565b905060200281019061137991906137d7565b90506113ac61138b60208301836132af565b602083013563ffffffff919091166000908152600160205260409020541490565b6113b6575061144a565b3063d045a0dc60c08301358360a08101356113d56101008301836137f8565b6113e6610100890160e08a01612fec565b6113f46101208a018a6137f8565b6040518963ffffffff1660e01b81526004016114169796959493929190613853565b6000604051808303818588803b15801561142f57600080fd5b505af1158015611443573d6000803e3d6000fd5b5050505050505b60010161134c565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa158015611491573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114b991908101906138d9565b604051638351eea760e01b8152600401610b389190612c42565b60408051808201909152600080825260208201526000806114f385611a6d565b909250905061151061150860208701876132af565b8383876122ec565b95945050505050565b6060611524826123c4565b6115885760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610b38565b600f61159383612441565b60106040516020016115a7939291906139b9565b6040516020818303038152906040529050919050565b6115c5611db0565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e190602401600060405180830381600087803b15801561162857600080fd5b505af115801561163c573d6000803e3d6000fd5b5050505050565b3330146116635760405163029a949d60e31b815260040160405180910390fd5b610ba887878787878787610b99565b61167a611db0565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016110be565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b6116fe611db0565b6001600160a01b03811661172857604051631e4fbdf760e01b815260006004820152602401610b38565b61173181611f63565b50565b61173c611db0565b611744611e7d565b60008151116117955760405162461bcd60e51b815260206004820152601e60248201527f46696c6520657874656e73696f6e2063616e6e6f7420626520656d70747900006044820152606401610b38565b60106117a182826139f7565b507f95c0419535f434fa69d4e8cbecdd93dbb4080262f09911d2ca00196d33fcda6f816040516110be9190612c42565b60006020820180359060019083906117e990866132af565b63ffffffff1681526020810191909152604001600020541492915050565b60006001600160e01b0319821663152a902d60e11b1480610a215750610a21826124d3565b6000818152600760205260408120546001600160a01b031680610a2157604051637e27328960e01b815260048101849052602401610b38565b610dbb8383836001612523565b63ffffffff811660009081526001602052604081205480610a215760405163f6ff4fb760e01b815263ffffffff84166004820152602401610b38565b60006118c06118bd8787612629565b90565b905060006118ce8787612648565b90506118e782826118e260208d018d6132af565b612658565b60408611156119ab57600061192161190560608c0160408d01613ab6565b61191260208d018d6132af565b61191c8b8b612662565b6126ad565b604051633e5ac80960e11b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637cb59012906119779086908d906000908790600401613ad3565b600060405180830381600087803b15801561199157600080fd5b505af11580156119a5573d6000803e3d6000fd5b50505050505b6001600160a01b038216887f7883fa30ea56937810e36990b0bbb8d629d0cf59f68baf8431ff657cebe7eef56119e460208d018d6132af565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b611a1682611054565b6001600160a01b0316836001600160a01b031614611a645782611a3883611054565b604051634342715b60e11b81526001600160a01b03928316600482015291166024820152604401610b38565b610dbb826126dc565b6060806020830135611a9257604051631e4ec46b60e01b815260040160405180910390fd5b6000611ae860208501356040860135611aae60808801886137f8565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061271792505050565b9093509050600081611afb576001611afe565b60025b9050611b1e611b1060208701876132af565b826108c860608901896137f8565b6004549093506001600160a01b03168015611ba45760405163043a78eb60e01b81526001600160a01b0382169063043a78eb90611b619088908890600401613b0e565b602060405180830381865afa158015611b7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba29190613b33565b505b505050915091565b611bb4612b78565b6000611bc3846000015161277c565b602085015190915015611bdd57611bdd84602001516127a4565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632637a450826040518060a001604052808b63ffffffff168152602001611c2d8c611872565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b8152600401611c69929190613b50565b60806040518083038185885af1158015611c87573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611cac9190613bf9565b979650505050505050565b6000828152600760205260408120546001600160a01b0390811690831615611ce457611ce4818486612886565b6001600160a01b03811615611d2257611d01600085600080612523565b6001600160a01b038116600090815260086020526040902080546000190190555b6001600160a01b03851615611d51576001600160a01b0385166000908152600860205260409020805460010190555b60008481526007602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6000546001600160a01b03163314610d9e5760405163118cdaa760e01b8152336004820152602401610b38565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b9101610fe1565b611e336128ea565b600e805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600e5460ff1615610d9e5760405163d93c066560e01b815260040160405180910390fd5b6127106001600160601b038216811015611ee75760405163dfd1fc1b60e01b8152600481018590526001600160601b038316602482015260448101829052606401610b38565b6001600160a01b038316611f1857604051634b4f842960e11b81526004810185905260006024820152604401610b38565b506040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752600d90529190942093519051909116600160a01b029116179055565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611fbb611e7d565b600e805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611e603390565b6001600160a01b03821661202257604051630b61174360e31b81526001600160a01b0383166004820152602401610b38565b6001600160a01b038381166000818152600a6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561163c57604051630a85bd0160e11b81526001600160a01b0384169063150b7a02906120d1908890889087908790600401613c43565b6020604051808303816000875af192505050801561210c575060408051601f3d908101601f1916820190925261210991810190613c76565b60015b612175573d80801561213a576040519150601f19603f3d011682016040523d82523d6000602084013e61213f565b606091505b50805160000361216d57604051633250574960e11b81526001600160a01b0385166004820152602401610b38565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b146121b157604051633250574960e11b81526001600160a01b0385166004820152602401610b38565b505050505050565b60005b8151811015612290576121eb8282815181106121da576121da6137c1565b6020026020010151604001516122c0565b8181815181106121fd576121fd6137c1565b6020026020010151604001516003600084848151811061221f5761221f6137c1565b60200260200101516000015163ffffffff1663ffffffff1681526020019081526020016000206000848481518110612259576122596137c1565b60200260200101516020015161ffff1661ffff168152602001908152602001600020908161228791906139f7565b506001016121bc565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674816040516110be9190613c93565b600281015161ffff8116600314610aed5781604051639a6d49cd60e01b8152600401610b389190612c42565b60408051808201909152600080825260208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161234f89611872565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b8152600401612384929190613b50565b6040805180830381865afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115109190613d1e565b6040516331a9108f60e11b8152600481018290526000903090636352211e90602401602060405180830381865afa92505050801561241f575060408051601f3d908101601f1916820190925261241c91810190613d3a565b60015b61242b57506000919050565b6001600160a01b0316151592915050565b919050565b6060600061244e8361290d565b60010190506000816001600160401b0381111561246d5761246d6130b6565b6040519080825280601f01601f191660200182016040528015612497576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846124a157509392505050565b60006001600160e01b031982166380ac58cd60e01b148061250457506001600160e01b03198216635b5e139f60e01b145b80610a2157506301ffc9a760e01b6001600160e01b0319831614610a21565b808061253757506001600160a01b03821615155b156125f95760006125478461182c565b90506001600160a01b038316158015906125735750826001600160a01b0316816001600160a01b031614155b8015612586575061258481846116c8565b155b156125af5760405163a9fbf51f60e01b81526001600160a01b0384166004820152602401610b38565b81156125f75783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260096020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b60006126386020828486613732565b61264191613d57565b9392505050565b6000612638604060208486613732565b610dbb83836129e5565b60606126718260408186613732565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b60608383836040516020016126c493929190613d75565b60405160208183030381529060405290509392505050565b60006126eb6000836000611cb7565b90506001600160a01b038116610aed57604051637e27328960e01b815260048101839052602401610b38565b805160609015158061274b576040805160208101879052908101859052606001604051602081830303815290604052612772565b848433856040516020016127629493929190613dbf565b6040516020818303038152906040525b9150935093915050565b60008134146127a0576040516304fb820960e51b8152346004820152602401610b38565b5090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015612804573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128289190613d3a565b90506001600160a01b038116612851576040516329b99a9560e11b815260040160405180910390fd5b610aed6001600160a01b038216337f000000000000000000000000000000000000000000000000000000000000000085612a4a565b612891838383612aa4565b610dbb576001600160a01b0383166128bf57604051637e27328960e01b815260048101829052602401610b38565b60405163177e802f60e01b81526001600160a01b038316600482015260248101829052604401610b38565b600e5460ff16610d9e57604051638dfc202b60e01b815260040160405180910390fd5b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061294c5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612978576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061299657662386f26fc10000830492506010015b6305f5e10083106129ae576305f5e100830492506008015b61271083106129c257612710830492506004015b606483106129d4576064830492506002015b600a8310610a215760010192915050565b6001600160a01b038216612a0f57604051633250574960e11b815260006004820152602401610b38565b6000612a1d83836000611cb7565b90506001600160a01b03811615610dbb576040516339e3563760e11b815260006004820152602401610b38565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610cef908590612b07565b60006001600160a01b038316158015906111305750826001600160a01b0316846001600160a01b03161480612ade5750612ade84846116c8565b806111305750506000908152600960205260409020546001600160a01b03908116911614919050565b600080602060008451602086016000885af180612b2a576040513d6000823e3d81fd5b50506000513d91508115612b42578060011415612b4f565b6001600160a01b0384163b155b15610cef57604051635274afe760e01b81526001600160a01b0385166004820152602401610b38565b60405180606001604052806000801916815260200160006001600160401b03168152602001612bba604051806040016040528060008152602001600081525090565b905290565b6001600160e01b03198116811461173157600080fd5b600060208284031215612be757600080fd5b813561264181612bbf565b60005b83811015612c0d578181015183820152602001612bf5565b50506000910152565b60008151808452612c2e816020860160208601612bf2565b601f01601f19169290920160200192915050565b6020815260006126416020830184612c16565b600060208284031215612c6757600080fd5b5035919050565b6001600160a01b038116811461173157600080fd5b60008060408385031215612c9657600080fd5b8235612ca181612c6e565b946020939093013593505050565b600060608284031215612cc157600080fd5b50919050565b60008083601f840112612cd957600080fd5b5081356001600160401b03811115612cf057600080fd5b602083019150836020828501011115610d7557600080fd5b600080600080600080600060e0888a031215612d2357600080fd5b612d2d8989612caf565b96506060880135955060808801356001600160401b0380821115612d5057600080fd5b612d5c8b838c01612cc7565b909750955060a08a01359150612d7182612c6e565b90935060c08901359080821115612d8757600080fd5b50612d948a828b01612cc7565b989b979a50959850939692959293505050565b600060c08284031215612cc157600080fd5b60008060008385036080811215612dcf57600080fd5b84356001600160401b03811115612de557600080fd5b612df187828801612da7565b9450506040601f1982011215612e0657600080fd5b506020840191506060840135612e1b81612c6e565b809150509250925092565b6000608082019050825182526001600160401b0360208401511660208301526040830151612e61604084018280518252602090810151910152565b5092915050565b600080600060608486031215612e7d57600080fd5b8335612e8881612c6e565b92506020840135612e9881612c6e565b929592945050506040919091013590565b60008060408385031215612ebc57600080fd5b50508035926020909101359150565b803563ffffffff8116811461243c57600080fd5b60008060408385031215612ef257600080fd5b612ca183612ecb565b6020810160058310612f1d57634e487b7160e01b600052602160045260246000fd5b91905290565b803561ffff8116811461243c57600080fd5b60008060408385031215612f4857600080fd5b612f5183612ecb565b9150612f5f60208401612f23565b90509250929050565b60008060208385031215612f7b57600080fd5b82356001600160401b03811115612f9157600080fd5b612f9d85828601612cc7565b90969095509350505050565b600080600060608486031215612fbe57600080fd5b833592506020840135612fd081612c6e565b915060408401356001600160601b0381168114612e1b57600080fd5b600060208284031215612ffe57600080fd5b813561264181612c6e565b60008060008060a0858703121561301f57600080fd5b6130298686612caf565b935060608501356001600160401b0381111561304457600080fd5b61305087828801612cc7565b909450925050608085013561306481612c6e565b939692955090935050565b801515811461173157600080fd5b6000806040838503121561309057600080fd5b823561309b81612c6e565b915060208301356130ab8161306f565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156130ee576130ee6130b6565b60405290565b604051606081016001600160401b03811182821017156130ee576130ee6130b6565b604051601f8201601f191681016001600160401b038111828210171561313e5761313e6130b6565b604052919050565b60006001600160401b0382111561315f5761315f6130b6565b50601f01601f191660200190565b600061318061317b84613146565b613116565b905082815283838301111561319457600080fd5b828260208301376000602084830101529392505050565b600082601f8301126131bc57600080fd5b6126418383356020850161316d565b600080600080608085870312156131e157600080fd5b84356131ec81612c6e565b935060208501356131fc81612c6e565b92506040850135915060608501356001600160401b0381111561321e57600080fd5b61322a878288016131ab565b91505092959194509250565b60008083601f84011261324857600080fd5b5081356001600160401b0381111561325f57600080fd5b6020830191508360208260051b8501011115610d7557600080fd5b6000806020838503121561328d57600080fd5b82356001600160401b038111156132a357600080fd5b612f9d85828601613236565b6000602082840312156132c157600080fd5b61264182612ecb565b600080600080606085870312156132e057600080fd5b6132e985612ecb565b93506132f760208601612f23565b925060408501356001600160401b0381111561331257600080fd5b61331e87828801612cc7565b95989497509550505050565b6000806040838503121561333d57600080fd5b82356001600160401b0381111561335357600080fd5b61335f85828601612da7565b92505060208301356130ab8161306f565b815181526020808301519082015260408101610a21565b6000806040838503121561339a57600080fd5b82356133a581612c6e565b915060208301356130ab81612c6e565b6000602082840312156133c757600080fd5b81356001600160401b038111156133dd57600080fd5b8201601f810184136133ee57600080fd5b6111308482356020840161316d565b60006060828403121561340f57600080fd5b6126418383612caf565b600181811c9082168061342d57607f821691505b602082108103612cc157634e487b7160e01b600052602260045260246000fd5b60006040828403121561345f57600080fd5b6134676130cc565b82358152602083013560208201528091505092915050565b8082028115828204841417610a2157634e487b7160e01b600052601160045260246000fd5b6000826134c157634e487b7160e01b600052601260045260246000fd5b500490565b601f821115610dbb576000816000526020600020601f850160051c810160208610156134ef5750805b601f850160051c820191505b818110156121b1578281556001016134fb565b6001600160401b03831115613525576135256130b6565b613539836135338354613419565b836134c6565b6000601f84116001811461356d57600085156135555750838201355b600019600387901b1c1916600186901b17835561163c565b600083815260209020601f19861690835b8281101561359e578685013582556020948501946001909201910161357e565b50868210156135bb5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60006020808352600084546135e181613419565b8060208701526040600180841660008114613603576001811461361f5761364f565b60ff19851660408a0152604084151560051b8a0101955061364f565b89600052602060002060005b858110156136465781548b820186015290830190880161362b565b8a016040019650505b509398975050505050505050565b60006001600160401b0380841115613677576136776130b6565b8360051b6020613688818301613116565b8681529185019181810190368411156136a057600080fd5b865b84811015613726578035868111156136ba5760008081fd5b880160603682900312156136ce5760008081fd5b6136d66130f4565b6136df82612ecb565b81526136ec868301612f23565b86820152604080830135898111156137045760008081fd5b613710368286016131ab565b91830191909152508452509183019183016136a2565b50979650505050505050565b6000808585111561374257600080fd5b8386111561374f57600080fd5b5050820193919092039150565b6000845161376e818460208901612bf2565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000611130602083018486613784565b634e487b7160e01b600052603260045260246000fd5b6000823561013e198336030181126137ee57600080fd5b9190910192915050565b6000808335601e1984360301811261380f57600080fd5b8301803591506001600160401b0382111561382957600080fd5b602001915036819003821315610d7557600080fd5b6001600160401b038116811461173157600080fd5b63ffffffff61386189612ecb565b168152602088013560208201526000604089013561387e8161383e565b6001600160401b03811660408401525087606083015260e060808301526138a960e083018789613784565b6001600160a01b03861660a084015282810360c08401526138cb818587613784565b9a9950505050505050505050565b6000602082840312156138eb57600080fd5b81516001600160401b0381111561390157600080fd5b8201601f8101841361391257600080fd5b805161392061317b82613146565b81815285602083850101111561393557600080fd5b611510826020830160208601612bf2565b6000815461395381613419565b6001828116801561396b5760018114613980576139af565b60ff19841687528215158302870194506139af565b8560005260208060002060005b858110156139a65781548a82015290840190820161398d565b50505082870194505b5050505092915050565b60006139c58286613946565b6963756c742d626561722d60b01b815284516139e881600a840160208901612bf2565b611cac600a8284010186613946565b81516001600160401b03811115613a1057613a106130b6565b613a2481613a1e8454613419565b846134c6565b602080601f831160018114613a595760008415613a415750858301515b600019600386901b1c1916600185901b1785556121b1565b600085815260208120601f198616915b82811015613a8857888601518255948401946001909101908401613a69565b5085821015613aa65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215613ac857600080fd5b81356126418161383e565b60018060a01b038516815283602082015261ffff83166040820152608060608201526000613b046080830184612c16565b9695505050505050565b604081526000613b216040830185612c16565b82810360208401526115108185612c16565b600060208284031215613b4557600080fd5b81516126418161306f565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a06080840152613b8660e0840182612c16565b90506060850151603f198483030160a0850152613ba38282612c16565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b600060408284031215613bdb57600080fd5b613be36130cc565b9050815181526020820151602082015292915050565b600060808284031215613c0b57600080fd5b613c136130f4565b825181526020830151613c258161383e565b6020820152613c378460408501613bc9565b60408201529392505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613b0490830184612c16565b600060208284031215613c8857600080fd5b815161264181612bbf565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613d1057888303603f190185528151805163ffffffff1684528781015161ffff16888501528601516060878501819052613cfc81860183612c16565b968901969450505090860190600101613cbc565b509098975050505050505050565b600060408284031215613d3057600080fd5b6126418383613bc9565b600060208284031215613d4c57600080fd5b815161264181612c6e565b80356020831015610a2157600019602084900360031b1b1692915050565b60c084901b6001600160c01b031916815260e083901b6001600160e01b03191660088201528151600090613db081600c850160208701612bf2565b91909101600c01949350505050565b84815283602082015282604082015260008251613de3816060850160208701612bf2565b919091016060019594505050505056fea26469706673582212203cbe81278ca3f9bda40941d7948b2317eaa78591041173aee829ad03a315b4f964736f6c6343000816003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff000000000000000000000000c0ffea512d7683a7088b3d7be2afe69546d0498b0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000a43756c742042656172730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064342454152530000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004068747470733a2f2f617277656176652e6e65742f454252467874503558516136634f4f3248626e346455613252516c324b426266387930467958544735636f2f
Deployed Bytecode
0x6080604052600436106103355760003560e01c80637d25a05e116101ab578063bb0b6a53116100f7578063d424388511610095578063f2fde38b1161006f578063f2fde38b146109b6578063f87cafb0146109d6578063fc0c546a14610569578063ff7bd03d146109f657600080fd5b8063d424388514610960578063d5abeb0114610980578063e985e9c51461099657600080fd5b8063c6414e7b116100d1578063c6414e7b146108e0578063c87b56dd1461090d578063ca5eb5e11461092d578063d045a0dc1461094d57600080fd5b8063bb0b6a5314610880578063bc70b354146108ad578063bd815db0146108cd57600080fd5b80639f68b96411610164578063b21a33e41161013e578063b21a33e41461080b578063b731ea0a14610820578063b88d4fde14610840578063b98bd0701461086057600080fd5b80639f68b964146107af578063a22cb465146107c3578063a72f5dd8146107e357600080fd5b80637d25a05e146106f757806382413eac146107325780638456cb59146107525780638da5cb5b146107675780638dc91ac21461078557806395d89b411461079a57600080fd5b806342842e0e116102855780635c975abb116102235780636c0360eb116101fd5780636c0360eb1461067f5780636fc1b31e1461069457806370a08231146106b4578063715018a6146106e257600080fd5b80635c975abb146106135780635e280f111461062b5780636352211e1461065f57600080fd5b80635535d4611161025f5780635535d4611461057c57806355f804b31461059c5780635944c753146105bc5780635a0dfe4d146105dc57600080fd5b806342842e0e1461051c578063487586971461053c57806352ae28791461056957600080fd5b806317442b70116102f257806323b872dd116102cc57806323b872dd146104885780632a55205a146104a85780633400288b146104e75780633f4ba83a1461050757600080fd5b806317442b701461041e5780631f5e13341461044057806321eb730b1461046857600080fd5b806301ffc9a71461033a57806306fdde031461036f578063081812fc14610391578063095ea7b3146103c9578063111ecdad146103eb57806313137d651461040b575b600080fd5b34801561034657600080fd5b5061035a610355366004612bd5565b610a16565b60405190151581526020015b60405180910390f35b34801561037b57600080fd5b50610384610a27565b6040516103669190612c42565b34801561039d57600080fd5b506103b16103ac366004612c55565b610ab9565b6040516001600160a01b039091168152602001610366565b3480156103d557600080fd5b506103e96103e4366004612c83565b610ae2565b005b3480156103f757600080fd5b506004546103b1906001600160a01b031681565b6103e9610419366004612d08565b610af1565b34801561042a57600080fd5b5060408051600181526002602082015201610366565b34801561044c57600080fd5b50610455600181565b60405161ffff9091168152602001610366565b61047b610476366004612db9565b610bb1565b6040516103669190612e26565b34801561049457600080fd5b506103e96104a3366004612e68565b610c6a565b3480156104b457600080fd5b506104c86104c3366004612ea9565b610cf5565b604080516001600160a01b039093168352602083019190915201610366565b3480156104f357600080fd5b506103e9610502366004612edf565b610d7c565b34801561051357600080fd5b506103e9610d8e565b34801561052857600080fd5b506103e9610537366004612e68565b610da0565b34801561054857600080fd5b5061055c610557366004612c55565b610dc0565b6040516103669190612efb565b34801561057557600080fd5b50306103b1565b34801561058857600080fd5b50610384610597366004612f35565b610ef6565b3480156105a857600080fd5b506103e96105b7366004612f68565b610f9b565b3480156105c857600080fd5b506103e96105d7366004612fa9565b610fed565b3480156105e857600080fd5b5061035a6105f7366004612edf565b63ffffffff919091166000908152600160205260409020541490565b34801561061f57600080fd5b50600e5460ff1661035a565b34801561063757600080fd5b506103b17f0000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff81565b34801561066b57600080fd5b506103b161067a366004612c55565b611054565b34801561068b57600080fd5b5061038461105f565b3480156106a057600080fd5b506103e96106af366004612fec565b61106c565b3480156106c057600080fd5b506106d46106cf366004612fec565b6110c9565b604051908152602001610366565b3480156106ee57600080fd5b506103e9611111565b34801561070357600080fd5b5061071a610712366004612edf565b600092915050565b6040516001600160401b039091168152602001610366565b34801561073e57600080fd5b5061035a61074d366004613009565b611123565b34801561075e57600080fd5b506103e9611138565b34801561077357600080fd5b506000546001600160a01b03166103b1565b34801561079157600080fd5b50610384611148565b3480156107a657600080fd5b50610384611155565b3480156107bb57600080fd5b50600061035a565b3480156107cf57600080fd5b506103e96107de36600461307d565b611164565b3480156107ef57600080fd5b50604080516311f0c6d360e11b81526001602082015201610366565b34801561081757600080fd5b50610455600281565b34801561082c57600080fd5b506002546103b1906001600160a01b031681565b34801561084c57600080fd5b506103e961085b3660046131cb565b61116f565b34801561086c57600080fd5b506103e961087b36600461327a565b611187565b34801561088c57600080fd5b506106d461089b3660046132af565b60016020526000908152604090205481565b3480156108b957600080fd5b506103846108c83660046132ca565b6111a1565b6103e96108db36600461327a565b611349565b3480156108ec57600080fd5b506109006108fb36600461332a565b6114d3565b6040516103669190613370565b34801561091957600080fd5b50610384610928366004612c55565b611519565b34801561093957600080fd5b506103e9610948366004612fec565b6115bd565b6103e961095b366004612d08565b611643565b34801561096c57600080fd5b506103e961097b366004612fec565b611672565b34801561098c57600080fd5b506106d46107d081565b3480156109a257600080fd5b5061035a6109b1366004613387565b6116c8565b3480156109c257600080fd5b506103e96109d1366004612fec565b6116f6565b3480156109e257600080fd5b506103e96109f13660046133b5565b611734565b348015610a0257600080fd5b5061035a610a113660046133fd565b6117d1565b6000610a2182611807565b92915050565b606060058054610a3690613419565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6290613419565b8015610aaf5780601f10610a8457610100808354040283529160200191610aaf565b820191906000526020600020905b815481529060010190602001808311610a9257829003601f168201915b5050505050905090565b6000610ac48261182c565b506000828152600960205260409020546001600160a01b0316610a21565b610aed828233611865565b5050565b7f0000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff6001600160a01b03163314610b41576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b60208701803590610b5b90610b56908a6132af565b611872565b14610b9957610b6d60208801886132af565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610b38565b610ba8878787878787876118ae565b50505050505050565b610bb9612b78565b610bd4336040860135610bcf60208801886132af565b611a0d565b600080610be086611a6d565b9092509050610c0c610bf560208801886132af565b8383610c06368a90038a018a61344d565b88611bac565b805190935033907f986156872b2ee0022b9585231dbbfde457f87f8a16b6c45e1a81c54c4ad8351f610c4160208a018a6132af565b6040805163ffffffff9092168252808b013560208301520160405180910390a350509392505050565b6001600160a01b038216610c9457604051633250574960e11b815260006004820152602401610b38565b6000610ca1838333611cb7565b9050836001600160a01b0316816001600160a01b031614610cef576040516364283d7b60e01b81526001600160a01b0380861660048301526024820184905282166044820152606401610b38565b50505050565b6000828152600d6020526040812080548291906001600160a01b03811690600160a01b90046001600160601b031681610d49575050600c546001600160a01b03811690600160a01b90046001600160601b03165b6000612710610d616001600160601b0384168961347f565b610d6b91906134a4565b9295509193505050505b9250929050565b610d84611db0565b610aed8282611ddd565b610d96611db0565b610d9e611e2b565b565b610dbb8383836040518060200160405280600081525061116f565b505050565b60008082118015610dd357506107d08211155b610e175760405162461bcd60e51b8152602060048201526015602482015274546f6b656e204944206f7574206f662072616e676560581b6044820152606401610b38565b600282111580610e3657506103e98210158015610e3657506103ea8211155b15610e4357506004919050565b60038210158015610e555750600f8211155b80610e6f57506103eb8210158015610e6f57506103f78211155b15610e7c57506003919050565b60108210158015610e8e575060288211155b80610ea857506103f88210158015610ea857506104108211155b15610eb557506002919050565b60298210158015610ec75750605a8211155b80610ee157506104118210158015610ee157506104428211155b15610eee57506001919050565b506000919050565b600360209081526000928352604080842090915290825290208054610f1a90613419565b80601f0160208091040260200160405190810160405280929190818152602001828054610f4690613419565b8015610f935780601f10610f6857610100808354040283529160200191610f93565b820191906000526020600020905b815481529060010190602001808311610f7657829003601f168201915b505050505081565b610fa3611db0565b600b610fb082848361350e565b507ff9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f6600b604051610fe191906135cd565b60405180910390a15050565b610ff5611db0565b610ffd611e7d565b611008838383611ea1565b6040516001600160601b03821681526001600160a01b038316907f23813f5ad446622633cb58c75ceef768a2111751b0f30477a63e06fcaedcff609060200160405180910390a2505050565b6000610a218261182c565b600f8054610f1a90613419565b611074611db0565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b60006001600160a01b0382166110f5576040516322718ad960e21b815260006004820152602401610b38565b506001600160a01b031660009081526008602052604090205490565b611119611db0565b610d9e6000611f63565b6001600160a01b03811630145b949350505050565b611140611db0565b610d9e611fb3565b60108054610f1a90613419565b606060068054610a3690613419565b610aed338383611ff0565b61117a848484610c6a565b610cef338585858561208f565b61118f611db0565b610aed61119c828461365d565b6121b9565b63ffffffff8416600090815260036020908152604080832061ffff871684529091528120805460609291906111d590613419565b80601f016020809104026020016040519081016040528092919081815260200182805461120190613419565b801561124e5780601f106112235761010080835404028352916020019161124e565b820191906000526020600020905b81548152906001019060200180831161123157829003601f168201915b50505050509050805160000361129e5783838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294506111309350505050565b60008390036112ae579050611130565b6002831061132c576112f584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122c092505050565b806113038460028188613732565b6040516020016113159392919061375c565b604051602081830303815290604052915050611130565b8383604051639a6d49cd60e01b8152600401610b389291906137ad565b60005b818110156114525736838383818110611367576113676137c1565b905060200281019061137991906137d7565b90506113ac61138b60208301836132af565b602083013563ffffffff919091166000908152600160205260409020541490565b6113b6575061144a565b3063d045a0dc60c08301358360a08101356113d56101008301836137f8565b6113e6610100890160e08a01612fec565b6113f46101208a018a6137f8565b6040518963ffffffff1660e01b81526004016114169796959493929190613853565b6000604051808303818588803b15801561142f57600080fd5b505af1158015611443573d6000803e3d6000fd5b5050505050505b60010161134c565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa158015611491573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114b991908101906138d9565b604051638351eea760e01b8152600401610b389190612c42565b60408051808201909152600080825260208201526000806114f385611a6d565b909250905061151061150860208701876132af565b8383876122ec565b95945050505050565b6060611524826123c4565b6115885760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610b38565b600f61159383612441565b60106040516020016115a7939291906139b9565b6040516020818303038152906040529050919050565b6115c5611db0565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff169063ca5eb5e190602401600060405180830381600087803b15801561162857600080fd5b505af115801561163c573d6000803e3d6000fd5b5050505050565b3330146116635760405163029a949d60e31b815260040160405180910390fd5b610ba887878787878787610b99565b61167a611db0565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016110be565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b6116fe611db0565b6001600160a01b03811661172857604051631e4fbdf760e01b815260006004820152602401610b38565b61173181611f63565b50565b61173c611db0565b611744611e7d565b60008151116117955760405162461bcd60e51b815260206004820152601e60248201527f46696c6520657874656e73696f6e2063616e6e6f7420626520656d70747900006044820152606401610b38565b60106117a182826139f7565b507f95c0419535f434fa69d4e8cbecdd93dbb4080262f09911d2ca00196d33fcda6f816040516110be9190612c42565b60006020820180359060019083906117e990866132af565b63ffffffff1681526020810191909152604001600020541492915050565b60006001600160e01b0319821663152a902d60e11b1480610a215750610a21826124d3565b6000818152600760205260408120546001600160a01b031680610a2157604051637e27328960e01b815260048101849052602401610b38565b610dbb8383836001612523565b63ffffffff811660009081526001602052604081205480610a215760405163f6ff4fb760e01b815263ffffffff84166004820152602401610b38565b60006118c06118bd8787612629565b90565b905060006118ce8787612648565b90506118e782826118e260208d018d6132af565b612658565b60408611156119ab57600061192161190560608c0160408d01613ab6565b61191260208d018d6132af565b61191c8b8b612662565b6126ad565b604051633e5ac80960e11b81529091506001600160a01b037f0000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff1690637cb59012906119779086908d906000908790600401613ad3565b600060405180830381600087803b15801561199157600080fd5b505af11580156119a5573d6000803e3d6000fd5b50505050505b6001600160a01b038216887f7883fa30ea56937810e36990b0bbb8d629d0cf59f68baf8431ff657cebe7eef56119e460208d018d6132af565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b611a1682611054565b6001600160a01b0316836001600160a01b031614611a645782611a3883611054565b604051634342715b60e11b81526001600160a01b03928316600482015291166024820152604401610b38565b610dbb826126dc565b6060806020830135611a9257604051631e4ec46b60e01b815260040160405180910390fd5b6000611ae860208501356040860135611aae60808801886137f8565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061271792505050565b9093509050600081611afb576001611afe565b60025b9050611b1e611b1060208701876132af565b826108c860608901896137f8565b6004549093506001600160a01b03168015611ba45760405163043a78eb60e01b81526001600160a01b0382169063043a78eb90611b619088908890600401613b0e565b602060405180830381865afa158015611b7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba29190613b33565b505b505050915091565b611bb4612b78565b6000611bc3846000015161277c565b602085015190915015611bdd57611bdd84602001516127a4565b7f0000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff6001600160a01b0316632637a450826040518060a001604052808b63ffffffff168152602001611c2d8c611872565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b8152600401611c69929190613b50565b60806040518083038185885af1158015611c87573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611cac9190613bf9565b979650505050505050565b6000828152600760205260408120546001600160a01b0390811690831615611ce457611ce4818486612886565b6001600160a01b03811615611d2257611d01600085600080612523565b6001600160a01b038116600090815260086020526040902080546000190190555b6001600160a01b03851615611d51576001600160a01b0385166000908152600860205260409020805460010190555b60008481526007602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6000546001600160a01b03163314610d9e5760405163118cdaa760e01b8152336004820152602401610b38565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b9101610fe1565b611e336128ea565b600e805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600e5460ff1615610d9e5760405163d93c066560e01b815260040160405180910390fd5b6127106001600160601b038216811015611ee75760405163dfd1fc1b60e01b8152600481018590526001600160601b038316602482015260448101829052606401610b38565b6001600160a01b038316611f1857604051634b4f842960e11b81526004810185905260006024820152604401610b38565b506040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752600d90529190942093519051909116600160a01b029116179055565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611fbb611e7d565b600e805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611e603390565b6001600160a01b03821661202257604051630b61174360e31b81526001600160a01b0383166004820152602401610b38565b6001600160a01b038381166000818152600a6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561163c57604051630a85bd0160e11b81526001600160a01b0384169063150b7a02906120d1908890889087908790600401613c43565b6020604051808303816000875af192505050801561210c575060408051601f3d908101601f1916820190925261210991810190613c76565b60015b612175573d80801561213a576040519150601f19603f3d011682016040523d82523d6000602084013e61213f565b606091505b50805160000361216d57604051633250574960e11b81526001600160a01b0385166004820152602401610b38565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b146121b157604051633250574960e11b81526001600160a01b0385166004820152602401610b38565b505050505050565b60005b8151811015612290576121eb8282815181106121da576121da6137c1565b6020026020010151604001516122c0565b8181815181106121fd576121fd6137c1565b6020026020010151604001516003600084848151811061221f5761221f6137c1565b60200260200101516000015163ffffffff1663ffffffff1681526020019081526020016000206000848481518110612259576122596137c1565b60200260200101516020015161ffff1661ffff168152602001908152602001600020908161228791906139f7565b506001016121bc565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674816040516110be9190613c93565b600281015161ffff8116600314610aed5781604051639a6d49cd60e01b8152600401610b389190612c42565b60408051808201909152600080825260208201527f0000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff6001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161234f89611872565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b8152600401612384929190613b50565b6040805180830381865afa1580156123a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115109190613d1e565b6040516331a9108f60e11b8152600481018290526000903090636352211e90602401602060405180830381865afa92505050801561241f575060408051601f3d908101601f1916820190925261241c91810190613d3a565b60015b61242b57506000919050565b6001600160a01b0316151592915050565b919050565b6060600061244e8361290d565b60010190506000816001600160401b0381111561246d5761246d6130b6565b6040519080825280601f01601f191660200182016040528015612497576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846124a157509392505050565b60006001600160e01b031982166380ac58cd60e01b148061250457506001600160e01b03198216635b5e139f60e01b145b80610a2157506301ffc9a760e01b6001600160e01b0319831614610a21565b808061253757506001600160a01b03821615155b156125f95760006125478461182c565b90506001600160a01b038316158015906125735750826001600160a01b0316816001600160a01b031614155b8015612586575061258481846116c8565b155b156125af5760405163a9fbf51f60e01b81526001600160a01b0384166004820152602401610b38565b81156125f75783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260096020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b60006126386020828486613732565b61264191613d57565b9392505050565b6000612638604060208486613732565b610dbb83836129e5565b60606126718260408186613732565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b60608383836040516020016126c493929190613d75565b60405160208183030381529060405290509392505050565b60006126eb6000836000611cb7565b90506001600160a01b038116610aed57604051637e27328960e01b815260048101839052602401610b38565b805160609015158061274b576040805160208101879052908101859052606001604051602081830303815290604052612772565b848433856040516020016127629493929190613dbf565b6040516020818303038152906040525b9150935093915050565b60008134146127a0576040516304fb820960e51b8152346004820152602401610b38565b5090565b60007f0000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff6001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015612804573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128289190613d3a565b90506001600160a01b038116612851576040516329b99a9560e11b815260040160405180910390fd5b610aed6001600160a01b038216337f0000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff85612a4a565b612891838383612aa4565b610dbb576001600160a01b0383166128bf57604051637e27328960e01b815260048101829052602401610b38565b60405163177e802f60e01b81526001600160a01b038316600482015260248101829052604401610b38565b600e5460ff16610d9e57604051638dfc202b60e01b815260040160405180910390fd5b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061294c5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612978576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061299657662386f26fc10000830492506010015b6305f5e10083106129ae576305f5e100830492506008015b61271083106129c257612710830492506004015b606483106129d4576064830492506002015b600a8310610a215760010192915050565b6001600160a01b038216612a0f57604051633250574960e11b815260006004820152602401610b38565b6000612a1d83836000611cb7565b90506001600160a01b03811615610dbb576040516339e3563760e11b815260006004820152602401610b38565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610cef908590612b07565b60006001600160a01b038316158015906111305750826001600160a01b0316846001600160a01b03161480612ade5750612ade84846116c8565b806111305750506000908152600960205260409020546001600160a01b03908116911614919050565b600080602060008451602086016000885af180612b2a576040513d6000823e3d81fd5b50506000513d91508115612b42578060011415612b4f565b6001600160a01b0384163b155b15610cef57604051635274afe760e01b81526001600160a01b0385166004820152602401610b38565b60405180606001604052806000801916815260200160006001600160401b03168152602001612bba604051806040016040528060008152602001600081525090565b905290565b6001600160e01b03198116811461173157600080fd5b600060208284031215612be757600080fd5b813561264181612bbf565b60005b83811015612c0d578181015183820152602001612bf5565b50506000910152565b60008151808452612c2e816020860160208601612bf2565b601f01601f19169290920160200192915050565b6020815260006126416020830184612c16565b600060208284031215612c6757600080fd5b5035919050565b6001600160a01b038116811461173157600080fd5b60008060408385031215612c9657600080fd5b8235612ca181612c6e565b946020939093013593505050565b600060608284031215612cc157600080fd5b50919050565b60008083601f840112612cd957600080fd5b5081356001600160401b03811115612cf057600080fd5b602083019150836020828501011115610d7557600080fd5b600080600080600080600060e0888a031215612d2357600080fd5b612d2d8989612caf565b96506060880135955060808801356001600160401b0380821115612d5057600080fd5b612d5c8b838c01612cc7565b909750955060a08a01359150612d7182612c6e565b90935060c08901359080821115612d8757600080fd5b50612d948a828b01612cc7565b989b979a50959850939692959293505050565b600060c08284031215612cc157600080fd5b60008060008385036080811215612dcf57600080fd5b84356001600160401b03811115612de557600080fd5b612df187828801612da7565b9450506040601f1982011215612e0657600080fd5b506020840191506060840135612e1b81612c6e565b809150509250925092565b6000608082019050825182526001600160401b0360208401511660208301526040830151612e61604084018280518252602090810151910152565b5092915050565b600080600060608486031215612e7d57600080fd5b8335612e8881612c6e565b92506020840135612e9881612c6e565b929592945050506040919091013590565b60008060408385031215612ebc57600080fd5b50508035926020909101359150565b803563ffffffff8116811461243c57600080fd5b60008060408385031215612ef257600080fd5b612ca183612ecb565b6020810160058310612f1d57634e487b7160e01b600052602160045260246000fd5b91905290565b803561ffff8116811461243c57600080fd5b60008060408385031215612f4857600080fd5b612f5183612ecb565b9150612f5f60208401612f23565b90509250929050565b60008060208385031215612f7b57600080fd5b82356001600160401b03811115612f9157600080fd5b612f9d85828601612cc7565b90969095509350505050565b600080600060608486031215612fbe57600080fd5b833592506020840135612fd081612c6e565b915060408401356001600160601b0381168114612e1b57600080fd5b600060208284031215612ffe57600080fd5b813561264181612c6e565b60008060008060a0858703121561301f57600080fd5b6130298686612caf565b935060608501356001600160401b0381111561304457600080fd5b61305087828801612cc7565b909450925050608085013561306481612c6e565b939692955090935050565b801515811461173157600080fd5b6000806040838503121561309057600080fd5b823561309b81612c6e565b915060208301356130ab8161306f565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156130ee576130ee6130b6565b60405290565b604051606081016001600160401b03811182821017156130ee576130ee6130b6565b604051601f8201601f191681016001600160401b038111828210171561313e5761313e6130b6565b604052919050565b60006001600160401b0382111561315f5761315f6130b6565b50601f01601f191660200190565b600061318061317b84613146565b613116565b905082815283838301111561319457600080fd5b828260208301376000602084830101529392505050565b600082601f8301126131bc57600080fd5b6126418383356020850161316d565b600080600080608085870312156131e157600080fd5b84356131ec81612c6e565b935060208501356131fc81612c6e565b92506040850135915060608501356001600160401b0381111561321e57600080fd5b61322a878288016131ab565b91505092959194509250565b60008083601f84011261324857600080fd5b5081356001600160401b0381111561325f57600080fd5b6020830191508360208260051b8501011115610d7557600080fd5b6000806020838503121561328d57600080fd5b82356001600160401b038111156132a357600080fd5b612f9d85828601613236565b6000602082840312156132c157600080fd5b61264182612ecb565b600080600080606085870312156132e057600080fd5b6132e985612ecb565b93506132f760208601612f23565b925060408501356001600160401b0381111561331257600080fd5b61331e87828801612cc7565b95989497509550505050565b6000806040838503121561333d57600080fd5b82356001600160401b0381111561335357600080fd5b61335f85828601612da7565b92505060208301356130ab8161306f565b815181526020808301519082015260408101610a21565b6000806040838503121561339a57600080fd5b82356133a581612c6e565b915060208301356130ab81612c6e565b6000602082840312156133c757600080fd5b81356001600160401b038111156133dd57600080fd5b8201601f810184136133ee57600080fd5b6111308482356020840161316d565b60006060828403121561340f57600080fd5b6126418383612caf565b600181811c9082168061342d57607f821691505b602082108103612cc157634e487b7160e01b600052602260045260246000fd5b60006040828403121561345f57600080fd5b6134676130cc565b82358152602083013560208201528091505092915050565b8082028115828204841417610a2157634e487b7160e01b600052601160045260246000fd5b6000826134c157634e487b7160e01b600052601260045260246000fd5b500490565b601f821115610dbb576000816000526020600020601f850160051c810160208610156134ef5750805b601f850160051c820191505b818110156121b1578281556001016134fb565b6001600160401b03831115613525576135256130b6565b613539836135338354613419565b836134c6565b6000601f84116001811461356d57600085156135555750838201355b600019600387901b1c1916600186901b17835561163c565b600083815260209020601f19861690835b8281101561359e578685013582556020948501946001909201910161357e565b50868210156135bb5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60006020808352600084546135e181613419565b8060208701526040600180841660008114613603576001811461361f5761364f565b60ff19851660408a0152604084151560051b8a0101955061364f565b89600052602060002060005b858110156136465781548b820186015290830190880161362b565b8a016040019650505b509398975050505050505050565b60006001600160401b0380841115613677576136776130b6565b8360051b6020613688818301613116565b8681529185019181810190368411156136a057600080fd5b865b84811015613726578035868111156136ba5760008081fd5b880160603682900312156136ce5760008081fd5b6136d66130f4565b6136df82612ecb565b81526136ec868301612f23565b86820152604080830135898111156137045760008081fd5b613710368286016131ab565b91830191909152508452509183019183016136a2565b50979650505050505050565b6000808585111561374257600080fd5b8386111561374f57600080fd5b5050820193919092039150565b6000845161376e818460208901612bf2565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000611130602083018486613784565b634e487b7160e01b600052603260045260246000fd5b6000823561013e198336030181126137ee57600080fd5b9190910192915050565b6000808335601e1984360301811261380f57600080fd5b8301803591506001600160401b0382111561382957600080fd5b602001915036819003821315610d7557600080fd5b6001600160401b038116811461173157600080fd5b63ffffffff61386189612ecb565b168152602088013560208201526000604089013561387e8161383e565b6001600160401b03811660408401525087606083015260e060808301526138a960e083018789613784565b6001600160a01b03861660a084015282810360c08401526138cb818587613784565b9a9950505050505050505050565b6000602082840312156138eb57600080fd5b81516001600160401b0381111561390157600080fd5b8201601f8101841361391257600080fd5b805161392061317b82613146565b81815285602083850101111561393557600080fd5b611510826020830160208601612bf2565b6000815461395381613419565b6001828116801561396b5760018114613980576139af565b60ff19841687528215158302870194506139af565b8560005260208060002060005b858110156139a65781548a82015290840190820161398d565b50505082870194505b5050505092915050565b60006139c58286613946565b6963756c742d626561722d60b01b815284516139e881600a840160208901612bf2565b611cac600a8284010186613946565b81516001600160401b03811115613a1057613a106130b6565b613a2481613a1e8454613419565b846134c6565b602080601f831160018114613a595760008415613a415750858301515b600019600386901b1c1916600185901b1785556121b1565b600085815260208120601f198616915b82811015613a8857888601518255948401946001909101908401613a69565b5085821015613aa65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215613ac857600080fd5b81356126418161383e565b60018060a01b038516815283602082015261ffff83166040820152608060608201526000613b046080830184612c16565b9695505050505050565b604081526000613b216040830185612c16565b82810360208401526115108185612c16565b600060208284031215613b4557600080fd5b81516126418161306f565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a06080840152613b8660e0840182612c16565b90506060850151603f198483030160a0850152613ba38282612c16565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b600060408284031215613bdb57600080fd5b613be36130cc565b9050815181526020820151602082015292915050565b600060808284031215613c0b57600080fd5b613c136130f4565b825181526020830151613c258161383e565b6020820152613c378460408501613bc9565b60408201529392505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613b0490830184612c16565b600060208284031215613c8857600080fd5b815161264181612bbf565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015613d1057888303603f190185528151805163ffffffff1684528781015161ffff16888501528601516060878501819052613cfc81860183612c16565b968901969450505090860190600101613cbc565b509098975050505050505050565b600060408284031215613d3057600080fd5b6126418383613bc9565b600060208284031215613d4c57600080fd5b815161264181612c6e565b80356020831015610a2157600019602084900360031b1b1692915050565b60c084901b6001600160c01b031916815260e083901b6001600160e01b03191660088201528151600090613db081600c850160208701612bf2565b91909101600c01949350505050565b84815283602082015282604082015260008251613de3816060850160208701612bf2565b919091016060019594505050505056fea26469706673582212203cbe81278ca3f9bda40941d7948b2317eaa78591041173aee829ad03a315b4f964736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff000000000000000000000000c0ffea512d7683a7088b3d7be2afe69546d0498b0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000a43756c742042656172730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064342454152530000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004068747470733a2f2f617277656176652e6e65742f454252467874503558516136634f4f3248626e346455613252516c324b426266387930467958544735636f2f
-----Decoded View---------------
Arg [0] : _name (string): Cult Bears
Arg [1] : _symbol (string): CBEARS
Arg [2] : _lzEndpoint (address): 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff
Arg [3] : _delegate (address): 0xC0fFea512d7683A7088b3D7Be2afE69546D0498B
Arg [4] : initialBaseURI (string): https://arweave.net/EBRFxtP5XQa6cOO2Hbn4dUa2RQl2KBbf8y0FyXTG5co/
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000006c7ab2202c98c4227c5c46f1417d81144da716ff
Arg [3] : 000000000000000000000000c0ffea512d7683a7088b3d7be2afe69546d0498b
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [6] : 43756c7420426561727300000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [8] : 4342454152530000000000000000000000000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [10] : 68747470733a2f2f617277656176652e6e65742f454252467874503558516136
Arg [11] : 634f4f3248626e346455613252516c324b426266387930467958544735636f2f
Deployed Bytecode Sourcemap
287:2808:54:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2787:168;;;;;;;;;;-1:-1:-1;2787:168:54;;;;;:::i;:::-;;:::i;:::-;;;565:14:57;;558:22;540:41;;528:2;513:18;2787:168:54;;;;;;;;2364:89:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3496:154::-;;;;;;;;;;-1:-1:-1;3496:154:36;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:57;;;1679:51;;1667:2;1652:18;3496:154:36;1533:203:57;3322:113:36;;;;;;;;;;-1:-1:-1;3322:113:36;;;;;:::i;:::-;;:::i;:::-;;1431:27:25;;;;;;;;;;-1:-1:-1;1431:27:25;;;;-1:-1:-1;;;;;1431:27:25;;;4368:708:12;;;;;;:::i;:::-;;:::i;1287:235:10:-;;;;;;;;;;-1:-1:-1;1287:235:10;;;843:1:13;3966:34:57;;678:1:12;4031:2:57;4016:18;;4009:43;3902:18;1287:235:10;3759:299:57;1265:31:25;;;;;;;;;;;;1295:1;1265:31;;;;;4237:6:57;4225:19;;;4207:38;;4195:2;4180:18;1265:31:25;4063:188:57;3266:634:25;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4142:578:36:-;;;;;;;;;;-1:-1:-1;4142:578:36;;;;;:::i;:::-;;:::i;2379:657:41:-;;;;;;;;;;-1:-1:-1;2379:657:41;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;6613:32:57;;;6595:51;;6677:2;6662:18;;6655:34;;;;6568:18;2379:657:41;6421:274:57;1724:108:11;;;;;;;;;;-1:-1:-1;1724:108:11;;;;;:::i;:::-;;:::i;3028:65:54:-;;;;;;;;;;;;;:::i;4786:132:36:-;;;;;;;;;;-1:-1:-1;4786:132:36;;;;;:::i;:::-;;:::i;1899:647:54:-;;;;;;;;;;-1:-1:-1;1899:647:54;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;875:93:19:-;;;;;;;;;;-1:-1:-1;956:4:19;875:93;;538::18;;;;;;;;;;-1:-1:-1;538:93:18;;;;;:::i;:::-;;:::i;1162:154:24:-;;;;;;;;;;-1:-1:-1;1162:154:24;;;;;:::i;:::-;;:::i;2552:229:54:-;;;;;;;;;;-1:-1:-1;2552:229:54;;;;;:::i;:::-;;:::i;7963:132:25:-;;;;;;;;;;-1:-1:-1;7963:132:25;;;;;:::i;:::-;8068:11;;;;;8045:4;8068:11;;;:5;:11;;;;;;:20;;7963:132;1850:84:46;;;;;;;;;;-1:-1:-1;1920:7:46;;;;1850:84;;446:46:11;;;;;;;;;;;;;;;2184:118:36;;;;;;;;;;-1:-1:-1;2184:118:36;;;;;:::i;:::-;;:::i;500:21:54:-;;;;;;;;;;;;;:::i;2770:163:25:-;;;;;;;;;;-1:-1:-1;2770:163:25;;;;;:::i;:::-;;:::i;1919:208:36:-;;;;;;;;;;-1:-1:-1;1919:208:36;;;;;:::i;:::-;;:::i;:::-;;;9684:25:57;;;9672:2;9657:18;1919:208:36;9538:177:57;2293:101:28;;;;;;;;;;;;;:::i;3507:128:12:-;;;;;;;;;;-1:-1:-1;3507:128:12;;;;;:::i;:::-;3596:12;3507:128;;;;;;;;-1:-1:-1;;;;;9882:31:57;;;9864:50;;9852:2;9837:18;3507:128:12;9720:200:57;2013:216:12;;;;;;;;;;-1:-1:-1;2013:216:12;;;;;:::i;:::-;;:::i;2961:61:54:-;;;;;;;;;;;;;:::i;1638:85:28:-;;;;;;;;;;-1:-1:-1;1684:7:28;1710:6;-1:-1:-1;;;;;1710:6:28;1638:85;;527:37:54;;;;;;;;;;;;;:::i;2517:93:36:-;;;;;;;;;;;;;:::i;1723:94:24:-;;;;;;;;;;-1:-1:-1;1782:4:24;1723:94;;3717:144:36;;;;;;;;;;-1:-1:-1;3717:144:36;;;;;:::i;:::-;;:::i;2281:145:25:-;;;;;;;;;;-1:-1:-1;2281:145:25;;;-1:-1:-1;;;11278:52:57;;2417:1:25;11361:2:57;11346:18;;11339:59;11251:18;2281:145:25;11108:296:57;1302:43:25;;;;;;;;;;;;1344:1;1302:43;;559:23:19;;;;;;;;;;-1:-1:-1;559:23:19;;;;-1:-1:-1;;;;;559:23:19;;;4984:233:36;;;;;;;;;;-1:-1:-1;4984:233:36;;;;;:::i;:::-;;:::i;1391:156:18:-;;;;;;;;;;-1:-1:-1;1391:156:18;;;;;:::i;:::-;;:::i;569:48:11:-;;;;;;;;;;-1:-1:-1;569:48:11;;;;;:::i;:::-;;;;;;;;;;;;;;3510:981:18;;;;;;;;;;-1:-1:-1;3510:981:18;;;;;:::i;:::-;;:::i;1698:1333:19:-;;;;;;:::i;:::-;;:::i;2939:321:25:-;;;;;;;;;;-1:-1:-1;2939:321:25;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1373:285:54:-;;;;;;;;;;-1:-1:-1;1373:285:54;;;;;:::i;:::-;;:::i;3252:105:11:-;;;;;;;;;;-1:-1:-1;3252:105:11;;;;;:::i;:::-;;:::i;3679:409:19:-;;;;;;:::i;:::-;;:::i;1100:139::-;;;;;;;;;;-1:-1:-1;1100:139:19;;;;;:::i;:::-;;:::i;570:40:54:-;;;;;;;;;;;;606:4;570:40;;3927:153:36;;;;;;;;;;-1:-1:-1;3927:153:36;;;;;:::i;:::-;;:::i;2543:215:28:-;;;;;;;;;;-1:-1:-1;2543:215:28;;;;;:::i;:::-;;:::i;1115:252:54:-;;;;;;;;;;-1:-1:-1;1115:252:54;;;;;:::i;:::-;;:::i;2771:149:12:-;;;;;;;;;;-1:-1:-1;2771:149:12;;;;;:::i;:::-;;:::i;2787:168:54:-;2889:4;2912:36;2936:11;2912:23;:36::i;:::-;2905:43;2787:168;-1:-1:-1;;2787:168:54:o;2364:89:36:-;2409:13;2441:5;2434:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2364:89;:::o;3496:154::-;3563:7;3582:22;3596:7;3582:13;:22::i;:::-;-1:-1:-1;6033:7:36;6059:24;;;:15;:24;;;;;;-1:-1:-1;;;;;6059:24:36;3622:21;5963:127;3322:113;3393:35;3402:2;3406:7;735:10:43;3393:8:36;:35::i;:::-;3322:113;;:::o;4368:708:12:-;4681:8;-1:-1:-1;;;;;4673:31:12;4694:10;4673:31;4669:68;;4713:24;;-1:-1:-1;;;4713:24:12;;4726:10;4713:24;;;1679:51:57;1652:18;;4713:24:12;;;;;;;;4669:68;4873:14;;;;;;4837:32;;4854:14;;4873:7;4854:14;:::i;:::-;4837:16;:32::i;:::-;:50;4833:103;;4905:14;;;;:7;:14;:::i;:::-;4896:40;;-1:-1:-1;;;4896:40:12;;18533:10:57;18521:23;;;4896:40:12;;;18503:42:57;4921:14:12;;;;18561:18:57;;;18554:34;18476:18;;4896:40:12;18331:263:57;4833:103:12;5010:59;5021:7;5030:5;5037:8;;5047:9;5058:10;;5010;:59::i;:::-;4368:708;;;;;;;:::o;3266:634:25:-;3427:34;;:::i;:::-;3473:57;3480:10;3492:18;;;;3512:17;;;;3492:10;3512:17;:::i;:::-;3473:6;:57::i;:::-;3542:20;3564;3588:31;3608:10;3588:19;:31::i;:::-;3541:78;;-1:-1:-1;3541:78:25;-1:-1:-1;3736:66:25;3744:17;;;;:10;:17;:::i;:::-;3763:7;3772;3736:66;;;;;;;3781:4;3736:66;:::i;:::-;3787:14;3736:7;:66::i;:::-;3826:15;;3723:79;;-1:-1:-1;3862:10:25;;3817:76;3843:17;;;;:10;:17;:::i;:::-;3874:18;3817:76;;18533:10:57;18521:23;;;18503:42;;3874:18:25;;;;18576:2:57;18561:18;;18554:34;18476:18;3817:76:25;;;;;;;3463:437;;3266:634;;;;;:::o;4142:578:36:-;-1:-1:-1;;;;;4236:16:36;;4232:87;;4275:33;;-1:-1:-1;;;4275:33:36;;4305:1;4275:33;;;1679:51:57;1652:18;;4275:33:36;1533:203:57;4232:87:36;4537:21;4561:34;4569:2;4573:7;735:10:43;4561:7:36;:34::i;:::-;4537:58;;4626:4;-1:-1:-1;;;;;4609:21:36;:13;-1:-1:-1;;;;;4609:21:36;;4605:109;;4653:50;;-1:-1:-1;;;4653:50:36;;-1:-1:-1;;;;;19476:15:57;;;4653:50:36;;;19458:34:57;19508:18;;;19501:34;;;19571:15;;19551:18;;;19544:43;19393:18;;4653:50:36;19218:375:57;4605:109:36;4222:498;4142:578;;;:::o;2379:657:41:-;2487:16;2566:26;;;:17;:26;;;;;2628:21;;2487:16;;2566:26;-1:-1:-1;;;;;2628:21:41;;;-1:-1:-1;;;2684:28:41;;-1:-1:-1;;;;;2684:28:41;2628:21;2723:173;;-1:-1:-1;;2790:19:41;:28;-1:-1:-1;;;;;2790:28:41;;;-1:-1:-1;;;2850:35:41;;-1:-1:-1;;;;;2850:35:41;2723:173;2906:21;3394:5;2931:27;-1:-1:-1;;;;;2931:27:41;;:9;:27;:::i;:::-;2930:49;;;;:::i;:::-;2998:15;;-1:-1:-1;2906:73:41;;-1:-1:-1;;;;2379:657:41;;;;;;:::o;1724:108:11:-;1531:13:28;:11;:13::i;:::-;1804:21:11::1;1813:4;1819:5;1804:8;:21::i;3028:65:54:-:0;1531:13:28;:11;:13::i;:::-;3076:10:54::1;:8;:10::i;:::-;3028:65::o:0;4786:132:36:-;4872:39;4889:4;4895:2;4899:7;4872:39;;;;;;;;;;;;:16;:39::i;:::-;4786:132;;;:::o;1899:647:54:-;1956:15;2001:1;1991:7;:11;:30;;;;;2017:4;2006:7;:15;;1991:30;1983:64;;;;-1:-1:-1;;;1983:64:54;;20424:2:57;1983:64:54;;;20406:21:57;20463:2;20443:18;;;20436:30;-1:-1:-1;;;20482:18:57;;;20475:51;20543:18;;1983:64:54;20222:345:57;1983:64:54;2073:1;2062:7;:12;;:52;;;;2090:4;2079:7;:15;;:34;;;;;2109:4;2098:7;:15;;2079:34;2058:87;;;-1:-1:-1;2123:22:54;;1899:647;-1:-1:-1;1899:647:54:o;2058:87::-;2171:1;2160:7;:12;;:29;;;;;2187:2;2176:7;:13;;2160:29;2159:71;;;;2206:4;2195:7;:15;;:34;;;;;2225:4;2214:7;:15;;2195:34;2155:109;;;-1:-1:-1;2239:25:54;;1899:647;-1:-1:-1;1899:647:54:o;2155:109::-;2290:2;2279:7;:13;;:30;;;;;2307:2;2296:7;:13;;2279:30;2278:72;;;;2326:4;2315:7;:15;;:34;;;;;2345:4;2334:7;:15;;2315:34;2274:111;;;-1:-1:-1;2359:26:54;;1899:647;-1:-1:-1;1899:647:54:o;2274:111::-;2411:2;2400:7;:13;;:30;;;;;2428:2;2417:7;:13;;2400:30;2399:72;;;;2447:4;2436:7;:15;;:34;;;;;2466:4;2455:7;:15;;2436:34;2395:105;;;-1:-1:-1;2480:20:54;;1899:647;-1:-1:-1;1899:647:54:o;2395:105::-;-1:-1:-1;2517:22:54;;1899:647;-1:-1:-1;1899:647:54:o;538:93:18:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1162:154:24:-;1531:13:28;:11;:13::i;:::-;1242:12:24::1;:28;1257:13:::0;;1242:12;:28:::1;:::i;:::-;;1285:24;1296:12;1285:24;;;;;;:::i;:::-;;;;;;;;1162:154:::0;;:::o;2552:229:54:-;1531:13:28;:11;:13::i;:::-;1474:19:46::1;:17;:19::i;:::-;2676:49:54::2;2693:7;2702:8;2712:12;2676:16;:49::i;:::-;2740:34;::::0;-1:-1:-1;;;;;23757:39:57;;23739:58;;-1:-1:-1;;;;;2740:34:54;::::2;::::0;::::2;::::0;23727:2:57;23712:18;2740:34:54::2;;;;;;;2552:229:::0;;;:::o;2184:118:36:-;2247:7;2273:22;2287:7;2273:13;:22::i;500:21:54:-;;;;;;;:::i;2770:163:25:-;1531:13:28;:11;:13::i;:::-;2853:12:25::1;:28:::0;;-1:-1:-1;;;;;;2853:28:25::1;-1:-1:-1::0;;;;;2853:28:25;::::1;::::0;;::::1;::::0;;;2896:30:::1;::::0;1679:51:57;;;2896:30:25::1;::::0;1667:2:57;1652:18;2896:30:25::1;;;;;;;;2770:163:::0;:::o;1919:208:36:-;1982:7;-1:-1:-1;;;;;2005:19:36;;2001:87;;2047:30;;-1:-1:-1;;;2047:30:36;;2074:1;2047:30;;;1679:51:57;1652:18;;2047:30:36;1533:203:57;2001:87:36;-1:-1:-1;;;;;;2104:16:36;;;;;:9;:16;;;;;;;1919:208::o;2293:101:28:-;1531:13;:11;:13::i;:::-;2357:30:::1;2384:1;2357:18;:30::i;2013:216:12:-:0;-1:-1:-1;;;;;2198:24:12;;2217:4;2198:24;2013:216;;;;;;;:::o;2961:61:54:-;1531:13:28;:11;:13::i;:::-;3007:8:54::1;:6;:8::i;527:37::-:0;;;;;;;:::i;2517:93:36:-;2564:13;2596:7;2589:14;;;;;:::i;3717:144::-;3802:52;735:10:43;3835:8:36;3845;3802:18;:52::i;4984:233::-;5097:31;5110:4;5116:2;5120:7;5097:12;:31::i;:::-;5138:72;735:10:43;5186:4:36;5192:2;5196:7;5205:4;5138:33;:72::i;1391:156:18:-;1531:13:28;:11;:13::i;:::-;1503:37:18::1;;1523:16:::0;;1503:37:::1;:::i;:::-;:19;:37::i;3510:981::-:0;3701:21;;;3677;3701;;;:15;:21;;;;;;;;:31;;;;;;;;;;3677:55;;3653:12;;3677:21;3701:31;3677:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3861:8;:15;3880:1;3861:20;3857:46;;3890:13;;3883:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3883:20:18;;-1:-1:-1;3883:20:18;;-1:-1:-1;;;;3883:20:18;3857:46;3988:1;3964:25;;;3960:46;;3998:8;-1:-1:-1;3991:15:18;;3960:46;4153:1;4129:25;;4125:267;;4170:34;4190:13;;4170:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4170:19:18;;-1:-1:-1;;;4170:34:18:i;:::-;4353:8;4363:17;:13;4377:1;4363:13;;:17;:::i;:::-;4340:41;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4333:48;;;;;4125:267;4470:13;;4455:29;;-1:-1:-1;;;4455:29:18;;;;;;;;;:::i;1698:1333:19:-;1799:9;1794:1037;1814:19;;;1794:1037;;;1854:29;1886:8;;1895:1;1886:11;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1854:43;-1:-1:-1;1980:50:19;1987:20;;;;1854:43;1987:20;:::i;:::-;2009;;;;8068:11:25;;;;;8045:4;8068:11;;;:5;:11;;;;;;:20;;7963:132;1980:50:19;1975:65;;2032:8;;;1975:65;2602:4;:22;2633:12;;;;:6;2696:11;;;;2725:14;;;;2633:6;2725:14;:::i;:::-;2757:15;;;;;;;;:::i;:::-;2790:16;;;;:6;:16;:::i;:::-;2602:218;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1840:991;1794:1037;1835:3;;1794:1037;;;;2988:10;-1:-1:-1;;;;;2978:43:19;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2978:45:19;;;;;;;;;;;;:::i;:::-;2961:63;;-1:-1:-1;;;2961:63:19;;;;;;;;:::i;2939:321:25:-;-1:-1:-1;;;;;;;;;;;;;;;;;3101:20:25;3123;3147:31;3167:10;3147:19;:31::i;:::-;3100:78;;-1:-1:-1;3100:78:25;-1:-1:-1;3195:58:25;3202:17;;;;:10;:17;:::i;:::-;3221:7;3230;3239:13;3195:6;:58::i;:::-;3188:65;2939:321;-1:-1:-1;;;;;2939:321:25:o;1373:285:54:-;1446:13;1479:21;1492:7;1479:12;:21::i;:::-;1471:81;;;;-1:-1:-1;;;1471:81:54;;29700:2:57;1471:81:54;;;29682:21:57;29739:2;29719:18;;;29712:30;29778:34;29758:18;;;29751:62;-1:-1:-1;;;29829:18:57;;;29822:45;29884:19;;1471:81:54;29498:411:57;1471:81:54;1593:7;1616:18;:7;:16;:18::i;:::-;1636:13;1576:74;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1562:89;;1373:285;;;:::o;3252:105:11:-;1531:13:28;:11;:13::i;:::-;3319:31:11::1;::::0;-1:-1:-1;;;3319:31:11;;-1:-1:-1;;;;;1697:32:57;;;3319:31:11::1;::::0;::::1;1679:51:57::0;3319:8:11::1;:20;::::0;::::1;::::0;1652:18:57;;3319:31:11::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;3252:105:::0;:::o;3679:409:19:-;3958:10;3980:4;3958:27;3954:50;;3994:10;;-1:-1:-1;;;3994:10:19;;;;;;;;;;;3954:50;4014:67;4033:7;4042:5;4049:8;;4059:9;4070:10;;4014:18;:67::i;1100:139::-;1531:13:28;:11;:13::i;:::-;1175:8:19::1;:20:::0;;-1:-1:-1;;;;;;1175:20:19::1;-1:-1:-1::0;;;;;1175:20:19;::::1;::::0;;::::1;::::0;;;1210:22:::1;::::0;1679:51:57;;;1210:22:19::1;::::0;1667:2:57;1652:18;1210:22:19::1;1533:203:57::0;3927:153:36;-1:-1:-1;;;;;4038:25:36;;;4015:4;4038:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;3927:153::o;2543:215:28:-;1531:13;:11;:13::i;:::-;-1:-1:-1;;;;;2627:22:28;::::1;2623:91;;2672:31;::::0;-1:-1:-1;;;2672:31:28;;2700:1:::1;2672:31;::::0;::::1;1679:51:57::0;1652:18;;2672:31:28::1;1533:203:57::0;2623:91:28::1;2723:28;2742:8;2723:18;:28::i;:::-;2543:215:::0;:::o;1115:252:54:-;1531:13:28;:11;:13::i;:::-;1474:19:46::1;:17;:19::i;:::-;1243:1:54::2;1223:9;1217:23;:27;1209:70;;;::::0;-1:-1:-1;;;1209:70:54;;31470:2:57;1209:70:54::2;::::0;::::2;31452:21:57::0;31509:2;31489:18;;;31482:30;31548:32;31528:18;;;31521:60;31598:18;;1209:70:54::2;31268:354:57::0;1209:70:54::2;1289:13;:25;1305:9:::0;1289:13;:25:::2;:::i;:::-;;1329:31;1350:9;1329:31;;;;;;:::i;2771:149:12:-:0;2853:4;2900:13;;;;;;2876:5;;2853:4;;2882:13;;2900:6;2882:13;:::i;:::-;2876:20;;;;;;;;;;;;;-1:-1:-1;2876:20:12;;:37;;2771:149;-1:-1:-1;;2771:149:12:o;2116:213:41:-;2218:4;-1:-1:-1;;;;;;2241:41:41;;-1:-1:-1;;;2241:41:41;;:81;;;2286:36;2310:11;2286:23;:36::i;16212:241:36:-;16275:7;5824:16;;;:7;:16;;;;;;-1:-1:-1;;;;;5824:16:36;;16337:88;;16383:31;;-1:-1:-1;;;16383:31:36;;;;;9684:25:57;;;9657:18;;16383:31:36;9538:177:57;14492:120:36;14572:33;14581:2;14585:7;14594:4;14600;14572:8;:33::i;2718:196:11:-;2822:11;;;2788:7;2822:11;;;:5;:11;;;;;;;2843:43;;2874:12;;-1:-1:-1;;;2874:12:11;;33151:10:57;33139:23;;2874:12:11;;;33121:42:57;33094:18;;2874:12:11;32977:192:57;5600:977:25;5913:17;5933:36;:17;:8;;:15;:17::i;:::-;2818:2:27;2707:123;5933:36:25;5913:56;;5979:15;5997:18;:8;;:16;:18::i;:::-;5979:36;-1:-1:-1;6026:43:25;6034:9;5979:36;6054:14;;;;:7;:14;:::i;:::-;6026:7;:43::i;:::-;285:2:27;-1:-1:-1;;6080:420:25;;;6121:23;6147:80;6174:13;;;;;;;;:::i;:::-;6189:14;;;;:7;:14;:::i;:::-;6205:21;:8;;:19;:21::i;:::-;6147:26;:80::i;:::-;6401:88;;-1:-1:-1;;;6401:88:25;;6121:106;;-1:-1:-1;;;;;;6401:8:25;:20;;;;:88;;6422:9;;6433:5;;6440:1;;6121:106;;6401:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6107:393;6080:420;-1:-1:-1;;;;;6515:55:25;;6528:5;6515:55;6535:14;;;;:7;:14;:::i;:::-;6515:55;;;18533:10:57;18521:23;;;18503:42;;18576:2;18561:18;;18554:34;;;18476:18;6515:55:25;;;;;;;5903:674;;5600:977;;;;;;;:::o;1823:228:24:-;1941:24;1956:8;1941:14;:24::i;:::-;-1:-1:-1;;;;;1932:33:24;:5;-1:-1:-1;;;;;1932:33:24;;1928:91;;1987:5;1994:24;2009:8;1994:14;:24::i;:::-;1974:45;;-1:-1:-1;;;1974:45:24;;-1:-1:-1;;;;;34138:15:57;;;1974:45:24;;;34120:34:57;34190:15;;34170:18;;;34163:43;34055:18;;1974:45:24;33908:304:57;1928:91:24;2029:15;2035:8;2029:5;:15::i;4140:942:25:-;4245:20;;4303:13;;;;4299:57;;4339:17;;-1:-1:-1;;;4339:17:25;;;;;;;;;;;4299:57;4366:15;4415:80;4438:13;;;;4453:18;;;;4473:21;;;;4438:10;4473:21;:::i;:::-;4415:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4415:22:25;;-1:-1:-1;;;4415:80:25:i;:::-;4391:104;;-1:-1:-1;4391:104:25;-1:-1:-1;4505:14:25;4391:104;4522:36;;1295:1;4522:36;;;1344:1;4522:36;4505:53;-1:-1:-1;4579:67:25;4594:17;;;;:10;:17;:::i;:::-;4613:7;4622:23;;;;:10;:23;:::i;4579:67::-;4904:12;;4569:77;;-1:-1:-1;;;;;;4904:12:25;4996:23;;4992:83;;5021:54;;-1:-1:-1;;;5021:54:25;;-1:-1:-1;;;;;5021:36:25;;;;;:54;;5058:7;;5067;;5021:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;4992:83;4289:793;;;4140:942;;;:::o;3188:766:13:-;3389:31;;:::i;:::-;3554:20;3577:26;3588:4;:14;;;3577:10;:26::i;:::-;3617:15;;;;3554:49;;-1:-1:-1;3617:19:13;3613:53;;3638:28;3650:4;:15;;;3638:11;:28::i;:::-;3755:8;-1:-1:-1;;;;;3755:13:13;;3777:12;3809:92;;;;;;;;3825:7;3809:92;;;;;;3834:25;3851:7;3834:16;:25::i;:::-;3809:92;;;;3861:8;3809:92;;;;3871:8;3809:92;;;;3899:1;3881:4;:15;;;:19;3809:92;;;;;3919:14;3755:192;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3677:270;3188:766;-1:-1:-1;;;;;;;3188:766:13:o;8861:795:36:-;8947:7;5824:16;;;:7;:16;;;;;;-1:-1:-1;;;;;5824:16:36;;;;9058:18;;;9054:86;;9092:37;9109:4;9115;9121:7;9092:16;:37::i;:::-;-1:-1:-1;;;;;9184:18:36;;;9180:256;;9300:48;9317:1;9321:7;9338:1;9342:5;9300:8;:48::i;:::-;-1:-1:-1;;;;;9391:15:36;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;9391:20:36;;;9180:256;-1:-1:-1;;;;;9450:16:36;;;9446:107;;-1:-1:-1;;;;;9510:13:36;;;;;;:9;:13;;;;;:18;;9527:1;9510:18;;;9446:107;9563:16;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9563:21:36;-1:-1:-1;;;;;9563:21:36;;;;;;;;;9600:27;;9563:16;;9600:27;;;;;;;9645:4;8861:795;-1:-1:-1;;;;8861:795:36:o;1796:162:28:-;1684:7;1710:6;-1:-1:-1;;;;;1710:6:28;735:10:43;1855:23:28;1851:101;;1901:40;;-1:-1:-1;;;1901:40:28;;735:10:43;1901:40:28;;;1679:51:57;1652:18;;1901:40:28;1533:203:57;2286:134:11;2359:11;;;;;;;:5;:11;;;;;;;;;:19;;;2393:20;;18503:42:57;;;18561:18;;18554:34;;;2393:20:11;;18476:18:57;2393:20:11;18331:263:57;2710:117:46;1721:16;:14;:16::i;:::-;2768:7:::1;:15:::0;;-1:-1:-1;;2768:15:46::1;::::0;;2798:22:::1;735:10:43::0;2807:12:46::1;2798:22;::::0;-1:-1:-1;;;;;1697:32:57;;;1679:51;;1667:2;1652:18;2798:22:46::1;;;;;;;2710:117::o:0;2002:128::-;1920:7;;;;2063:61;;;2098:15;;-1:-1:-1;;;2098:15:46;;;;;;;;;;;4608:543:41;3394:5;-1:-1:-1;;;;;4770:26:41;;;-1:-1:-1;4766:180:41;;;4873:62;;-1:-1:-1;;;4873:62:41;;;;;36761:25:57;;;-1:-1:-1;;;;;36822:39:57;;36802:18;;;36795:67;36878:18;;;36871:34;;;36734:18;;4873:62:41;36560:351:57;4766:180:41;-1:-1:-1;;;;;4959:22:41;;4955:115;;5004:55;;-1:-1:-1;;;5004:55:41;;;;;37090:25:57;;;5056:1:41;37131:18:57;;;37124:60;37063:18;;5004:55:41;36916:274:57;4955:115:41;-1:-1:-1;5109:35:41;;;;;;;;-1:-1:-1;;;;;5109:35:41;;;;;-1:-1:-1;;;;;5109:35:41;;;;;;;;;;-1:-1:-1;5080:26:41;;;:17;:26;;;;;;:64;;;;;;;-1:-1:-1;;;5080:64:41;;;;;;4608:543::o;2912:187:28:-;2985:16;3004:6;;-1:-1:-1;;;;;3020:17:28;;;-1:-1:-1;;;;;;3020:17:28;;;;;;3052:40;;3004:6;;;;;;;3052:40;;2985:16;3052:40;2975:124;2912:187;:::o;2463:115:46:-;1474:19;:17;:19::i;:::-;2522:7:::1;:14:::0;;-1:-1:-1;;2522:14:46::1;2532:4;2522:14;::::0;;2551:20:::1;2558:12;735:10:43::0;;656:96;15665:312:36;-1:-1:-1;;;;;15772:22:36;;15768:91;;15817:31;;-1:-1:-1;;;15817:31:36;;-1:-1:-1;;;;;1697:32:57;;15817:31:36;;;1679:51:57;1652:18;;15817:31:36;1533:203:57;15768:91:36;-1:-1:-1;;;;;15868:25:36;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;15868:46:36;;;;;;;;;;15929:41;;540::57;;;15929::36;;513:18:57;15929:41:36;;;;;;;15665:312;;;:::o;985:924:40:-;-1:-1:-1;;;;;1165:14:40;;;:18;1161:742;;1203:67;;-1:-1:-1;;;1203:67:40;;-1:-1:-1;;;;;1203:36:40;;;;;:67;;1240:8;;1250:4;;1256:7;;1265:4;;1203:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1203:67:40;;;;;;;;-1:-1:-1;;1203:67:40;;;;;;;;;;;;:::i;:::-;;;1199:694;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1560:6;:13;1577:1;1560:18;1556:323;;1664:39;;-1:-1:-1;;;1664:39:40;;-1:-1:-1;;;;;1697:32:57;;1664:39:40;;;1679:51:57;1652:18;;1664:39:40;1533:203:57;1556:323:40;1831:6;1825:13;1816:6;1812:2;1808:15;1801:38;1199:694;-1:-1:-1;;;;;;1317:51:40;;-1:-1:-1;;;1317:51:40;1313:182;;1437:39;;-1:-1:-1;;;1437:39:40;;-1:-1:-1;;;;;1697:32:57;;1437:39:40;;;1679:51:57;1652:18;;1437:39:40;1533:203:57;1313:182:40;1271:238;985:924;;;;;:::o;2237:514:18:-;2345:9;2340:354;2364:16;:23;2360:1;:27;2340:354;;;2522:48;2542:16;2559:1;2542:19;;;;;;;;:::i;:::-;;;;;;;:27;;;2522:19;:48::i;:::-;2656:16;2673:1;2656:19;;;;;;;;:::i;:::-;;;;;;;:27;;;2584:15;:40;2600:16;2617:1;2600:19;;;;;;;;:::i;:::-;;;;;;;:23;;;2584:40;;;;;;;;;;;;;;;:69;2625:16;2642:1;2625:19;;;;;;;;:::i;:::-;;;;;;;:27;;;2584:69;;;;;;;;;;;;;;;:99;;;;;;:::i;:::-;-1:-1:-1;2389:3:18;;2340:354;;;;2709:35;2727:16;2709:35;;;;;;:::i;4631:264::-;4801:1;4787:16;;4781:23;4827:28;;;463:1;4827:28;4823:65;;4879:8;4864:24;;-1:-1:-1;;;4864:24:18;;;;;;;;:::i;2038:391:13:-;-1:-1:-1;;;;;;;;;;;;;;;;;2259:8:13;-1:-1:-1;;;;;2259:14:13;;2291:86;;;;;;;;2307:7;2291:86;;;;;;2316:25;2333:7;2316:16;:25::i;:::-;2291:86;;;;2343:8;2291:86;;;;2353:8;2291:86;;;;2363:13;2291:86;;;;;2403:4;2259:163;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;1664:229:54:-;1746:21;;-1:-1:-1;;;1746:21:54;;;;;9684:25:57;;;1726:4:54;;1746;;:12;;9657:18:57;;1746:21:54;;;;;;;;;;;;;;;;;;-1:-1:-1;1746:21:54;;;;;;;;-1:-1:-1;;1746:21:54;;;;;;;;;;;;:::i;:::-;;;1742:145;;-1:-1:-1;1871:5:54;;1664:229;-1:-1:-1;1664:229:54:o;1742:145::-;-1:-1:-1;;;;;1813:19:54;;;;1664:229;-1:-1:-1;;1664:229:54:o;1742:145::-;1664:229;;;:::o;637:632:48:-;693:13;742:14;759:17;770:5;759:10;:17::i;:::-;779:1;759:21;742:38;;794:20;828:6;-1:-1:-1;;;;;817:18:48;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;817:18:48;-1:-1:-1;794:41:48;-1:-1:-1;924:28:48;;;940:2;924:28;979:247;-1:-1:-1;;1010:5:48;-1:-1:-1;;;1109:2:48;1098:14;;1093:32;1010:5;1080:46;1170:2;1161:11;;;-1:-1:-1;1190:21:48;979:247;1190:21;-1:-1:-1;1246:6:48;637:632;-1:-1:-1;;;637:632:48:o;1560:300:36:-;1662:4;-1:-1:-1;;;;;;1697:40:36;;-1:-1:-1;;;1697:40:36;;:104;;-1:-1:-1;;;;;;;1753:48:36;;-1:-1:-1;;;1753:48:36;1697:104;:156;;;-1:-1:-1;;;;;;;;;;862:40:49;;;1817:36:36;763:146:49;14794:662:36;14954:9;:31;;;-1:-1:-1;;;;;;14967:18:36;;;;14954:31;14950:460;;;15001:13;15017:22;15031:7;15017:13;:22::i;:::-;15001:38;-1:-1:-1;;;;;;15167:18:36;;;;;;:35;;;15198:4;-1:-1:-1;;;;;15189:13:36;:5;-1:-1:-1;;;;;15189:13:36;;;15167:35;:69;;;;;15207:29;15224:5;15231:4;15207:16;:29::i;:::-;15206:30;15167:69;15163:142;;;15263:27;;-1:-1:-1;;;15263:27:36;;-1:-1:-1;;;;;1697:32:57;;15263:27:36;;;1679:51:57;1652:18;;15263:27:36;1533:203:57;15163:142:36;15323:9;15319:81;;;15377:7;15373:2;-1:-1:-1;;;;;15357:28:36;15366:5;-1:-1:-1;;;;;15357:28:36;;;;;;;;;;;15319:81;14987:423;14950:460;-1:-1:-1;;15420:24:36;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;15420:29:36;-1:-1:-1;;;;;15420:29:36;;;;;;;;;;14794:662::o;1237:123:27:-;1297:7;1331:21;236:2;1297:7;1331:4;;:21;:::i;:::-;1323:30;;;:::i;:::-;1316:37;1237:123;-1:-1:-1;;;1237:123:27:o;1524:148::-;1585:7;1627:36;285:2;236;1627:4;;:36;:::i;2057:131:24:-;2161:20;2167:3;2172:8;2161:5;:20::i;2119:124:27:-;2183:12;2214:22;:4;285:2;2214:4;;:22;:::i;:::-;2207:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2207:29:27;;2119:124;-1:-1:-1;;;;;;2119:124:27:o;684:241:23:-;841:12;889:6;897:7;906:11;872:46;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;865:53;;684:241;;;;;:::o;11510:227:36:-;11561:21;11585:40;11601:1;11605:7;11622:1;11585:7;:40::i;:::-;11561:64;-1:-1:-1;;;;;;11639:27:36;;11635:96;;11689:31;;-1:-1:-1;;;11689:31:36;;;;;9684:25:57;;;9657:18;;11689:31:36;9538:177:57;673:394:27;865:18;;803:20;;865:22;;;907:153;;1025:35;;;;;;41903:19:57;;;41938:12;;;41931:28;;;41975:12;;1025:35:27;;;;;;;;;;;;907:153;;;949:7;958:8;985:10;998:11;932:78;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;907:153;897:163;;673:394;;;;;;:::o;4650:191:13:-;4716:17;4762:10;4749:9;:23;4745:62;;4781:26;;-1:-1:-1;;;4781:26:13;;4797:9;4781:26;;;9684:25:57;9657:18;;4781:26:13;9538:177:57;4745:62:13;-1:-1:-1;4824:10:13;4650:191::o;5218:410::-;5371:15;5389:8;-1:-1:-1;;;;;5389:16:13;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5371:36;-1:-1:-1;;;;;;5421:21:13;;5417:54;;5451:20;;-1:-1:-1;;;5451:20:13;;;;;;;;;;;5417:54;5545:76;-1:-1:-1;;;;;5545:32:13;;5578:10;5598:8;5609:11;5545:32;:76::i;7105:368:36:-;7217:38;7231:5;7238:7;7247;7217:13;:38::i;:::-;7212:255;;-1:-1:-1;;;;;7275:19:36;;7271:186;;7321:31;;-1:-1:-1;;;7321:31:36;;;;;9684:25:57;;;9657:18;;7321:31:36;9538:177:57;7271:186:36;7398:44;;-1:-1:-1;;;7398:44:36;;-1:-1:-1;;;;;6613:32:57;;7398:44:36;;;6595:51:57;6662:18;;;6655:34;;;6568:18;;7398:44:36;6421:274:57;2202:126:46;1920:7;;;;2260:62;;2296:15;;-1:-1:-1;;;2296:15:46;;;;;;;;;;;25316:916:51;25369:7;;-1:-1:-1;;;25444:17:51;;25440:103;;-1:-1:-1;;;25481:17:51;;;-1:-1:-1;25526:2:51;25516:12;25440:103;25569:8;25560:5;:17;25556:103;;25606:8;25597:17;;;-1:-1:-1;25642:2:51;25632:12;25556:103;25685:8;25676:5;:17;25672:103;;25722:8;25713:17;;;-1:-1:-1;25758:2:51;25748:12;25672:103;25801:7;25792:5;:16;25788:100;;25837:7;25828:16;;;-1:-1:-1;25872:1:51;25862:11;25788:100;25914:7;25905:5;:16;25901:100;;25950:7;25941:16;;;-1:-1:-1;25985:1:51;25975:11;25901:100;26027:7;26018:5;:16;26014:100;;26063:7;26054:16;;;-1:-1:-1;26098:1:51;26088:11;26014:100;26140:7;26131:5;:16;26127:66;;26177:1;26167:11;26219:6;25316:916;-1:-1:-1;;25316:916:51:o;9978:327:36:-;-1:-1:-1;;;;;10045:16:36;;10041:87;;10084:33;;-1:-1:-1;;;10084:33:36;;10114:1;10084:33;;;1679:51:57;1652:18;;10084:33:36;1533:203:57;10041:87:36;10137:21;10161:32;10169:2;10173:7;10190:1;10161:7;:32::i;:::-;10137:56;-1:-1:-1;;;;;;10207:27:36;;;10203:96;;10257:31;;-1:-1:-1;;;10257:31:36;;10285:1;10257:31;;;1679:51:57;1652:18;;10257:31:36;1533:203:57;1670:188:35;1797:53;;;-1:-1:-1;;;;;42750:15:57;;;1797:53:35;;;42732:34:57;42802:15;;42782:18;;;42775:43;42834:18;;;;42827:34;;;1797:53:35;;;;;;;;;;42667:18:57;;;;1797:53:35;;;;;;;;-1:-1:-1;;;;;1797:53:35;-1:-1:-1;;;1797:53:35;;;1770:81;;1790:5;;1770:19;:81::i;6401:272:36:-;6504:4;-1:-1:-1;;;;;6539:21:36;;;;;;:127;;;6586:7;-1:-1:-1;;;;;6577:16:36;:5;-1:-1:-1;;;;;6577:16:36;;:52;;;;6597:32;6614:5;6621:7;6597:16;:32::i;:::-;6577:88;;;-1:-1:-1;;6033:7:36;6059:24;;;:15;:24;;;;;;-1:-1:-1;;;;;6059:24:36;;;6633:32;;;;6520:146;-1:-1:-1;6401:272:36:o;7738:720:35:-;7818:18;7846:19;7984:4;7981:1;7974:4;7968:11;7961:4;7955;7951:15;7948:1;7941:5;7934;7929:60;8041:7;8031:176;;8085:4;8079:11;8130:16;8127:1;8122:3;8107:40;8176:16;8171:3;8164:29;8031:176;-1:-1:-1;;8284:1:35;8278:8;8234:16;;-1:-1:-1;8310:15:35;;:68;;8362:11;8377:1;8362:16;;8310:68;;;-1:-1:-1;;;;;8328:26:35;;;:31;8310:68;8306:146;;;8401:40;;-1:-1:-1;;;8401:40:35;;-1:-1:-1;;;;;1697:32:57;;8401:40:35;;;1679:51:57;1652:18;;8401:40:35;1533:203:57;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:57:-;-1:-1:-1;;;;;;88:32:57;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:57;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:57;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:57:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:57;;1348:180;-1:-1:-1;1348:180:57:o;1741:131::-;-1:-1:-1;;;;;1816:31:57;;1806:42;;1796:70;;1862:1;1859;1852:12;1877:315;1945:6;1953;2006:2;1994:9;1985:7;1981:23;1977:32;1974:52;;;2022:1;2019;2012:12;1974:52;2061:9;2048:23;2080:31;2105:5;2080:31;:::i;:::-;2130:5;2182:2;2167:18;;;;2154:32;;-1:-1:-1;;;1877:315:57:o;2197:154::-;2256:5;2301:2;2292:6;2287:3;2283:16;2279:25;2276:45;;;2317:1;2314;2307:12;2276:45;-1:-1:-1;2339:6:57;2197:154;-1:-1:-1;2197:154:57:o;2356:347::-;2407:8;2417:6;2471:3;2464:4;2456:6;2452:17;2448:27;2438:55;;2489:1;2486;2479:12;2438:55;-1:-1:-1;2512:20:57;;-1:-1:-1;;;;;2544:30:57;;2541:50;;;2587:1;2584;2577:12;2541:50;2624:4;2616:6;2612:17;2600:29;;2676:3;2669:4;2660:6;2652;2648:19;2644:30;2641:39;2638:59;;;2693:1;2690;2683:12;2708:1046;2849:6;2857;2865;2873;2881;2889;2897;2950:3;2938:9;2929:7;2925:23;2921:33;2918:53;;;2967:1;2964;2957:12;2918:53;2990;3035:7;3024:9;2990:53;:::i;:::-;2980:63;;3090:2;3079:9;3075:18;3062:32;3052:42;;3145:3;3134:9;3130:19;3117:33;-1:-1:-1;;;;;3210:2:57;3202:6;3199:14;3196:34;;;3226:1;3223;3216:12;3196:34;3265:58;3315:7;3306:6;3295:9;3291:22;3265:58;:::i;:::-;3342:8;;-1:-1:-1;3239:84:57;-1:-1:-1;3427:3:57;3412:19;;3399:33;;-1:-1:-1;3441:31:57;3399:33;3441:31;:::i;:::-;3491:5;;-1:-1:-1;3549:3:57;3534:19;;3521:33;;3566:16;;;3563:36;;;3595:1;3592;3585:12;3563:36;;3634:60;3686:7;3675:8;3664:9;3660:24;3634:60;:::i;:::-;2708:1046;;;;-1:-1:-1;2708:1046:57;;-1:-1:-1;2708:1046:57;;;;3608:86;;-1:-1:-1;;;2708:1046:57:o;4256:158::-;4318:5;4363:3;4354:6;4349:3;4345:16;4341:26;4338:46;;;4380:1;4377;4370:12;4419:655;4555:6;4563;4571;4615:9;4606:7;4602:23;4645:3;4641:2;4637:12;4634:32;;;4662:1;4659;4652:12;4634:32;4702:9;4689:23;-1:-1:-1;;;;;4727:6:57;4724:30;4721:50;;;4767:1;4764;4757:12;4721:50;4790:69;4851:7;4842:6;4831:9;4827:22;4790:69;:::i;:::-;4780:79;-1:-1:-1;;4893:2:57;-1:-1:-1;;4875:16:57;;4871:25;4868:45;;;4909:1;4906;4899:12;4868:45;;4947:2;4936:9;4932:18;4922:28;;5000:2;4989:9;4985:18;4972:32;5013:31;5038:5;5013:31;:::i;:::-;5063:5;5053:15;;;4419:655;;;;;:::o;5237:465::-;5393:4;5435:3;5424:9;5420:19;5412:27;;5472:6;5466:13;5455:9;5448:32;-1:-1:-1;;;;;5540:4:57;5532:6;5528:17;5522:24;5518:49;5511:4;5500:9;5496:20;5489:79;5615:4;5607:6;5603:17;5597:24;5630:66;5690:4;5679:9;5675:20;5661:12;5157;;5145:25;;5219:4;5208:16;;;5202:23;5186:14;;5179:47;5079:153;5630:66;;5237:465;;;;:::o;5707:456::-;5784:6;5792;5800;5853:2;5841:9;5832:7;5828:23;5824:32;5821:52;;;5869:1;5866;5859:12;5821:52;5908:9;5895:23;5927:31;5952:5;5927:31;:::i;:::-;5977:5;-1:-1:-1;6034:2:57;6019:18;;6006:32;6047:33;6006:32;6047:33;:::i;:::-;5707:456;;6099:7;;-1:-1:-1;;;6153:2:57;6138:18;;;;6125:32;;5707:456::o;6168:248::-;6236:6;6244;6297:2;6285:9;6276:7;6272:23;6268:32;6265:52;;;6313:1;6310;6303:12;6265:52;-1:-1:-1;;6336:23:57;;;6406:2;6391:18;;;6378:32;;-1:-1:-1;6168:248:57:o;6700:163::-;6767:20;;6827:10;6816:22;;6806:33;;6796:61;;6853:1;6850;6843:12;6868:252;6935:6;6943;6996:2;6984:9;6975:7;6971:23;6967:32;6964:52;;;7012:1;7009;7002:12;6964:52;7035:28;7053:9;7035:28;:::i;7125:349::-;7278:2;7263:18;;7311:1;7300:13;;7290:144;;7356:10;7351:3;7347:20;7344:1;7337:31;7391:4;7388:1;7381:15;7419:4;7416:1;7409:15;7290:144;7443:25;;;7125:349;:::o;7479:159::-;7546:20;;7606:6;7595:18;;7585:29;;7575:57;;7628:1;7625;7618:12;7643:256;7709:6;7717;7770:2;7758:9;7749:7;7745:23;7741:32;7738:52;;;7786:1;7783;7776:12;7738:52;7809:28;7827:9;7809:28;:::i;:::-;7799:38;;7856:37;7889:2;7878:9;7874:18;7856:37;:::i;:::-;7846:47;;7643:256;;;;;:::o;8127:410::-;8198:6;8206;8259:2;8247:9;8238:7;8234:23;8230:32;8227:52;;;8275:1;8272;8265:12;8227:52;8315:9;8302:23;-1:-1:-1;;;;;8340:6:57;8337:30;8334:50;;;8380:1;8377;8370:12;8334:50;8419:58;8469:7;8460:6;8449:9;8445:22;8419:58;:::i;:::-;8496:8;;8393:84;;-1:-1:-1;8127:410:57;-1:-1:-1;;;;8127:410:57:o;8542:503::-;8618:6;8626;8634;8687:2;8675:9;8666:7;8662:23;8658:32;8655:52;;;8703:1;8700;8693:12;8655:52;8739:9;8726:23;8716:33;;8799:2;8788:9;8784:18;8771:32;8812:31;8837:5;8812:31;:::i;:::-;8862:5;-1:-1:-1;8919:2:57;8904:18;;8891:32;-1:-1:-1;;;;;8954:40:57;;8942:53;;8932:81;;9009:1;9006;8999:12;9286:247;9345:6;9398:2;9386:9;9377:7;9373:23;9369:32;9366:52;;;9414:1;9411;9404:12;9366:52;9453:9;9440:23;9472:31;9497:5;9472:31;:::i;9925:668::-;10037:6;10045;10053;10061;10114:3;10102:9;10093:7;10089:23;10085:33;10082:53;;;10131:1;10128;10121:12;10082:53;10154;10199:7;10188:9;10154:53;:::i;:::-;10144:63;;10258:2;10247:9;10243:18;10230:32;-1:-1:-1;;;;;10277:6:57;10274:30;10271:50;;;10317:1;10314;10307:12;10271:50;10356:58;10406:7;10397:6;10386:9;10382:22;10356:58;:::i;:::-;10433:8;;-1:-1:-1;10330:84:57;-1:-1:-1;;10518:3:57;10503:19;;10490:33;10532:31;10490:33;10532:31;:::i;:::-;9925:668;;;;-1:-1:-1;9925:668:57;;-1:-1:-1;;9925:668:57:o;10598:118::-;10684:5;10677:13;10670:21;10663:5;10660:32;10650:60;;10706:1;10703;10696:12;10721:382;10786:6;10794;10847:2;10835:9;10826:7;10822:23;10818:32;10815:52;;;10863:1;10860;10853:12;10815:52;10902:9;10889:23;10921:31;10946:5;10921:31;:::i;:::-;10971:5;-1:-1:-1;11028:2:57;11013:18;;11000:32;11041:30;11000:32;11041:30;:::i;:::-;11090:7;11080:17;;;10721:382;;;;;:::o;11409:127::-;11470:10;11465:3;11461:20;11458:1;11451:31;11501:4;11498:1;11491:15;11525:4;11522:1;11515:15;11541:251;11613:2;11607:9;;;11643:15;;-1:-1:-1;;;;;11673:34:57;;11709:22;;;11670:62;11667:88;;;11735:18;;:::i;:::-;11771:2;11764:22;11541:251;:::o;11797:253::-;11869:2;11863:9;11911:4;11899:17;;-1:-1:-1;;;;;11931:34:57;;11967:22;;;11928:62;11925:88;;;11993:18;;:::i;12055:275::-;12126:2;12120:9;12191:2;12172:13;;-1:-1:-1;;12168:27:57;12156:40;;-1:-1:-1;;;;;12211:34:57;;12247:22;;;12208:62;12205:88;;;12273:18;;:::i;:::-;12309:2;12302:22;12055:275;;-1:-1:-1;12055:275:57:o;12335:186::-;12383:4;-1:-1:-1;;;;;12408:6:57;12405:30;12402:56;;;12438:18;;:::i;:::-;-1:-1:-1;12504:2:57;12483:15;-1:-1:-1;;12479:29:57;12510:4;12475:40;;12335:186::o;12526:336::-;12590:5;12619:52;12635:35;12663:6;12635:35;:::i;:::-;12619:52;:::i;:::-;12610:61;;12694:6;12687:5;12680:21;12734:3;12725:6;12720:3;12716:16;12713:25;12710:45;;;12751:1;12748;12741:12;12710:45;12800:6;12795:3;12788:4;12781:5;12777:16;12764:43;12854:1;12847:4;12838:6;12831:5;12827:18;12823:29;12816:40;12526:336;;;;;:::o;12867:220::-;12909:5;12962:3;12955:4;12947:6;12943:17;12939:27;12929:55;;12980:1;12977;12970:12;12929:55;13002:79;13077:3;13068:6;13055:20;13048:4;13040:6;13036:17;13002:79;:::i;13092:665::-;13187:6;13195;13203;13211;13264:3;13252:9;13243:7;13239:23;13235:33;13232:53;;;13281:1;13278;13271:12;13232:53;13320:9;13307:23;13339:31;13364:5;13339:31;:::i;:::-;13389:5;-1:-1:-1;13446:2:57;13431:18;;13418:32;13459:33;13418:32;13459:33;:::i;:::-;13511:7;-1:-1:-1;13565:2:57;13550:18;;13537:32;;-1:-1:-1;13620:2:57;13605:18;;13592:32;-1:-1:-1;;;;;13636:30:57;;13633:50;;;13679:1;13676;13669:12;13633:50;13702:49;13743:7;13734:6;13723:9;13719:22;13702:49;:::i;:::-;13692:59;;;13092:665;;;;;;;:::o;13762:395::-;13853:8;13863:6;13917:3;13910:4;13902:6;13898:17;13894:27;13884:55;;13935:1;13932;13925:12;13884:55;-1:-1:-1;13958:20:57;;-1:-1:-1;;;;;13990:30:57;;13987:50;;;14033:1;14030;14023:12;13987:50;14070:4;14062:6;14058:17;14046:29;;14130:3;14123:4;14113:6;14110:1;14106:14;14098:6;14094:27;14090:38;14087:47;14084:67;;;14147:1;14144;14137:12;14162:504;14287:6;14295;14348:2;14336:9;14327:7;14323:23;14319:32;14316:52;;;14364:1;14361;14354:12;14316:52;14404:9;14391:23;-1:-1:-1;;;;;14429:6:57;14426:30;14423:50;;;14469:1;14466;14459:12;14423:50;14508:98;14598:7;14589:6;14578:9;14574:22;14508:98;:::i;14671:184::-;14729:6;14782:2;14770:9;14761:7;14757:23;14753:32;14750:52;;;14798:1;14795;14788:12;14750:52;14821:28;14839:9;14821:28;:::i;15042:553::-;15128:6;15136;15144;15152;15205:2;15193:9;15184:7;15180:23;15176:32;15173:52;;;15221:1;15218;15211:12;15173:52;15244:28;15262:9;15244:28;:::i;:::-;15234:38;;15291:37;15324:2;15313:9;15309:18;15291:37;:::i;:::-;15281:47;;15379:2;15368:9;15364:18;15351:32;-1:-1:-1;;;;;15398:6:57;15395:30;15392:50;;;15438:1;15435;15428:12;15392:50;15477:58;15527:7;15518:6;15507:9;15503:22;15477:58;:::i;:::-;15042:553;;;;-1:-1:-1;15554:8:57;-1:-1:-1;;;;15042:553:57:o;16103:489::-;16197:6;16205;16258:2;16246:9;16237:7;16233:23;16229:32;16226:52;;;16274:1;16271;16264:12;16226:52;16314:9;16301:23;-1:-1:-1;;;;;16339:6:57;16336:30;16333:50;;;16379:1;16376;16369:12;16333:50;16402:69;16463:7;16454:6;16443:9;16439:22;16402:69;:::i;:::-;16392:79;;;16521:2;16510:9;16506:18;16493:32;16534:28;16556:5;16534:28;:::i;16597:257::-;5157:12;;5145:25;;5219:4;5208:16;;;5202:23;5186:14;;;5179:47;16787:2;16772:18;;16799:49;5079:153;16859:388;16927:6;16935;16988:2;16976:9;16967:7;16963:23;16959:32;16956:52;;;17004:1;17001;16994:12;16956:52;17043:9;17030:23;17062:31;17087:5;17062:31;:::i;:::-;17112:5;-1:-1:-1;17169:2:57;17154:18;;17141:32;17182:33;17141:32;17182:33;:::i;17252:450::-;17321:6;17374:2;17362:9;17353:7;17349:23;17345:32;17342:52;;;17390:1;17387;17380:12;17342:52;17430:9;17417:23;-1:-1:-1;;;;;17455:6:57;17452:30;17449:50;;;17495:1;17492;17485:12;17449:50;17518:22;;17571:4;17563:13;;17559:27;-1:-1:-1;17549:55:57;;17600:1;17597;17590:12;17549:55;17623:73;17688:7;17683:2;17670:16;17665:2;17661;17657:11;17623:73;:::i;17707:234::-;17790:6;17843:2;17831:9;17822:7;17818:23;17814:32;17811:52;;;17859:1;17856;17849:12;17811:52;17882:53;17927:7;17916:9;17882:53;:::i;17946:380::-;18025:1;18021:12;;;;18068;;;18089:61;;18143:4;18135:6;18131:17;18121:27;;18089:61;18196:2;18188:6;18185:14;18165:18;18162:38;18159:161;;18242:10;18237:3;18233:20;18230:1;18223:31;18277:4;18274:1;18267:15;18305:4;18302:1;18295:15;18599:346;18686:6;18739:2;18727:9;18718:7;18714:23;18710:32;18707:52;;;18755:1;18752;18745:12;18707:52;18781:22;;:::i;:::-;18839:9;18826:23;18819:5;18812:38;18910:2;18899:9;18895:18;18882:32;18877:2;18870:5;18866:14;18859:56;18934:5;18924:15;;;18599:346;;;;:::o;19598:265::-;19671:9;;;19702;;19719:15;;;19713:22;;19699:37;19689:168;;19779:10;19774:3;19770:20;19767:1;19760:31;19814:4;19811:1;19804:15;19842:4;19839:1;19832:15;20000:217;20040:1;20066;20056:132;;20110:10;20105:3;20101:20;20098:1;20091:31;20145:4;20142:1;20135:15;20173:4;20170:1;20163:15;20056:132;-1:-1:-1;20202:9:57;;20000:217::o;20698:543::-;20800:2;20795:3;20792:11;20789:446;;;20836:1;20860:5;20857:1;20850:16;20904:4;20901:1;20891:18;20974:2;20962:10;20958:19;20955:1;20951:27;20945:4;20941:38;21010:4;20998:10;20995:20;20992:47;;;-1:-1:-1;21033:4:57;20992:47;21088:2;21083:3;21079:12;21076:1;21072:20;21066:4;21062:31;21052:41;;21143:82;21161:2;21154:5;21151:13;21143:82;;;21206:17;;;21187:1;21176:13;21143:82;;21417:1206;-1:-1:-1;;;;;21536:3:57;21533:27;21530:53;;;21563:18;;:::i;:::-;21592:94;21682:3;21642:38;21674:4;21668:11;21642:38;:::i;:::-;21636:4;21592:94;:::i;:::-;21712:1;21737:2;21732:3;21729:11;21754:1;21749:616;;;;22409:1;22426:3;22423:93;;;-1:-1:-1;22482:19:57;;;22469:33;22423:93;-1:-1:-1;;21374:1:57;21370:11;;;21366:24;21362:29;21352:40;21398:1;21394:11;;;21349:57;22529:78;;21722:895;;21749:616;20645:1;20638:14;;;20682:4;20669:18;;-1:-1:-1;;21785:17:57;;;21886:9;21908:229;21922:7;21919:1;21916:14;21908:229;;;22011:19;;;21998:33;21983:49;;22118:4;22103:20;;;;22071:1;22059:14;;;;21938:12;21908:229;;;21912:3;22165;22156:7;22153:16;22150:159;;;22289:1;22285:6;22279:3;22273;22270:1;22266:11;22262:21;22258:34;22254:39;22241:9;22236:3;22232:19;22219:33;22215:79;22207:6;22200:95;22150:159;;;22352:1;22346:3;22343:1;22339:11;22335:19;22329:4;22322:33;21722:895;;21417:1206;;;:::o;22628:962::-;22737:4;22766:2;22795;22784:9;22777:21;22818:1;22851:6;22845:13;22881:36;22907:9;22881:36;:::i;:::-;22953:6;22948:2;22937:9;22933:18;22926:34;22979:2;23000:1;23032;23021:9;23017:17;23048:1;23043:158;;;;23215:1;23210:354;;;;23010:554;;23043:158;23110:3;23106:8;23095:9;23091:24;23086:2;23075:9;23071:18;23064:52;23188:2;23176:6;23169:14;23162:22;23159:1;23155:30;23144:9;23140:46;23136:55;23129:62;;23043:158;;23210:354;23241:6;23238:1;23231:17;23289:2;23286:1;23276:16;23314:1;23328:180;23342:6;23339:1;23336:13;23328:180;;;23435:14;;23411:17;;;23407:26;;23400:50;23478:16;;;;23357:10;;23328:180;;;23532:17;;23551:2;23528:26;;-1:-1:-1;;23010:554:57;-1:-1:-1;23581:3:57;;22628:962;-1:-1:-1;;;;;;;;22628:962:57:o;23808:1575::-;24000:9;-1:-1:-1;;;;;24075:2:57;24067:6;24064:14;24061:40;;;24081:18;;:::i;:::-;24127:6;24124:1;24120:14;24153:4;24177:28;24201:2;24197;24193:11;24177:28;:::i;:::-;24239:19;;;24309:14;;;;24274:12;;;;24346:14;24335:26;;24332:46;;;24374:1;24371;24364:12;24332:46;24398:5;24412:938;24428:6;24423:3;24420:15;24412:938;;;24514:3;24501:17;24550:2;24537:11;24534:19;24531:109;;;24594:1;24623:2;24619;24612:14;24531:109;24663:23;;24731:4;24710:14;24706:23;;;24702:34;24699:124;;;24777:1;24806:2;24802;24795:14;24699:124;24851:22;;:::i;:::-;24902:21;24920:2;24902:21;:::i;:::-;24893:7;24886:38;24962:30;24988:2;24984;24980:11;24962:30;:::i;:::-;24957:2;24948:7;24944:16;24937:56;25016:2;25066;25062;25058:11;25045:25;25097:2;25089:6;25086:14;25083:104;;;25141:1;25170:2;25166;25159:14;25083:104;25225:49;25259:14;25250:6;25246:2;25242:15;25225:49;:::i;:::-;25207:16;;;25200:75;;;;-1:-1:-1;25288:20:57;;-1:-1:-1;25328:12:57;;;;24445;;24412:938;;;-1:-1:-1;25372:5:57;23808:1575;-1:-1:-1;;;;;;;23808:1575:57:o;25388:331::-;25493:9;25504;25546:8;25534:10;25531:24;25528:44;;;25568:1;25565;25558:12;25528:44;25597:6;25587:8;25584:20;25581:40;;;25617:1;25614;25607:12;25581:40;-1:-1:-1;;25643:23:57;;;25688:25;;;;;-1:-1:-1;25388:331:57:o;25724:476::-;25915:3;25953:6;25947:13;25969:66;26028:6;26023:3;26016:4;26008:6;26004:17;25969:66;:::i;:::-;26057:16;;26110:6;26102;26057:16;26082:35;26174:1;26136:18;;26163:13;;;-1:-1:-1;26136:18:57;;25724:476;-1:-1:-1;;;25724:476:57:o;26205:266::-;26293:6;26288:3;26281:19;26345:6;26338:5;26331:4;26326:3;26322:14;26309:43;-1:-1:-1;26397:1:57;26372:16;;;26390:4;26368:27;;;26361:38;;;;26453:2;26432:15;;;-1:-1:-1;;26428:29:57;26419:39;;;26415:50;;26205:266::o;26476:244::-;26633:2;26622:9;26615:21;26596:4;26653:61;26710:2;26699:9;26695:18;26687:6;26679;26653:61;:::i;26725:127::-;26786:10;26781:3;26777:20;26774:1;26767:31;26817:4;26814:1;26807:15;26841:4;26838:1;26831:15;26857:331;26956:4;27014:11;27001:25;27108:3;27104:8;27093;27077:14;27073:29;27069:44;27049:18;27045:69;27035:97;;27128:1;27125;27118:12;27035:97;27149:33;;;;;26857:331;-1:-1:-1;;26857:331:57:o;27193:521::-;27270:4;27276:6;27336:11;27323:25;27430:2;27426:7;27415:8;27399:14;27395:29;27391:43;27371:18;27367:68;27357:96;;27449:1;27446;27439:12;27357:96;27476:33;;27528:20;;;-1:-1:-1;;;;;;27560:30:57;;27557:50;;;27603:1;27600;27593:12;27557:50;27636:4;27624:17;;-1:-1:-1;27667:14:57;27663:27;;;27653:38;;27650:58;;;27704:1;27701;27694:12;27719:129;-1:-1:-1;;;;;27797:5:57;27793:30;27786:5;27783:41;27773:69;;27838:1;27835;27828:12;27853:988;28227:10;28200:25;28218:6;28200:25;:::i;:::-;28196:42;28185:9;28178:61;28302:4;28294:6;28290:17;28277:31;28270:4;28259:9;28255:20;28248:61;28159:4;28356;28348:6;28344:17;28331:31;28371:30;28395:5;28371:30;:::i;:::-;-1:-1:-1;;;;;28443:5:57;28439:30;28432:4;28421:9;28417:20;28410:60;;28506:6;28501:2;28490:9;28486:18;28479:34;28550:3;28544;28533:9;28529:19;28522:32;28577:62;28634:3;28623:9;28619:19;28611:6;28603;28577:62;:::i;:::-;-1:-1:-1;;;;;28676:32:57;;28696:3;28655:19;;28648:61;28746:22;;;28740:3;28725:19;;28718:51;28786:49;28750:6;28820;28812;28786:49;:::i;:::-;28778:57;27853:988;-1:-1:-1;;;;;;;;;;27853:988:57:o;28846:647::-;28925:6;28978:2;28966:9;28957:7;28953:23;28949:32;28946:52;;;28994:1;28991;28984:12;28946:52;29027:9;29021:16;-1:-1:-1;;;;;29052:6:57;29049:30;29046:50;;;29092:1;29089;29082:12;29046:50;29115:22;;29168:4;29160:13;;29156:27;-1:-1:-1;29146:55:57;;29197:1;29194;29187:12;29146:55;29226:2;29220:9;29251:48;29267:31;29295:2;29267:31;:::i;29251:48::-;29322:2;29315:5;29308:17;29362:7;29357:2;29352;29348;29344:11;29340:20;29337:33;29334:53;;;29383:1;29380;29373:12;29334:53;29396:67;29460:2;29455;29448:5;29444:14;29439:2;29435;29431:11;29396:67;:::i;29914:723::-;29964:3;30005:5;29999:12;30034:36;30060:9;30034:36;:::i;:::-;30089:1;30106:17;;;30132:133;;;;30279:1;30274:357;;;;30099:532;;30132:133;-1:-1:-1;;30165:24:57;;30153:37;;30238:14;;30231:22;30219:35;;30210:45;;;-1:-1:-1;30132:133:57;;30274:357;30305:5;30302:1;30295:16;30334:4;30379;30376:1;30366:18;30406:1;30420:165;30434:6;30431:1;30428:13;30420:165;;;30512:14;;30499:11;;;30492:35;30555:16;;;;30449:10;;30420:165;;;30424:3;;;30614:6;30609:3;30605:16;30598:23;;30099:532;;;;;29914:723;;;;:::o;30642:621::-;30964:3;30992:38;31026:3;31018:6;30992:38;:::i;:::-;-1:-1:-1;;;31046:2:57;31039:24;31092:6;31086:13;31108:74;31175:6;31170:2;31166;31162:11;31155:4;31147:6;31143:17;31108:74;:::i;:::-;31198:59;31253:2;31244:6;31240:2;31236:15;31232:24;31224:6;31198:59;:::i;31627:1345::-;31753:3;31747:10;-1:-1:-1;;;;;31772:6:57;31769:30;31766:56;;;31802:18;;:::i;:::-;31831:97;31921:6;31881:38;31913:4;31907:11;31881:38;:::i;:::-;31875:4;31831:97;:::i;:::-;31983:4;;32040:2;32029:14;;32057:1;32052:663;;;;32759:1;32776:6;32773:89;;;-1:-1:-1;32828:19:57;;;32822:26;32773:89;-1:-1:-1;;21374:1:57;21370:11;;;21366:24;21362:29;21352:40;21398:1;21394:11;;;21349:57;32875:81;;32022:944;;32052:663;20645:1;20638:14;;;20682:4;20669:18;;-1:-1:-1;;32088:20:57;;;32206:236;32220:7;32217:1;32214:14;32206:236;;;32309:19;;;32303:26;32288:42;;32401:27;;;;32369:1;32357:14;;;;32236:19;;32206:236;;;32210:3;32470:6;32461:7;32458:19;32455:201;;;32531:19;;;32525:26;-1:-1:-1;;32614:1:57;32610:14;;;32626:3;32606:24;32602:37;32598:42;32583:58;32568:74;;32455:201;-1:-1:-1;;;;;32702:1:57;32686:14;;;32682:22;32669:36;;-1:-1:-1;31627:1345:57:o;33174:245::-;33232:6;33285:2;33273:9;33264:7;33260:23;33256:32;33253:52;;;33301:1;33298;33291:12;33253:52;33340:9;33327:23;33359:30;33383:5;33359:30;:::i;33424:479::-;33691:1;33687;33682:3;33678:11;33674:19;33666:6;33662:32;33651:9;33644:51;33731:6;33726:2;33715:9;33711:18;33704:34;33786:6;33778;33774:19;33769:2;33758:9;33754:18;33747:47;33830:3;33825:2;33814:9;33810:18;33803:31;33625:4;33851:46;33892:3;33881:9;33877:19;33869:6;33851:46;:::i;:::-;33843:54;33424:479;-1:-1:-1;;;;;;33424:479:57:o;34217:379::-;34410:2;34399:9;34392:21;34373:4;34436:45;34477:2;34466:9;34462:18;34454:6;34436:45;:::i;:::-;34529:9;34521:6;34517:22;34512:2;34501:9;34497:18;34490:50;34557:33;34583:6;34575;34557:33;:::i;34601:245::-;34668:6;34721:2;34709:9;34700:7;34696:23;34692:32;34689:52;;;34737:1;34734;34727:12;34689:52;34769:9;34763:16;34788:28;34810:5;34788:28;:::i;34851:887::-;35070:2;35059:9;35052:21;35128:10;35119:6;35113:13;35109:30;35104:2;35093:9;35089:18;35082:58;35194:4;35186:6;35182:17;35176:24;35171:2;35160:9;35156:18;35149:52;35033:4;35248:2;35240:6;35236:15;35230:22;35289:4;35283:3;35272:9;35268:19;35261:33;35317:52;35364:3;35353:9;35349:19;35335:12;35317:52;:::i;:::-;35303:66;;35418:2;35410:6;35406:15;35400:22;35492:2;35488:7;35476:9;35468:6;35464:22;35460:36;35453:4;35442:9;35438:20;35431:66;35520:41;35554:6;35538:14;35520:41;:::i;:::-;35630:3;35618:16;;;;35612:23;35605:31;35598:39;35592:3;35577:19;;35570:68;-1:-1:-1;;;;;;;;35699:32:57;;;;35692:4;35677:20;;;35670:62;35506:55;34851:887::o;35743:284::-;35813:5;35861:4;35849:9;35844:3;35840:19;35836:30;35833:50;;;35879:1;35876;35869:12;35833:50;35901:22;;:::i;:::-;35892:31;;35952:9;35946:16;35939:5;35932:31;36016:2;36005:9;36001:18;35995:25;35990:2;35983:5;35979:14;35972:49;35743:284;;;;:::o;36032:523::-;36134:6;36187:3;36175:9;36166:7;36162:23;36158:33;36155:53;;;36204:1;36201;36194:12;36155:53;36230:22;;:::i;:::-;36281:9;36275:16;36268:5;36261:31;36337:2;36326:9;36322:18;36316:25;36350:32;36374:7;36350:32;:::i;:::-;36409:2;36398:14;;36391:31;36454:70;36516:7;36511:2;36496:18;;36454:70;:::i;:::-;36449:2;36438:14;;36431:94;36442:5;36032:523;-1:-1:-1;;;36032:523:57:o;37195:489::-;-1:-1:-1;;;;;37464:15:57;;;37446:34;;37516:15;;37511:2;37496:18;;37489:43;37563:2;37548:18;;37541:34;;;37611:3;37606:2;37591:18;;37584:31;;;37389:4;;37632:46;;37658:19;;37650:6;37632:46;:::i;37689:249::-;37758:6;37811:2;37799:9;37790:7;37786:23;37782:32;37779:52;;;37827:1;37824;37817:12;37779:52;37859:9;37853:16;37878:30;37902:5;37878:30;:::i;39291:1164::-;39507:4;39536:2;39576;39565:9;39561:18;39606:2;39595:9;39588:21;39629:6;39664;39658:13;39695:6;39687;39680:22;39721:2;39711:12;;39754:2;39743:9;39739:18;39732:25;;39816:2;39806:6;39803:1;39799:14;39788:9;39784:30;39780:39;39854:2;39846:6;39842:15;39875:1;39885:541;39899:6;39896:1;39893:13;39885:541;;;39964:22;;;-1:-1:-1;;39960:36:57;39948:49;;40020:13;;40092:9;;40103:10;40088:26;40073:42;;40162:11;;;40156:18;40176:6;40152:31;40135:15;;;40128:56;40223:11;;40217:18;40056:4;40255:15;;;40248:27;;;40298:48;40330:15;;;40217:18;40298:48;:::i;:::-;40404:12;;;;40288:58;-1:-1:-1;;;40369:15:57;;;;39921:1;39914:9;39885:541;;;-1:-1:-1;40443:6:57;;39291:1164;-1:-1:-1;;;;;;;;39291:1164:57:o;40460:257::-;40558:6;40611:2;40599:9;40590:7;40586:23;40582:32;40579:52;;;40627:1;40624;40617:12;40579:52;40650:61;40703:7;40692:9;40650:61;:::i;40722:251::-;40792:6;40845:2;40833:9;40824:7;40820:23;40816:32;40813:52;;;40861:1;40858;40851:12;40813:52;40893:9;40887:16;40912:31;40937:5;40912:31;:::i;40978:255::-;41098:19;;41137:2;41129:11;;41126:101;;;-1:-1:-1;;41198:2:57;41194:12;;;41191:1;41187:20;41183:33;41172:45;40978:255;;;;:::o;41238:503::-;41475:3;41453:16;;;-1:-1:-1;;;;;;41449:51:57;41437:64;;41556:3;41534:16;;;-1:-1:-1;;;;;;41530:43:57;41526:1;41517:11;;41510:64;41597:13;;-1:-1:-1;;41619:75:57;41597:13;41682:2;41673:12;;41666:4;41654:17;;41619:75;:::i;:::-;41714:16;;;;41732:2;41710:25;;41238:503;-1:-1:-1;;;;41238:503:57:o;41998:489::-;42241:6;42236:3;42229:19;42278:6;42273:2;42268:3;42264:12;42257:28;42315:6;42310:2;42305:3;42301:12;42294:28;42211:3;42351:6;42345:13;42367:73;42433:6;42428:2;42423:3;42419:12;42414:2;42406:6;42402:15;42367:73;:::i;:::-;42460:16;;;;42478:2;42456:25;;41998:489;-1:-1:-1;;;;;41998:489:57:o
Swarm Source
ipfs://3cbe81278ca3f9bda40941d7948b2317eaa78591041173aee829ad03a315b4f9
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
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.