Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 51 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Approval For... | 20352513 | 190 days ago | IN | 0 ETH | 0.00010958 | ||||
Set Approval For... | 20326298 | 194 days ago | IN | 0 ETH | 0.0004171 | ||||
Set Approval For... | 20294268 | 198 days ago | IN | 0 ETH | 0.00015648 | ||||
Set Approval For... | 20261527 | 203 days ago | IN | 0 ETH | 0.00014623 | ||||
Set Approval For... | 20258283 | 203 days ago | IN | 0 ETH | 0.0002081 | ||||
Withdraw Funds | 19969568 | 244 days ago | IN | 0 ETH | 0.00081177 | ||||
Airdrop | 19941089 | 248 days ago | IN | 0 ETH | 0.00209382 | ||||
Airdrop | 19941076 | 248 days ago | IN | 0 ETH | 0.01248777 | ||||
Set Approval For... | 19885119 | 255 days ago | IN | 0 ETH | 0.00017607 | ||||
Safe Transfer Fr... | 19870123 | 257 days ago | IN | 0 ETH | 0.00078415 | ||||
Safe Transfer Fr... | 19870120 | 257 days ago | IN | 0 ETH | 0.00087052 | ||||
Airdrop | 19834123 | 263 days ago | IN | 0 ETH | 0.00085308 | ||||
Safe Transfer Fr... | 19805960 | 266 days ago | IN | 0 ETH | 0.00060606 | ||||
Renounce Role | 19778989 | 270 days ago | IN | 0 ETH | 0.00021687 | ||||
Renounce Role | 19778986 | 270 days ago | IN | 0 ETH | 0.00024605 | ||||
Renounce Role | 19778984 | 270 days ago | IN | 0 ETH | 0.00024614 | ||||
Grant Role | 19778978 | 270 days ago | IN | 0 ETH | 0.00042282 | ||||
Set Mint Admin R... | 19778854 | 270 days ago | IN | 0 ETH | 0.00033937 | ||||
Set Contract Adm... | 19778850 | 270 days ago | IN | 0 ETH | 0.0003642 | ||||
Accept Ownership | 19778509 | 270 days ago | IN | 0 ETH | 0.00013676 | ||||
Transfer Ownersh... | 19778103 | 270 days ago | IN | 0 ETH | 0.00027359 | ||||
Airdrop | 19769578 | 272 days ago | IN | 0 ETH | 0.18823053 | ||||
Airdrop | 19769442 | 272 days ago | IN | 0 ETH | 0.00378999 | ||||
Set Approval For... | 19767489 | 272 days ago | IN | 0 ETH | 0.00042197 | ||||
Set Approval For... | 19767422 | 272 days ago | IN | 0 ETH | 0.00073939 |
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers. Name tag integration is not available in advanced view.
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
||||
---|---|---|---|---|---|---|---|
20374049 | 187 days ago | 0 ETH | |||||
20374049 | 187 days ago | 0 ETH | |||||
20352513 | 190 days ago | 0 ETH | |||||
20350825 | 190 days ago | 0 ETH | |||||
20350825 | 190 days ago | 0 ETH | |||||
20326298 | 194 days ago | 0 ETH | |||||
20294310 | 198 days ago | 0 ETH | |||||
20294310 | 198 days ago | 0 ETH | |||||
20294304 | 198 days ago | 0 ETH | |||||
20294304 | 198 days ago | 0 ETH | |||||
20294292 | 198 days ago | 0 ETH | |||||
20294292 | 198 days ago | 0 ETH | |||||
20294280 | 198 days ago | 0 ETH | |||||
20294280 | 198 days ago | 0 ETH | |||||
20294268 | 198 days ago | 0 ETH | |||||
20261527 | 203 days ago | 0 ETH | |||||
20258284 | 203 days ago | 0 ETH | |||||
20258284 | 203 days ago | 0 ETH | |||||
20258283 | 203 days ago | 0 ETH | |||||
20101898 | 225 days ago | 0 ETH | |||||
20101898 | 225 days ago | 0 ETH | |||||
19994138 | 240 days ago | 0 ETH | |||||
19994138 | 240 days ago | 0 ETH | |||||
19994093 | 240 days ago | 0 ETH | |||||
19994093 | 240 days ago | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
SilksHorseDiamond
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
No with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.9; // Importing necessary libraries and contracts import { AccessControlInternal } from "@solidstate/contracts/access/access_control/AccessControlInternal.sol"; import { AccessControlStorage } from "@solidstate/contracts/access/access_control/AccessControlStorage.sol"; import { ERC2981 } from "@solidstate/contracts/token/common/ERC2981/ERC2981.sol"; import { ERC2981Storage } from "@solidstate/contracts/token/common/ERC2981/ERC2981Storage.sol"; import { ERC721MetadataStorage } from "@solidstate/contracts/token/ERC721/metadata/ERC721MetadataStorage.sol"; import { PausableInternal } from "@solidstate/contracts/security/pausable/PausableInternal.sol"; import { SolidStateDiamond } from "@solidstate/contracts/proxy/diamond/SolidStateDiamond.sol"; // Import custom library import "./libraries/LibSilksHorseDiamond.sol"; /** * @title SilksHorseDiamond * @dev A Solidity smart contract representing a Diamond upgradeable NFT (ERC721) with additional features. */ contract SilksHorseDiamond is AccessControlInternal, ERC2981, PausableInternal, SolidStateDiamond { using AccessControlStorage for AccessControlStorage.Layout; /** * @dev Constructor for initializing the SilksHorseDiamond contract. * @param _contractOwner The address of the contract owner. * @param _tokenName The name of the NFT token. * @param _tokenSymbol The symbol of the NFT token. * @param _tokenBaseURI The base URI for metadata of NFTs. * @param _royaltyReceiver The address that receives royalties from NFT sales. * @param _royaltyBasePoints The base points (0-10000) for calculating royalties. * @param _seasonInfos Array of season info objects to use for initialization * @param _payoutTiers Array of pay out tier objects to use for initialization */ constructor( address _contractOwner, string memory _tokenName, string memory _tokenSymbol, string memory _tokenBaseURI, uint256 _startTokenId, address _royaltyReceiver, uint16 _royaltyBasePoints, uint256 _maxHorsesPerWallet, SeasonInfo[] memory _seasonInfos, PayoutTier[] memory _payoutTiers ) SolidStateDiamond() { // Setting metadata for the NFT ERC721MetadataStorage.layout().name = _tokenName; ERC721MetadataStorage.layout().symbol = _tokenSymbol; ERC721MetadataStorage.layout().baseURI = _tokenBaseURI; // Setting default royalty information ERC2981Storage.layout().defaultRoyaltyReceiver = _royaltyReceiver; ERC2981Storage.layout().defaultRoyaltyBPS = _royaltyBasePoints; // Setting the contract owner and pausing the contract initially _setOwner(_contractOwner); _pause(); // Granting roles to the contract owner _grantRole(AccessControlStorage.DEFAULT_ADMIN_ROLE, _contractOwner); // Defining and granting admin roles for the contract _setRoleAdmin(CONTRACT_ADMIN_ROLE, AccessControlStorage.DEFAULT_ADMIN_ROLE); _grantRole(CONTRACT_ADMIN_ROLE, _contractOwner); // Defining and granting admin roles for minting NFTs _setRoleAdmin(MINT_ADMIN_ROLE, AccessControlStorage.DEFAULT_ADMIN_ROLE); _grantRole(MINT_ADMIN_ROLE, _contractOwner); LibSilksHorseDiamond.Layout storage lsh = LibSilksHorseDiamond.layout(); lsh.nextAvailableTokenId = _startTokenId; lsh.maxHorsesPerWallet = _maxHorsesPerWallet; for (uint256 i = 0; i < _seasonInfos.length; i++){ lsh.seasonInfos[_seasonInfos[i].seasonId] = _seasonInfos[i]; } for (uint256 i = 0; i < _payoutTiers.length; i++){ lsh.payoutTiers[_payoutTiers[i].tierId] = _payoutTiers[i]; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { EnumerableSet } from '../../data/EnumerableSet.sol'; import { AddressUtils } from '../../utils/AddressUtils.sol'; import { UintUtils } from '../../utils/UintUtils.sol'; import { IAccessControlInternal } from './IAccessControlInternal.sol'; import { AccessControlStorage } from './AccessControlStorage.sol'; /** * @title Role-based access control system * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license) */ abstract contract AccessControlInternal is IAccessControlInternal { using AddressUtils for address; using EnumerableSet for EnumerableSet.AddressSet; using UintUtils for uint256; modifier onlyRole(bytes32 role) { _checkRole(role); _; } /* * @notice query whether role is assigned to account * @param role role to query * @param account account to query * @return whether role is assigned to account */ function _hasRole( bytes32 role, address account ) internal view virtual returns (bool) { return AccessControlStorage.layout().roles[role].members.contains(account); } /** * @notice revert if sender does not have given role * @param role role to query */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, msg.sender); } /** * @notice revert if given account does not have given role * @param role role to query * @param account to query */ function _checkRole(bytes32 role, address account) internal view virtual { if (!_hasRole(role, account)) { revert( string( abi.encodePacked( 'AccessControl: account ', account.toString(), ' is missing role ', uint256(role).toHexString(32) ) ) ); } } /* * @notice query admin role for given role * @param role role to query * @return admin role */ function _getRoleAdmin( bytes32 role ) internal view virtual returns (bytes32) { return AccessControlStorage.layout().roles[role].adminRole; } /** * @notice set role as admin role * @param role role to set * @param adminRole admin role to set */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = _getRoleAdmin(role); AccessControlStorage.layout().roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /* * @notice assign role to given account * @param role role to assign * @param account recipient of role assignment */ function _grantRole(bytes32 role, address account) internal virtual { AccessControlStorage.layout().roles[role].members.add(account); emit RoleGranted(role, account, msg.sender); } /* * @notice unassign role from given account * @param role role to unassign * @parm account */ function _revokeRole(bytes32 role, address account) internal virtual { AccessControlStorage.layout().roles[role].members.remove(account); emit RoleRevoked(role, account, msg.sender); } /** * @notice relinquish role * @param role role to relinquish */ function _renounceRole(bytes32 role) internal virtual { _revokeRole(role, msg.sender); } /** * @notice query role for member at given index * @param role role to query * @param index index to query */ function _getRoleMember( bytes32 role, uint256 index ) internal view virtual returns (address) { return AccessControlStorage.layout().roles[role].members.at(index); } /** * @notice query role for member count * @param role role to query */ function _getRoleMemberCount( bytes32 role ) internal view virtual returns (uint256) { return AccessControlStorage.layout().roles[role].members.length(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { EnumerableSet } from '../../data/EnumerableSet.sol'; library AccessControlStorage { struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; } struct Layout { mapping(bytes32 => RoleData) roles; } bytes32 internal constant DEFAULT_ADMIN_ROLE = 0x00; bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.AccessControl'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Partial AccessControl interface needed by internal functions */ interface IAccessControlInternal { event RoleAdminChanged( bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole ); event RoleGranted( bytes32 indexed role, address indexed account, address indexed sender ); event RoleRevoked( bytes32 indexed role, address indexed account, address indexed sender ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173 } from '../../interfaces/IERC173.sol'; import { IOwnableInternal } from './IOwnableInternal.sol'; interface IOwnable is IOwnableInternal, IERC173 {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173Internal } from '../../interfaces/IERC173Internal.sol'; interface IOwnableInternal is IERC173Internal { error Ownable__NotOwner(); error Ownable__NotTransitiveOwner(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IOwnable } from './IOwnable.sol'; import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol'; interface ISafeOwnable is ISafeOwnableInternal, IOwnable { /** * @notice get the nominated owner who has permission to call acceptOwnership */ function nomineeOwner() external view returns (address); /** * @notice accept transfer of contract ownership */ function acceptOwnership() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IOwnableInternal } from './IOwnableInternal.sol'; interface ISafeOwnableInternal is IOwnableInternal { error SafeOwnable__NotNomineeOwner(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173 } from '../../interfaces/IERC173.sol'; import { IOwnable } from './IOwnable.sol'; import { OwnableInternal } from './OwnableInternal.sol'; /** * @title Ownership access control based on ERC173 */ abstract contract Ownable is IOwnable, OwnableInternal { /** * @inheritdoc IERC173 */ function owner() public view virtual returns (address) { return _owner(); } /** * @inheritdoc IERC173 */ function transferOwnership(address account) public virtual onlyOwner { _transferOwnership(account); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173 } from '../../interfaces/IERC173.sol'; import { AddressUtils } from '../../utils/AddressUtils.sol'; import { IOwnableInternal } from './IOwnableInternal.sol'; import { OwnableStorage } from './OwnableStorage.sol'; abstract contract OwnableInternal is IOwnableInternal { using AddressUtils for address; modifier onlyOwner() { if (msg.sender != _owner()) revert Ownable__NotOwner(); _; } modifier onlyTransitiveOwner() { if (msg.sender != _transitiveOwner()) revert Ownable__NotTransitiveOwner(); _; } function _owner() internal view virtual returns (address) { return OwnableStorage.layout().owner; } function _transitiveOwner() internal view virtual returns (address owner) { owner = _owner(); while (owner.isContract()) { try IERC173(owner).owner() returns (address transitiveOwner) { owner = transitiveOwner; } catch { break; } } } function _transferOwnership(address account) internal virtual { _setOwner(account); } function _setOwner(address account) internal virtual { OwnableStorage.Layout storage l = OwnableStorage.layout(); emit OwnershipTransferred(l.owner, account); l.owner = account; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; library OwnableStorage { struct Layout { address owner; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.Ownable'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { Ownable } from './Ownable.sol'; import { ISafeOwnable } from './ISafeOwnable.sol'; import { OwnableInternal } from './OwnableInternal.sol'; import { SafeOwnableInternal } from './SafeOwnableInternal.sol'; /** * @title Ownership access control based on ERC173 with ownership transfer safety check */ abstract contract SafeOwnable is ISafeOwnable, Ownable, SafeOwnableInternal { /** * @inheritdoc ISafeOwnable */ function nomineeOwner() public view virtual returns (address) { return _nomineeOwner(); } /** * @inheritdoc ISafeOwnable */ function acceptOwnership() public virtual onlyNomineeOwner { _acceptOwnership(); } function _transferOwnership( address account ) internal virtual override(OwnableInternal, SafeOwnableInternal) { super._transferOwnership(account); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol'; import { OwnableInternal } from './OwnableInternal.sol'; import { SafeOwnableStorage } from './SafeOwnableStorage.sol'; abstract contract SafeOwnableInternal is ISafeOwnableInternal, OwnableInternal { modifier onlyNomineeOwner() { if (msg.sender != _nomineeOwner()) revert SafeOwnable__NotNomineeOwner(); _; } /** * @notice get the nominated owner who has permission to call acceptOwnership */ function _nomineeOwner() internal view virtual returns (address) { return SafeOwnableStorage.layout().nomineeOwner; } /** * @notice accept transfer of contract ownership */ function _acceptOwnership() internal virtual { _setOwner(msg.sender); delete SafeOwnableStorage.layout().nomineeOwner; } /** * @notice grant permission to given address to claim contract ownership */ function _transferOwnership(address account) internal virtual override { _setNomineeOwner(account); } /** * @notice set nominee owner */ function _setNomineeOwner(address account) internal virtual { SafeOwnableStorage.layout().nomineeOwner = account; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; library SafeOwnableStorage { struct Layout { address nomineeOwner; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.SafeOwnable'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title Set implementation with enumeration functions * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license) */ library EnumerableSet { error EnumerableSet__IndexOutOfBounds(); struct Set { bytes32[] _values; // 1-indexed to allow 0 to signify nonexistence mapping(bytes32 => uint256) _indexes; } struct Bytes32Set { Set _inner; } struct AddressSet { Set _inner; } struct UintSet { Set _inner; } function at( Bytes32Set storage set, uint256 index ) internal view returns (bytes32) { return _at(set._inner, index); } function at( AddressSet storage set, uint256 index ) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } function at( UintSet storage set, uint256 index ) internal view returns (uint256) { return uint256(_at(set._inner, index)); } function contains( Bytes32Set storage set, bytes32 value ) internal view returns (bool) { return _contains(set._inner, value); } function contains( AddressSet storage set, address value ) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } function contains( UintSet storage set, uint256 value ) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } function indexOf( Bytes32Set storage set, bytes32 value ) internal view returns (uint256) { return _indexOf(set._inner, value); } function indexOf( AddressSet storage set, address value ) internal view returns (uint256) { return _indexOf(set._inner, bytes32(uint256(uint160(value)))); } function indexOf( UintSet storage set, uint256 value ) internal view returns (uint256) { return _indexOf(set._inner, bytes32(value)); } function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } function add( Bytes32Set storage set, bytes32 value ) internal returns (bool) { return _add(set._inner, value); } function add( AddressSet storage set, address value ) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } function remove( Bytes32Set storage set, bytes32 value ) internal returns (bool) { return _remove(set._inner, value); } function remove( AddressSet storage set, address value ) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } function remove( UintSet storage set, uint256 value ) internal returns (bool) { return _remove(set._inner, bytes32(value)); } function toArray( Bytes32Set storage set ) internal view returns (bytes32[] memory) { return set._inner._values; } function toArray( AddressSet storage set ) internal view returns (address[] memory) { bytes32[] storage values = set._inner._values; address[] storage array; assembly { array.slot := values.slot } return array; } function toArray( UintSet storage set ) internal view returns (uint256[] memory) { bytes32[] storage values = set._inner._values; uint256[] storage array; assembly { array.slot := values.slot } return array; } function _at( Set storage set, uint256 index ) private view returns (bytes32) { if (index >= set._values.length) revert EnumerableSet__IndexOutOfBounds(); return set._values[index]; } function _contains( Set storage set, bytes32 value ) private view returns (bool) { return set._indexes[value] != 0; } function _indexOf( Set storage set, bytes32 value ) private view returns (uint256) { unchecked { return set._indexes[value] - 1; } } function _length(Set storage set) private view returns (uint256) { return set._values.length; } function _add( Set storage set, bytes32 value ) private returns (bool status) { if (!_contains(set, value)) { set._values.push(value); set._indexes[value] = set._values.length; status = true; } } function _remove( Set storage set, bytes32 value ) private returns (bool status) { uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { unchecked { bytes32 last = set._values[set._values.length - 1]; // move last value to now-vacant index set._values[valueIndex - 1] = last; set._indexes[last] = valueIndex; } // clear last index set._values.pop(); delete set._indexes[value]; status = true; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC165Internal } from './IERC165Internal.sol'; /** * @title ERC165 interface registration interface * @dev see https://eips.ethereum.org/EIPS/eip-165 */ interface IERC165 is IERC165Internal { /** * @notice query whether contract has registered support for given interface * @param interfaceId interface id * @return bool whether interface is supported */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title ERC165 interface registration interface */ interface IERC165Internal { }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC173Internal } from './IERC173Internal.sol'; /** * @title Contract ownership standard interface * @dev see https://eips.ethereum.org/EIPS/eip-173 */ interface IERC173 is IERC173Internal { /** * @notice get the ERC173 contract owner * @return contract owner */ function owner() external view returns (address); /** * @notice transfer contract ownership to new account * @param account address of new owner */ function transferOwnership(address account) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title Partial ERC173 interface needed by internal functions */ interface IERC173Internal { event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC165 } from './IERC165.sol'; import { IERC2981Internal } from './IERC2981Internal.sol'; /** * @title ERC2981 interface * @dev see https://eips.ethereum.org/EIPS/eip-2981 */ interface IERC2981 is IERC2981Internal, IERC165 { /** * @notice called with the sale price to determine how much royalty is owed and to whom * @param tokenId the ERC721 or ERC1155 token id to query for royalty information * @param salePrice the sale price of the given asset * @return receiever rightful recipient of royalty * @return royaltyAmount amount of royalty owed */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiever, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title ERC2981 interface */ interface IERC2981Internal { }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC165 } from '../../../interfaces/IERC165.sol'; import { IERC165Base } from './IERC165Base.sol'; import { ERC165BaseInternal } from './ERC165BaseInternal.sol'; import { ERC165BaseStorage } from './ERC165BaseStorage.sol'; /** * @title ERC165 implementation */ abstract contract ERC165Base is IERC165Base, ERC165BaseInternal { /** * @inheritdoc IERC165 */ function supportsInterface(bytes4 interfaceId) public view returns (bool) { return _supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC165BaseInternal } from './IERC165BaseInternal.sol'; import { ERC165BaseStorage } from './ERC165BaseStorage.sol'; /** * @title ERC165 implementation */ abstract contract ERC165BaseInternal is IERC165BaseInternal { /** * @notice indicates whether an interface is already supported based on the interfaceId * @param interfaceId id of interface to check * @return bool indicating whether interface is supported */ function _supportsInterface( bytes4 interfaceId ) internal view virtual returns (bool) { return ERC165BaseStorage.layout().supportedInterfaces[interfaceId]; } /** * @notice sets status of interface support * @param interfaceId id of interface to set status for * @param status boolean indicating whether interface will be set as supported */ function _setSupportsInterface( bytes4 interfaceId, bool status ) internal virtual { if (interfaceId == 0xffffffff) revert ERC165Base__InvalidInterfaceId(); ERC165BaseStorage.layout().supportedInterfaces[interfaceId] = status; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; library ERC165BaseStorage { struct Layout { mapping(bytes4 => bool) supportedInterfaces; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.ERC165Base'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC165 } from '../../../interfaces/IERC165.sol'; import { IERC165BaseInternal } from './IERC165BaseInternal.sol'; interface IERC165Base is IERC165, IERC165BaseInternal {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC165Internal } from '../../../interfaces/IERC165Internal.sol'; interface IERC165BaseInternal is IERC165Internal { error ERC165Base__InvalidInterfaceId(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { Proxy } from '../../Proxy.sol'; import { IDiamondBase } from './IDiamondBase.sol'; import { DiamondBaseStorage } from './DiamondBaseStorage.sol'; /** * @title EIP-2535 "Diamond" proxy base contract * @dev see https://eips.ethereum.org/EIPS/eip-2535 */ abstract contract DiamondBase is IDiamondBase, Proxy { /** * @inheritdoc Proxy */ function _getImplementation() internal view virtual override returns (address implementation) { // inline storage layout retrieval uses less gas DiamondBaseStorage.Layout storage l; bytes32 slot = DiamondBaseStorage.STORAGE_SLOT; assembly { l.slot := slot } implementation = address(bytes20(l.facets[msg.sig])); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @dev derived from https://github.com/mudgen/diamond-2 (MIT license) */ library DiamondBaseStorage { struct Layout { // function selector => (facet address, selector slot position) mapping(bytes4 => bytes32) facets; // total number of selectors registered uint16 selectorCount; // array of selector slots with 8 selectors per slot mapping(uint256 => bytes32) selectorSlots; address fallbackAddress; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.DiamondBase'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IProxy } from '../../IProxy.sol'; interface IDiamondBase is IProxy {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol'; import { DiamondBase } from '../base/DiamondBase.sol'; import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol'; import { IDiamondFallback } from './IDiamondFallback.sol'; /** * @title Fallback feature for EIP-2535 "Diamond" proxy */ abstract contract DiamondFallback is IDiamondFallback, OwnableInternal, DiamondBase { /** * @inheritdoc IDiamondFallback */ function getFallbackAddress() external view returns (address fallbackAddress) { fallbackAddress = _getFallbackAddress(); } /** * @inheritdoc IDiamondFallback */ function setFallbackAddress(address fallbackAddress) external onlyOwner { _setFallbackAddress(fallbackAddress); } /** * @inheritdoc DiamondBase * @notice query custom fallback address is no implementation is found */ function _getImplementation() internal view virtual override returns (address implementation) { implementation = super._getImplementation(); if (implementation == address(0)) { implementation = _getFallbackAddress(); } } /** * @notice query the address of the fallback implementation * @return fallbackAddress address of fallback implementation */ function _getFallbackAddress() internal view virtual returns (address fallbackAddress) { fallbackAddress = DiamondBaseStorage.layout().fallbackAddress; } /** * @notice set the address of the fallback implementation * @param fallbackAddress address of fallback implementation */ function _setFallbackAddress(address fallbackAddress) internal virtual { DiamondBaseStorage.layout().fallbackAddress = fallbackAddress; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IDiamondBase } from '../base/IDiamondBase.sol'; interface IDiamondFallback is IDiamondBase { /** * @notice query the address of the fallback implementation * @return fallbackAddress address of fallback implementation */ function getFallbackAddress() external view returns (address fallbackAddress); /** * @notice set the address of the fallback implementation * @param fallbackAddress address of fallback implementation */ function setFallbackAddress(address fallbackAddress) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { ISafeOwnable } from '../../access/ownable/ISafeOwnable.sol'; import { IERC165 } from '../../interfaces/IERC165.sol'; import { IDiamondBase } from './base/IDiamondBase.sol'; import { IDiamondFallback } from './fallback/IDiamondFallback.sol'; import { IDiamondReadable } from './readable/IDiamondReadable.sol'; import { IDiamondWritable } from './writable/IDiamondWritable.sol'; interface ISolidStateDiamond is IDiamondBase, IDiamondFallback, IDiamondReadable, IDiamondWritable, ISafeOwnable, IERC165 { receive() external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol'; import { IDiamondReadable } from './IDiamondReadable.sol'; /** * @title EIP-2535 "Diamond" proxy introspection contract * @dev derived from https://github.com/mudgen/diamond-2 (MIT license) */ abstract contract DiamondReadable is IDiamondReadable { /** * @inheritdoc IDiamondReadable */ function facets() external view returns (Facet[] memory diamondFacets) { DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout(); diamondFacets = new Facet[](l.selectorCount); uint8[] memory numFacetSelectors = new uint8[](l.selectorCount); uint256 numFacets; uint256 selectorIndex; // loop through function selectors for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) { bytes32 slot = l.selectorSlots[slotIndex]; for ( uint256 selectorSlotIndex; selectorSlotIndex < 8; selectorSlotIndex++ ) { selectorIndex++; if (selectorIndex > l.selectorCount) { break; } bytes4 selector = bytes4(slot << (selectorSlotIndex << 5)); address facet = address(bytes20(l.facets[selector])); bool continueLoop; for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { if (diamondFacets[facetIndex].target == facet) { diamondFacets[facetIndex].selectors[ numFacetSelectors[facetIndex] ] = selector; // probably will never have more than 256 functions from one facet contract require(numFacetSelectors[facetIndex] < 255); numFacetSelectors[facetIndex]++; continueLoop = true; break; } } if (continueLoop) { continue; } diamondFacets[numFacets].target = facet; diamondFacets[numFacets].selectors = new bytes4[]( l.selectorCount ); diamondFacets[numFacets].selectors[0] = selector; numFacetSelectors[numFacets] = 1; numFacets++; } } for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { uint256 numSelectors = numFacetSelectors[facetIndex]; bytes4[] memory selectors = diamondFacets[facetIndex].selectors; // setting the number of selectors assembly { mstore(selectors, numSelectors) } } // setting the number of facets assembly { mstore(diamondFacets, numFacets) } } /** * @inheritdoc IDiamondReadable */ function facetFunctionSelectors( address facet ) external view returns (bytes4[] memory selectors) { DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout(); selectors = new bytes4[](l.selectorCount); uint256 numSelectors; uint256 selectorIndex; // loop through function selectors for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) { bytes32 slot = l.selectorSlots[slotIndex]; for ( uint256 selectorSlotIndex; selectorSlotIndex < 8; selectorSlotIndex++ ) { selectorIndex++; if (selectorIndex > l.selectorCount) { break; } bytes4 selector = bytes4(slot << (selectorSlotIndex << 5)); if (facet == address(bytes20(l.facets[selector]))) { selectors[numSelectors] = selector; numSelectors++; } } } // set the number of selectors in the array assembly { mstore(selectors, numSelectors) } } /** * @inheritdoc IDiamondReadable */ function facetAddresses() external view returns (address[] memory addresses) { DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout(); addresses = new address[](l.selectorCount); uint256 numFacets; uint256 selectorIndex; for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) { bytes32 slot = l.selectorSlots[slotIndex]; for ( uint256 selectorSlotIndex; selectorSlotIndex < 8; selectorSlotIndex++ ) { selectorIndex++; if (selectorIndex > l.selectorCount) { break; } bytes4 selector = bytes4(slot << (selectorSlotIndex << 5)); address facet = address(bytes20(l.facets[selector])); bool continueLoop; for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) { if (facet == addresses[facetIndex]) { continueLoop = true; break; } } if (continueLoop) { continue; } addresses[numFacets] = facet; numFacets++; } } // set the number of facet addresses in the array assembly { mstore(addresses, numFacets) } } /** * @inheritdoc IDiamondReadable */ function facetAddress( bytes4 selector ) external view returns (address facet) { facet = address(bytes20(DiamondBaseStorage.layout().facets[selector])); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title Diamond proxy introspection interface * @dev see https://eips.ethereum.org/EIPS/eip-2535 */ interface IDiamondReadable { struct Facet { address target; bytes4[] selectors; } /** * @notice get all facets and their selectors * @return diamondFacets array of structured facet data */ function facets() external view returns (Facet[] memory diamondFacets); /** * @notice get all selectors for given facet address * @param facet address of facet to query * @return selectors array of function selectors */ function facetFunctionSelectors( address facet ) external view returns (bytes4[] memory selectors); /** * @notice get addresses of all facets used by diamond * @return addresses array of facet addresses */ function facetAddresses() external view returns (address[] memory addresses); /** * @notice get the address of the facet associated with given selector * @param selector function selector to query * @return facet facet address (zero address if not found) */ function facetAddress( bytes4 selector ) external view returns (address facet); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IOwnable, Ownable, OwnableInternal } from '../../access/ownable/Ownable.sol'; import { ISafeOwnable, SafeOwnable } from '../../access/ownable/SafeOwnable.sol'; import { IERC165 } from '../../interfaces/IERC165.sol'; import { IERC173 } from '../../interfaces/IERC173.sol'; import { ERC165Base, ERC165BaseStorage } from '../../introspection/ERC165/base/ERC165Base.sol'; import { DiamondBase } from './base/DiamondBase.sol'; import { DiamondFallback, IDiamondFallback } from './fallback/DiamondFallback.sol'; import { DiamondReadable, IDiamondReadable } from './readable/DiamondReadable.sol'; import { DiamondWritable, IDiamondWritable } from './writable/DiamondWritable.sol'; import { ISolidStateDiamond } from './ISolidStateDiamond.sol'; /** * @title SolidState "Diamond" proxy reference implementation */ abstract contract SolidStateDiamond is ISolidStateDiamond, DiamondBase, DiamondFallback, DiamondReadable, DiamondWritable, SafeOwnable, ERC165Base { constructor() { bytes4[] memory selectors = new bytes4[](12); uint256 selectorIndex; // register DiamondFallback selectors[selectorIndex++] = IDiamondFallback .getFallbackAddress .selector; selectors[selectorIndex++] = IDiamondFallback .setFallbackAddress .selector; _setSupportsInterface(type(IDiamondFallback).interfaceId, true); // register DiamondWritable selectors[selectorIndex++] = IDiamondWritable.diamondCut.selector; _setSupportsInterface(type(IDiamondWritable).interfaceId, true); // register DiamondReadable selectors[selectorIndex++] = IDiamondReadable.facets.selector; selectors[selectorIndex++] = IDiamondReadable .facetFunctionSelectors .selector; selectors[selectorIndex++] = IDiamondReadable.facetAddresses.selector; selectors[selectorIndex++] = IDiamondReadable.facetAddress.selector; _setSupportsInterface(type(IDiamondReadable).interfaceId, true); // register ERC165 selectors[selectorIndex++] = IERC165.supportsInterface.selector; _setSupportsInterface(type(IERC165).interfaceId, true); // register SafeOwnable selectors[selectorIndex++] = Ownable.owner.selector; selectors[selectorIndex++] = SafeOwnable.nomineeOwner.selector; selectors[selectorIndex++] = Ownable.transferOwnership.selector; selectors[selectorIndex++] = SafeOwnable.acceptOwnership.selector; _setSupportsInterface(type(IERC173).interfaceId, true); // diamond cut FacetCut[] memory facetCuts = new FacetCut[](1); facetCuts[0] = FacetCut({ target: address(this), action: FacetCutAction.ADD, selectors: selectors }); _diamondCut(facetCuts, address(0), ''); // set owner _setOwner(msg.sender); } receive() external payable {} function _transferOwnership( address account ) internal virtual override(OwnableInternal, SafeOwnable) { super._transferOwnership(account); } /** * @inheritdoc DiamondFallback */ function _getImplementation() internal view override(DiamondBase, DiamondFallback) returns (address implementation) { implementation = super._getImplementation(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol'; import { IDiamondWritable } from './IDiamondWritable.sol'; import { DiamondWritableInternal } from './DiamondWritableInternal.sol'; /** * @title EIP-2535 "Diamond" proxy update contract */ abstract contract DiamondWritable is IDiamondWritable, DiamondWritableInternal, OwnableInternal { /** * @inheritdoc IDiamondWritable */ function diamondCut( FacetCut[] calldata facetCuts, address target, bytes calldata data ) external onlyOwner { _diamondCut(facetCuts, target, data); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { AddressUtils } from '../../../utils/AddressUtils.sol'; import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol'; import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol'; abstract contract DiamondWritableInternal is IDiamondWritableInternal { using AddressUtils for address; bytes32 private constant CLEAR_ADDRESS_MASK = bytes32(uint256(0xffffffffffffffffffffffff)); bytes32 private constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224)); /** * @notice update functions callable on Diamond proxy * @param facetCuts array of structured Diamond facet update data * @param target optional recipient of initialization delegatecall * @param data optional initialization call data */ function _diamondCut( FacetCut[] memory facetCuts, address target, bytes memory data ) internal virtual { DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout(); unchecked { uint256 originalSelectorCount = l.selectorCount; uint256 selectorCount = originalSelectorCount; bytes32 selectorSlot; // Check if last selector slot is not full if (selectorCount & 7 > 0) { // get last selectorSlot selectorSlot = l.selectorSlots[selectorCount >> 3]; } for (uint256 i; i < facetCuts.length; i++) { FacetCut memory facetCut = facetCuts[i]; FacetCutAction action = facetCut.action; if (facetCut.selectors.length == 0) revert DiamondWritable__SelectorNotSpecified(); if (action == FacetCutAction.ADD) { (selectorCount, selectorSlot) = _addFacetSelectors( l, selectorCount, selectorSlot, facetCut ); } else if (action == FacetCutAction.REPLACE) { _replaceFacetSelectors(l, facetCut); } else if (action == FacetCutAction.REMOVE) { (selectorCount, selectorSlot) = _removeFacetSelectors( l, selectorCount, selectorSlot, facetCut ); } } if (selectorCount != originalSelectorCount) { l.selectorCount = uint16(selectorCount); } // If last selector slot is not full if (selectorCount & 7 > 0) { l.selectorSlots[selectorCount >> 3] = selectorSlot; } emit DiamondCut(facetCuts, target, data); _initialize(target, data); } } function _addFacetSelectors( DiamondBaseStorage.Layout storage l, uint256 selectorCount, bytes32 selectorSlot, FacetCut memory facetCut ) internal returns (uint256, bytes32) { unchecked { if ( facetCut.target != address(this) && !facetCut.target.isContract() ) revert DiamondWritable__TargetHasNoCode(); for (uint256 i; i < facetCut.selectors.length; i++) { bytes4 selector = facetCut.selectors[i]; bytes32 oldFacet = l.facets[selector]; if (address(bytes20(oldFacet)) != address(0)) revert DiamondWritable__SelectorAlreadyAdded(); // add facet for selector l.facets[selector] = bytes20(facetCut.target) | bytes32(selectorCount); uint256 selectorInSlotPosition = (selectorCount & 7) << 5; // clear selector position in slot and add selector selectorSlot = (selectorSlot & ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) | (bytes32(selector) >> selectorInSlotPosition); // if slot is full then write it to storage if (selectorInSlotPosition == 224) { l.selectorSlots[selectorCount >> 3] = selectorSlot; selectorSlot = 0; } selectorCount++; } return (selectorCount, selectorSlot); } } function _removeFacetSelectors( DiamondBaseStorage.Layout storage l, uint256 selectorCount, bytes32 selectorSlot, FacetCut memory facetCut ) internal returns (uint256, bytes32) { unchecked { if (facetCut.target != address(0)) revert DiamondWritable__RemoveTargetNotZeroAddress(); uint256 selectorSlotCount = selectorCount >> 3; uint256 selectorInSlotIndex = selectorCount & 7; for (uint256 i; i < facetCut.selectors.length; i++) { bytes4 selector = facetCut.selectors[i]; bytes32 oldFacet = l.facets[selector]; if (address(bytes20(oldFacet)) == address(0)) revert DiamondWritable__SelectorNotFound(); if (address(bytes20(oldFacet)) == address(this)) revert DiamondWritable__SelectorIsImmutable(); if (selectorSlot == 0) { selectorSlotCount--; selectorSlot = l.selectorSlots[selectorSlotCount]; selectorInSlotIndex = 7; } else { selectorInSlotIndex--; } bytes4 lastSelector; uint256 oldSelectorsSlotCount; uint256 oldSelectorInSlotPosition; // adding a block here prevents stack too deep error { // replace selector with last selector in l.facets lastSelector = bytes4( selectorSlot << (selectorInSlotIndex << 5) ); if (lastSelector != selector) { // update last selector slot position info l.facets[lastSelector] = (oldFacet & CLEAR_ADDRESS_MASK) | bytes20(l.facets[lastSelector]); } delete l.facets[selector]; uint256 oldSelectorCount = uint16(uint256(oldFacet)); oldSelectorsSlotCount = oldSelectorCount >> 3; oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5; } if (oldSelectorsSlotCount != selectorSlotCount) { bytes32 oldSelectorSlot = l.selectorSlots[ oldSelectorsSlotCount ]; // clears the selector we are deleting and puts the last selector in its place. oldSelectorSlot = (oldSelectorSlot & ~(CLEAR_SELECTOR_MASK >> oldSelectorInSlotPosition)) | (bytes32(lastSelector) >> oldSelectorInSlotPosition); // update storage with the modified slot l.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot; } else { // clears the selector we are deleting and puts the last selector in its place. selectorSlot = (selectorSlot & ~(CLEAR_SELECTOR_MASK >> oldSelectorInSlotPosition)) | (bytes32(lastSelector) >> oldSelectorInSlotPosition); } if (selectorInSlotIndex == 0) { delete l.selectorSlots[selectorSlotCount]; selectorSlot = 0; } } selectorCount = (selectorSlotCount << 3) | selectorInSlotIndex; return (selectorCount, selectorSlot); } } function _replaceFacetSelectors( DiamondBaseStorage.Layout storage l, FacetCut memory facetCut ) internal { unchecked { if (!facetCut.target.isContract()) revert DiamondWritable__TargetHasNoCode(); for (uint256 i; i < facetCut.selectors.length; i++) { bytes4 selector = facetCut.selectors[i]; bytes32 oldFacet = l.facets[selector]; address oldFacetAddress = address(bytes20(oldFacet)); if (oldFacetAddress == address(0)) revert DiamondWritable__SelectorNotFound(); if (oldFacetAddress == address(this)) revert DiamondWritable__SelectorIsImmutable(); if (oldFacetAddress == facetCut.target) revert DiamondWritable__ReplaceTargetIsIdentical(); // replace old facet address l.facets[selector] = (oldFacet & CLEAR_ADDRESS_MASK) | bytes20(facetCut.target); } } } function _initialize(address target, bytes memory data) private { if ((target == address(0)) != (data.length == 0)) revert DiamondWritable__InvalidInitializationParameters(); if (target != address(0)) { if (target != address(this)) { if (!target.isContract()) revert DiamondWritable__TargetHasNoCode(); } (bool success, ) = target.delegatecall(data); if (!success) { assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol'; /** * @title Diamond proxy upgrade interface * @dev see https://eips.ethereum.org/EIPS/eip-2535 */ interface IDiamondWritable is IDiamondWritableInternal { /** * @notice update diamond facets and optionally execute arbitrary initialization function * @param facetCuts array of structured Diamond facet update data * @param target optional target of initialization delegatecall * @param data optional initialization function call data */ function diamondCut( FacetCut[] calldata facetCuts, address target, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; interface IDiamondWritableInternal { enum FacetCutAction { ADD, REPLACE, REMOVE } event DiamondCut(FacetCut[] facetCuts, address target, bytes data); error DiamondWritable__InvalidInitializationParameters(); error DiamondWritable__RemoveTargetNotZeroAddress(); error DiamondWritable__ReplaceTargetIsIdentical(); error DiamondWritable__SelectorAlreadyAdded(); error DiamondWritable__SelectorIsImmutable(); error DiamondWritable__SelectorNotFound(); error DiamondWritable__SelectorNotSpecified(); error DiamondWritable__TargetHasNoCode(); struct FacetCut { address target; FacetCutAction action; bytes4[] selectors; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; interface IProxy { error Proxy__ImplementationIsNotContract(); fallback() external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { AddressUtils } from '../utils/AddressUtils.sol'; import { IProxy } from './IProxy.sol'; /** * @title Base proxy contract */ abstract contract Proxy is IProxy { using AddressUtils for address; /** * @notice delegate all calls to implementation contract * @dev reverts if implementation address contains no code, for compatibility with metamorphic contracts * @dev memory location in use by assembly may be unsafe in other contexts */ fallback() external payable virtual { address implementation = _getImplementation(); if (!implementation.isContract()) revert Proxy__ImplementationIsNotContract(); assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall( gas(), implementation, 0, calldatasize(), 0, 0 ) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @notice get logic implementation address * @return implementation address */ function _getImplementation() internal virtual returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; interface IPausableInternal { error Pausable__Paused(); error Pausable__NotPaused(); event Paused(address account); event Unpaused(address account); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IPausableInternal } from './IPausableInternal.sol'; import { PausableStorage } from './PausableStorage.sol'; /** * @title Internal functions for Pausable security control module. */ abstract contract PausableInternal is IPausableInternal { modifier whenNotPaused() { if (_paused()) revert Pausable__Paused(); _; } modifier whenPaused() { if (!_paused()) revert Pausable__NotPaused(); _; } /** * @notice query whether contract is paused * @return status whether contract is paused */ function _paused() internal view virtual returns (bool status) { status = PausableStorage.layout().paused; } /** * @notice Triggers paused state, when contract is unpaused. */ function _pause() internal virtual whenNotPaused { PausableStorage.layout().paused = true; emit Paused(msg.sender); } /** * @notice Triggers unpaused state, when contract is paused. */ function _unpause() internal virtual whenPaused { delete PausableStorage.layout().paused; emit Unpaused(msg.sender); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; library PausableStorage { struct Layout { bool paused; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.Pausable'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { IERC2981 } from '../../../interfaces/IERC2981.sol'; import { ERC2981Storage } from './ERC2981Storage.sol'; import { ERC2981Internal } from './ERC2981Internal.sol'; /** * @title ERC2981 implementation */ abstract contract ERC2981 is IERC2981, ERC2981Internal { /** * @notice inheritdoc IERC2981 */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address, uint256) { return _royaltyInfo(tokenId, salePrice); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { ERC2981Storage } from './ERC2981Storage.sol'; import { IERC2981Internal } from '../../../interfaces/IERC2981Internal.sol'; /** * @title ERC2981 internal functions */ abstract contract ERC2981Internal is IERC2981Internal { /** * @notice calculate how much royalty is owed and to whom * @dev royalty must be paid in addition to, rather than deducted from, salePrice * @param tokenId the ERC721 or ERC1155 token id to query for royalty information * @param salePrice the sale price of the given asset * @return royaltyReceiver rightful recipient of royalty * @return royalty amount of royalty owed */ function _royaltyInfo( uint256 tokenId, uint256 salePrice ) internal view virtual returns (address royaltyReceiver, uint256 royalty) { uint256 royaltyBPS = _getRoyaltyBPS(tokenId); // intermediate multiplication overflow is theoretically possible here, but // not an issue in practice because of practical constraints of salePrice return (_getRoyaltyReceiver(tokenId), (royaltyBPS * salePrice) / 10000); } /** * @notice query the royalty rate (denominated in basis points) for given token id * @dev implementation supports per-token-id values as well as a global default * @param tokenId token whose royalty rate to query * @return royaltyBPS royalty rate */ function _getRoyaltyBPS( uint256 tokenId ) internal view virtual returns (uint16 royaltyBPS) { ERC2981Storage.Layout storage l = ERC2981Storage.layout(); royaltyBPS = l.royaltiesBPS[tokenId]; if (royaltyBPS == 0) { royaltyBPS = l.defaultRoyaltyBPS; } } /** * @notice query the royalty receiver for given token id * @dev implementation supports per-token-id values as well as a global default * @param tokenId token whose royalty receiver to query * @return royaltyReceiver royalty receiver */ function _getRoyaltyReceiver( uint256 tokenId ) internal view virtual returns (address royaltyReceiver) { ERC2981Storage.Layout storage l = ERC2981Storage.layout(); royaltyReceiver = l.royaltyReceivers[tokenId]; if (royaltyReceiver == address(0)) { royaltyReceiver = l.defaultRoyaltyReceiver; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; library ERC2981Storage { struct Layout { // token id -> royalty (denominated in basis points) mapping(uint256 => uint16) royaltiesBPS; uint16 defaultRoyaltyBPS; // token id -> receiver address mapping(uint256 => address) royaltyReceivers; address defaultRoyaltyReceiver; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.ERC2981'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; library ERC721MetadataStorage { bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.ERC721Metadata'); struct Layout { string name; string symbol; string baseURI; mapping(uint256 => string) tokenURIs; } function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { UintUtils } from './UintUtils.sol'; library AddressUtils { using UintUtils for uint256; error AddressUtils__InsufficientBalance(); error AddressUtils__NotContract(); error AddressUtils__SendValueFailed(); function toString(address account) internal pure returns (string memory) { return uint256(uint160(account)).toHexString(20); } function isContract(address account) internal view returns (bool) { uint256 size; assembly { size := extcodesize(account) } return size > 0; } function sendValue(address payable account, uint256 amount) internal { (bool success, ) = account.call{ value: amount }(''); if (!success) revert AddressUtils__SendValueFailed(); } function functionCall( address target, bytes memory data ) internal returns (bytes memory) { return functionCall(target, data, 'AddressUtils: failed low-level call'); } function functionCall( address target, bytes memory data, string memory error ) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, error); } function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, 'AddressUtils: failed low-level call with value' ); } function functionCallWithValue( address target, bytes memory data, uint256 value, string memory error ) internal returns (bytes memory) { if (value > address(this).balance) revert AddressUtils__InsufficientBalance(); return _functionCallWithValue(target, data, value, error); } /** * @notice execute arbitrary external call with limited gas usage and amount of copied return data * @dev derived from https://github.com/nomad-xyz/ExcessivelySafeCall (MIT License) * @param target recipient of call * @param gasAmount gas allowance for call * @param value native token value to include in call * @param maxCopy maximum number of bytes to copy from return data * @param data encoded call data * @return success whether call is successful * @return returnData copied return data */ function excessivelySafeCall( address target, uint256 gasAmount, uint256 value, uint16 maxCopy, bytes memory data ) internal returns (bool success, bytes memory returnData) { returnData = new bytes(maxCopy); assembly { // execute external call via assembly to avoid automatic copying of return data success := call( gasAmount, target, value, add(data, 0x20), mload(data), 0, 0 ) // determine whether to limit amount of data to copy let toCopy := returndatasize() if gt(toCopy, maxCopy) { toCopy := maxCopy } // store the length of the copied bytes mstore(returnData, toCopy) // copy the bytes from returndata[0:toCopy] returndatacopy(add(returnData, 0x20), 0, toCopy) } } function _functionCallWithValue( address target, bytes memory data, uint256 value, string memory error ) private returns (bytes memory) { if (!isContract(target)) revert AddressUtils__NotContract(); (bool success, bytes memory returnData) = target.call{ value: value }( data ); if (success) { return returnData; } else if (returnData.length > 0) { assembly { let returnData_size := mload(returnData) revert(add(32, returnData), returnData_size) } } else { revert(error); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title utility functions for uint256 operations * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license) */ library UintUtils { error UintUtils__InsufficientHexLength(); bytes16 private constant HEX_SYMBOLS = '0123456789abcdef'; function add(uint256 a, int256 b) internal pure returns (uint256) { return b < 0 ? sub(a, -b) : a + uint256(b); } function sub(uint256 a, int256 b) internal pure returns (uint256) { return b < 0 ? add(a, -b) : a - uint256(b); } function toString(uint256 value) internal pure returns (string memory) { if (value == 0) { return '0'; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return '0x00'; } uint256 length = 0; for (uint256 temp = value; temp != 0; temp >>= 8) { unchecked { length++; } } return toHexString(value, length); } function toHexString( uint256 value, uint256 length ) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = '0'; buffer[1] = 'x'; unchecked { for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_SYMBOLS[value & 0xf]; value >>= 4; } } if (value != 0) revert UintUtils__InsufficientHexLength(); return string(buffer); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.9; import {EnumerableSet} from "@solidstate/contracts/data/EnumerableSet.sol"; struct SeasonInfo { uint256 seasonId; string description; bool paused; bool valid; } struct PayoutTier { uint256 tierId; string description; uint256 price; uint256 maxPerTx; uint256 payoutPct; uint256 maxSupply; bool paused; bool valid; } enum MintMethod { PURCHASE, AIRDROP, EXTERNAL_MINT } bytes32 constant CONTRACT_ADMIN_ROLE = keccak256("silks.contracts.roles.ContractAdminRole"); bytes32 constant MINT_ADMIN_ROLE = keccak256("silks.contracts.roles.MintAdminRole"); bytes32 constant HORSE_PURCHASING_PAUSED = keccak256('silks.contracts.paused.HorsePurchasing'); error InvalidAddress(address _address); error InvalidSeason(uint256 _sent); error InvalidPayoutTier(uint256 _sent); error InvalidTokenId(uint256 _sent); error InvalidIntValue(string _reason, uint256 _sent, uint256 _expected); error InvalidStringValue(string _reason, string _sent, string _expected); error InvalidExternalMintAddress(address _sender); error MaxHorsesPerWalletExceeded(address _walletAddress); error PayoutTierMaxSupplyExceeded(uint256 _payoutTier); error MintFailed(string _reason, uint256 _seasonId, uint256 _payoutTier, uint256 _quantity, MintMethod _method, address _to); library LibSilksHorseDiamond { bytes32 internal constant STORAGE_SLOT = keccak256('silks.contracts.storage.SilksHorseDiamond'); struct Layout { mapping(uint256 => EnumerableSet.UintSet) seasonHorses; mapping(uint256 => SeasonInfo) seasonInfos; mapping(uint256 => PayoutTier) payoutTiers; mapping(uint256 => PayoutTier) horsePayoutTier; mapping(uint256 => EnumerableSet.UintSet) payoutTierHorses; mapping(uint256 => SeasonInfo) horseSeasonInfo; mapping(address => bool) allowedExternalMintAddresses; uint256 maxHorsesPerWallet; uint256 nextAvailableTokenId; } function layout() internal pure returns ( Layout storage l ) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
{ "evmVersion": "paris", "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_contractOwner","type":"address"},{"internalType":"string","name":"_tokenName","type":"string"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"string","name":"_tokenBaseURI","type":"string"},{"internalType":"uint256","name":"_startTokenId","type":"uint256"},{"internalType":"address","name":"_royaltyReceiver","type":"address"},{"internalType":"uint16","name":"_royaltyBasePoints","type":"uint16"},{"internalType":"uint256","name":"_maxHorsesPerWallet","type":"uint256"},{"components":[{"internalType":"uint256","name":"seasonId","type":"uint256"},{"internalType":"string","name":"description","type":"string"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"valid","type":"bool"}],"internalType":"struct SeasonInfo[]","name":"_seasonInfos","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"tierId","type":"uint256"},{"internalType":"string","name":"description","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"maxPerTx","type":"uint256"},{"internalType":"uint256","name":"payoutPct","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"valid","type":"bool"}],"internalType":"struct PayoutTier[]","name":"_payoutTiers","type":"tuple[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DiamondWritable__InvalidInitializationParameters","type":"error"},{"inputs":[],"name":"DiamondWritable__RemoveTargetNotZeroAddress","type":"error"},{"inputs":[],"name":"DiamondWritable__ReplaceTargetIsIdentical","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorAlreadyAdded","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorIsImmutable","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotFound","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotSpecified","type":"error"},{"inputs":[],"name":"DiamondWritable__TargetHasNoCode","type":"error"},{"inputs":[],"name":"ERC165Base__InvalidInterfaceId","type":"error"},{"inputs":[],"name":"Ownable__NotOwner","type":"error"},{"inputs":[],"name":"Ownable__NotTransitiveOwner","type":"error"},{"inputs":[],"name":"Pausable__NotPaused","type":"error"},{"inputs":[],"name":"Pausable__Paused","type":"error"},{"inputs":[],"name":"Proxy__ImplementationIsNotContract","type":"error"},{"inputs":[],"name":"SafeOwnable__NotNomineeOwner","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritableInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondWritableInternal.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"DiamondCut","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritableInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondWritableInternal.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facet","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondReadable.Facet[]","name":"diamondFacets","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackAddress","outputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nomineeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"name":"setFallbackAddress","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":[{"internalType":"address","name":"account","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620063de380380620063de8339818101604052810190620000379190620027a0565b6000600c67ffffffffffffffff811115620000575762000056620021e6565b5b604051908082528060200260200182016040528015620000865781602001602082028036833780820191505090505b5090506000632c40805960e01b828280620000a19062002960565b935081518110620000b757620000b6620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050639142376560e01b828280620001199062002960565b9350815181106200012f576200012e620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050620001ae7fbd02b73c00000000000000000000000000000000000000000000000000000000600162000c3060201b60201c565b631f931c1c60e01b828280620001c49062002960565b935081518110620001da57620001d9620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050620002597f1f931c1c00000000000000000000000000000000000000000000000000000000600162000c3060201b60201c565b637a0ed62760e01b8282806200026f9062002960565b935081518110620002855762000284620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505063adfca15e60e01b828280620002e79062002960565b935081518110620002fd57620002fc620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506352ef6b2c60e01b8282806200035f9062002960565b935081518110620003755762000374620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505063cdffacc660e01b828280620003d79062002960565b935081518110620003ed57620003ec620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506200046c7f48e2b09300000000000000000000000000000000000000000000000000000000600162000c3060201b60201c565b6301ffc9a760e01b828280620004829062002960565b935081518110620004985762000497620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050620005177f01ffc9a700000000000000000000000000000000000000000000000000000000600162000c3060201b60201c565b638da5cb5b60e01b8282806200052d9062002960565b935081518110620005435762000542620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050638ab5150a60e01b828280620005a59062002960565b935081518110620005bb57620005ba620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505063f2fde38b60e01b8282806200061d9062002960565b935081518110620006335762000632620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506379ba509760e01b828280620006959062002960565b935081518110620006ab57620006aa620029ad565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506200072a7f7f5828d000000000000000000000000000000000000000000000000000000000600162000c3060201b60201c565b6000600167ffffffffffffffff8111156200074a5762000749620021e6565b5b6040519080825280602002602001820160405280156200078757816020015b6200077362002106565b815260200190600190039081620007695790505b50905060405180606001604052803073ffffffffffffffffffffffffffffffffffffffff16815260200160006002811115620007c857620007c7620029dc565b5b81526020018481525081600081518110620007e857620007e7620029ad565b5b6020026020010181905250620008168160006040518060200160405280600081525062000d0e60201b60201c565b620008273362000f9360201b60201c565b505050886200083b6200106c60201b60201c565b60000190816200084c919062002c4c565b50876200085e6200106c60201b60201c565b60010190816200086f919062002c4c565b5086620008816200106c60201b60201c565b600201908162000892919062002c4c565b5084620008a46200109960201b60201c565b60030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083620008f66200109960201b60201c565b60010160006101000a81548161ffff021916908361ffff160217905550620009248a62000f9360201b60201c565b62000934620010c660201b60201c565b620009496000801b8b6200117560201b60201c565b6200097e7f76493909ee513f9bd866a75497a2b0a2713f973b0c77556dbe5dcc1473dcc0136000801b6200121060201b60201c565b620009b07f76493909ee513f9bd866a75497a2b0a2713f973b0c77556dbe5dcc1473dcc0138b6200117560201b60201c565b620009e57f7dc7a9428f8cc2d7d0a73dfc0f0d4791fa005321ee0ba5d966a60588b12e576c6000801b6200121060201b60201c565b62000a177f7dc7a9428f8cc2d7d0a73dfc0f0d4791fa005321ee0ba5d966a60588b12e576c8b6200117560201b60201c565b600062000a296200128560201b60201c565b905086816008018190555083816007018190555060005b835181101562000b195783818151811062000a605762000a5f620029ad565b5b602002602001015182600101600086848151811062000a845762000a83620029ad565b5b602002602001015160000151815260200190815260200160002060008201518160000155602082015181600101908162000abf919062002c4c565b5060408201518160020160006101000a81548160ff02191690831515021790555060608201518160020160016101000a81548160ff021916908315150217905550905050808062000b109062002960565b91505062000a40565b5060005b825181101562000c1e5782818151811062000b3d5762000b3c620029ad565b5b602002602001015182600201600085848151811062000b615762000b60620029ad565b5b602002602001015160000151815260200190815260200160002060008201518160000155602082015181600101908162000b9c919062002c4c565b5060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555060e08201518160060160016101000a81548160ff021916908315150217905550905050808062000c159062002960565b91505062000b1d565b505050505050505050505050620030e6565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160362000c90576040517fb0a19dd500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8062000ca1620012b260201b60201c565b6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600062000d20620012df60201b60201c565b905060008160010160009054906101000a900461ffff1661ffff169050600081905060008060078316111562000d6d57836002016000600384901c81526020019081526020016000205490505b60005b875181101562000ee657600088828151811062000d925762000d91620029ad565b5b6020026020010151905060008160200151905060008260400151510362000de5576040517feb6c3aeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600281111562000dfc5762000dfb620029dc565b5b81600281111562000e125762000e11620029dc565b5b0362000e3a5762000e2c878686856200130c60201b60201c565b809550819650505062000ed6565b6001600281111562000e515762000e50620029dc565b5b81600281111562000e675762000e66620029dc565b5b0362000e855762000e7f8783620015cf60201b60201c565b62000ed5565b60028081111562000e9b5762000e9a620029dc565b5b81600281111562000eb15762000eb0620029dc565b5b0362000ed45762000ecb878686856200189660201b60201c565b80955081965050505b5b5b5050808060010191505062000d70565b5082821462000f0f57818460010160006101000a81548161ffff021916908361ffff1602179055505b600060078316111562000f3b5780846002016000600385901c8152602001908152602001600020819055505b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405162000f709392919062003023565b60405180910390a162000f8a868662001d8a60201b60201c565b50505050505050565b600062000fa562001f4860201b60201c565b90508173ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000807f99574a7094154bb123ae6ae102096f0bf9679b85a5cd1e727aaa0ae5f132e6b190508091505090565b6000807ff298352fd56f58214bf2245c2b202523f72fca3199077ce992640958228b281f90508091505090565b620010d662001f7560201b60201c565b156200110e576040517f059519da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016200112062001f9d60201b60201c565b60000160006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258336040516200116b91906200306e565b60405180910390a1565b620011b0816200118a62001fca60201b60201c565b600001600085815260200190815260200160002060000162001ff760201b90919060201c565b503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062001223836200202f60201b60201c565b9050816200123662001fca60201b60201c565b6000016000858152602001908152602001600020600201819055508181847fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff60405160405180910390a4505050565b6000807fa9766cf30247385bd274fe73461f870e9ad8351016f172911cfa198f44cc28e590508091505090565b6000807ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890508091505090565b6000807f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390508091505090565b6000803073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161415801562001378575062001376836000015173ffffffffffffffffffffffffffffffffffffffff166200206060201b60201c565b155b15620013b0576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b836040015151811015620015bf57600084604001518281518110620013dd57620013dc620029ad565b5b602002602001015190506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1614620014a9576040517f92474ee200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760001b866000015160601b6bffffffffffffffffffffffff191617896000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055506000600560078a16901b905080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c19891617975060e08103620015a657878a600201600060038c901c8152602001908152602001600020819055506000801b97505b88806001019950505050508080600101915050620013b3565b5084849150915094509492505050565b620015fa816000015173ffffffffffffffffffffffffffffffffffffffff166200206060201b60201c565b62001631576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81604001515181101562001891576000826040015182815181106200165e576200165d620029ad565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054905060008160601c9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200172f576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362001795576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620017ff576040517f617557e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015160601b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b831617866000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002081905550505050808060010191505062001634565b505050565b600080600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161462001904576040517feacd242400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600386901c9050600060078716905060005b85604001515181101562001d6f57600086604001518281518110620019425762001941620029ad565b5b6020026020010151905060008a6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff160362001a0e576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff160362001a77576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b890362001aad578480600190039550508a60020160008681526020019081526020016000205498506007935062001ab7565b8380600190039450505b6000806000600587901b8c901b9250847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161462001bda578d6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b8516178e6000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055505b8d6000016000867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206000905560008460001c61ffff169050600381901c9250600560078216901b91505087821462001ce25760008e600201600084815260200190815260200160002054905081847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c827fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198216179050808f6002016000858152602001908152602001600020819055505062001d33565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b6000870362001d5c578d6002016000898152602001908152602001600020600090556000801b9b505b5050505050808060010191505062001918565b5080600383901b179650868693509350505094509492505050565b60008151141515600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151462001dfb576040517f26df4ccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462001f44573073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462001ec35762001e8b8273ffffffffffffffffffffffffffffffffffffffff166200206060201b60201c565b62001ec2576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b60008273ffffffffffffffffffffffffffffffffffffffff168260405162001eec9190620030cd565b600060405180830381855af49150503d806000811462001f29576040519150601f19603f3d011682016040523d82523d6000602084013e62001f2e565b606091505b505090508062001f42573d6000803e3d6000fd5b505b5050565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b600062001f8762001f9d60201b60201c565b60000160009054906101000a900460ff16905090565b6000807f68721c0bbf2c02a4d65000340d1370666be06a630022208d4baa9bd7a4b6fea890508091505090565b6000807fd3889cc5458b268d0544e5534672df1296288ca3f93cbd39bd6f497a5c62281190508091505090565b600062002027836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6200207360201b60201c565b905092915050565b60006200204162001fca60201b60201c565b6000016000838152602001908152602001600020600201549050919050565b600080823b905060008111915050919050565b6000620020878383620020e360201b60201c565b620020dd5782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160006002811115620021455762002144620029dc565b5b8152602001606081525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620021938262002166565b9050919050565b620021a58162002186565b8114620021b157600080fd5b50565b600081519050620021c5816200219a565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200222082620021d5565b810181811067ffffffffffffffff82111715620022425762002241620021e6565b5b80604052505050565b60006200225762002152565b905062002265828262002215565b919050565b600067ffffffffffffffff821115620022885762002287620021e6565b5b6200229382620021d5565b9050602081019050919050565b60005b83811015620022c0578082015181840152602081019050620022a3565b60008484015250505050565b6000620022e3620022dd846200226a565b6200224b565b905082815260208101848484011115620023025762002301620021d0565b5b6200230f848285620022a0565b509392505050565b600082601f8301126200232f576200232e620021cb565b5b815162002341848260208601620022cc565b91505092915050565b6000819050919050565b6200235f816200234a565b81146200236b57600080fd5b50565b6000815190506200237f8162002354565b92915050565b600061ffff82169050919050565b6200239e8162002385565b8114620023aa57600080fd5b50565b600081519050620023be8162002393565b92915050565b600067ffffffffffffffff821115620023e257620023e1620021e6565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b60008115159050919050565b620024198162002402565b81146200242557600080fd5b50565b60008151905062002439816200240e565b92915050565b600060808284031215620024585762002457620023f8565b5b6200246460806200224b565b9050600062002476848285016200236e565b600083015250602082015167ffffffffffffffff8111156200249d576200249c620023fd565b5b620024ab8482850162002317565b6020830152506040620024c18482850162002428565b6040830152506060620024d78482850162002428565b60608301525092915050565b6000620024fa620024f484620023c4565b6200224b565b9050808382526020820190506020840283018581111562002520576200251f620023f3565b5b835b818110156200256e57805167ffffffffffffffff811115620025495762002548620021cb565b5b8086016200255889826200243f565b8552602085019450505060208101905062002522565b5050509392505050565b600082601f83011262002590576200258f620021cb565b5b8151620025a2848260208601620024e3565b91505092915050565b600067ffffffffffffffff821115620025c957620025c8620021e6565b5b602082029050602081019050919050565b60006101008284031215620025f457620025f3620023f8565b5b620026016101006200224b565b9050600062002613848285016200236e565b600083015250602082015167ffffffffffffffff8111156200263a5762002639620023fd565b5b620026488482850162002317565b60208301525060406200265e848285016200236e565b604083015250606062002674848285016200236e565b60608301525060806200268a848285016200236e565b60808301525060a0620026a0848285016200236e565b60a08301525060c0620026b68482850162002428565b60c08301525060e0620026cc8482850162002428565b60e08301525092915050565b6000620026ef620026e984620025ab565b6200224b565b90508083825260208201905060208402830185811115620027155762002714620023f3565b5b835b818110156200276357805167ffffffffffffffff8111156200273e576200273d620021cb565b5b8086016200274d8982620025da565b8552602085019450505060208101905062002717565b5050509392505050565b600082601f830112620027855762002784620021cb565b5b815162002797848260208601620026d8565b91505092915050565b6000806000806000806000806000806101408b8d031215620027c757620027c66200215c565b5b6000620027d78d828e01620021b4565b9a505060208b015167ffffffffffffffff811115620027fb57620027fa62002161565b5b620028098d828e0162002317565b99505060408b015167ffffffffffffffff8111156200282d576200282c62002161565b5b6200283b8d828e0162002317565b98505060608b015167ffffffffffffffff8111156200285f576200285e62002161565b5b6200286d8d828e0162002317565b9750506080620028808d828e016200236e565b96505060a0620028938d828e01620021b4565b95505060c0620028a68d828e01620023ad565b94505060e0620028b98d828e016200236e565b9350506101008b015167ffffffffffffffff811115620028de57620028dd62002161565b5b620028ec8d828e0162002578565b9250506101208b015167ffffffffffffffff81111562002911576200291062002161565b5b6200291f8d828e016200276d565b9150509295989b9194979a5092959850565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006200296d826200234a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620029a257620029a162002931565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062002a5e57607f821691505b60208210810362002a745762002a7362002a16565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830262002ade7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262002a9f565b62002aea868362002a9f565b95508019841693508086168417925050509392505050565b6000819050919050565b600062002b2d62002b2762002b21846200234a565b62002b02565b6200234a565b9050919050565b6000819050919050565b62002b498362002b0c565b62002b6162002b588262002b34565b84845462002aac565b825550505050565b600090565b62002b7862002b69565b62002b8581848462002b3e565b505050565b5b8181101562002bad5762002ba160008262002b6e565b60018101905062002b8b565b5050565b601f82111562002bfc5762002bc68162002a7a565b62002bd18462002a8f565b8101602085101562002be1578190505b62002bf962002bf08562002a8f565b83018262002b8a565b50505b505050565b600082821c905092915050565b600062002c216000198460080262002c01565b1980831691505092915050565b600062002c3c838362002c0e565b9150826002028217905092915050565b62002c578262002a0b565b67ffffffffffffffff81111562002c735762002c72620021e6565b5b62002c7f825462002a45565b62002c8c82828562002bb1565b600060209050601f83116001811462002cc4576000841562002caf578287015190505b62002cbb858262002c2e565b86555062002d2b565b601f19841662002cd48662002a7a565b60005b8281101562002cfe5784890151825560018201915060208501945060208101905062002cd7565b8683101562002d1e578489015162002d1a601f89168262002c0e565b8355505b6001600288020188555050505b505050505050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b62002d6a8162002186565b82525050565b6003811062002d845762002d83620029dc565b5b50565b600081905062002d978262002d70565b919050565b600062002da98262002d87565b9050919050565b62002dbb8162002d9c565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b62002e248162002ded565b82525050565b600062002e38838362002e19565b60208301905092915050565b6000602082019050919050565b600062002e5e8262002dc1565b62002e6a818562002dcc565b935062002e778362002ddd565b8060005b8381101562002eae57815162002e92888262002e2a565b975062002e9f8362002e44565b92505060018101905062002e7b565b5085935050505092915050565b600060608301600083015162002ed5600086018262002d5f565b50602083015162002eea602086018262002db0565b506040830151848203604086015262002f04828262002e51565b9150508091505092915050565b600062002f1f838362002ebb565b905092915050565b6000602082019050919050565b600062002f418262002d33565b62002f4d818562002d3e565b93508360208202850162002f618562002d4f565b8060005b8581101562002fa3578484038952815162002f81858262002f11565b945062002f8e8362002f27565b925060208a0199505060018101905062002f65565b50829750879550505050505092915050565b62002fc08162002186565b82525050565b600081519050919050565b600082825260208201905092915050565b600062002fef8262002fc6565b62002ffb818562002fd1565b93506200300d818560208601620022a0565b6200301881620021d5565b840191505092915050565b600060608201905081810360008301526200303f818662002f34565b905062003050602083018562002fb5565b818103604083015262003064818462002fe2565b9050949350505050565b600060208201905062003085600083018462002fb5565b92915050565b600081905092915050565b6000620030a38262002fc6565b620030af81856200308b565b9350620030c1818560208601620022a0565b80840191505092915050565b6000620030db828462003096565b915081905092915050565b6132e880620030f66000396000f3fe6080604052600436106100c65760003560e01c80637a0ed6271161007f578063914237651161005957806391423765146102e6578063adfca15e1461030f578063cdffacc61461034c578063f2fde38b14610389576100cd565b80637a0ed627146102655780638ab5150a146102905780638da5cb5b146102bb576100cd565b806301ffc9a7146101545780631f931c1c146101915780632a55205a146101ba5780632c408059146101f857806352ef6b2c1461022357806379ba50971461024e576100cd565b366100cd57005b60006100d76103b2565b90506100f88173ffffffffffffffffffffffffffffffffffffffff166103c1565b61012e576040517f87c9fc3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3660008037600080366000845af43d6000803e806000811461014f573d6000f35b3d6000fd5b34801561016057600080fd5b5061017b60048036038101906101769190612568565b6103d4565b60405161018891906125b0565b60405180910390f35b34801561019d57600080fd5b506101b860048036038101906101b391906126e4565b6103e6565b005b3480156101c657600080fd5b506101e160048036038101906101dc91906127af565b6104b4565b6040516101ef92919061280d565b60405180910390f35b34801561020457600080fd5b5061020d6104cc565b60405161021a9190612836565b60405180910390f35b34801561022f57600080fd5b506102386104db565b604051610245919061290f565b60405180910390f35b34801561025a57600080fd5b5061026361073c565b005b34801561027157600080fd5b5061027a6107b2565b6040516102879190612aee565b60405180910390f35b34801561029c57600080fd5b506102a5610d13565b6040516102b29190612836565b60405180910390f35b3480156102c757600080fd5b506102d0610d22565b6040516102dd9190612836565b60405180910390f35b3480156102f257600080fd5b5061030d60048036038101906103089190612b10565b610d31565b005b34801561031b57600080fd5b5061033660048036038101906103319190612b10565b610da9565b6040516103439190612bac565b60405180910390f35b34801561035857600080fd5b50610373600480360381019061036e9190612568565b610fc6565b6040516103809190612836565b60405180910390f35b34801561039557600080fd5b506103b060048036038101906103ab9190612b10565b61102d565b005b60006103bc6110a5565b905090565b600080823b905060008111915050919050565b60006103df826110f3565b9050919050565b6103ee611164565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610452576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ad8585906104629190612e7f565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611197565b5050505050565b6000806104c184846113d2565b915091509250929050565b60006104d6611414565b905090565b606060006104e7611447565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff81111561051957610518612bdf565b5b6040519080825280602002602001820160405280156105475781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff1682101561073257600084600201600083815260200190815260200160002054905060005b600881101561071d57838061059f90612ec3565b9450508560010160009054906101000a900461ffff1661ffff16841161071d576000600582901b83901b90506000876000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b8881101561069b578a818151811061064557610644612f0b565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610688576001915061069b565b808061069390612ec3565b91505061062a565b5080156106aa5750505061070a565b818a89815181106106be576106bd612f0b565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050878061070390612ec3565b9850505050505b808061071590612ec3565b91505061058b565b5050808061072a90612ec3565b915050610550565b5081845250505090565b610744611474565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107a8576040517fefd1052d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107b06114a7565b565b606060006107be611447565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff8111156107f0576107ef612bdf565b5b60405190808252806020026020018201604052801561082957816020015b6108166124cc565b81526020019060019003908161080e5790505b50915060008160010160009054906101000a900461ffff1661ffff1667ffffffffffffffff81111561085e5761085d612bdf565b5b60405190808252806020026020018201604052801561088c5781602001602082028036833780820191505090505b50905060008060005b8460010160009054906101000a900461ffff1661ffff16821015610c9f57600085600201600083815260200190815260200160002054905060005b6008811015610c8a5783806108e490612ec3565b9450508660010160009054906101000a900461ffff1661ffff168411610c8a576000600582901b83901b90506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b88811015610adb578273ffffffffffffffffffffffffffffffffffffffff168c82815181106109a1576109a0612f0b565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610ac857838c82815181106109dc576109db612f0b565b5b6020026020010151602001518b83815181106109fb576109fa612f0b565b5b602002602001015160ff1681518110610a1757610a16612f0b565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a8281518110610a7857610a77612f0b565b5b602002602001015160ff1610610a8d57600080fd5b898181518110610aa057610a9f612f0b565b5b602002602001018051809190610ab590612f47565b60ff1660ff168152505060019150610adb565b8080610ad390612ec3565b91505061096f565b508015610aea57505050610c77565b818b8981518110610afe57610afd612f0b565b5b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508960010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610b6c57610b6b612bdf565b5b604051908082528060200260200182016040528015610b9a5781602001602082028036833780820191505090505b508b8981518110610bae57610bad612f0b565b5b602002602001015160200181905250828b8981518110610bd157610bd0612f0b565b5b602002602001015160200151600081518110610bf057610bef612f0b565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506001898981518110610c5157610c50612f0b565b5b602002602001019060ff16908160ff16815250508780610c7090612ec3565b9850505050505b8080610c8290612ec3565b9150506108d0565b50508080610c9790612ec3565b915050610895565b5060005b82811015610d08576000848281518110610cc057610cbf612f0b565b5b602002602001015160ff1690506000878381518110610ce257610ce1612f0b565b5b602002602001015160200151905081815250508080610d0090612ec3565b915050610ca3565b508185525050505090565b6000610d1d611474565b905090565b6000610d2c611164565b905090565b610d39611164565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d9d576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610da6816114e0565b50565b60606000610db5611447565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610de757610de6612bdf565b5b604051908082528060200260200182016040528015610e155781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff16821015610fba57600084600201600083815260200190815260200160002054905060005b6008811015610fa5578380610e6d90612ec3565b9450508560010160009054906101000a900461ffff1661ffff168411610fa5576000600582901b83901b9050866000016000827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1603610f915780888781518110610f3657610f35612f0b565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508580610f8d90612ec3565b9650505b508080610f9d90612ec3565b915050610e59565b50508080610fb290612ec3565b915050610e1e565b50818452505050919050565b6000610fd0611447565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9050919050565b611035611164565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611099576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110a28161152d565b50565b60006110af611539565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036110f0576110ed611414565b90505b90565b60006110fd6115e5565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b600061116e611612565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006111a1611447565b905060008160010160009054906101000a900461ffff1661ffff16905060008190506000806007831611156111ed57836002016000600384901c81526020019081526020016000205490505b60005b875181101561133157600088828151811061120e5761120d612f0b565b5b60200260200101519050600081602001519050600082604001515103611260576040517feb6c3aeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600281111561127457611273612f70565b5b81600281111561128757611286612f70565b5b036112a5576112988786868561163f565b8095508196505050611322565b600160028111156112b9576112b8612f70565b5b8160028111156112cc576112cb612f70565b5b036112e0576112db87836118f1565b611321565b6002808111156112f3576112f2612f70565b5b81600281111561130657611305612f70565b5b036113205761131787868685611ba7565b80955081965050505b5b5b505080806001019150506111f0565b5082821461135957818460010160006101000a81548161ffff021916908361ffff1602179055505b60006007831611156113845780846002016000600385901c8152602001908152602001600020819055505b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113b793929190613178565b60405180910390a16113c9868661208d565b50505050505050565b60008060006113e08561223a565b61ffff1690506113ef85612295565b61271085836113fe91906131bd565b611408919061322e565b92509250509250929050565b600061141e611447565b60030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000807f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390508091505090565b600061147e61233c565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6114b033612369565b6114b861233c565b60000160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055565b806114e9611447565b60030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6115368161243a565b50565b60008060007f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93905080915081600001600080357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9250505090565b6000807ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890508091505090565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b6000803073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16141580156116a257506116a0836000015173ffffffffffffffffffffffffffffffffffffffff166103c1565b155b156116d9576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8360400151518110156118e15760008460400151828151811061170257611701612f0b565b5b602002602001015190506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff16146117cd576040517f92474ee200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760001b866000015160601b6bffffffffffffffffffffffff191617896000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055506000600560078a16901b905080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c19891617975060e081036118c957878a600201600060038c901c8152602001908152602001600020819055506000801b97505b888060010199505050505080806001019150506116dc565b5084849150915094509492505050565b611914816000015173ffffffffffffffffffffffffffffffffffffffff166103c1565b61194a576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b816040015151811015611ba25760008260400151828151811061197357611972612f0b565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054905060008160601c9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a43576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611aa8576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611b11576040517f617557e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015160601b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b831617866000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002081905550505050808060010191505061194d565b505050565b600080600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611c14576040517feacd242400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600386901c9050600060078716905060005b85604001515181101561207257600086604001518281518110611c4e57611c4d612f0b565b5b6020026020010151905060008a6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611d19576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611d81576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b8903611db5578480600190039550508a600201600086815260200190815260200160002054985060079350611dbf565b8380600190039450505b6000806000600587901b8c901b9250847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614611ee1578d6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b8516178e6000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055505b8d6000016000867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206000905560008460001c61ffff169050600381901c9250600560078216901b915050878214611fe75760008e600201600084815260200190815260200160002054905081847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c827fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198216179050808f60020160008581526020019081526020016000208190555050612038565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b60008703612060578d6002016000898152602001908152602001600020600090556000801b9b505b50505050508080600101915050611c28565b5080600383901b179650868693509350505094509492505050565b60008151141515600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515146120fd576040517f26df4ccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612236573073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146121ba576121838273ffffffffffffffffffffffffffffffffffffffff166103c1565b6121b9576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516121e1919061329b565b600060405180830381855af49150503d806000811461221c576040519150601f19603f3d011682016040523d82523d6000602084013e612221565b606091505b5050905080612234573d6000803e3d6000fd5b505b5050565b600080612245612446565b905080600001600084815260200190815260200160002060009054906101000a900461ffff16915060008261ffff160361228f578060010160009054906101000a900461ffff1691505b50919050565b6000806122a0612446565b905080600201600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612336578060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505b50919050565b6000807f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789090508091505090565b6000612373611612565b90508173ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b61244381612473565b50565b6000807ff298352fd56f58214bf2245c2b202523f72fca3199077ce992640958228b281f90508091505090565b61247c8161247f565b50565b8061248861233c565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61254581612510565b811461255057600080fd5b50565b6000813590506125628161253c565b92915050565b60006020828403121561257e5761257d612506565b5b600061258c84828501612553565b91505092915050565b60008115159050919050565b6125aa81612595565b82525050565b60006020820190506125c560008301846125a1565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126125f0576125ef6125cb565b5b8235905067ffffffffffffffff81111561260d5761260c6125d0565b5b602083019150836020820283011115612629576126286125d5565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061265b82612630565b9050919050565b61266b81612650565b811461267657600080fd5b50565b60008135905061268881612662565b92915050565b60008083601f8401126126a4576126a36125cb565b5b8235905067ffffffffffffffff8111156126c1576126c06125d0565b5b6020830191508360018202830111156126dd576126dc6125d5565b5b9250929050565b600080600080600060608688031215612700576126ff612506565b5b600086013567ffffffffffffffff81111561271e5761271d61250b565b5b61272a888289016125da565b9550955050602061273d88828901612679565b935050604086013567ffffffffffffffff81111561275e5761275d61250b565b5b61276a8882890161268e565b92509250509295509295909350565b6000819050919050565b61278c81612779565b811461279757600080fd5b50565b6000813590506127a981612783565b92915050565b600080604083850312156127c6576127c5612506565b5b60006127d48582860161279a565b92505060206127e58582860161279a565b9150509250929050565b6127f881612650565b82525050565b61280781612779565b82525050565b600060408201905061282260008301856127ef565b61282f60208301846127fe565b9392505050565b600060208201905061284b60008301846127ef565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61288681612650565b82525050565b6000612898838361287d565b60208301905092915050565b6000602082019050919050565b60006128bc82612851565b6128c6818561285c565b93506128d18361286d565b8060005b838110156129025781516128e9888261288c565b97506128f4836128a4565b9250506001810190506128d5565b5085935050505092915050565b6000602082019050818103600083015261292981846128b1565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61299281612510565b82525050565b60006129a48383612989565b60208301905092915050565b6000602082019050919050565b60006129c88261295d565b6129d28185612968565b93506129dd83612979565b8060005b83811015612a0e5781516129f58882612998565b9750612a00836129b0565b9250506001810190506129e1565b5085935050505092915050565b6000604083016000830151612a33600086018261287d565b5060208301518482036020860152612a4b82826129bd565b9150508091505092915050565b6000612a648383612a1b565b905092915050565b6000602082019050919050565b6000612a8482612931565b612a8e818561293c565b935083602082028501612aa08561294d565b8060005b85811015612adc5784840389528151612abd8582612a58565b9450612ac883612a6c565b925060208a01995050600181019050612aa4565b50829750879550505050505092915050565b60006020820190508181036000830152612b088184612a79565b905092915050565b600060208284031215612b2657612b25612506565b5b6000612b3484828501612679565b91505092915050565b600082825260208201905092915050565b6000612b598261295d565b612b638185612b3d565b9350612b6e83612979565b8060005b83811015612b9f578151612b868882612998565b9750612b91836129b0565b925050600181019050612b72565b5085935050505092915050565b60006020820190508181036000830152612bc68184612b4e565b905092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612c1782612bce565b810181811067ffffffffffffffff82111715612c3657612c35612bdf565b5b80604052505050565b6000612c496124fc565b9050612c558282612c0e565b919050565b600067ffffffffffffffff821115612c7557612c74612bdf565b5b602082029050602081019050919050565b600080fd5b600080fd5b60038110612c9d57600080fd5b50565b600081359050612caf81612c90565b92915050565b600067ffffffffffffffff821115612cd057612ccf612bdf565b5b602082029050602081019050919050565b6000612cf4612cef84612cb5565b612c3f565b90508083825260208201905060208402830185811115612d1757612d166125d5565b5b835b81811015612d405780612d2c8882612553565b845260208401935050602081019050612d19565b5050509392505050565b600082601f830112612d5f57612d5e6125cb565b5b8135612d6f848260208601612ce1565b91505092915050565b600060608284031215612d8e57612d8d612c86565b5b612d986060612c3f565b90506000612da884828501612679565b6000830152506020612dbc84828501612ca0565b602083015250604082013567ffffffffffffffff811115612de057612ddf612c8b565b5b612dec84828501612d4a565b60408301525092915050565b6000612e0b612e0684612c5a565b612c3f565b90508083825260208201905060208402830185811115612e2e57612e2d6125d5565b5b835b81811015612e7557803567ffffffffffffffff811115612e5357612e526125cb565b5b808601612e608982612d78565b85526020850194505050602081019050612e30565b5050509392505050565b6000612e8c368484612df8565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612ece82612779565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612f0057612eff612e94565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff82169050919050565b6000612f5282612f3a565b915060ff8203612f6557612f64612e94565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60038110612fdc57612fdb612f70565b5b50565b6000819050612fed82612fcb565b919050565b6000612ffd82612fdf565b9050919050565b61300d81612ff2565b82525050565b600060608301600083015161302b600086018261287d565b50602083015161303e6020860182613004565b506040830151848203604086015261305682826129bd565b9150508091505092915050565b600061306f8383613013565b905092915050565b6000602082019050919050565b600061308f82612f9f565b6130998185612faa565b9350836020820285016130ab85612fbb565b8060005b858110156130e757848403895281516130c88582613063565b94506130d383613077565b925060208a019950506001810190506130af565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613133578082015181840152602081019050613118565b60008484015250505050565b600061314a826130f9565b6131548185613104565b9350613164818560208601613115565b61316d81612bce565b840191505092915050565b600060608201905081810360008301526131928186613084565b90506131a160208301856127ef565b81810360408301526131b3818461313f565b9050949350505050565b60006131c882612779565b91506131d383612779565b92508282026131e181612779565b915082820484148315176131f8576131f7612e94565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061323982612779565b915061324483612779565b925082613254576132536131ff565b5b828204905092915050565b600081905092915050565b6000613275826130f9565b61327f818561325f565b935061328f818560208601613115565b80840191505092915050565b60006132a7828461326a565b91508190509291505056fea2646970667358221220b873d44b7534267ad89dd57fcd9a804e732ba809b24c960573180d6dfe2dee7a64736f6c634300081400330000000000000000000000007edac4f0251a484a28f757d8f6e83783a1f382850000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000002150000000000000000000000000260b04d02ff90d2ade661ffcff63d039c5f2dfde00000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000e53696c6b7320486f727365205632000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e53494c4b535f484f5253455f5632000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002168747470733a2f2f6e66742e73696c6b732e696f2f6d657461646174612f63312f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000007e8000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001753696c6b73203230323420486f72736520536561736f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000470de4df820000000000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c3120506374205061796f75740000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106100c65760003560e01c80637a0ed6271161007f578063914237651161005957806391423765146102e6578063adfca15e1461030f578063cdffacc61461034c578063f2fde38b14610389576100cd565b80637a0ed627146102655780638ab5150a146102905780638da5cb5b146102bb576100cd565b806301ffc9a7146101545780631f931c1c146101915780632a55205a146101ba5780632c408059146101f857806352ef6b2c1461022357806379ba50971461024e576100cd565b366100cd57005b60006100d76103b2565b90506100f88173ffffffffffffffffffffffffffffffffffffffff166103c1565b61012e576040517f87c9fc3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3660008037600080366000845af43d6000803e806000811461014f573d6000f35b3d6000fd5b34801561016057600080fd5b5061017b60048036038101906101769190612568565b6103d4565b60405161018891906125b0565b60405180910390f35b34801561019d57600080fd5b506101b860048036038101906101b391906126e4565b6103e6565b005b3480156101c657600080fd5b506101e160048036038101906101dc91906127af565b6104b4565b6040516101ef92919061280d565b60405180910390f35b34801561020457600080fd5b5061020d6104cc565b60405161021a9190612836565b60405180910390f35b34801561022f57600080fd5b506102386104db565b604051610245919061290f565b60405180910390f35b34801561025a57600080fd5b5061026361073c565b005b34801561027157600080fd5b5061027a6107b2565b6040516102879190612aee565b60405180910390f35b34801561029c57600080fd5b506102a5610d13565b6040516102b29190612836565b60405180910390f35b3480156102c757600080fd5b506102d0610d22565b6040516102dd9190612836565b60405180910390f35b3480156102f257600080fd5b5061030d60048036038101906103089190612b10565b610d31565b005b34801561031b57600080fd5b5061033660048036038101906103319190612b10565b610da9565b6040516103439190612bac565b60405180910390f35b34801561035857600080fd5b50610373600480360381019061036e9190612568565b610fc6565b6040516103809190612836565b60405180910390f35b34801561039557600080fd5b506103b060048036038101906103ab9190612b10565b61102d565b005b60006103bc6110a5565b905090565b600080823b905060008111915050919050565b60006103df826110f3565b9050919050565b6103ee611164565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610452576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104ad8585906104629190612e7f565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611197565b5050505050565b6000806104c184846113d2565b915091509250929050565b60006104d6611414565b905090565b606060006104e7611447565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff81111561051957610518612bdf565b5b6040519080825280602002602001820160405280156105475781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff1682101561073257600084600201600083815260200190815260200160002054905060005b600881101561071d57838061059f90612ec3565b9450508560010160009054906101000a900461ffff1661ffff16841161071d576000600582901b83901b90506000876000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b8881101561069b578a818151811061064557610644612f0b565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610688576001915061069b565b808061069390612ec3565b91505061062a565b5080156106aa5750505061070a565b818a89815181106106be576106bd612f0b565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050878061070390612ec3565b9850505050505b808061071590612ec3565b91505061058b565b5050808061072a90612ec3565b915050610550565b5081845250505090565b610744611474565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107a8576040517fefd1052d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107b06114a7565b565b606060006107be611447565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff8111156107f0576107ef612bdf565b5b60405190808252806020026020018201604052801561082957816020015b6108166124cc565b81526020019060019003908161080e5790505b50915060008160010160009054906101000a900461ffff1661ffff1667ffffffffffffffff81111561085e5761085d612bdf565b5b60405190808252806020026020018201604052801561088c5781602001602082028036833780820191505090505b50905060008060005b8460010160009054906101000a900461ffff1661ffff16821015610c9f57600085600201600083815260200190815260200160002054905060005b6008811015610c8a5783806108e490612ec3565b9450508660010160009054906101000a900461ffff1661ffff168411610c8a576000600582901b83901b90506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b88811015610adb578273ffffffffffffffffffffffffffffffffffffffff168c82815181106109a1576109a0612f0b565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610ac857838c82815181106109dc576109db612f0b565b5b6020026020010151602001518b83815181106109fb576109fa612f0b565b5b602002602001015160ff1681518110610a1757610a16612f0b565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a8281518110610a7857610a77612f0b565b5b602002602001015160ff1610610a8d57600080fd5b898181518110610aa057610a9f612f0b565b5b602002602001018051809190610ab590612f47565b60ff1660ff168152505060019150610adb565b8080610ad390612ec3565b91505061096f565b508015610aea57505050610c77565b818b8981518110610afe57610afd612f0b565b5b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508960010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610b6c57610b6b612bdf565b5b604051908082528060200260200182016040528015610b9a5781602001602082028036833780820191505090505b508b8981518110610bae57610bad612f0b565b5b602002602001015160200181905250828b8981518110610bd157610bd0612f0b565b5b602002602001015160200151600081518110610bf057610bef612f0b565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506001898981518110610c5157610c50612f0b565b5b602002602001019060ff16908160ff16815250508780610c7090612ec3565b9850505050505b8080610c8290612ec3565b9150506108d0565b50508080610c9790612ec3565b915050610895565b5060005b82811015610d08576000848281518110610cc057610cbf612f0b565b5b602002602001015160ff1690506000878381518110610ce257610ce1612f0b565b5b602002602001015160200151905081815250508080610d0090612ec3565b915050610ca3565b508185525050505090565b6000610d1d611474565b905090565b6000610d2c611164565b905090565b610d39611164565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d9d576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610da6816114e0565b50565b60606000610db5611447565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610de757610de6612bdf565b5b604051908082528060200260200182016040528015610e155781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff16821015610fba57600084600201600083815260200190815260200160002054905060005b6008811015610fa5578380610e6d90612ec3565b9450508560010160009054906101000a900461ffff1661ffff168411610fa5576000600582901b83901b9050866000016000827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1603610f915780888781518110610f3657610f35612f0b565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508580610f8d90612ec3565b9650505b508080610f9d90612ec3565b915050610e59565b50508080610fb290612ec3565b915050610e1e565b50818452505050919050565b6000610fd0611447565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9050919050565b611035611164565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611099576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110a28161152d565b50565b60006110af611539565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036110f0576110ed611414565b90505b90565b60006110fd6115e5565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b600061116e611612565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006111a1611447565b905060008160010160009054906101000a900461ffff1661ffff16905060008190506000806007831611156111ed57836002016000600384901c81526020019081526020016000205490505b60005b875181101561133157600088828151811061120e5761120d612f0b565b5b60200260200101519050600081602001519050600082604001515103611260576040517feb6c3aeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600281111561127457611273612f70565b5b81600281111561128757611286612f70565b5b036112a5576112988786868561163f565b8095508196505050611322565b600160028111156112b9576112b8612f70565b5b8160028111156112cc576112cb612f70565b5b036112e0576112db87836118f1565b611321565b6002808111156112f3576112f2612f70565b5b81600281111561130657611305612f70565b5b036113205761131787868685611ba7565b80955081965050505b5b5b505080806001019150506111f0565b5082821461135957818460010160006101000a81548161ffff021916908361ffff1602179055505b60006007831611156113845780846002016000600385901c8152602001908152602001600020819055505b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113b793929190613178565b60405180910390a16113c9868661208d565b50505050505050565b60008060006113e08561223a565b61ffff1690506113ef85612295565b61271085836113fe91906131bd565b611408919061322e565b92509250509250929050565b600061141e611447565b60030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000807f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390508091505090565b600061147e61233c565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6114b033612369565b6114b861233c565b60000160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055565b806114e9611447565b60030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6115368161243a565b50565b60008060007f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93905080915081600001600080357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9250505090565b6000807ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890508091505090565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b6000803073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16141580156116a257506116a0836000015173ffffffffffffffffffffffffffffffffffffffff166103c1565b155b156116d9576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8360400151518110156118e15760008460400151828151811061170257611701612f0b565b5b602002602001015190506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff16146117cd576040517f92474ee200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760001b866000015160601b6bffffffffffffffffffffffff191617896000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055506000600560078a16901b905080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c19891617975060e081036118c957878a600201600060038c901c8152602001908152602001600020819055506000801b97505b888060010199505050505080806001019150506116dc565b5084849150915094509492505050565b611914816000015173ffffffffffffffffffffffffffffffffffffffff166103c1565b61194a576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b816040015151811015611ba25760008260400151828151811061197357611972612f0b565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054905060008160601c9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a43576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611aa8576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611b11576040517f617557e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015160601b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b831617866000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002081905550505050808060010191505061194d565b505050565b600080600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611c14576040517feacd242400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600386901c9050600060078716905060005b85604001515181101561207257600086604001518281518110611c4e57611c4d612f0b565b5b6020026020010151905060008a6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611d19576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611d81576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b8903611db5578480600190039550508a600201600086815260200190815260200160002054985060079350611dbf565b8380600190039450505b6000806000600587901b8c901b9250847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614611ee1578d6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b8516178e6000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055505b8d6000016000867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206000905560008460001c61ffff169050600381901c9250600560078216901b915050878214611fe75760008e600201600084815260200190815260200160002054905081847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c827fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198216179050808f60020160008581526020019081526020016000208190555050612038565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b60008703612060578d6002016000898152602001908152602001600020600090556000801b9b505b50505050508080600101915050611c28565b5080600383901b179650868693509350505094509492505050565b60008151141515600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515146120fd576040517f26df4ccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612236573073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146121ba576121838273ffffffffffffffffffffffffffffffffffffffff166103c1565b6121b9576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516121e1919061329b565b600060405180830381855af49150503d806000811461221c576040519150601f19603f3d011682016040523d82523d6000602084013e612221565b606091505b5050905080612234573d6000803e3d6000fd5b505b5050565b600080612245612446565b905080600001600084815260200190815260200160002060009054906101000a900461ffff16915060008261ffff160361228f578060010160009054906101000a900461ffff1691505b50919050565b6000806122a0612446565b905080600201600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612336578060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505b50919050565b6000807f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789090508091505090565b6000612373611612565b90508173ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b61244381612473565b50565b6000807ff298352fd56f58214bf2245c2b202523f72fca3199077ce992640958228b281f90508091505090565b61247c8161247f565b50565b8061248861233c565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61254581612510565b811461255057600080fd5b50565b6000813590506125628161253c565b92915050565b60006020828403121561257e5761257d612506565b5b600061258c84828501612553565b91505092915050565b60008115159050919050565b6125aa81612595565b82525050565b60006020820190506125c560008301846125a1565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126125f0576125ef6125cb565b5b8235905067ffffffffffffffff81111561260d5761260c6125d0565b5b602083019150836020820283011115612629576126286125d5565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061265b82612630565b9050919050565b61266b81612650565b811461267657600080fd5b50565b60008135905061268881612662565b92915050565b60008083601f8401126126a4576126a36125cb565b5b8235905067ffffffffffffffff8111156126c1576126c06125d0565b5b6020830191508360018202830111156126dd576126dc6125d5565b5b9250929050565b600080600080600060608688031215612700576126ff612506565b5b600086013567ffffffffffffffff81111561271e5761271d61250b565b5b61272a888289016125da565b9550955050602061273d88828901612679565b935050604086013567ffffffffffffffff81111561275e5761275d61250b565b5b61276a8882890161268e565b92509250509295509295909350565b6000819050919050565b61278c81612779565b811461279757600080fd5b50565b6000813590506127a981612783565b92915050565b600080604083850312156127c6576127c5612506565b5b60006127d48582860161279a565b92505060206127e58582860161279a565b9150509250929050565b6127f881612650565b82525050565b61280781612779565b82525050565b600060408201905061282260008301856127ef565b61282f60208301846127fe565b9392505050565b600060208201905061284b60008301846127ef565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61288681612650565b82525050565b6000612898838361287d565b60208301905092915050565b6000602082019050919050565b60006128bc82612851565b6128c6818561285c565b93506128d18361286d565b8060005b838110156129025781516128e9888261288c565b97506128f4836128a4565b9250506001810190506128d5565b5085935050505092915050565b6000602082019050818103600083015261292981846128b1565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61299281612510565b82525050565b60006129a48383612989565b60208301905092915050565b6000602082019050919050565b60006129c88261295d565b6129d28185612968565b93506129dd83612979565b8060005b83811015612a0e5781516129f58882612998565b9750612a00836129b0565b9250506001810190506129e1565b5085935050505092915050565b6000604083016000830151612a33600086018261287d565b5060208301518482036020860152612a4b82826129bd565b9150508091505092915050565b6000612a648383612a1b565b905092915050565b6000602082019050919050565b6000612a8482612931565b612a8e818561293c565b935083602082028501612aa08561294d565b8060005b85811015612adc5784840389528151612abd8582612a58565b9450612ac883612a6c565b925060208a01995050600181019050612aa4565b50829750879550505050505092915050565b60006020820190508181036000830152612b088184612a79565b905092915050565b600060208284031215612b2657612b25612506565b5b6000612b3484828501612679565b91505092915050565b600082825260208201905092915050565b6000612b598261295d565b612b638185612b3d565b9350612b6e83612979565b8060005b83811015612b9f578151612b868882612998565b9750612b91836129b0565b925050600181019050612b72565b5085935050505092915050565b60006020820190508181036000830152612bc68184612b4e565b905092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612c1782612bce565b810181811067ffffffffffffffff82111715612c3657612c35612bdf565b5b80604052505050565b6000612c496124fc565b9050612c558282612c0e565b919050565b600067ffffffffffffffff821115612c7557612c74612bdf565b5b602082029050602081019050919050565b600080fd5b600080fd5b60038110612c9d57600080fd5b50565b600081359050612caf81612c90565b92915050565b600067ffffffffffffffff821115612cd057612ccf612bdf565b5b602082029050602081019050919050565b6000612cf4612cef84612cb5565b612c3f565b90508083825260208201905060208402830185811115612d1757612d166125d5565b5b835b81811015612d405780612d2c8882612553565b845260208401935050602081019050612d19565b5050509392505050565b600082601f830112612d5f57612d5e6125cb565b5b8135612d6f848260208601612ce1565b91505092915050565b600060608284031215612d8e57612d8d612c86565b5b612d986060612c3f565b90506000612da884828501612679565b6000830152506020612dbc84828501612ca0565b602083015250604082013567ffffffffffffffff811115612de057612ddf612c8b565b5b612dec84828501612d4a565b60408301525092915050565b6000612e0b612e0684612c5a565b612c3f565b90508083825260208201905060208402830185811115612e2e57612e2d6125d5565b5b835b81811015612e7557803567ffffffffffffffff811115612e5357612e526125cb565b5b808601612e608982612d78565b85526020850194505050602081019050612e30565b5050509392505050565b6000612e8c368484612df8565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612ece82612779565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612f0057612eff612e94565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff82169050919050565b6000612f5282612f3a565b915060ff8203612f6557612f64612e94565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60038110612fdc57612fdb612f70565b5b50565b6000819050612fed82612fcb565b919050565b6000612ffd82612fdf565b9050919050565b61300d81612ff2565b82525050565b600060608301600083015161302b600086018261287d565b50602083015161303e6020860182613004565b506040830151848203604086015261305682826129bd565b9150508091505092915050565b600061306f8383613013565b905092915050565b6000602082019050919050565b600061308f82612f9f565b6130998185612faa565b9350836020820285016130ab85612fbb565b8060005b858110156130e757848403895281516130c88582613063565b94506130d383613077565b925060208a019950506001810190506130af565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613133578082015181840152602081019050613118565b60008484015250505050565b600061314a826130f9565b6131548185613104565b9350613164818560208601613115565b61316d81612bce565b840191505092915050565b600060608201905081810360008301526131928186613084565b90506131a160208301856127ef565b81810360408301526131b3818461313f565b9050949350505050565b60006131c882612779565b91506131d383612779565b92508282026131e181612779565b915082820484148315176131f8576131f7612e94565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061323982612779565b915061324483612779565b925082613254576132536131ff565b5b828204905092915050565b600081905092915050565b6000613275826130f9565b61327f818561325f565b935061328f818560208601613115565b80840191505092915050565b60006132a7828461326a565b91508190509291505056fea2646970667358221220b873d44b7534267ad89dd57fcd9a804e732ba809b24c960573180d6dfe2dee7a64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007edac4f0251a484a28f757d8f6e83783a1f382850000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000002150000000000000000000000000260b04d02ff90d2ade661ffcff63d039c5f2dfde00000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000e53696c6b7320486f727365205632000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e53494c4b535f484f5253455f5632000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002168747470733a2f2f6e66742e73696c6b732e696f2f6d657461646174612f63312f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000007e8000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001753696c6b73203230323420486f72736520536561736f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000470de4df820000000000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c3120506374205061796f75740000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _contractOwner (address): 0x7edAC4f0251a484a28F757d8f6e83783a1f38285
Arg [1] : _tokenName (string): Silks Horse V2
Arg [2] : _tokenSymbol (string): SILKS_HORSE_V2
Arg [3] : _tokenBaseURI (string): https://nft.silks.io/metadata/c1/
Arg [4] : _startTokenId (uint256): 8528
Arg [5] : _royaltyReceiver (address): 0x260B04d02FF90d2AdE661fFCFF63d039C5F2DFDE
Arg [6] : _royaltyBasePoints (uint16): 500
Arg [7] : _maxHorsesPerWallet (uint256): 0
Arg [8] : _seasonInfos (tuple[]): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [9] : _payoutTiers (tuple[]): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
37 Constructor Arguments found :
Arg [0] : 0000000000000000000000007edac4f0251a484a28f757d8f6e83783a1f38285
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001c0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000002150
Arg [5] : 000000000000000000000000260b04d02ff90d2ade661ffcff63d039c5f2dfde
Arg [6] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000220
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000320
Arg [10] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [11] : 53696c6b7320486f727365205632000000000000000000000000000000000000
Arg [12] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [13] : 53494c4b535f484f5253455f5632000000000000000000000000000000000000
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000021
Arg [15] : 68747470733a2f2f6e66742e73696c6b732e696f2f6d657461646174612f6331
Arg [16] : 2f00000000000000000000000000000000000000000000000000000000000000
Arg [17] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [19] : 00000000000000000000000000000000000000000000000000000000000007e8
Arg [20] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [21] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [22] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [23] : 0000000000000000000000000000000000000000000000000000000000000017
Arg [24] : 53696c6b73203230323420486f72736520536561736f6e000000000000000000
Arg [25] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [26] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [27] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [28] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [29] : 0000000000000000000000000000000000000000000000000470de4df8200000
Arg [30] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [31] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [32] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [33] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [34] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [35] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [36] : 3120506374205061796f75740000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.