Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60806040 | 20031060 | 638 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
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 Name:
TokenLauncherFactoryFacet
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { IAccessControl } from "@solidstate/contracts/access/access_control/IAccessControl.sol";
import { ITokenLauncherFactory } from "../interfaces/ITokenLauncherFactory.sol";
import { ITokenFiErc20 } from "../interfaces/ITokenFiErc20.sol";
import { ITokenFiErc20Init } from "../interfaces/ITokenFiErc20Init.sol";
import { ITokenFiErc721 } from "../interfaces/ITokenFiErc721.sol";
import { ITokenFiErc721Init } from "../interfaces/ITokenFiErc721Init.sol";
import { ITokenFiErc1155 } from "../interfaces/ITokenFiErc1155.sol";
import { ITokenFiErc1155Init } from "../interfaces/ITokenFiErc1155Init.sol";
import { LibTokenLauncherFactoryStorage } from "../libraries/LibTokenLauncherFactoryStorage.sol";
import { LibTokenLauncherConsts } from "../libraries/LibTokenLauncherConsts.sol";
import { IPaymentModule } from "../../common/admin/interfaces/IPaymentModule.sol";
import { ICrossPaymentModule } from "../../common/admin/interfaces/ICrossPaymentModule.sol";
import { IPlatformModule } from "../../common/admin/interfaces/IPlatformModule.sol";
import { LibPaymentModuleConsts } from "../../common/admin/libraries/LibPaymentModuleConsts.sol";
import { IDiamondCut } from "../../common/diamonds/interfaces/IDiamondCut.sol";
import { LibDiamond } from "../../common/diamonds/libraries/LibDiamond.sol";
import { LibDiamondHelpers } from "../../common/diamonds/libraries/LibDiamondHelpers.sol";
import { Diamond } from "../../common/diamonds/Diamond.sol";
import { IDiamondProxy } from "../../common/diamonds/interfaces/IDiamondProxy.sol";
contract TokenLauncherFactoryFacet is ITokenLauncherFactory {
// solhint-disable-next-line function-max-lines
function createErc20(CreateErc20Input memory input) external payable override returns (address tokenAddress) {
uint256 paymentIndex = _processPayment(TokenType.ERC20, input.referrer, input.paymentToken);
tokenAddress = _createErc20(input, paymentIndex);
}
function createErc20WithPaymentSignature(
CreateErc20Input memory input,
ICrossPaymentModule.CrossPaymentSignatureInput memory crossPaymentSignatureInput
) external override returns (address tokenAddress) {
_spendCrossPaymentSignature(TokenType.ERC20, crossPaymentSignatureInput);
tokenAddress = _createErc20(input, crossPaymentSignatureInput.paymentIndex);
}
function _createErc20(CreateErc20Input memory input, uint256 paymentIndex) private returns (address tokenAddress) {
LibTokenLauncherFactoryStorage.DiamondStorage storage ds = LibTokenLauncherFactoryStorage.diamondStorage();
// Now let's create a diamond
tokenAddress = _createTokenDiamond();
_prepareTokenFiErc20Diamond(tokenAddress, input.tokenInfo);
// set TokenFiErc20Implementation for etherscan
IDiamondProxy(tokenAddress).setImplementation(ds.tokenFiErc20Implementation);
ITokenFiErc20 token = ITokenFiErc20(tokenAddress);
// set metadata
token.setName(input.tokenInfo.name);
token.setSymbol(input.tokenInfo.symbol);
token.setDecimals(input.tokenInfo.decimals);
// mint initial supply to treasury if it's not a reflection token
if (input.tokenInfo.initialSupply > 0) {
token.mint(input.tokenInfo.treasury, input.tokenInfo.initialSupply);
}
// exempt this address as a liquidity factory
token.addExemptAddress(address(this));
// exempt the buybackHandler to avoid recursive transfer
token.addExemptAddress(ds.buybackHandler);
// set buybackHandler
token.setBuybackHandler(ds.buybackHandler);
// grant BUYBACK_CALLER_ROLE to the tokenFiErc20
IAccessControl(ds.buybackHandler).grantRole(LibTokenLauncherConsts.BUYBACK_CALLER_ROLE, tokenAddress);
// Log new token into store
StoreTokenInput memory storeInput = StoreTokenInput({
tokenAddress: tokenAddress,
owner: input.tokenInfo.owner,
referrer: input.referrer,
paymentIndex: paymentIndex,
tokenType: TokenType.ERC20
});
_addToken(storeInput);
}
function createErc721(CreateErc721Input memory input) external payable override returns (address tokenAddress) {
uint256 paymentIndex = _processPayment(TokenType.ERC721, input.referrer, input.paymentToken);
tokenAddress = _createErc721(input, paymentIndex);
}
function createErc721WithPaymentSignature(
CreateErc721Input memory input,
ICrossPaymentModule.CrossPaymentSignatureInput memory crossPaymentSignatureInput
) external override returns (address tokenAddress) {
_spendCrossPaymentSignature(TokenType.ERC721, crossPaymentSignatureInput);
tokenAddress = _createErc721(input, crossPaymentSignatureInput.paymentIndex);
}
function _createErc721(CreateErc721Input memory input, uint256 paymentIndex) private returns (address tokenAddress) {
// Now let's create a diamond
tokenAddress = _createTokenDiamond();
_prepareTokenFiErc721Diamond(tokenAddress, input.tokenInfo);
// set TokenFiErc721Implementation for etherscan
LibTokenLauncherFactoryStorage.DiamondStorage storage ds = LibTokenLauncherFactoryStorage.diamondStorage();
IDiamondProxy(tokenAddress).setImplementation(ds.tokenFiErc721Implementation);
// add a new payment platform for the mint payment of the created token
IPlatformModule.Service[] memory services = new IPlatformModule.Service[](1);
services[0] = IPlatformModule.Service({ name: "ERC721 Mint", usdPrice: input.publicMintPaymentInfo.usdPrice });
IPlatformModule.Platform memory platform = IPlatformModule.Platform({
name: input.tokenInfo.name,
id: keccak256(abi.encodePacked(tokenAddress)),
owner: input.tokenInfo.owner,
treasury: input.publicMintPaymentInfo.treasury,
referrerBasisPoints: input.publicMintPaymentInfo.referrerBasisPoints,
burnToken: IPlatformModule(address(this)).getPlatformById(LibTokenLauncherConsts.PRODUCT_ID).burnToken,
burnBasisPoints: input.publicMintPaymentInfo.burnBasisPoints,
isDiscountEnabled: false,
services: services
});
IPlatformModule(address(this)).addPlatform(platform);
// set TokenInfo
ITokenFiErc721(tokenAddress).setTokenInfo(input.tokenInfo);
// grant PAYMENT_PROCESSOR_ROLE to the created Token
IAccessControl(address(this)).grantRole(LibPaymentModuleConsts.PAYMENT_PROCESSOR_ROLE, tokenAddress);
// Log new token into store
StoreTokenInput memory storeInput = StoreTokenInput({
tokenAddress: tokenAddress,
owner: input.tokenInfo.owner,
referrer: input.referrer,
paymentIndex: paymentIndex,
tokenType: TokenType.ERC721
});
_addToken(storeInput);
}
function createErc1155(CreateErc1155Input memory input) external payable override returns (address tokenAddress) {
uint256 paymentIndex = _processPayment(TokenType.ERC1155, input.referrer, input.paymentToken);
tokenAddress = _createErc1155(input, paymentIndex);
}
function createErc1155WithPaymentSignature(
CreateErc1155Input memory input,
ICrossPaymentModule.CrossPaymentSignatureInput memory crossPaymentSignatureInput
) external override returns (address tokenAddress) {
_spendCrossPaymentSignature(TokenType.ERC1155, crossPaymentSignatureInput);
tokenAddress = _createErc1155(input, crossPaymentSignatureInput.paymentIndex);
}
function _createErc1155(CreateErc1155Input memory input, uint256 paymentIndex) private returns (address tokenAddress) {
// Now let's create a diamond
tokenAddress = _createTokenDiamond();
_prepareTokenFiErc1155Diamond(tokenAddress, input.tokenInfo);
// set TokenFiErc1155Implementation for etherscan
LibTokenLauncherFactoryStorage.DiamondStorage storage ds = LibTokenLauncherFactoryStorage.diamondStorage();
IDiamondProxy(tokenAddress).setImplementation(ds.tokenFiErc1155Implementation);
// add a new payment platform for the mint payment of the created token
IPlatformModule.Service[] memory services;
IPlatformModule.Platform memory platform = IPlatformModule.Platform({
name: input.tokenInfo.name,
id: keccak256(abi.encodePacked(tokenAddress)),
owner: tokenAddress,
treasury: input.publicMintPaymentInfo.treasury,
referrerBasisPoints: input.publicMintPaymentInfo.referrerBasisPoints,
burnToken: IPlatformModule(address(this)).getPlatformById(LibTokenLauncherConsts.PRODUCT_ID).burnToken,
burnBasisPoints: input.publicMintPaymentInfo.burnBasisPoints,
isDiscountEnabled: false,
services: services
});
IPlatformModule(address(this)).addPlatform(platform);
// grant PAYMENT_PROCESSOR_ROLE to the created Token
IAccessControl(address(this)).grantRole(LibPaymentModuleConsts.PAYMENT_PROCESSOR_ROLE, tokenAddress);
//create initial tokens
for (uint256 i = 0; i < input.initialTokens.length; i++) {
ITokenFiErc1155(tokenAddress).createToken(input.initialTokens[i]);
}
// Log new token into store
StoreTokenInput memory storeInput = StoreTokenInput({
tokenAddress: tokenAddress,
owner: input.tokenInfo.owner,
referrer: input.referrer,
paymentIndex: paymentIndex,
tokenType: TokenType.ERC1155
});
_addToken(storeInput);
}
function _spendCrossPaymentSignature(TokenType tokenType, ICrossPaymentModule.CrossPaymentSignatureInput memory crossPaymentSignatureInput) private {
// Now let's process the payment
uint32[] memory services = new uint32[](1);
services[0] = uint32(tokenType);
uint32[] memory serviceAmounts = new uint32[](1);
serviceAmounts[0] = 1;
ICrossPaymentModule.ProcessCrossPaymentOutput memory processCrossPaymentOutput = ICrossPaymentModule.ProcessCrossPaymentOutput({
platformId: LibTokenLauncherConsts.PRODUCT_ID,
services: services,
serviceAmounts: serviceAmounts,
spender: msg.sender,
destinationChainId: ICrossPaymentModule(address(this)).getChainID(),
payer: crossPaymentSignatureInput.payer,
sourceChainId: crossPaymentSignatureInput.sourceChainId,
paymentIndex: crossPaymentSignatureInput.paymentIndex
});
ICrossPaymentModule(address(this)).spendCrossPaymentSignature(msg.sender, processCrossPaymentOutput, crossPaymentSignatureInput.signature);
}
function _processPayment(TokenType tokenType, address referrer, address paymentToken) private returns (uint256 paymentIndex) {
// Now let's process the payment
uint32[] memory services = new uint32[](1);
services[0] = uint32(tokenType);
uint32[] memory serviceAmounts = new uint32[](1);
serviceAmounts[0] = 1;
IPaymentModule.ProcessPaymentInput memory paymentInput = IPaymentModule.ProcessPaymentInput({
platformId: LibTokenLauncherConsts.PRODUCT_ID,
services: services,
serviceAmounts: serviceAmounts,
referrer: referrer,
user: msg.sender,
tokenAddress: paymentToken
});
paymentIndex = IPaymentModule(address(this)).processPayment{ value: msg.value }(paymentInput);
}
function _createTokenDiamond() private returns (address tokenAddress) {
// Create the new Diamond
LibDiamond.DiamondStorage storage diamondStorage = LibDiamond.diamondStorage();
LibDiamond.FacetAddressAndPosition memory diamondCutFacet = diamondStorage.selectorToFacetAndPosition[IDiamondCut.diamondCut.selector];
tokenAddress = address(new Diamond(address(this), diamondCutFacet.facetAddress));
}
function _prepareCommonFacetCuts() private view returns (IDiamondCut.FacetCut[] memory commonFacetCuts) {
LibTokenLauncherFactoryStorage.DiamondStorage storage ds = LibTokenLauncherFactoryStorage.diamondStorage();
commonFacetCuts = new IDiamondCut.FacetCut[](5);
// Add AccessControlFacet
bytes4[] memory functionSelectors = LibDiamondHelpers.getAccessControlSelectors();
commonFacetCuts[1] = IDiamondCut.FacetCut({
facetAddress: ds.accessControlFacet,
action: IDiamondCut.FacetCutAction.Add,
functionSelectors: functionSelectors
});
// Add PausableFacet
functionSelectors = LibDiamondHelpers.getPausableSelectors();
commonFacetCuts[2] = IDiamondCut.FacetCut({
facetAddress: ds.pausableFacet,
action: IDiamondCut.FacetCutAction.Add,
functionSelectors: functionSelectors
});
// Add DiamondLoupeFacet
functionSelectors = LibDiamondHelpers.getDiamondLoupeSelectors();
commonFacetCuts[3] = IDiamondCut.FacetCut({
facetAddress: ds.loupeFacet,
action: IDiamondCut.FacetCutAction.Add,
functionSelectors: functionSelectors
});
// Add DiamondProxy
functionSelectors = LibDiamondHelpers.getDiamondProxySelectors();
commonFacetCuts[4] = IDiamondCut.FacetCut({
facetAddress: ds.proxyFacet,
action: IDiamondCut.FacetCutAction.Add,
functionSelectors: functionSelectors
});
}
function _prepareTokenFiErc20Diamond(address tokenFiErc20, ITokenFiErc20.TokenInfo memory input) private {
LibTokenLauncherFactoryStorage.DiamondStorage storage ds = LibTokenLauncherFactoryStorage.diamondStorage();
IDiamondCut.FacetCut[] memory cut = _prepareCommonFacetCuts();
// Add TokenFiErc20Facet
bytes4[] memory functionSelectors = LibTokenLauncherFactoryStorage.getTokenFiErc20FunctionSelectors();
cut[0] = IDiamondCut.FacetCut({ facetAddress: ds.tokenFiErc20Facet, action: IDiamondCut.FacetCutAction.Add, functionSelectors: functionSelectors });
// Add Facets to TokenFiErc20 Diamond and initialize it
bytes memory _calldata = abi.encodeCall(ITokenFiErc20Init.init, input);
IDiamondCut(tokenFiErc20).diamondCut(cut, ds.tokenFiErc20DiamondInit, _calldata);
}
function _prepareTokenFiErc721Diamond(address tokenFiErc721, ITokenFiErc721.TokenInfo memory input) private {
LibTokenLauncherFactoryStorage.DiamondStorage storage ds = LibTokenLauncherFactoryStorage.diamondStorage();
IDiamondCut.FacetCut[] memory cut = _prepareCommonFacetCuts();
// Add TokenFiErc721Facet
bytes4[] memory functionSelectors = LibTokenLauncherFactoryStorage.getTokenFiErc721FunctionSelectors();
cut[0] = IDiamondCut.FacetCut({ facetAddress: ds.tokenFiErc721Facet, action: IDiamondCut.FacetCutAction.Add, functionSelectors: functionSelectors });
// Add Facets to TokenFiErc721 Diamond and initialize it
bytes memory _calldata = abi.encodeCall(ITokenFiErc721Init.init, input);
IDiamondCut(tokenFiErc721).diamondCut(cut, ds.tokenFiErc721DiamondInit, _calldata);
}
function _prepareTokenFiErc1155Diamond(address tokenFiErc1155, ITokenFiErc1155.TokenInfo memory input) private {
LibTokenLauncherFactoryStorage.DiamondStorage storage ds = LibTokenLauncherFactoryStorage.diamondStorage();
IDiamondCut.FacetCut[] memory cut = _prepareCommonFacetCuts();
// Add TokenFiErc1155Facet
bytes4[] memory functionSelectors = LibTokenLauncherFactoryStorage.getTokenFiErc1155FunctionSelectors();
cut[0] = IDiamondCut.FacetCut({ facetAddress: ds.tokenFiErc1155Facet, action: IDiamondCut.FacetCutAction.Add, functionSelectors: functionSelectors });
// Add Facets to TokenFiErc1155 Diamond and initialize it
bytes memory _calldata = abi.encodeCall(ITokenFiErc1155Init.init, input);
IDiamondCut(tokenFiErc1155).diamondCut(cut, ds.tokenFiErc1155DiamondInit, _calldata);
}
function _addToken(StoreTokenInput memory input) private {
LibTokenLauncherFactoryStorage.DiamondStorage storage ds = LibTokenLauncherFactoryStorage.diamondStorage();
ds.tokensByOwnerByType[input.tokenType][input.owner].push(input.tokenAddress);
ds.tokenOwnerByToken[input.tokenAddress] = input.owner;
ds.tokensByType[input.tokenType].push(input.tokenAddress);
emit TokenCreated(ds.currentBlockTokenCreated, input);
ds.currentBlockTokenCreated = block.number;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IAccessControl } from './IAccessControl.sol';
import { AccessControlInternal } from './AccessControlInternal.sol';
/**
* @title Role-based access control system
* @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)
*/
abstract contract AccessControl is IAccessControl, AccessControlInternal {
/**
* @inheritdoc IAccessControl
*/
function grantRole(
bytes32 role,
address account
) external onlyRole(_getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @inheritdoc IAccessControl
*/
function hasRole(
bytes32 role,
address account
) external view returns (bool) {
return _hasRole(role, account);
}
/**
* @inheritdoc IAccessControl
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32) {
return _getRoleAdmin(role);
}
/**
* @inheritdoc IAccessControl
*/
function revokeRole(
bytes32 role,
address account
) external onlyRole(_getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @inheritdoc IAccessControl
*/
function renounceRole(bytes32 role) external {
_renounceRole(role);
}
/**
* @inheritdoc IAccessControl
*/
function getRoleMember(
bytes32 role,
uint256 index
) external view returns (address) {
return _getRoleMember(role, index);
}
/**
* @inheritdoc IAccessControl
*/
function getRoleMemberCount(bytes32 role) external view returns (uint256) {
return _getRoleMemberCount(role);
}
}// 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;
import { IAccessControlInternal } from './IAccessControlInternal.sol';
/**
* @title AccessControl interface
*/
interface IAccessControl is IAccessControlInternal {
/*
* @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
) external view returns (bool);
/*
* @notice query admin role for given role
* @param role role to query
* @return admin role
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/*
* @notice assign role to given account
* @param role role to assign
* @param account recipient of role assignment
*/
function grantRole(bytes32 role, address account) external;
/*
* @notice unassign role from given account
* @param role role to unassign
* @parm account
*/
function revokeRole(bytes32 role, address account) external;
/**
* @notice relinquish role
* @param role role to relinquish
*/
function renounceRole(bytes32 role) external;
/**
* @notice Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(
bytes32 role,
uint256 index
) external view returns (address);
/**
* @notice Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) external view returns (uint256);
}// 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;
/**
* @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 { IERC165 } from './IERC165.sol';
import { IERC1155Internal } from './IERC1155Internal.sol';
/**
* @title ERC1155 interface
* @dev see https://eips.ethereum.org/EIPS/eip-1155
*/
interface IERC1155 is IERC1155Internal, IERC165 {
/**
* @notice query the balance of given token held by given address
* @param account address to query
* @param id token to query
* @return token balance
*/
function balanceOf(
address account,
uint256 id
) external view returns (uint256);
/**
* @notice query the balances of given tokens held by given addresses
* @param accounts addresss to query
* @param ids tokens to query
* @return token balances
*/
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
/**
* @notice query approval status of given operator with respect to given address
* @param account address to query for approval granted
* @param operator address to query for approval received
* @return whether operator is approved to spend tokens held by account
*/
function isApprovedForAll(
address account,
address operator
) external view returns (bool);
/**
* @notice grant approval to or revoke approval from given operator to spend held tokens
* @param operator address whose approval status to update
* @param status whether operator should be considered approved
*/
function setApprovalForAll(address operator, bool status) external;
/**
* @notice transfer tokens between given addresses, checking for ERC1155Receiver implementation if applicable
* @param from sender of tokens
* @param to receiver of tokens
* @param id token ID
* @param amount quantity of tokens to transfer
* @param data data payload
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
/**
* @notice transfer batch of tokens between given addresses, checking for ERC1155Receiver implementation if applicable
* @param from sender of tokens
* @param to receiver of tokens
* @param ids list of token IDs
* @param amounts list of quantities of tokens to transfer
* @param data data payload
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title Partial ERC1155 interface needed by internal functions
*/
interface IERC1155Internal {
event TransferSingle(
address indexed operator,
address indexed from,
address indexed to,
uint256 id,
uint256 value
);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(
address indexed account,
address indexed operator,
bool approved
);
}// 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 { IERC20Internal } from './IERC20Internal.sol';
/**
* @title ERC20 interface
* @dev see https://eips.ethereum.org/EIPS/eip-20
*/
interface IERC20 is IERC20Internal {
/**
* @notice query the total minted token supply
* @return token supply
*/
function totalSupply() external view returns (uint256);
/**
* @notice query the token balance of given account
* @param account address to query
* @return token balance
*/
function balanceOf(address account) external view returns (uint256);
/**
* @notice query the allowance granted from given holder to given spender
* @param holder approver of allowance
* @param spender recipient of allowance
* @return token allowance
*/
function allowance(
address holder,
address spender
) external view returns (uint256);
/**
* @notice grant approval to spender to spend tokens
* @dev prefer ERC20Extended functions to avoid transaction-ordering vulnerability (see https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729)
* @param spender recipient of allowance
* @param amount quantity of tokens approved for spending
* @return success status (always true; otherwise function should revert)
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @notice transfer tokens to given recipient
* @param recipient beneficiary of token transfer
* @param amount quantity of tokens to transfer
* @return success status (always true; otherwise function should revert)
*/
function transfer(
address recipient,
uint256 amount
) external returns (bool);
/**
* @notice transfer tokens to given recipient on behalf of given holder
* @param holder holder of tokens prior to transfer
* @param recipient beneficiary of token transfer
* @param amount quantity of tokens to transfer
* @return success status (always true; otherwise function should revert)
*/
function transferFrom(
address holder,
address recipient,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title Partial ERC20 interface needed by internal functions
*/
interface IERC20Internal {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC165 } from './IERC165.sol';
import { IERC721Internal } from './IERC721Internal.sol';
/**
* @title ERC721 interface
* @dev see https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721 is IERC721Internal, IERC165 {
/**
* @notice query the balance of given address
* @return balance quantity of tokens held
*/
function balanceOf(address account) external view returns (uint256 balance);
/**
* @notice query the owner of given token
* @param tokenId token to query
* @return owner token owner
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable
* @param from sender of token
* @param to receiver of token
* @param tokenId token id
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable
* @param from sender of token
* @param to receiver of token
* @param tokenId token id
* @param data data payload
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external payable;
/**
* @notice transfer token between given addresses, without checking for ERC721Receiver implementation if applicable
* @param from sender of token
* @param to receiver of token
* @param tokenId token id
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @notice grant approval to given account to spend token
* @param operator address to be approved
* @param tokenId token to approve
*/
function approve(address operator, uint256 tokenId) external payable;
/**
* @notice get approval status for given token
* @param tokenId token to query
* @return operator address approved to spend token
*/
function getApproved(
uint256 tokenId
) external view returns (address operator);
/**
* @notice grant approval to or revoke approval from given account to spend all tokens held by sender
* @param operator address to be approved
* @param status approval status
*/
function setApprovalForAll(address operator, bool status) external;
/**
* @notice query approval status of given operator with respect to given address
* @param account address to query for approval granted
* @param operator address to query for approval received
* @return status whether operator is approved to spend tokens held by account
*/
function isApprovedForAll(
address account,
address operator
) external view returns (bool status);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title Partial ERC721 interface needed by internal functions
*/
interface IERC721Internal {
event Transfer(
address indexed from,
address indexed to,
uint256 indexed tokenId
);
event Approval(
address indexed owner,
address indexed operator,
uint256 indexed tokenId
);
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IPausableInternal } from './IPausableInternal.sol';
interface IPausable is IPausableInternal {
/**
* @notice query whether contract is paused
* @return status whether contract is paused
*/
function paused() external view returns (bool status);
}// 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 { IPausable } from './IPausable.sol';
import { PausableInternal } from './PausableInternal.sol';
/**
* @title Pausable security control module.
*/
abstract contract Pausable is IPausable, PausableInternal {
/**
* @inheritdoc IPausable
*/
function paused() external view virtual returns (bool status) {
status = _paused();
}
}// 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 { IERC1155Internal } from '../../../interfaces/IERC1155Internal.sol';
/**
* @title ERC1155 base interface
*/
interface IERC1155BaseInternal is IERC1155Internal {
error ERC1155Base__ArrayLengthMismatch();
error ERC1155Base__BalanceQueryZeroAddress();
error ERC1155Base__NotOwnerOrApproved();
error ERC1155Base__SelfApproval();
error ERC1155Base__BurnExceedsBalance();
error ERC1155Base__BurnFromZeroAddress();
error ERC1155Base__ERC1155ReceiverRejected();
error ERC1155Base__ERC1155ReceiverNotImplemented();
error ERC1155Base__MintToZeroAddress();
error ERC1155Base__TransferExceedsBalance();
error ERC1155Base__TransferToZeroAddress();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC1155BaseInternal } from '../base/IERC1155BaseInternal.sol';
/**
* @title ERC1155 enumerable and aggregate function interface
*/
interface IERC1155Enumerable is IERC1155BaseInternal {
/**
* @notice query total minted supply of given token
* @param id token id to query
* @return token supply
*/
function totalSupply(uint256 id) external view returns (uint256);
/**
* @notice query total number of holders for given token
* @param id token id to query
* @return quantity of holders
*/
function totalHolders(uint256 id) external view returns (uint256);
/**
* @notice query holders of given token
* @param id token id to query
* @return list of holder addresses
*/
function accountsByToken(
uint256 id
) external view returns (address[] memory);
/**
* @notice query tokens held by given address
* @param account address to query
* @return list of token ids
*/
function tokensByAccount(
address account
) external view returns (uint256[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC1155MetadataInternal } from './IERC1155MetadataInternal.sol';
/**
* @title ERC1155Metadata interface
*/
interface IERC1155Metadata is IERC1155MetadataInternal {
/**
* @notice get generated URI for given token
* @return token URI
*/
function uri(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title Partial ERC1155Metadata interface needed by internal functions
*/
interface IERC1155MetadataInternal {
event URI(string value, uint256 indexed tokenId);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC20Internal } from '../../../interfaces/IERC20Internal.sol';
/**
* @title ERC20 base interface
*/
interface IERC20BaseInternal is IERC20Internal {
error ERC20Base__ApproveFromZeroAddress();
error ERC20Base__ApproveToZeroAddress();
error ERC20Base__BurnExceedsBalance();
error ERC20Base__BurnFromZeroAddress();
error ERC20Base__InsufficientAllowance();
error ERC20Base__MintToZeroAddress();
error ERC20Base__TransferExceedsBalance();
error ERC20Base__TransferFromZeroAddress();
error ERC20Base__TransferToZeroAddress();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC20ExtendedInternal } from './IERC20ExtendedInternal.sol';
/**
* @title ERC20 extended interface
*/
interface IERC20Extended is IERC20ExtendedInternal {
/**
* @notice increase spend amount granted to spender
* @param spender address whose allowance to increase
* @param amount quantity by which to increase allowance
* @return success status (always true; otherwise function will revert)
*/
function increaseAllowance(
address spender,
uint256 amount
) external returns (bool);
/**
* @notice decrease spend amount granted to spender
* @param spender address whose allowance to decrease
* @param amount quantity by which to decrease allowance
* @return success status (always true; otherwise function will revert)
*/
function decreaseAllowance(
address spender,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC20BaseInternal } from '../base/IERC20BaseInternal.sol';
/**
* @title ERC20 extended internal interface
*/
interface IERC20ExtendedInternal is IERC20BaseInternal {
error ERC20Extended__ExcessiveAllowance();
error ERC20Extended__InsufficientAllowance();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC20MetadataInternal } from './IERC20MetadataInternal.sol';
/**
* @title ERC20 metadata interface
*/
interface IERC20Metadata is IERC20MetadataInternal {
/**
* @notice return token name
* @return token name
*/
function name() external view returns (string memory);
/**
* @notice return token symbol
* @return token symbol
*/
function symbol() external view returns (string memory);
/**
* @notice return token decimals, generally used only for display purposes
* @return token decimals
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title ERC20 metadata internal interface
*/
interface IERC20MetadataInternal {
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC2612Internal } from './IERC2612Internal.sol';
/**
* @title ERC2612 interface
* @dev see https://eips.ethereum.org/EIPS/eip-2612.
*/
interface IERC2612 is IERC2612Internal {
/**
* @notice return the EIP-712 domain separator unique to contract and chain
* @return domainSeparator domain separator
*/
function DOMAIN_SEPARATOR() external view returns (bytes32 domainSeparator);
/**
* @notice get the current ERC2612 nonce for the given address
* @return current nonce
*/
function nonces(address owner) external view returns (uint256);
/**
* @notice approve spender to transfer tokens held by owner via signature
* @dev this function may be vulnerable to approval replay attacks
* @param owner holder of tokens and signer of permit
* @param spender beneficiary of approval
* @param amount quantity of tokens to approve
* @param v secp256k1 'v' value
* @param r secp256k1 'r' value
* @param s secp256k1 's' value
*/
function permit(
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
interface IERC2612Internal {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC721Internal } from '../../../interfaces/IERC721Internal.sol';
/**
* @title ERC721 base interface
*/
interface IERC721BaseInternal is IERC721Internal {
error ERC721Base__NotOwnerOrApproved();
error ERC721Base__SelfApproval();
error ERC721Base__BalanceQueryZeroAddress();
error ERC721Base__ERC721ReceiverNotImplemented();
error ERC721Base__InvalidOwner();
error ERC721Base__MintToZeroAddress();
error ERC721Base__NonExistentToken();
error ERC721Base__NotTokenOwner();
error ERC721Base__TokenAlreadyMinted();
error ERC721Base__TransferToZeroAddress();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
interface IERC721Enumerable {
/**
* @notice get total token supply
* @return total supply
*/
function totalSupply() external view returns (uint256);
/**
* @notice get token of given owner at given internal storage index
* @param owner token holder to query
* @param index position in owner's token list to query
* @return tokenId id of retrieved token
*/
function tokenOfOwnerByIndex(
address owner,
uint256 index
) external view returns (uint256 tokenId);
/**
* @notice get token at given internal storage index
* @param index position in global token list to query
* @return tokenId id of retrieved token
*/
function tokenByIndex(
uint256 index
) external view returns (uint256 tokenId);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC721MetadataInternal } from './IERC721MetadataInternal.sol';
/**
* @title ERC721Metadata interface
*/
interface IERC721Metadata is IERC721MetadataInternal {
/**
* @notice get token name
* @return token name
*/
function name() external view returns (string memory);
/**
* @notice get token symbol
* @return token symbol
*/
function symbol() external view returns (string memory);
/**
* @notice get generated URI for given token
* @return token URI
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC721BaseInternal } from '../base/IERC721BaseInternal.sol';
/**
* @title ERC721Metadata internal interface
*/
interface IERC721MetadataInternal is IERC721BaseInternal {
error ERC721Metadata__NonExistentToken();
}// 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: MIT
pragma solidity 0.8.23;
import { IPaymentModule } from "./IPaymentModule.sol";
interface ICrossPaymentModule {
struct CrossPaymentSignatureInput {
address payer;
uint256 sourceChainId;
uint256 paymentIndex;
bytes signature;
}
struct ProcessCrossPaymentOutput {
bytes32 platformId;
uint32[] services;
uint32[] serviceAmounts;
address spender;
uint256 destinationChainId;
address payer;
uint256 sourceChainId;
uint256 paymentIndex;
}
function updateCrossPaymentSignerAddress(address newSignerAddress) external;
function processCrossPayment(
IPaymentModule.ProcessPaymentInput memory paymentInput,
address spender,
uint256 destinationChainId
) external payable returns (uint256);
function spendCrossPaymentSignature(address spender, ProcessCrossPaymentOutput memory output, bytes memory signature) external;
function getCrossPaymentSignerAddress() external view returns (address);
function getCrossPaymentOutputByIndex(uint256 paymentIndex) external view returns (ProcessCrossPaymentOutput memory);
function prefixedMessage(bytes32 hash) external pure returns (bytes32);
function getHashedMessage(ProcessCrossPaymentOutput memory output) external pure returns (bytes32);
function recoverSigner(bytes32 message, bytes memory signature) external pure returns (address);
function checkSignature(ProcessCrossPaymentOutput memory output, bytes memory signature) external view;
function getChainID() external view returns (uint256);
/** EVENTS */
event CrossPaymentProcessed(uint256 indexed previousBlock, uint256 indexed paymentIndex);
event CrossPaymentSignatureSpent(uint256 indexed previousBlock, uint256 indexed sourceChainId, uint256 indexed paymentIndex);
event CrossPaymentSignerAddressUpdated(address indexed oldSigner, address indexed newSigner);
/** ERRORS */
error ProcessCrossPaymentError(string errorMessage);
error CheckSignatureError(string errorMessage);
error ProcessCrossPaymentSignatureError(string errorMessage);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
interface IPaymentModule {
enum PaymentMethod {
NATIVE,
USD,
ALTCOIN
}
enum PaymentType {
NATIVE,
GIFT,
CROSSCHAIN
}
struct AcceptedToken {
string name;
PaymentMethod tokenType;
address token;
address router;
bool isV2Router;
uint256 slippageTolerance;
}
struct ProcessPaymentInput {
bytes32 platformId;
uint32[] services;
uint32[] serviceAmounts;
address referrer;
address user;
address tokenAddress;
}
struct ProcessPaymentOutput {
ProcessPaymentInput processPaymentInput;
uint256 usdPrice;
uint256 paymentAmount;
uint256 burnedAmount;
uint256 treasuryShare;
uint256 referrerShare;
}
struct ProcessCrossPaymentOutput {
bytes32 platformId;
uint32[] services;
uint32[] serviceAmounts;
address payer;
address spender;
uint256 sourceChainId;
uint256 destinationChainId;
}
// solhint-disable-next-line func-name-mixedcase
function PAYMENT_PROCESSOR_ROLE() external pure returns (bytes32);
function adminWithdraw(address tokenAddress, uint256 amount, address treasury) external;
function setUsdToken(address newUsdToken) external;
function setRouterAddress(address newRouter) external;
function addAcceptedToken(AcceptedToken memory acceptedToken) external;
function removeAcceptedToken(address tokenAddress) external;
function updateAcceptedToken(AcceptedToken memory acceptedToken) external;
function setV3PoolFeeForTokenNative(address token, uint24 poolFee) external;
function getUsdToken() external view returns (address);
function processPayment(ProcessPaymentInput memory params) external payable returns (uint256);
function getPaymentByIndex(uint256 paymentIndex) external view returns (ProcessPaymentOutput memory);
function getQuoteTokenPrice(address token0, address token1) external view returns (uint256 price);
function getV3PoolFeeForTokenWithNative(address token) external view returns (uint24);
function isV2Router() external view returns (bool);
function getRouterAddress() external view returns (address);
function getAcceptedTokenByAddress(address tokenAddress) external view returns (AcceptedToken memory);
function getAcceptedTokens() external view returns (address[] memory);
/** EVENTS */
event TokenBurned(uint256 indexed tokenBurnedLastBlock, address indexed tokenAddress, uint256 amount);
event PaymentProcessed(uint256 indexed previousBlock, uint256 indexed paymentIndex);
event TreasuryAddressUpdated(address indexed oldTreasury, address indexed newTreasury);
/** ERRORS */
error ProcessPaymentError(string errorMessage);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
interface IPlatformModule {
struct Service {
string name;
uint256 usdPrice;
}
struct Platform {
string name;
bytes32 id;
address owner;
address treasury;
uint256 referrerBasisPoints;
address burnToken;
uint256 burnBasisPoints;
bool isDiscountEnabled;
Service[] services;
}
// solhint-disable-next-line func-name-mixedcase
function PLATFORM_MANAGER_ROLE() external pure returns (bytes32);
function getPlatformCount() external view returns (uint256);
function getPlatformIds() external view returns (bytes32[] memory);
function getPlatformIdByIndex(uint256 index) external view returns (bytes32);
function getPlatformById(bytes32 platformId) external view returns (IPlatformModule.Platform memory);
function addPlatform(IPlatformModule.Platform memory platform) external;
function removePlatform(uint256 index) external;
function updatePlatform(IPlatformModule.Platform memory platform) external;
function addPlatformService(bytes32 platformId, IPlatformModule.Service memory service) external;
function removePlatformService(bytes32 platformId, uint256 serviceId) external;
function updatePlatformService(bytes32 platformId, uint256 serviceId, IPlatformModule.Service memory service) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
library LibPaymentModuleConsts {
bytes32 internal constant PAYMENT_PROCESSOR_ROLE = keccak256("PAYMENT_PROCESSOR_ROLE");
bytes32 internal constant PLATFORM_MANAGER_ROLE = keccak256("PLATFORM_MANAGER_ROLE");
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
/******************************************************************************\
* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
*
* Implementation of a diamond.
/******************************************************************************/
import { LibDiamond } from "./libraries/LibDiamond.sol";
import { IDiamondCut } from "./interfaces/IDiamondCut.sol";
contract Diamond {
constructor(address _contractOwner, address _diamondCutFacet) payable {
LibDiamond.setContractOwner(_contractOwner);
// Add the diamondCut external function from the diamondCutFacet
IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);
bytes4[] memory functionSelectors = new bytes4[](1);
functionSelectors[0] = IDiamondCut.diamondCut.selector;
cut[0] = IDiamondCut.FacetCut({ facetAddress: _diamondCutFacet, action: IDiamondCut.FacetCutAction.Add, functionSelectors: functionSelectors });
LibDiamond.diamondCut(cut, address(0), "");
}
// Find facet for function that is called and execute the
// function if a facet is found and return any value.
// solhint-disable-next-line no-complex-fallback
fallback() external payable {
LibDiamond.DiamondStorage storage ds;
bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
// get diamond storage
assembly {
ds.slot := position
}
// get facet from function selector
address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;
require(facet != address(0), "Diamond: Function does not exist");
// Execute external function from facet using delegatecall and return any value.
assembly {
// copy function selector and any arguments
calldatacopy(0, 0, calldatasize())
// execute function call using the facet
let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
// get any return value
returndatacopy(0, 0, returndatasize())
// return any return value or error back to the caller
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
receive() external payable {}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
/******************************************************************************\
* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/
interface IDiamondCut {
enum FacetCutAction {
Add,
Replace,
Remove
}
// Add=0, Replace=1, Remove=2
struct FacetCut {
address facetAddress;
FacetCutAction action;
bytes4[] functionSelectors;
}
/// @notice Add/replace/remove any number of functions and optionally execute
/// a function with delegatecall
/// @param _diamondCut Contains the facet addresses and function selectors
/// @param _init The address of the contract or facet to execute _calldata
/// @param _calldata A function call, including function selector and arguments
/// _calldata is executed with delegatecall on _init
function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
/******************************************************************************\
* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/
// A loupe is a small magnifying glass used to look at diamonds.
// These functions look at diamonds
interface IDiamondLoupe {
/// These functions are expected to be called frequently
/// by tools.
struct Facet {
address facetAddress;
bytes4[] functionSelectors;
}
/// @notice Gets all facet addresses and their four byte function selectors.
/// @return facets_ Facet
function facets() external view returns (Facet[] memory facets_);
/// @notice Gets all the function selectors supported by a specific facet.
/// @param _facet The facet address.
/// @return facetFunctionSelectors_
function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);
/// @notice Get all the facet addresses used by a diamond.
/// @return facetAddresses_
function facetAddresses() external view returns (address[] memory facetAddresses_);
/// @notice Gets the facet that supports the given selector.
/// @dev If facet is not found return address(0).
/// @param _functionSelector The function selector.
/// @return facetAddress_ The facet address.
function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
/******************************************************************************\
* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/
interface IDiamondProxy {
function implementation() external view returns (address);
function setImplementation(address _implementation) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { IPausable } from "@solidstate/contracts/security/pausable/Pausable.sol";
interface IPausableFacet is IPausable {
function pause() external;
function unpause() external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
/******************************************************************************\
* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/
import { IDiamondCut } from "../interfaces/IDiamondCut.sol";
// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.
// The loupe functions are required by the EIP2535 Diamonds standard
error InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);
library LibDiamond {
bytes32 public constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");
struct FacetAddressAndPosition {
address facetAddress;
uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array
}
struct FacetFunctionSelectors {
bytes4[] functionSelectors;
uint256 facetAddressPosition; // position of facetAddress in facetAddresses array
}
struct DiamondStorage {
// maps function selector to the facet address and
// the position of the selector in the facetFunctionSelectors.selectors array
mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
// maps facet addresses to function selectors
mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
// facet addresses
address[] facetAddresses;
// Used to query if a contract implements an interface.
// Used to implement ERC-165.
mapping(bytes4 => bool) supportedInterfaces;
// owner of the contract
address contractOwner;
}
function diamondStorage() internal pure returns (DiamondStorage storage ds) {
bytes32 position = DIAMOND_STORAGE_POSITION;
// solhint-disable-next-line no-inline-assembly
assembly {
ds.slot := position
}
}
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function setContractOwner(address _newOwner) internal {
DiamondStorage storage ds = diamondStorage();
address previousOwner = ds.contractOwner;
ds.contractOwner = _newOwner;
emit OwnershipTransferred(previousOwner, _newOwner);
}
function contractOwner() internal view returns (address contractOwner_) {
contractOwner_ = diamondStorage().contractOwner;
}
function enforceIsContractOwner() internal view {
require(msg.sender == diamondStorage().contractOwner, "LibDiamond: Must be contract owner");
}
event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);
// Internal function version of diamondCut
function diamondCut(IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata) internal {
for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
if (action == IDiamondCut.FacetCutAction.Add) {
addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
} else if (action == IDiamondCut.FacetCutAction.Replace) {
replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
} else if (action == IDiamondCut.FacetCutAction.Remove) {
removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
} else {
revert("LibDiamondCut: Incorrect FacetCutAction");
}
}
emit DiamondCut(_diamondCut, _init, _calldata);
initializeDiamondCut(_init, _calldata);
}
function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
DiamondStorage storage ds = diamondStorage();
require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
// add new facet address if it does not exist
if (selectorPosition == 0) {
addFacet(ds, _facetAddress);
}
for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
bytes4 selector = _functionSelectors[selectorIndex];
address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");
addFunction(ds, selector, selectorPosition, _facetAddress);
selectorPosition++;
}
}
function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
DiamondStorage storage ds = diamondStorage();
require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
// add new facet address if it does not exist
if (selectorPosition == 0) {
addFacet(ds, _facetAddress);
}
for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
bytes4 selector = _functionSelectors[selectorIndex];
address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function");
removeFunction(ds, oldFacetAddress, selector);
addFunction(ds, selector, selectorPosition, _facetAddress);
selectorPosition++;
}
}
function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
DiamondStorage storage ds = diamondStorage();
// if function does not exist then do nothing and return
require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)");
for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
bytes4 selector = _functionSelectors[selectorIndex];
address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
removeFunction(ds, oldFacetAddress, selector);
}
}
function addFacet(DiamondStorage storage ds, address _facetAddress) internal {
enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code");
ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;
ds.facetAddresses.push(_facetAddress);
}
function addFunction(DiamondStorage storage ds, bytes4 _selector, uint96 _selectorPosition, address _facetAddress) internal {
ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;
ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);
ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;
}
function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal {
require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
// an immutable function is a function defined directly in a diamond
require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function");
// replace selector with last selector, then delete last selector
uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;
uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;
// if not the same then replace _selector with lastSelector
if (selectorPosition != lastSelectorPosition) {
bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];
ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;
ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);
}
// delete the last selector
ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();
delete ds.selectorToFacetAndPosition[_selector];
// if no more selectors for facet address then delete the facet address
if (lastSelectorPosition == 0) {
// replace facet address with last facet address and delete last facet address
uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;
uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
if (facetAddressPosition != lastFacetAddressPosition) {
address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];
ds.facetAddresses[facetAddressPosition] = lastFacetAddress;
ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;
}
ds.facetAddresses.pop();
delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
}
}
function initializeDiamondCut(address _init, bytes memory _calldata) internal {
if (_init == address(0)) {
return;
}
enforceHasContractCode(_init, "LibDiamondCut: _init address has no code");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory error) = _init.delegatecall(_calldata);
if (!success) {
if (error.length > 0) {
// bubble up error
/// @solidity memory-safe-assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(error)
revert(add(32, error), returndata_size)
}
} else {
revert InitializationFunctionReverted(_init, _calldata);
}
}
}
function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
uint256 contractSize;
// solhint-disable-next-line no-inline-assembly
assembly {
contractSize := extcodesize(_contract)
}
require(contractSize > 0, _errorMessage);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { IAccessControl } from "@solidstate/contracts/access/access_control/AccessControl.sol";
import { IDiamondLoupe } from "../interfaces/IDiamondLoupe.sol";
import { IDiamondProxy } from "../interfaces/IDiamondProxy.sol";
import { IPausableFacet, IPausable } from "../interfaces/IPausableFacet.sol";
library LibDiamondHelpers {
function getAccessControlSelectors() internal pure returns (bytes4[] memory functionSelectors) {
functionSelectors = new bytes4[](7);
functionSelectors[0] = IAccessControl.hasRole.selector;
functionSelectors[1] = IAccessControl.getRoleAdmin.selector;
functionSelectors[2] = IAccessControl.grantRole.selector;
functionSelectors[3] = IAccessControl.revokeRole.selector;
functionSelectors[4] = IAccessControl.renounceRole.selector;
functionSelectors[5] = IAccessControl.getRoleMember.selector;
functionSelectors[6] = IAccessControl.getRoleMemberCount.selector;
}
function getPausableSelectors() internal pure returns (bytes4[] memory functionSelectors) {
functionSelectors = new bytes4[](3);
functionSelectors[0] = IPausable.paused.selector;
functionSelectors[1] = IPausableFacet.pause.selector;
functionSelectors[2] = IPausableFacet.unpause.selector;
}
function getDiamondLoupeSelectors() internal pure returns (bytes4[] memory functionSelectors) {
functionSelectors = new bytes4[](4);
functionSelectors[0] = IDiamondLoupe.facetFunctionSelectors.selector;
functionSelectors[1] = IDiamondLoupe.facetAddress.selector;
functionSelectors[2] = IDiamondLoupe.facetAddresses.selector;
functionSelectors[3] = IDiamondLoupe.facets.selector;
}
function getDiamondProxySelectors() internal pure returns (bytes4[] memory functionSelectors) {
functionSelectors = new bytes4[](2);
functionSelectors[0] = IDiamondProxy.implementation.selector;
functionSelectors[1] = IDiamondProxy.setImplementation.selector;
}
function getReentrancyGuardSelectors() internal pure returns (bytes4[] memory functionSelectors) {
functionSelectors = new bytes4[](0);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { ICrossPaymentModule } from "../../common/admin/interfaces/ICrossPaymentModule.sol";
interface ITokenFiErc1155 {
struct TokenInfo {
string name;
string symbol;
string collectionLogo;
string baseURI;
bool isPublicMintEnabled;
bool isAdminMintEnabled;
address owner;
}
struct CreateTokenInput {
uint256 tokenId;
uint256 maxSupply;
uint256 publicMintUsdPrice;
uint8 decimals;
string uri;
}
function adminMint(address account, uint256 id, uint256 amount) external;
function setTokenInfo(TokenInfo memory _newTokenInfo) external;
function createToken(CreateTokenInput memory input) external;
function setTokenPublicMintPrice(uint256 _tokenId, uint256 _price) external;
function setTokenUri(uint256 _tokenId, string memory _uri) external;
function mint(address account, uint256 id, uint256 amount, address paymentToken, address referrer) external payable;
function mintWithPaymentSignature(
address account,
uint256 id,
uint256 amount,
ICrossPaymentModule.CrossPaymentSignatureInput memory crossPaymentSignatureInput
) external;
function tokenInfo() external view returns (TokenInfo memory);
function maxSupply(uint256 tokenId) external view returns (uint256);
function decimals(uint256 tokenId) external view returns (uint256);
function paymentServiceIndexByTokenId(uint256 tokenId) external view returns (uint256);
function exists(uint256 id) external view returns (bool);
function getExistingTokenIds() external view returns (uint256[] memory);
function paymentModule() external view returns (address);
event TokenInfoUpdated(TokenInfo indexed oldTokenInfo, TokenInfo indexed newTokenInfo);
event MintPaymentProccessed(address indexed user, uint256 indexed paymentId);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { ITokenFiErc1155 } from "./ITokenFiErc1155.sol";
interface ITokenFiErc1155Init {
function init(ITokenFiErc1155.TokenInfo memory input) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
interface ITokenFiErc20 {
struct FeeDetails {
uint256 percentage;
bool onlyOnSwaps;
}
struct Fees {
FeeDetails transferFee;
FeeDetails burn;
FeeDetails reflection;
FeeDetails buyback;
}
struct BuybackDetails {
address pairToken;
address router;
uint256 liquidityBasisPoints;
uint256 priceImpactBasisPoints;
}
struct TokenInfo {
string name;
string symbol;
string logo;
uint8 decimals;
uint256 initialSupply;
uint256 maxSupply;
address treasury;
address owner;
Fees fees;
BuybackDetails buybackDetails;
}
struct TotalReflection {
uint256 tTotal;
uint256 rTotal;
uint256 tFeeTotal;
}
struct ReflectionInfo {
TotalReflection totalReflection;
mapping(address => uint256) rOwned;
mapping(address => uint256) tOwned;
mapping(address => bool) isExcludedFromReflectionRewards;
address[] excluded;
}
/** ONLY ROLES */
function mint(address to, uint256 amount) external;
function updateTokenLauncher(address _newTokenLauncher) external;
function updateTreasury(address _newTreasury) external;
function setName(string memory name) external;
function setSymbol(string memory symbol) external;
function setDecimals(uint8 decimals) external;
function updateFees(Fees memory _fees) external;
function setBuybackDetails(BuybackDetails memory _buybackDetails) external;
function setBuybackHandler(address _newBuybackHandler) external;
function addExchangePool(address pool) external;
function removeExchangePool(address pool) external;
function addExemptAddress(address account) external;
function removeExemptAddress(address account) external;
/** VIEW */
function fees() external view returns (Fees memory);
function tokenInfo() external view returns (TokenInfo memory);
function buybackHandler() external view returns (address);
function isExchangePool(address pool) external view returns (bool);
function isExemptedFromTax(address account) external view returns (bool);
function isReflectionToken() external view returns (bool);
/** REFLECTION Implemetation */
function reflect(uint256 tAmount) external;
function excludeAccount(address account) external;
function includeAccount(address account) external;
function isExcludedFromReflectionRewards(address account) external view returns (bool);
function totalReflection() external view returns (TotalReflection memory);
function reflectionFromToken(uint256 tAmount, bool deductTransferFee) external view returns (uint256);
function tokenFromReflection(uint256 rAmount) external view returns (uint256);
function totalFees() external view returns (uint256);
event ExemptedAdded(address indexed account);
event ExemptedRemoved(address indexed account);
event ExchangePoolAdded(address indexed pool);
event ExchangePoolRemoved(address indexed pool);
event TokenLauncherUpdated(address indexed oldTokenLauncher, address indexed newTokenLauncher);
event TransferTax(address indexed account, address indexed receiver, uint256 amount, string indexed taxType);
event BuybackHandlerUpdated(address indexed oldBuybackHandler, address indexed newBuybackHandler);
event BuybackDetailsUpdated(address indexed router, address indexed pairToken, uint256 liquidityBasisPoints, uint256 priceImpactBasisPoints);
event TreasuryUpdated(address indexed oldTreasury, address indexed newTreasury);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { ITokenFiErc20 } from "./ITokenFiErc20.sol";
interface ITokenFiErc20Init {
function init(ITokenFiErc20.TokenInfo memory input) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { ICrossPaymentModule } from "../../common/admin/interfaces/ICrossPaymentModule.sol";
interface ITokenFiErc721 {
enum PaymentServices {
TOKEN_MINT
}
struct TokenInfo {
string name;
string symbol;
string collectionLogo;
string baseURI;
uint256 maxSupply;
bool isPublicMintEnabled;
bool isAdminMintEnabled;
address owner;
}
function adminMint(address _to) external;
function adminMintBatch(address _to, uint256 _amount) external;
function setTokenInfo(TokenInfo memory _newTokenInfo) external;
function setTokenUri(uint256 tokenId, string memory uri) external;
function mint(address _to, address paymentToken, address referrer) external payable;
function mintWithPaymentSignature(address _to, ICrossPaymentModule.CrossPaymentSignatureInput memory crossPaymentSignatureInput) external;
function mintBatch(address _to, uint256 _amount, address paymentToken, address referrer) external payable;
function mintBatchWithPaymentSignature(
address _to,
uint256 _amount,
ICrossPaymentModule.CrossPaymentSignatureInput memory crossPaymentSignatureInput
) external;
function tokenInfo() external view returns (TokenInfo memory);
function paymentModule() external view returns (address);
event TokenInfoUpdated(TokenInfo indexed oldTokenInfo, TokenInfo indexed newTokenInfo);
event MintPaymentProccessed(address indexed user, uint256 indexed paymentId);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { ITokenFiErc721 } from "./ITokenFiErc721.sol";
interface ITokenFiErc721Init {
function init(ITokenFiErc721.TokenInfo memory input) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
interface ITokenLauncherCommon {
enum TokenType {
ERC20,
ERC721,
ERC1155
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { ITokenLauncherCommon } from "./ITokenLauncherCommon.sol";
import { ITokenFiErc20 } from "./ITokenFiErc20.sol";
import { ITokenFiErc721 } from "./ITokenFiErc721.sol";
import { ITokenFiErc1155 } from "./ITokenFiErc1155.sol";
import { ICrossPaymentModule } from "../../common/admin/interfaces/ICrossPaymentModule.sol";
interface ITokenLauncherFactory is ITokenLauncherCommon {
struct CreateErc20Input {
ITokenFiErc20.TokenInfo tokenInfo;
address referrer;
address paymentToken;
}
struct PublicErc721MintPaymentInfo {
uint256 usdPrice;
address treasury;
uint256 burnBasisPoints;
uint256 referrerBasisPoints;
}
struct CreateErc721Input {
ITokenFiErc721.TokenInfo tokenInfo;
PublicErc721MintPaymentInfo publicMintPaymentInfo;
address referrer;
address paymentToken;
}
struct PublicErc1155MintPaymentInfo {
address treasury;
uint256 burnBasisPoints;
uint256 referrerBasisPoints;
}
struct CreateErc1155Input {
ITokenFiErc1155.TokenInfo tokenInfo;
PublicErc1155MintPaymentInfo publicMintPaymentInfo;
ITokenFiErc1155.CreateTokenInput[] initialTokens;
address referrer;
address paymentToken;
}
struct StoreTokenInput {
address tokenAddress;
address owner;
address referrer;
uint256 paymentIndex;
TokenType tokenType;
}
function createErc20(CreateErc20Input memory input) external payable returns (address tokenAddress);
function createErc20WithPaymentSignature(
CreateErc20Input memory input,
ICrossPaymentModule.CrossPaymentSignatureInput memory crossPaymentSignatureInput
) external returns (address tokenAddress);
function createErc721(CreateErc721Input memory input) external payable returns (address tokenAddress);
function createErc721WithPaymentSignature(
CreateErc721Input memory input,
ICrossPaymentModule.CrossPaymentSignatureInput memory crossPaymentSignatureInput
) external returns (address tokenAddress);
function createErc1155(CreateErc1155Input memory input) external payable returns (address tokenAddress);
function createErc1155WithPaymentSignature(
CreateErc1155Input memory input,
ICrossPaymentModule.CrossPaymentSignatureInput memory crossPaymentSignatureInput
) external returns (address tokenAddress);
/** EVNETS */
event TokenCreated(uint256 indexed currentBlockTokenCreated, StoreTokenInput input);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
library LibTokenLauncherConsts {
bytes32 internal constant PRODUCT_ID = keccak256("tokenfi.tokenLauncher");
// TOKEN LAUNCHER ROLES
bytes32 internal constant FEE_MANAGER_ROLE = keccak256("FEE_MANAGER_ROLE");
bytes32 public constant BUYBACK_CALLER_ROLE = keccak256("BUYBACK_CALLER_ROLE");
uint256 public constant SLIPPAGE_TOLERANCE = 500;
uint256 public constant REFLECTION_MAX = type(uint256).max / 2;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { ITokenLauncherCommon } from "../interfaces/ITokenLauncherCommon.sol";
// ITokenFiErc20
import { IERC20 } from "@solidstate/contracts/interfaces/IERC20.sol";
import { IERC20Extended } from "@solidstate/contracts/token/ERC20/extended/IERC20Extended.sol";
import { IERC20Metadata } from "@solidstate/contracts/token/ERC20/metadata/IERC20Metadata.sol";
import { IERC2612 } from "@solidstate/contracts/token/ERC20/permit/IERC2612.sol";
import { ITokenFiErc20 } from "../interfaces/ITokenFiErc20.sol";
// ITokenFiErc721
import { IERC721 } from "@solidstate/contracts/interfaces/IERC721.sol";
import { IERC721Enumerable } from "@solidstate/contracts/token/ERC721/enumerable/IERC721Enumerable.sol";
import { IERC721Metadata } from "@solidstate/contracts/token/ERC721/metadata/IERC721Metadata.sol";
import { ITokenFiErc721 } from "../interfaces/ITokenFiErc721.sol";
// ITokenFiErc1155
import { IERC165 } from "@solidstate/contracts/interfaces/IERC165.sol";
import { IERC1155 } from "@solidstate/contracts/interfaces/IERC1155.sol";
import { IERC1155Enumerable } from "@solidstate/contracts/token/ERC1155/enumerable/IERC1155Enumerable.sol";
import { IERC1155Metadata } from "@solidstate/contracts/token/ERC1155/metadata/IERC1155Metadata.sol";
import { ITokenFiErc1155 } from "../interfaces/ITokenFiErc1155.sol";
library LibTokenLauncherFactoryStorage {
bytes32 internal constant DIAMOND_STORAGE_POSITION = keccak256("tokenfi.tokenlauncher.factory.diamond.storage");
struct DiamondStorage {
mapping(ITokenLauncherCommon.TokenType => address[]) tokensByType;
mapping(ITokenLauncherCommon.TokenType => mapping(address => address[])) tokensByOwnerByType;
mapping(address => address) tokenOwnerByToken;
uint256 currentBlockTokenCreated;
uint256 currentBlockTokenOwnerUpdated;
address buybackHandler;
address accessControlFacet;
address pausableFacet;
address loupeFacet;
address proxyFacet;
address tokenFiErc20Facet;
address tokenFiErc20DiamondInit;
address tokenFiErc721Facet;
address tokenFiErc721DiamondInit;
address tokenFiErc1155Facet;
address tokenFiErc1155DiamondInit;
address tokenFiErc20Implementation;
address tokenFiErc721Implementation;
address tokenFiErc1155Implementation;
}
function diamondStorage() internal pure returns (DiamondStorage storage ds) {
bytes32 position = DIAMOND_STORAGE_POSITION;
assembly {
ds.slot := position
}
}
function getTokenFiErc20FunctionSelectors() internal pure returns (bytes4[] memory) {
bytes4[] memory selectors = new bytes4[](41);
/** IERC20 selectors */
selectors[0] = IERC20.totalSupply.selector;
selectors[1] = IERC20.balanceOf.selector;
selectors[2] = IERC20.allowance.selector;
selectors[3] = IERC20.approve.selector;
selectors[4] = IERC20.transfer.selector;
selectors[5] = IERC20.transferFrom.selector;
/** IERC20Extended selectors */
selectors[6] = IERC20Extended.increaseAllowance.selector;
selectors[7] = IERC20Extended.decreaseAllowance.selector;
/** IERC20Metadata selectors */
selectors[8] = IERC20Metadata.name.selector;
selectors[9] = IERC20Metadata.symbol.selector;
selectors[10] = IERC20Metadata.decimals.selector;
/** IERC2612 selectors */
selectors[11] = IERC2612.DOMAIN_SEPARATOR.selector;
selectors[12] = IERC2612.nonces.selector;
selectors[13] = IERC2612.permit.selector;
/** ITokenFiErc20 selectors */
selectors[14] = ITokenFiErc20.mint.selector;
selectors[15] = ITokenFiErc20.updateTokenLauncher.selector;
selectors[16] = ITokenFiErc20.updateTreasury.selector;
selectors[17] = ITokenFiErc20.setName.selector;
selectors[18] = ITokenFiErc20.setSymbol.selector;
selectors[19] = ITokenFiErc20.setDecimals.selector;
selectors[20] = ITokenFiErc20.updateFees.selector;
selectors[21] = ITokenFiErc20.setBuybackDetails.selector;
selectors[22] = ITokenFiErc20.setBuybackHandler.selector;
selectors[23] = ITokenFiErc20.addExchangePool.selector;
selectors[24] = ITokenFiErc20.removeExchangePool.selector;
selectors[25] = ITokenFiErc20.addExemptAddress.selector;
selectors[26] = ITokenFiErc20.removeExemptAddress.selector;
/** VIEW */
selectors[27] = ITokenFiErc20.fees.selector;
selectors[28] = ITokenFiErc20.tokenInfo.selector;
selectors[29] = ITokenFiErc20.buybackHandler.selector;
selectors[30] = ITokenFiErc20.isExchangePool.selector;
selectors[31] = ITokenFiErc20.isExemptedFromTax.selector;
selectors[32] = ITokenFiErc20.isReflectionToken.selector;
// Reflection function selectors
selectors[33] = ITokenFiErc20.reflect.selector;
selectors[34] = ITokenFiErc20.excludeAccount.selector;
selectors[35] = ITokenFiErc20.includeAccount.selector;
selectors[36] = ITokenFiErc20.isExcludedFromReflectionRewards.selector;
selectors[37] = ITokenFiErc20.totalReflection.selector;
selectors[38] = ITokenFiErc20.reflectionFromToken.selector;
selectors[39] = ITokenFiErc20.tokenFromReflection.selector;
selectors[40] = ITokenFiErc20.totalFees.selector;
return selectors;
}
function getTokenFiErc721FunctionSelectors() internal pure returns (bytes4[] memory) {
bytes4[] memory selectors = new bytes4[](24);
// IERC165 selectors
selectors[0] = IERC165.supportsInterface.selector;
// IERC721 function selectors
selectors[1] = IERC721.balanceOf.selector;
selectors[2] = IERC721.ownerOf.selector;
// selectors[8] = IERC721.safeTransferFrom.selector;
selectors[3] = IERC721.transferFrom.selector;
selectors[4] = IERC721.approve.selector;
selectors[5] = IERC721.getApproved.selector;
selectors[6] = IERC721.setApprovalForAll.selector;
selectors[7] = IERC721.isApprovedForAll.selector;
// IERC721Enumerable selectors
selectors[8] = IERC721Enumerable.totalSupply.selector;
selectors[9] = IERC721Enumerable.tokenOfOwnerByIndex.selector;
selectors[10] = IERC721Enumerable.tokenByIndex.selector;
// IERC721Metadata selectors
selectors[11] = IERC721Metadata.name.selector;
selectors[12] = IERC721Metadata.symbol.selector;
selectors[13] = IERC721Metadata.tokenURI.selector;
// ITokenFiErc721 function selectors
selectors[14] = ITokenFiErc721.adminMint.selector;
selectors[15] = ITokenFiErc721.adminMintBatch.selector;
selectors[16] = ITokenFiErc721.setTokenInfo.selector;
selectors[17] = ITokenFiErc721.setTokenUri.selector;
selectors[18] = ITokenFiErc721.mint.selector;
selectors[19] = ITokenFiErc721.mintWithPaymentSignature.selector;
selectors[20] = ITokenFiErc721.mintBatch.selector;
selectors[21] = ITokenFiErc721.mintBatchWithPaymentSignature.selector;
selectors[22] = ITokenFiErc721.tokenInfo.selector;
selectors[23] = ITokenFiErc721.paymentModule.selector;
return selectors;
}
function getTokenFiErc1155FunctionSelectors() internal pure returns (bytes4[] memory) {
bytes4[] memory selectors = new bytes4[](26);
// IERC165 selectors
selectors[0] = IERC165.supportsInterface.selector;
// IERC1155 selectors
selectors[1] = IERC1155.balanceOf.selector;
selectors[2] = IERC1155.balanceOfBatch.selector;
selectors[3] = IERC1155.isApprovedForAll.selector;
selectors[4] = IERC1155.setApprovalForAll.selector;
selectors[5] = IERC1155.safeTransferFrom.selector;
selectors[6] = IERC1155.safeBatchTransferFrom.selector;
// IERC1155Enumerable selectors
selectors[7] = IERC1155Enumerable.totalSupply.selector;
selectors[8] = IERC1155Enumerable.totalHolders.selector;
selectors[9] = IERC1155Enumerable.accountsByToken.selector;
selectors[10] = IERC1155Enumerable.tokensByAccount.selector;
// IERC1155Metadata selectors
selectors[11] = IERC1155Metadata.uri.selector;
// ITokenFiErc1155 selectors
selectors[12] = ITokenFiErc1155.adminMint.selector;
selectors[13] = ITokenFiErc1155.setTokenInfo.selector;
selectors[14] = ITokenFiErc1155.createToken.selector;
selectors[15] = ITokenFiErc1155.setTokenPublicMintPrice.selector;
selectors[16] = ITokenFiErc1155.setTokenUri.selector;
selectors[17] = ITokenFiErc1155.mint.selector;
selectors[18] = ITokenFiErc1155.mintWithPaymentSignature.selector;
selectors[19] = ITokenFiErc1155.tokenInfo.selector;
selectors[20] = ITokenFiErc1155.maxSupply.selector;
selectors[21] = ITokenFiErc1155.decimals.selector;
selectors[22] = ITokenFiErc1155.paymentServiceIndexByTokenId.selector;
selectors[23] = ITokenFiErc1155.exists.selector;
selectors[24] = ITokenFiErc1155.getExistingTokenIds.selector;
selectors[25] = ITokenFiErc1155.paymentModule.selector;
return selectors;
}
}{
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "none",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 10
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"currentBlockTokenCreated","type":"uint256"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"paymentIndex","type":"uint256"},{"internalType":"enum ITokenLauncherCommon.TokenType","name":"tokenType","type":"uint8"}],"indexed":false,"internalType":"struct ITokenLauncherFactory.StoreTokenInput","name":"input","type":"tuple"}],"name":"TokenCreated","type":"event"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"collectionLogo","type":"string"},{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"bool","name":"isPublicMintEnabled","type":"bool"},{"internalType":"bool","name":"isAdminMintEnabled","type":"bool"},{"internalType":"address","name":"owner","type":"address"}],"internalType":"struct ITokenFiErc1155.TokenInfo","name":"tokenInfo","type":"tuple"},{"components":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"uint256","name":"burnBasisPoints","type":"uint256"},{"internalType":"uint256","name":"referrerBasisPoints","type":"uint256"}],"internalType":"struct ITokenLauncherFactory.PublicErc1155MintPaymentInfo","name":"publicMintPaymentInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"publicMintUsdPrice","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"string","name":"uri","type":"string"}],"internalType":"struct ITokenFiErc1155.CreateTokenInput[]","name":"initialTokens","type":"tuple[]"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"paymentToken","type":"address"}],"internalType":"struct ITokenLauncherFactory.CreateErc1155Input","name":"input","type":"tuple"}],"name":"createErc1155","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"collectionLogo","type":"string"},{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"bool","name":"isPublicMintEnabled","type":"bool"},{"internalType":"bool","name":"isAdminMintEnabled","type":"bool"},{"internalType":"address","name":"owner","type":"address"}],"internalType":"struct ITokenFiErc1155.TokenInfo","name":"tokenInfo","type":"tuple"},{"components":[{"internalType":"address","name":"treasury","type":"address"},{"internalType":"uint256","name":"burnBasisPoints","type":"uint256"},{"internalType":"uint256","name":"referrerBasisPoints","type":"uint256"}],"internalType":"struct ITokenLauncherFactory.PublicErc1155MintPaymentInfo","name":"publicMintPaymentInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"publicMintUsdPrice","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"string","name":"uri","type":"string"}],"internalType":"struct ITokenFiErc1155.CreateTokenInput[]","name":"initialTokens","type":"tuple[]"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"paymentToken","type":"address"}],"internalType":"struct ITokenLauncherFactory.CreateErc1155Input","name":"input","type":"tuple"},{"components":[{"internalType":"address","name":"payer","type":"address"},{"internalType":"uint256","name":"sourceChainId","type":"uint256"},{"internalType":"uint256","name":"paymentIndex","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct ICrossPaymentModule.CrossPaymentSignatureInput","name":"crossPaymentSignatureInput","type":"tuple"}],"name":"createErc1155WithPaymentSignature","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"components":[{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenFiErc20.FeeDetails","name":"transferFee","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenFiErc20.FeeDetails","name":"burn","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenFiErc20.FeeDetails","name":"reflection","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenFiErc20.FeeDetails","name":"buyback","type":"tuple"}],"internalType":"struct ITokenFiErc20.Fees","name":"fees","type":"tuple"},{"components":[{"internalType":"address","name":"pairToken","type":"address"},{"internalType":"address","name":"router","type":"address"},{"internalType":"uint256","name":"liquidityBasisPoints","type":"uint256"},{"internalType":"uint256","name":"priceImpactBasisPoints","type":"uint256"}],"internalType":"struct ITokenFiErc20.BuybackDetails","name":"buybackDetails","type":"tuple"}],"internalType":"struct ITokenFiErc20.TokenInfo","name":"tokenInfo","type":"tuple"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"paymentToken","type":"address"}],"internalType":"struct ITokenLauncherFactory.CreateErc20Input","name":"input","type":"tuple"}],"name":"createErc20","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"components":[{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenFiErc20.FeeDetails","name":"transferFee","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenFiErc20.FeeDetails","name":"burn","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenFiErc20.FeeDetails","name":"reflection","type":"tuple"},{"components":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"bool","name":"onlyOnSwaps","type":"bool"}],"internalType":"struct ITokenFiErc20.FeeDetails","name":"buyback","type":"tuple"}],"internalType":"struct ITokenFiErc20.Fees","name":"fees","type":"tuple"},{"components":[{"internalType":"address","name":"pairToken","type":"address"},{"internalType":"address","name":"router","type":"address"},{"internalType":"uint256","name":"liquidityBasisPoints","type":"uint256"},{"internalType":"uint256","name":"priceImpactBasisPoints","type":"uint256"}],"internalType":"struct ITokenFiErc20.BuybackDetails","name":"buybackDetails","type":"tuple"}],"internalType":"struct ITokenFiErc20.TokenInfo","name":"tokenInfo","type":"tuple"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"paymentToken","type":"address"}],"internalType":"struct ITokenLauncherFactory.CreateErc20Input","name":"input","type":"tuple"},{"components":[{"internalType":"address","name":"payer","type":"address"},{"internalType":"uint256","name":"sourceChainId","type":"uint256"},{"internalType":"uint256","name":"paymentIndex","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct ICrossPaymentModule.CrossPaymentSignatureInput","name":"crossPaymentSignatureInput","type":"tuple"}],"name":"createErc20WithPaymentSignature","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"collectionLogo","type":"string"},{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"bool","name":"isPublicMintEnabled","type":"bool"},{"internalType":"bool","name":"isAdminMintEnabled","type":"bool"},{"internalType":"address","name":"owner","type":"address"}],"internalType":"struct ITokenFiErc721.TokenInfo","name":"tokenInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"usdPrice","type":"uint256"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"uint256","name":"burnBasisPoints","type":"uint256"},{"internalType":"uint256","name":"referrerBasisPoints","type":"uint256"}],"internalType":"struct ITokenLauncherFactory.PublicErc721MintPaymentInfo","name":"publicMintPaymentInfo","type":"tuple"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"paymentToken","type":"address"}],"internalType":"struct ITokenLauncherFactory.CreateErc721Input","name":"input","type":"tuple"}],"name":"createErc721","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"collectionLogo","type":"string"},{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"bool","name":"isPublicMintEnabled","type":"bool"},{"internalType":"bool","name":"isAdminMintEnabled","type":"bool"},{"internalType":"address","name":"owner","type":"address"}],"internalType":"struct ITokenFiErc721.TokenInfo","name":"tokenInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"usdPrice","type":"uint256"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"uint256","name":"burnBasisPoints","type":"uint256"},{"internalType":"uint256","name":"referrerBasisPoints","type":"uint256"}],"internalType":"struct ITokenLauncherFactory.PublicErc721MintPaymentInfo","name":"publicMintPaymentInfo","type":"tuple"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"paymentToken","type":"address"}],"internalType":"struct ITokenLauncherFactory.CreateErc721Input","name":"input","type":"tuple"},{"components":[{"internalType":"address","name":"payer","type":"address"},{"internalType":"uint256","name":"sourceChainId","type":"uint256"},{"internalType":"uint256","name":"paymentIndex","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct ICrossPaymentModule.CrossPaymentSignatureInput","name":"crossPaymentSignatureInput","type":"tuple"}],"name":"createErc721WithPaymentSignature","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b506159f2806100206000396000f3fe6080604052600436106200005c5760003560e01c80636791a805146200006157806394ed410e14620000905780639f65bd5314620000b5578063b205911314620000da578063cb4a55d914620000f1578063ded782941462000116575b600080fd5b620000786200007236600462003657565b6200012d565b604051620000879190620036a4565b60405180910390f35b3480156200009d57600080fd5b5062000078620000af366004620038e0565b6200015b565b348015620000c257600080fd5b5062000078620000d43660046200394a565b6200017a565b62000078620000eb36600462003c88565b62000199565b348015620000fe57600080fd5b50620000786200011036600462003cc0565b620001c0565b620000786200012736600462003cfa565b620001df565b6000806200014660008460200151856040015162000206565b905062000154838262000377565b9392505050565b60006200016a60018362000804565b62000154838360400151620009fd565b60006200018960008362000804565b6200015483836040015162000377565b600080620001b260028460600151856080015162000206565b905062000154838262000e0b565b6000620001cf60028362000804565b6200015483836040015162000e0b565b600080620001f860018460400151856060015162000206565b9050620001548382620009fd565b6040805160018082528183019092526000918291906020808301908036833701905050905084600281111562000240576200024062003d32565b8160008151811062000256576200025662003d48565b63ffffffff9290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050509050600181600081518110620002a857620002a862003d48565b63ffffffff9092166020928302919091018201526040805160c081018252600080516020620059a683398151915281529182018490528181018390526001600160a01b038088166060840152336080840152861660a083015251635d048b2560e11b8152309063ba09164a9034906200032690859060040162003da2565b60206040518083038185885af115801562000345573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906200036c919062003e24565b979650505050505050565b6000806200038462001187565b905062000390620011ab565b9150620003a28285600001516200127b565b6010810154604051636bc26a1360e11b81526001600160a01b038481169263d784d42692620003d89290911690600401620036a4565b600060405180830381600087803b158015620003f357600080fd5b505af115801562000408573d6000803e3d6000fd5b505085515160405163c47f002760e01b81528593506001600160a01b038416925063c47f0027916200043d9160040162003e92565b600060405180830381600087803b1580156200045857600080fd5b505af11580156200046d573d6000803e3d6000fd5b5050865160200151604051635c26412360e11b81526001600160a01b038516935063b84c82469250620004a4919060040162003e92565b600060405180830381600087803b158015620004bf57600080fd5b505af1158015620004d4573d6000803e3d6000fd5b5050865160600151604051633d09cad560e11b815260ff90911660048201526001600160a01b0384169250637a1395aa9150602401600060405180830381600087803b1580156200052457600080fd5b505af115801562000539573d6000803e3d6000fd5b5050865160800151159150620005cc905057845160c08101516080909101516040516340c10f1960e01b81526001600160a01b038416926340c10f199262000597926004016001600160a01b03929092168252602082015260400190565b600060405180830381600087803b158015620005b257600080fd5b505af1158015620005c7573d6000803e3d6000fd5b505050505b604051636078c0f960e01b81526001600160a01b03821690636078c0f990620005fa903090600401620036a4565b600060405180830381600087803b1580156200061557600080fd5b505af11580156200062a573d6000803e3d6000fd5b5050506005830154604051636078c0f960e01b81526001600160a01b038085169350636078c0f9926200066392911690600401620036a4565b600060405180830381600087803b1580156200067e57600080fd5b505af115801562000693573d6000803e3d6000fd5b505050600583015460405163019cc55360e51b81526001600160a01b038085169350633398aa6092620006cc92911690600401620036a4565b600060405180830381600087803b158015620006e757600080fd5b505af1158015620006fc573d6000803e3d6000fd5b5050506005830154604051632f2ff15d60e01b81526001600160a01b039091169150632f2ff15d9062000756907f0e512f22a4a66880dbe62f43c3840e18a3b81e1a4c1c40bba7dc19b0503e51a990879060040162003ea7565b600060405180830381600087803b1580156200077157600080fd5b505af115801562000786573d6000803e3d6000fd5b5050505060006040518060a00160405280856001600160a01b03168152602001876000015160e001516001600160a01b0316815260200187602001516001600160a01b0316815260200186815260200160006002811115620007ec57620007ec62003d32565b90529050620007fb81620013a7565b50505092915050565b604080516001808252818301909252600091602080830190803683370190505090508260028111156200083b576200083b62003d32565b8160008151811062000851576200085162003d48565b63ffffffff9290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050509050600181600081518110620008a357620008a362003d48565b602002602001019063ffffffff16908163ffffffff16815250506000604051806101000160405280600080516020620059a68339815191528152602001848152602001838152602001336001600160a01b03168152602001306001600160a01b031663564b81ef6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200093a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000960919062003e24565b815260200185600001516001600160a01b031681526020018560200151815260200185604001518152509050306001600160a01b031663b459f7ca338387606001516040518463ffffffff1660e01b8152600401620009c29392919062003ebe565b600060405180830381600087803b158015620009dd57600080fd5b505af1158015620009f2573d6000803e3d6000fd5b505050505050505050565b600062000a09620011ab565b905062000a1b81846000015162001518565b600062000a2762001187565b6011810154604051636bc26a1360e11b81529192506001600160a01b038085169263d784d4269262000a5e921690600401620036a4565b600060405180830381600087803b15801562000a7957600080fd5b505af115801562000a8e573d6000803e3d6000fd5b50600092506001915062000a9f9050565b60405190808252806020026020018201604052801562000ae757816020015b60408051808201909152606081526000602082015281526020019060019003908162000abe5790505b5060408051608081018252600b9181019182526a115490cdcc8c48135a5b9d60aa1b60608201529081526020878101515190820152815191925090829060009062000b365762000b3662003d48565b6020026020010181905250600060405180610120016040528087600001516000015181526020018560405160200162000b70919062003f70565b60408051601f1981840301815291815281516020928301208352895160e001516001600160a01b03908116848401528a83018051909301511683820152905160609081015190830152516323cb241360e11b8152600080516020620059a683398151915260048201526080909101903090634796482690602401600060405180830381865afa15801562000c08573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000c329190810190620040ba565b60a001516001600160a01b031681526020018760200151604001518152602001600015158152602001838152509050306001600160a01b031663f5616c1f826040518263ffffffff1660e01b815260040162000c8f919062004236565b600060405180830381600087803b15801562000caa57600080fd5b505af115801562000cbf573d6000803e3d6000fd5b50508751604051636fe49ad960e01b81526001600160a01b0388169350636fe49ad9925062000cf29190600401620042f2565b600060405180830381600087803b15801562000d0d57600080fd5b505af115801562000d22573d6000803e3d6000fd5b5050604051632f2ff15d60e01b8152309250632f2ff15d915062000d5c90600080516020620059c683398151915290889060040162003ea7565b600060405180830381600087803b15801562000d7757600080fd5b505af115801562000d8c573d6000803e3d6000fd5b5050505060006040518060a00160405280866001600160a01b03168152602001886000015160e001516001600160a01b0316815260200188604001516001600160a01b031681526020018781526020016001600281111562000df25762000df262003d32565b9052905062000e0181620013a7565b5050505092915050565b600062000e17620011ab565b905062000e2981846000015162001608565b600062000e3562001187565b6012810154604051636bc26a1360e11b81529192506001600160a01b038085169263d784d4269262000e6c921690600401620036a4565b600060405180830381600087803b15801562000e8757600080fd5b505af115801562000e9c573d6000803e3d6000fd5b505050506060600060405180610120016040528087600001516000015181526020018560405160200162000ed1919062003f70565b60408051808303601f19018152918152815160209283012083526001600160a01b0388811684840152918a018051519092168382015290518101516060830152516323cb241360e11b8152600080516020620059a683398151915260048201526080909101903090634796482690602401600060405180830381865afa15801562000f60573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000f8a9190810190620040ba565b60a001516001600160a01b031681526020018760200151602001518152602001600015158152602001838152509050306001600160a01b031663f5616c1f826040518263ffffffff1660e01b815260040162000fe7919062004236565b600060405180830381600087803b1580156200100257600080fd5b505af115801562001017573d6000803e3d6000fd5b5050604051632f2ff15d60e01b8152309250632f2ff15d91506200105190600080516020620059c683398151915290889060040162003ea7565b600060405180830381600087803b1580156200106c57600080fd5b505af115801562001081573d6000803e3d6000fd5b5050505060005b8660400151518110156200112557846001600160a01b03166307e10c0d88604001518381518110620010be57620010be62003d48565b60200260200101516040518263ffffffff1660e01b8152600401620010e49190620043bf565b600060405180830381600087803b158015620010ff57600080fd5b505af115801562001114573d6000803e3d6000fd5b505060019092019150620010889050565b5060006040518060a00160405280866001600160a01b03168152602001886000015160c001516001600160a01b0316815260200188606001516001600160a01b0316815260200187815260200160028081111562000df25762000df262003d32565b7fae91e73249036d298733b3485b49b39bcb9229df52016e2810a03f18355028f690565b6307e4c70760e21b60009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c60208181526040805180820182527f9f0ce991cd9c4f6eaf19f214129f7a5c88ce0f46a01a0f164d4f0d44366a92a8546001600160a01b038116808352600160a01b9091046001600160601b0316938201939093529051909130916200123f9062003168565b6001600160a01b03928316815291166020820152604001604051809103906000f08015801562001273573d6000803e3d6000fd5b509250505090565b60006200128762001187565b9050600062001295620016f8565b90506000620012a3620018b7565b6040805160608101909152600a8501546001600160a01b0316815290915060208101600081526020018281525082600081518110620012e657620012e662003d48565b602002602001018190525060008460405160240162001306919062004468565b60408051601f198184030181529181526020820180516001600160e01b0316634e06b2e160e11b179052600b86015490516307e4c70760e21b81529192506001600160a01b0380891692631f931c1c926200136b928892911690869060040162004598565b600060405180830381600087803b1580156200138657600080fd5b505af11580156200139b573d6000803e3d6000fd5b50505050505050505050565b6000620013b362001187565b905080600101600083608001516002811115620013d457620013d462003d32565b6002811115620013e857620013e862003d32565b81526020808201929092526040908101600090812085840180516001600160a01b0390811684529185528383208751815460018101835591855286852090910180549184166001600160a01b0319928316179055905187518316845260028088019096529383208054949092169316929092179091556080840151839281111562001477576200147762003d32565b60028111156200148b576200148b62003d32565b81526020808201929092526040908101600090812085518154600181018355918352939091200180546001600160a01b0319166001600160a01b0390931692909217909155600382015490517f5bb644ee2a83060962b095d7d1eb91687997dbc60b60ea2a63eba7cd42c16fb6906200150690859062004690565b60405180910390a24360039091015550565b60006200152462001187565b9050600062001532620016f8565b905060006200154062002227565b6040805160608101909152600c8501546001600160a01b031681529091506020810160008152602001828152508260008151811062001583576200158362003d48565b6020026020010181905250600084604051602401620015a39190620042f2565b60408051601f198184030181529181526020820180516001600160e01b03166345d4de7b60e01b179052600d86015490516307e4c70760e21b81529192506001600160a01b0380891692631f931c1c926200136b928892911690869060040162004598565b60006200161462001187565b9050600062001622620016f8565b9050600062001630620027a4565b6040805160608101909152600e8501546001600160a01b031681529091506020810160008152602001828152508260008151811062001673576200167362003d48565b6020026020010181905250600084604051602401620016939190620046e4565b60408051601f198184030181529181526020820180516001600160e01b031663c952bb1960e01b179052600f86015490516307e4c70760e21b81529192506001600160a01b0380891692631f931c1c926200136b928892911690869060040162004598565b606060006200170662001187565b60408051600580825260c08201909252919250816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200171e57905050915060006200175c62002d93565b604080516060810190915260068401546001600160a01b03168152909150602081016000815260200182815250836001815181106200179f576200179f62003d48565b6020026020010181905250620017b462002f4d565b604080516060810190915260078401546001600160a01b0316815290915060208101600081526020018281525083600281518110620017f757620017f762003d48565b60200260200101819052506200180c62003001565b604080516060810190915260088401546001600160a01b03168152909150602081016000815260200182815250836003815181106200184f576200184f62003d48565b602002602001018190525062001864620030f0565b604080516060810190915260098401546001600160a01b0316815290915060208101600081526020018281525083600481518110620018a757620018a762003d48565b6020026020010181905250505090565b60408051602980825261054082019092526060916000919060208201610520803683370190505090506318160ddd60e01b81600081518110620018fe57620018fe62003d48565b6001600160e01b03199092166020928302919091019091015280516370a0823160e01b908290600190811062001938576200193862003d48565b6001600160e01b0319909216602092830291909101909101528051636eb1769f60e11b908290600290811062001972576200197262003d48565b6001600160e01b031990921660209283029190910190910152805163095ea7b360e01b9082906003908110620019ac57620019ac62003d48565b6001600160e01b031990921660209283029190910190910152805163a9059cbb60e01b9082906004908110620019e657620019e662003d48565b6001600160e01b03199092166020928302919091019091015280516323b872dd60e01b908290600590811062001a205762001a2062003d48565b6001600160e01b0319909216602092830291909101909101528051633950935160e01b908290600690811062001a5a5762001a5a62003d48565b6001600160e01b031990921660209283029190910190910152805163a457c2d760e01b908290600790811062001a945762001a9462003d48565b6001600160e01b03199092166020928302919091019091015280516306fdde0360e01b908290600890811062001ace5762001ace62003d48565b6001600160e01b03199092166020928302919091019091015280516395d89b4160e01b908290600990811062001b085762001b0862003d48565b6001600160e01b031990921660209283029190910190910152805163313ce56760e01b908290600a90811062001b425762001b4262003d48565b6001600160e01b0319909216602092830291909101909101528051633644e51560e01b908290600b90811062001b7c5762001b7c62003d48565b6001600160e01b0319909216602092830291909101909101528051623f675f60e91b908290600c90811062001bb55762001bb562003d48565b6001600160e01b031990921660209283029190910190910152805163d505accf60e01b908290600d90811062001bef5762001bef62003d48565b6001600160e01b03199092166020928302919091019091015280516340c10f1960e01b908290600e90811062001c295762001c2962003d48565b6001600160e01b0319909216602092830291909101909101528051631780542160e31b908290600f90811062001c635762001c6362003d48565b6001600160e01b0319909216602092830291909101909101528051637f51bb1f60e01b908290601090811062001c9d5762001c9d62003d48565b6001600160e01b031990921660209283029190910190910152805163c47f002760e01b908290601190811062001cd75762001cd762003d48565b6001600160e01b0319909216602092830291909101909101528051635c26412360e11b908290601290811062001d115762001d1162003d48565b6001600160e01b0319909216602092830291909101909101528051633d09cad560e11b908290601390811062001d4b5762001d4b62003d48565b6001600160e01b0319909216602092830291909101909101528051633cae3f5f60e11b908290601490811062001d855762001d8562003d48565b6001600160e01b0319909216602092830291909101909101528051633aa1d1d560e11b908290601590811062001dbf5762001dbf62003d48565b6001600160e01b031990921660209283029190910190910152805163019cc55360e51b908290601690811062001df95762001df962003d48565b6001600160e01b03199092166020928302919091019091015280516316c0896d60e31b908290601790811062001e335762001e3362003d48565b6001600160e01b031990921660209283029190910190910152805163612881a360e11b908290601890811062001e6d5762001e6d62003d48565b6001600160e01b0319909216602092830291909101909101528051636078c0f960e01b908290601990811062001ea75762001ea762003d48565b6001600160e01b0319909216602092830291909101909101528051631ec70d6760e21b908290601a90811062001ee15762001ee162003d48565b6001600160e01b0319909216602092830291909101909101528051634d78e9ad60e11b908290601b90811062001f1b5762001f1b62003d48565b6001600160e01b0319909216602092830291909101909101528051636addb66360e01b908290601c90811062001f555762001f5562003d48565b6001600160e01b03199092166020928302919091019091015280516311c565df60e01b908290601d90811062001f8f5762001f8f62003d48565b6001600160e01b03199092166020928302919091019091015280516318f60b6960e01b908290601e90811062001fc95762001fc962003d48565b6001600160e01b03199092166020928302919091019091015280516311557f7960e11b908290601f90811062002003576200200362003d48565b6001600160e01b0319909216602092830291909101820152815163997d0feb60e01b918391811062002039576200203962003d48565b6001600160e01b031990921660209283029190910190910152805163029d58c160e11b908290602190811062002073576200207362003d48565b6001600160e01b0319909216602092830291909101909101528051631e59818360e31b9082906022908110620020ad57620020ad62003d48565b6001600160e01b031990921660209283029190910190910152805163f84354f160e01b9082906023908110620020e757620020e762003d48565b6001600160e01b031990921660209283029190910190910152805163045a6e8360e51b908290602490811062002121576200212162003d48565b6001600160e01b031990921660209283029190910190910152805163011424b960e51b90829060259081106200215b576200215b62003d48565b6001600160e01b0319909216602092830291909101909101528051634549b03960e01b908290602690811062002195576200219562003d48565b6001600160e01b0319909216602092830291909101909101528051632d83811960e01b9082906027908110620021cf57620021cf62003d48565b6001600160e01b03199092166020928302919091019091015280516313114a9d60e01b908290602890811062002209576200220962003d48565b6001600160e01b031990921660209283029190910190910152919050565b60408051601880825261032082019092526060916000919060208201610300803683370190505090506301ffc9a760e01b816000815181106200226e576200226e62003d48565b6001600160e01b03199092166020928302919091019091015280516370a0823160e01b9082906001908110620022a857620022a862003d48565b6001600160e01b03199092166020928302919091019091015280516331a9108f60e11b9082906002908110620022e257620022e262003d48565b6001600160e01b03199092166020928302919091019091015280516323b872dd60e01b90829060039081106200231c576200231c62003d48565b6001600160e01b031990921660209283029190910190910152805163095ea7b360e01b908290600490811062002356576200235662003d48565b6001600160e01b031990921660209283029190910190910152805163020604bf60e21b908290600590811062002390576200239062003d48565b6001600160e01b031990921660209283029190910190910152805163a22cb46560e01b9082906006908110620023ca57620023ca62003d48565b6001600160e01b031990921660209283029190910190910152805163e985e9c560e01b908290600790811062002404576200240462003d48565b6001600160e01b03199092166020928302919091019091015280516318160ddd60e01b90829060089081106200243e576200243e62003d48565b6001600160e01b0319909216602092830291909101909101528051632f745c5960e01b908290600990811062002478576200247862003d48565b6001600160e01b0319909216602092830291909101909101528051634f6ccce760e01b908290600a908110620024b257620024b262003d48565b6001600160e01b03199092166020928302919091019091015280516306fdde0360e01b908290600b908110620024ec57620024ec62003d48565b6001600160e01b03199092166020928302919091019091015280516395d89b4160e01b908290600c90811062002526576200252662003d48565b6001600160e01b031990921660209283029190910190910152805163c87b56dd60e01b908290600d90811062002560576200256062003d48565b6001600160e01b0319909216602092830291909101909101528051634bb4ee0760e11b908290600e9081106200259a576200259a62003d48565b6001600160e01b0319909216602092830291909101909101528051637600c26f60e11b908290600f908110620025d457620025d462003d48565b6001600160e01b0319909216602092830291909101909101528051636fe49ad960e01b90829060109081106200260e576200260e62003d48565b6001600160e01b0319909216602092830291909101909101528051632bfbbc4f60e11b908290601190811062002648576200264862003d48565b6001600160e01b031990921660209283029190910190910152805163318c2e2160e11b908290601290811062002682576200268262003d48565b6001600160e01b031990921660209283029190910190910152805163b7b1140160e01b9082906013908110620026bc57620026bc62003d48565b6001600160e01b031990921660209283029190910190910152805163a09b654560e01b9082906014908110620026f657620026f662003d48565b6001600160e01b03199092166020928302919091019091015280516337ef227760e11b908290601590811062002730576200273062003d48565b6001600160e01b0319909216602092830291909101909101528051636addb66360e01b90829060169081106200276a576200276a62003d48565b6001600160e01b0319909216602092830291909101909101528051631850e64b60e11b908290601790811062002209576200220962003d48565b60408051601a80825261036082019092526060916000919060208201610340803683370190505090506301ffc9a760e01b81600081518110620027eb57620027eb62003d48565b6001600160e01b0319909216602092830291909101909101528051627eeac760e11b908290600190811062002824576200282462003d48565b6001600160e01b03199092166020928302919091019091015280516313849cfd60e21b90829060029081106200285e576200285e62003d48565b6001600160e01b031990921660209283029190910190910152805163e985e9c560e01b908290600390811062002898576200289862003d48565b6001600160e01b031990921660209283029190910190910152805163a22cb46560e01b9082906004908110620028d257620028d262003d48565b6001600160e01b0319909216602092830291909101909101528051637921219560e11b90829060059081106200290c576200290c62003d48565b6001600160e01b0319909216602092830291909101909101528051631759616b60e11b908290600690811062002946576200294662003d48565b6001600160e01b031990921660209283029190910190910152805163bd85b03960e01b908290600790811062002980576200298062003d48565b6001600160e01b03199092166020928302919091019091015280516313ba55df60e01b9082906008908110620029ba57620029ba62003d48565b6001600160e01b0319909216602092830291909101909101528051636dcfd84160e01b9082906009908110620029f457620029f462003d48565b6001600160e01b03199092166020928302919091019091015280516385bff2e760e01b908290600a90811062002a2e5762002a2e62003d48565b6001600160e01b03199092166020928302919091019091015280516303a24d0760e21b908290600b90811062002a685762002a6862003d48565b6001600160e01b0319909216602092830291909101909101528051624a84cb60e01b908290600c90811062002aa15762002aa162003d48565b6001600160e01b0319909216602092830291909101909101528051636d487de160e01b908290600d90811062002adb5762002adb62003d48565b6001600160e01b03199092166020928302919091019091015280516307e10c0d60e01b908290600e90811062002b155762002b1562003d48565b6001600160e01b031990921660209283029190910190910152805163eeecf93f60e01b908290600f90811062002b4f5762002b4f62003d48565b6001600160e01b0319909216602092830291909101909101528051632bfbbc4f60e11b908290601090811062002b895762002b8962003d48565b6001600160e01b0319909216602092830291909101909101528051630582268f60e51b908290601190811062002bc35762002bc362003d48565b6001600160e01b031990921660209283029190910190910152805163ddc97a4160e01b908290601290811062002bfd5762002bfd62003d48565b6001600160e01b0319909216602092830291909101909101528051636addb66360e01b908290601390811062002c375762002c3762003d48565b6001600160e01b03199092166020928302919091019091015280516321a7dd6560e21b908290601490811062002c715762002c7162003d48565b6001600160e01b0319909216602092830291909101909101528051631fa3f33160e11b908290601590811062002cab5762002cab62003d48565b6001600160e01b031990921660209283029190910190910152805163fd94616360e01b908290601690811062002ce55762002ce562003d48565b6001600160e01b0319909216602092830291909101909101528051634f558e7960e01b908290601790811062002d1f5762002d1f62003d48565b6001600160e01b0319909216602092830291909101909101528051631969630160e21b908290601890811062002d595762002d5962003d48565b6001600160e01b0319909216602092830291909101909101528051631850e64b60e11b908290601990811062002209576200220962003d48565b60408051600780825261010082019092526060916020820160e0803683370190505090506391d1485460e01b8160008151811062002dd55762002dd562003d48565b6001600160e01b031990921660209283029190910190910152805163248a9ca360e01b908290600190811062002e0f5762002e0f62003d48565b6001600160e01b0319909216602092830291909101909101528051632f2ff15d60e01b908290600290811062002e495762002e4962003d48565b6001600160e01b031990921660209283029190910190910152805163d547741f60e01b908290600390811062002e835762002e8362003d48565b6001600160e01b0319909216602092830291909101909101528051638bb9c5bf60e01b908290600490811062002ebd5762002ebd62003d48565b6001600160e01b0319909216602092830291909101909101528051632404341f60e21b908290600590811062002ef75762002ef762003d48565b6001600160e01b031990921660209283029190910190910152805163ca15c87360e01b908290600690811062002f315762002f3162003d48565b6001600160e01b03199092166020928302919091019091015290565b60408051600380825260808201909252606091602082018380368337019050509050635c975abb60e01b8160008151811062002f8d5762002f8d62003d48565b6001600160e01b0319909216602092830291909101909101528051638456cb5960e01b908290600190811062002fc75762002fc762003d48565b6001600160e01b0319909216602092830291909101909101528051631fa5d41d60e11b908290600290811062002f315762002f3162003d48565b60408051600480825260a082019092526060916020820160808036833701905050905063adfca15e60e01b8160008151811062003042576200304262003d48565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b90829060019081106200307c576200307c62003d48565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620030b657620030b662003d48565b6001600160e01b0319909216602092830291909101909101528051637a0ed62760e01b908290600390811062002f315762002f3162003d48565b6040805160028082526060808301845292602083019080368337019050509050635c60da1b60e01b816000815181106200312e576200312e62003d48565b6001600160e01b0319909216602092830291909101909101528051636bc26a1360e11b908290600190811062002f315762002f3162003d48565b61120b806200479b83390190565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620031b157620031b162003176565b60405290565b604051608081016001600160401b0381118282101715620031b157620031b162003176565b604051606081016001600160401b0381118282101715620031b157620031b162003176565b60405161014081016001600160401b0381118282101715620031b157620031b162003176565b60405161010081016001600160401b0381118282101715620031b157620031b162003176565b60405160a081016001600160401b0381118282101715620031b157620031b162003176565b60405160e081016001600160401b0381118282101715620031b157620031b162003176565b60405161012081016001600160401b0381118282101715620031b157620031b162003176565b604051601f8201601f191681016001600160401b0381118282101715620032e857620032e862003176565b604052919050565b60006001600160401b038211156200330c576200330c62003176565b50601f01601f191660200190565b6000620033316200332b84620032f0565b620032bd565b90508281528383830111156200334657600080fd5b828260208301376000602084830101529392505050565b600082601f8301126200336f57600080fd5b62000154838335602085016200331a565b803560ff811681146200339257600080fd5b919050565b6001600160a01b0381168114620033ad57600080fd5b50565b8035620033928162003397565b8015158114620033ad57600080fd5b80356200339281620033bd565b600060408284031215620033ec57600080fd5b620033f66200318c565b90508135815260208201356200340c81620033bd565b602082015292915050565b600061010082840312156200342b57600080fd5b62003435620031b7565b9050620034438383620033d9565b8152620034548360408401620033d9565b6020820152620034688360808401620033d9565b60408201526200347c8360c08401620033d9565b606082015292915050565b6000608082840312156200349a57600080fd5b620034a4620031b7565b90508135620034b38162003397565b81526020820135620034c58162003397565b80602083015250604082013560408201526060820135606082015292915050565b600060608284031215620034f957600080fd5b62003503620031dc565b905081356001600160401b03808211156200351d57600080fd5b9083019061028082860312156200353357600080fd5b6200353d62003201565b8235828111156200354d57600080fd5b6200355b878286016200335d565b8252506020830135828111156200357157600080fd5b6200357f878286016200335d565b6020830152506040830135828111156200359857600080fd5b620035a6878286016200335d565b604083015250620035ba6060840162003380565b60608201526080830135608082015260a083013560a0820152620035e160c08401620033b0565b60c0820152620035f460e08401620033b0565b60e082015261010091506200360c8683850162003417565b828201526200362086610200850162003487565b61012082015283525062003639905060208301620033b0565b60208201526200364c60408301620033b0565b604082015292915050565b6000602082840312156200366a57600080fd5b81356001600160401b038111156200368157600080fd5b6200368f84828501620034e6565b949350505050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b600060808284031215620036cb57600080fd5b620036d5620031b7565b9050813581526020820135620034c58162003397565b600060e08284031215620036fe57600080fd5b62003708620031b7565b905081356001600160401b03808211156200372257600080fd5b9083019061010082860312156200373857600080fd5b6200374262003227565b8235828111156200375257600080fd5b62003760878286016200335d565b8252506020830135828111156200377657600080fd5b62003784878286016200335d565b6020830152506040830135828111156200379d57600080fd5b620037ab878286016200335d565b604083015250606083013582811115620037c457600080fd5b620037d2878286016200335d565b60608301525060808301356080820152620037f060a08401620033cc565b60a08201526200380360c08401620033cc565b60c08201526200381660e08401620033b0565b60e08201528352506200382f90508360208401620036b8565b60208201526200384260a08301620033b0565b60408201526200347c60c08301620033b0565b6000608082840312156200386857600080fd5b62003872620031b7565b90508135620038818162003397565b8152602082810135908201526040808301359082015260608201356001600160401b03811115620038b157600080fd5b8201601f81018413620038c357600080fd5b620038d4848235602084016200331a565b60608301525092915050565b60008060408385031215620038f457600080fd5b82356001600160401b03808211156200390c57600080fd5b6200391a86838701620036eb565b935060208501359150808211156200393157600080fd5b50620039408582860162003855565b9150509250929050565b600080604083850312156200395e57600080fd5b82356001600160401b03808211156200397657600080fd5b6200391a86838701620034e6565b6000606082840312156200399757600080fd5b620039a1620031dc565b90508135620039b08162003397565b80825250602082013560208201526040820135604082015292915050565b60006001600160401b03821115620039ea57620039ea62003176565b5060051b60200190565b600082601f83011262003a0657600080fd5b8135602062003a196200332b83620039ce565b82815260059290921b8401810191818101908684111562003a3957600080fd5b8286015b8481101562003aec5780356001600160401b038082111562003a5f5760008081fd5b9088019060a0828b03601f190181131562003a7a5760008081fd5b62003a846200324d565b87840135815260408085013589830152606080860135828401526080915062003aaf82870162003380565b9083015291840135918383111562003ac75760008081fd5b62003ad78d8a858801016200335d565b90820152865250505091830191830162003a3d565b509695505050505050565b600060e0828403121562003b0a57600080fd5b62003b146200324d565b905081356001600160401b038082111562003b2e57600080fd5b9083019060e0828603121562003b4357600080fd5b62003b4d62003272565b82358281111562003b5d57600080fd5b62003b6b878286016200335d565b82525060208301358281111562003b8157600080fd5b62003b8f878286016200335d565b60208301525060408301358281111562003ba857600080fd5b62003bb6878286016200335d565b60408301525060608301358281111562003bcf57600080fd5b62003bdd878286016200335d565b60608301525062003bf160808401620033cc565b608082015262003c0460a08401620033cc565b60a082015262003c1760c08401620033b0565b60c0820152835262003c2d856020860162003984565b6020840152608084013591508082111562003c4757600080fd5b5062003c5684828501620039f4565b60408301525062003c6a60a08301620033b0565b606082015262003c7d60c08301620033b0565b608082015292915050565b60006020828403121562003c9b57600080fd5b81356001600160401b0381111562003cb257600080fd5b6200368f8482850162003af7565b6000806040838503121562003cd457600080fd5b82356001600160401b038082111562003cec57600080fd5b6200391a8683870162003af7565b60006020828403121562003d0d57600080fd5b81356001600160401b0381111562003d2457600080fd5b6200368f84828501620036eb565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008151808452602080850194506020840160005b8381101562003d9757815163ffffffff168752958201959082019060010162003d73565b509495945050505050565b60208152815160208201526000602083015160c0604084015262003dca60e084018262003d5e565b90506040840151601f1984830301606085015262003de9828262003d5e565b915050606084015160018060a01b0380821660808601528060808701511660a08601528060a08701511660c086015250508091505092915050565b60006020828403121562003e3757600080fd5b5051919050565b60005b8381101562003e5b57818101518382015260200162003e41565b50506000910152565b6000815180845262003e7e81602086016020860162003e3e565b601f01601f19169290920160200192915050565b60208152600062000154602083018462003e64565b9182526001600160a01b0316602082015260400190565b600060018060a01b0380861683526060602084015284516060840152602085015161010080608086015262003ef861016086018362003d5e565b91506040870151605f198684030160a087015262003f17838262003d5e565b9250508260608801511660c0860152608087015160e086015260a0870151925062003f458186018462003697565b5060c086015161012085015260e086015161014085015283810360408501526200036c818662003e64565b60609190911b6001600160601b031916815260140190565b600082601f83011262003f9a57600080fd5b815162003fab6200332b82620032f0565b81815284602083860101111562003fc157600080fd5b6200368f82602083016020870162003e3e565b8051620033928162003397565b80516200339281620033bd565b600082601f8301126200400057600080fd5b81516020620040136200332b83620039ce565b82815260059290921b840181019181810190868411156200403357600080fd5b8286015b8481101562003aec5780516001600160401b0380821115620040595760008081fd5b908801906040828b03601f1901811315620040745760008081fd5b6200407e6200318c565b8784015183811115620040915760008081fd5b620040a18d8a8388010162003f88565b8252509201518683015250835291830191830162004037565b600060208284031215620040cd57600080fd5b81516001600160401b0380821115620040e557600080fd5b908301906101208286031215620040fb57600080fd5b6200410562003297565b8251828111156200411557600080fd5b620041238782860162003f88565b825250602083015160208201526200413e6040840162003fd4565b6040820152620041516060840162003fd4565b6060820152608083015160808201526200416e60a0840162003fd4565b60a082015260c083015160c08201526200418b60e0840162003fe1565b60e08201526101008084015183811115620041a557600080fd5b620041b38882870162003fee565b918301919091525095945050505050565b600082825180855260208086019550808260051b84010181860160005b848110156200422957601f198684030189528151604081518186526200420a8287018262003e64565b92870151958701959095525098840198925090830190600101620041e1565b5090979650505050505050565b60208152600082516101208060208501526200425761014085018362003e64565b915060208501516040850152604085015162004277606086018262003697565b5060608501516200428c608086018262003697565b50608085015160a085015260a0850151620042ab60c086018262003697565b5060c085015160e085015260e0850151610100620042cc8187018315159052565b860151858403601f1901838701529050620042e88382620041c4565b9695505050505050565b60208152600082516101008060208501526200431361012085018362003e64565b91506020850151601f198086850301604087015262004333848362003e64565b9350604087015191508086850301606087015262004352848362003e64565b935060608701519150808685030160808701525062004372838262003e64565b925050608085015160a085015260a08501516200439360c086018215159052565b5060c085015180151560e08601525060e0850151620043b58286018262003697565b5090949350505050565b6020815281516020820152602082015160408201526040820151606082015260ff60608301511660808201526000608083015160a0808401526200368f60c084018262003e64565b805182526020908101511515910152565b6200442582825162004407565b602081015162004439604084018262004407565b5060408101516200444e608084018262004407565b5060608101516200446360c084018262004407565b505050565b60208152600082516102806020840152620044886102a084018262003e64565b90506020840151601f1980858403016040860152620044a8838362003e64565b9250604086015191508085840301606086015250620044c8828262003e64565b9150506060840151620044e0608085018260ff169052565b50608084015160a084015260a084015160c084015260c08401516200450960e085018262003697565b5060e0840151610100620045208186018362003697565b8501519050610120620045368582018362004418565b85015180516001600160a01b039081166102208701526020820151166102408601526040810151610260860152606081015161028086015290505b509392505050565b60038110620033ad57634e487b7160e01b600052602160045260246000fd5b60006060808301606084528087518083526080925060808601915060808160051b8701016020808b016000805b858110156200465c578a8503607f19018752825180516001600160a01b03168652848101518a870190620045f98162004579565b878701526040918201519187018b90528151908190529085019083908a8801905b80831015620046465783516001600160e01b03191682529287019260019290920191908701906200461a565b50988601989650505091830191600101620045c5565b5050506200466d8189018b62003697565b50868103604088015262004682818962003e64565b9a9950505050505050505050565b81516001600160a01b0390811682526020808401518216908301526040808401519091169082015260608083015190820152608082015160a0820190620046d78162004579565b8060808401525092915050565b602081526000825160e060208401526200470361010084018262003e64565b90506020840151601f198085840301604086015262004723838362003e64565b9250604086015191508085840301606086015262004742838362003e64565b925060608601519150808584030160808601525062004762828262003e64565b9150506080840151151560a084015260a08401516200478560c085018215159052565b5060c08401516200457160e08501826200369756fe608060405260405161120b38038061120b83398101604081905261002291610dc2565b61002b82610136565b604080516001808252818301909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816100425750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b816000815181106100b1576100b1610df5565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038516815290810160008152602001828152508260008151811061010157610101610df5565b602002602001018190525061012d8260006040518060200160405280600081525061019660201b60201c565b505050506110e0565b60006101406103b4565b6004810180546001600160a01b038581166001600160a01b031983168117909355604051939450169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60005b83518110156103695760008482815181106101b6576101b6610df5565b6020026020010151602001519050600060028111156101d7576101d7610e0b565b8160028111156101e9576101e9610e0b565b0361023d5761023885838151811061020357610203610df5565b60200260200101516000015186848151811061022157610221610df5565b6020026020010151604001516103d860201b60201c565b610360565b600181600281111561025157610251610e0b565b036102a05761023885838151811061026b5761026b610df5565b60200260200101516000015186848151811061028957610289610df5565b60200260200101516040015161055560201b60201c565b60028160028111156102b4576102b4610e0b565b03610303576102388583815181106102ce576102ce610df5565b6020026020010151600001518684815181106102ec576102ec610df5565b6020026020010151604001516106db60201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b50600101610199565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161039d93929190610e71565b60405180910390a16103af82826107f2565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90565b60008151116103f95760405162461bcd60e51b815260040161035790610f74565b60006104036103b4565b90506001600160a01b03831661042b5760405162461bcd60e51b815260040161035790610fbf565b6001600160a01b0383166000908152600182016020526040812054906001600160601b03821690036104615761046182856108b8565b60005b835181101561054e57600084828151811061048157610481610df5565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b031680156105275760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610357565b6105338583868a610922565b8361053d81611021565b945050600190920191506104649050565b5050505050565b60008151116105765760405162461bcd60e51b815260040161035790610f74565b60006105806103b4565b90506001600160a01b0383166105a85760405162461bcd60e51b815260040161035790610fbf565b6001600160a01b0383166000908152600182016020526040812054906001600160601b03821690036105de576105de82856108b8565b60005b835181101561054e5760008482815181106105fe576105fe610df5565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0390811690871681036106a95760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610357565b6106b48582846109c2565b6106c08583868a610922565b836106ca81611021565b945050600190920191506105e19050565b60008151116106fc5760405162461bcd60e51b815260040161035790610f74565b60006107066103b4565b90506001600160a01b038316156107855760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610357565b60005b82518110156107ec5760008382815181106107a5576107a5610df5565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b03166107e28482846109c2565b5050600101610788565b50505050565b6001600160a01b038216610804575050565b610826826040518060600160405280602881526020016111bf60289139610d85565b600080836001600160a01b031683604051610841919061104f565b600060405180830381855af49150503d806000811461087c576040519150601f19603f3d011682016040523d82523d6000602084013e610881565b606091505b5091509150816107ec5780511561089b5780518082602001fd5b838360405163192105d760e01b815260040161035792919061106b565b6108da816040518060600160405280602481526020016111e760249139610d85565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160e01b0319831660008181526020868152604080832080546001600160601b03909716600160a01b026001600160a01b0397881617815594909516808352600180890183529583208054968701815583528183206008870401805460e09890981c60046007909816979097026101000a96870263ffffffff9097021990971695909517909555529290915281546001600160a01b031916179055565b6001600160a01b038216610a3e5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610357565b306001600160a01b03831603610aad5760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401610357565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b03169291610afc91611097565b9050808214610bee576001600160a01b03841660009081526001860160205260408120805483908110610b3157610b31610df5565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110610b8257610b82610df5565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480610c1757610c176110b0565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900361054e576002850154600090610c7a90600190611097565b6001600160a01b0386166000908152600180890160205260409091200154909150808214610d29576000876002018381548110610cb957610cb9610df5565b6000918252602090912001546002890180546001600160a01b039092169250829184908110610cea57610cea610df5565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480610d3c57610d3c6110b0565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b81816107ec5760405162461bcd60e51b815260040161035791906110c6565b80516001600160a01b0381168114610dbd57600080fd5b919050565b60008060408385031215610dd557600080fd5b610dde83610da6565b9150610dec60208401610da6565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b60005b83811015610e3c578181015183820152602001610e24565b50506000910152565b60008151808452610e5d816020860160208601610e21565b601f01601f19169290920160200192915050565b60006060808301606084528087518083526080925060808601915060808160051b8701016020808b0160005b84811015610f4457898403607f19018652815180516001600160a01b03168552838101518986019060038110610ee357634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015610f2f5783516001600160e01b0319168252928601926001929092019190860190610f05565b50978501979550505090820190600101610e9d565b50506001600160a01b038a16908801528681036040880152610f668189610e45565b9a9950505050505050505050565b6020808252602b908201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660408201526a1858d95d081d1bc818dd5d60aa1b606082015260800190565b6020808252602c908201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260408201526b65206164647265737328302960a01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60006001600160601b038281166002600160601b031981016110455761104561100b565b6001019392505050565b60008251611061818460208701610e21565b9190910192915050565b6001600160a01b038316815260406020820181905260009061108f90830184610e45565b949350505050565b818103818111156110aa576110aa61100b565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006110d96020830184610e45565b9392505050565b60d1806110ee6000396000f3fe608060405236600a57005b600080356001600160e01b03191681527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602081905260409091205481906001600160a01b03168060a15760405162461bcd60e51b815260206004820181905260248201527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f74206578697374604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e80801560bf573d6000f35b3d6000fdfea164736f6c6343000817000a4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465ca16e7727e34eddfd016efc2c74be18308b7e9d9c361f0e67d4167ec00bcb635d7d8b7014b7ed36eb085c9e3e427b642d74cab75ecefda8a757042e63ec59919a164736f6c6343000817000a
Deployed Bytecode
0x6080604052600436106200005c5760003560e01c80636791a805146200006157806394ed410e14620000905780639f65bd5314620000b5578063b205911314620000da578063cb4a55d914620000f1578063ded782941462000116575b600080fd5b620000786200007236600462003657565b6200012d565b604051620000879190620036a4565b60405180910390f35b3480156200009d57600080fd5b5062000078620000af366004620038e0565b6200015b565b348015620000c257600080fd5b5062000078620000d43660046200394a565b6200017a565b62000078620000eb36600462003c88565b62000199565b348015620000fe57600080fd5b50620000786200011036600462003cc0565b620001c0565b620000786200012736600462003cfa565b620001df565b6000806200014660008460200151856040015162000206565b905062000154838262000377565b9392505050565b60006200016a60018362000804565b62000154838360400151620009fd565b60006200018960008362000804565b6200015483836040015162000377565b600080620001b260028460600151856080015162000206565b905062000154838262000e0b565b6000620001cf60028362000804565b6200015483836040015162000e0b565b600080620001f860018460400151856060015162000206565b9050620001548382620009fd565b6040805160018082528183019092526000918291906020808301908036833701905050905084600281111562000240576200024062003d32565b8160008151811062000256576200025662003d48565b63ffffffff9290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050509050600181600081518110620002a857620002a862003d48565b63ffffffff9092166020928302919091018201526040805160c081018252600080516020620059a683398151915281529182018490528181018390526001600160a01b038088166060840152336080840152861660a083015251635d048b2560e11b8152309063ba09164a9034906200032690859060040162003da2565b60206040518083038185885af115801562000345573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906200036c919062003e24565b979650505050505050565b6000806200038462001187565b905062000390620011ab565b9150620003a28285600001516200127b565b6010810154604051636bc26a1360e11b81526001600160a01b038481169263d784d42692620003d89290911690600401620036a4565b600060405180830381600087803b158015620003f357600080fd5b505af115801562000408573d6000803e3d6000fd5b505085515160405163c47f002760e01b81528593506001600160a01b038416925063c47f0027916200043d9160040162003e92565b600060405180830381600087803b1580156200045857600080fd5b505af11580156200046d573d6000803e3d6000fd5b5050865160200151604051635c26412360e11b81526001600160a01b038516935063b84c82469250620004a4919060040162003e92565b600060405180830381600087803b158015620004bf57600080fd5b505af1158015620004d4573d6000803e3d6000fd5b5050865160600151604051633d09cad560e11b815260ff90911660048201526001600160a01b0384169250637a1395aa9150602401600060405180830381600087803b1580156200052457600080fd5b505af115801562000539573d6000803e3d6000fd5b5050865160800151159150620005cc905057845160c08101516080909101516040516340c10f1960e01b81526001600160a01b038416926340c10f199262000597926004016001600160a01b03929092168252602082015260400190565b600060405180830381600087803b158015620005b257600080fd5b505af1158015620005c7573d6000803e3d6000fd5b505050505b604051636078c0f960e01b81526001600160a01b03821690636078c0f990620005fa903090600401620036a4565b600060405180830381600087803b1580156200061557600080fd5b505af11580156200062a573d6000803e3d6000fd5b5050506005830154604051636078c0f960e01b81526001600160a01b038085169350636078c0f9926200066392911690600401620036a4565b600060405180830381600087803b1580156200067e57600080fd5b505af115801562000693573d6000803e3d6000fd5b505050600583015460405163019cc55360e51b81526001600160a01b038085169350633398aa6092620006cc92911690600401620036a4565b600060405180830381600087803b158015620006e757600080fd5b505af1158015620006fc573d6000803e3d6000fd5b5050506005830154604051632f2ff15d60e01b81526001600160a01b039091169150632f2ff15d9062000756907f0e512f22a4a66880dbe62f43c3840e18a3b81e1a4c1c40bba7dc19b0503e51a990879060040162003ea7565b600060405180830381600087803b1580156200077157600080fd5b505af115801562000786573d6000803e3d6000fd5b5050505060006040518060a00160405280856001600160a01b03168152602001876000015160e001516001600160a01b0316815260200187602001516001600160a01b0316815260200186815260200160006002811115620007ec57620007ec62003d32565b90529050620007fb81620013a7565b50505092915050565b604080516001808252818301909252600091602080830190803683370190505090508260028111156200083b576200083b62003d32565b8160008151811062000851576200085162003d48565b63ffffffff9290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050509050600181600081518110620008a357620008a362003d48565b602002602001019063ffffffff16908163ffffffff16815250506000604051806101000160405280600080516020620059a68339815191528152602001848152602001838152602001336001600160a01b03168152602001306001600160a01b031663564b81ef6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200093a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000960919062003e24565b815260200185600001516001600160a01b031681526020018560200151815260200185604001518152509050306001600160a01b031663b459f7ca338387606001516040518463ffffffff1660e01b8152600401620009c29392919062003ebe565b600060405180830381600087803b158015620009dd57600080fd5b505af1158015620009f2573d6000803e3d6000fd5b505050505050505050565b600062000a09620011ab565b905062000a1b81846000015162001518565b600062000a2762001187565b6011810154604051636bc26a1360e11b81529192506001600160a01b038085169263d784d4269262000a5e921690600401620036a4565b600060405180830381600087803b15801562000a7957600080fd5b505af115801562000a8e573d6000803e3d6000fd5b50600092506001915062000a9f9050565b60405190808252806020026020018201604052801562000ae757816020015b60408051808201909152606081526000602082015281526020019060019003908162000abe5790505b5060408051608081018252600b9181019182526a115490cdcc8c48135a5b9d60aa1b60608201529081526020878101515190820152815191925090829060009062000b365762000b3662003d48565b6020026020010181905250600060405180610120016040528087600001516000015181526020018560405160200162000b70919062003f70565b60408051601f1981840301815291815281516020928301208352895160e001516001600160a01b03908116848401528a83018051909301511683820152905160609081015190830152516323cb241360e11b8152600080516020620059a683398151915260048201526080909101903090634796482690602401600060405180830381865afa15801562000c08573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000c329190810190620040ba565b60a001516001600160a01b031681526020018760200151604001518152602001600015158152602001838152509050306001600160a01b031663f5616c1f826040518263ffffffff1660e01b815260040162000c8f919062004236565b600060405180830381600087803b15801562000caa57600080fd5b505af115801562000cbf573d6000803e3d6000fd5b50508751604051636fe49ad960e01b81526001600160a01b0388169350636fe49ad9925062000cf29190600401620042f2565b600060405180830381600087803b15801562000d0d57600080fd5b505af115801562000d22573d6000803e3d6000fd5b5050604051632f2ff15d60e01b8152309250632f2ff15d915062000d5c90600080516020620059c683398151915290889060040162003ea7565b600060405180830381600087803b15801562000d7757600080fd5b505af115801562000d8c573d6000803e3d6000fd5b5050505060006040518060a00160405280866001600160a01b03168152602001886000015160e001516001600160a01b0316815260200188604001516001600160a01b031681526020018781526020016001600281111562000df25762000df262003d32565b9052905062000e0181620013a7565b5050505092915050565b600062000e17620011ab565b905062000e2981846000015162001608565b600062000e3562001187565b6012810154604051636bc26a1360e11b81529192506001600160a01b038085169263d784d4269262000e6c921690600401620036a4565b600060405180830381600087803b15801562000e8757600080fd5b505af115801562000e9c573d6000803e3d6000fd5b505050506060600060405180610120016040528087600001516000015181526020018560405160200162000ed1919062003f70565b60408051808303601f19018152918152815160209283012083526001600160a01b0388811684840152918a018051519092168382015290518101516060830152516323cb241360e11b8152600080516020620059a683398151915260048201526080909101903090634796482690602401600060405180830381865afa15801562000f60573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000f8a9190810190620040ba565b60a001516001600160a01b031681526020018760200151602001518152602001600015158152602001838152509050306001600160a01b031663f5616c1f826040518263ffffffff1660e01b815260040162000fe7919062004236565b600060405180830381600087803b1580156200100257600080fd5b505af115801562001017573d6000803e3d6000fd5b5050604051632f2ff15d60e01b8152309250632f2ff15d91506200105190600080516020620059c683398151915290889060040162003ea7565b600060405180830381600087803b1580156200106c57600080fd5b505af115801562001081573d6000803e3d6000fd5b5050505060005b8660400151518110156200112557846001600160a01b03166307e10c0d88604001518381518110620010be57620010be62003d48565b60200260200101516040518263ffffffff1660e01b8152600401620010e49190620043bf565b600060405180830381600087803b158015620010ff57600080fd5b505af115801562001114573d6000803e3d6000fd5b505060019092019150620010889050565b5060006040518060a00160405280866001600160a01b03168152602001886000015160c001516001600160a01b0316815260200188606001516001600160a01b0316815260200187815260200160028081111562000df25762000df262003d32565b7fae91e73249036d298733b3485b49b39bcb9229df52016e2810a03f18355028f690565b6307e4c70760e21b60009081527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c60208181526040805180820182527f9f0ce991cd9c4f6eaf19f214129f7a5c88ce0f46a01a0f164d4f0d44366a92a8546001600160a01b038116808352600160a01b9091046001600160601b0316938201939093529051909130916200123f9062003168565b6001600160a01b03928316815291166020820152604001604051809103906000f08015801562001273573d6000803e3d6000fd5b509250505090565b60006200128762001187565b9050600062001295620016f8565b90506000620012a3620018b7565b6040805160608101909152600a8501546001600160a01b0316815290915060208101600081526020018281525082600081518110620012e657620012e662003d48565b602002602001018190525060008460405160240162001306919062004468565b60408051601f198184030181529181526020820180516001600160e01b0316634e06b2e160e11b179052600b86015490516307e4c70760e21b81529192506001600160a01b0380891692631f931c1c926200136b928892911690869060040162004598565b600060405180830381600087803b1580156200138657600080fd5b505af11580156200139b573d6000803e3d6000fd5b50505050505050505050565b6000620013b362001187565b905080600101600083608001516002811115620013d457620013d462003d32565b6002811115620013e857620013e862003d32565b81526020808201929092526040908101600090812085840180516001600160a01b0390811684529185528383208751815460018101835591855286852090910180549184166001600160a01b0319928316179055905187518316845260028088019096529383208054949092169316929092179091556080840151839281111562001477576200147762003d32565b60028111156200148b576200148b62003d32565b81526020808201929092526040908101600090812085518154600181018355918352939091200180546001600160a01b0319166001600160a01b0390931692909217909155600382015490517f5bb644ee2a83060962b095d7d1eb91687997dbc60b60ea2a63eba7cd42c16fb6906200150690859062004690565b60405180910390a24360039091015550565b60006200152462001187565b9050600062001532620016f8565b905060006200154062002227565b6040805160608101909152600c8501546001600160a01b031681529091506020810160008152602001828152508260008151811062001583576200158362003d48565b6020026020010181905250600084604051602401620015a39190620042f2565b60408051601f198184030181529181526020820180516001600160e01b03166345d4de7b60e01b179052600d86015490516307e4c70760e21b81529192506001600160a01b0380891692631f931c1c926200136b928892911690869060040162004598565b60006200161462001187565b9050600062001622620016f8565b9050600062001630620027a4565b6040805160608101909152600e8501546001600160a01b031681529091506020810160008152602001828152508260008151811062001673576200167362003d48565b6020026020010181905250600084604051602401620016939190620046e4565b60408051601f198184030181529181526020820180516001600160e01b031663c952bb1960e01b179052600f86015490516307e4c70760e21b81529192506001600160a01b0380891692631f931c1c926200136b928892911690869060040162004598565b606060006200170662001187565b60408051600580825260c08201909252919250816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200171e57905050915060006200175c62002d93565b604080516060810190915260068401546001600160a01b03168152909150602081016000815260200182815250836001815181106200179f576200179f62003d48565b6020026020010181905250620017b462002f4d565b604080516060810190915260078401546001600160a01b0316815290915060208101600081526020018281525083600281518110620017f757620017f762003d48565b60200260200101819052506200180c62003001565b604080516060810190915260088401546001600160a01b03168152909150602081016000815260200182815250836003815181106200184f576200184f62003d48565b602002602001018190525062001864620030f0565b604080516060810190915260098401546001600160a01b0316815290915060208101600081526020018281525083600481518110620018a757620018a762003d48565b6020026020010181905250505090565b60408051602980825261054082019092526060916000919060208201610520803683370190505090506318160ddd60e01b81600081518110620018fe57620018fe62003d48565b6001600160e01b03199092166020928302919091019091015280516370a0823160e01b908290600190811062001938576200193862003d48565b6001600160e01b0319909216602092830291909101909101528051636eb1769f60e11b908290600290811062001972576200197262003d48565b6001600160e01b031990921660209283029190910190910152805163095ea7b360e01b9082906003908110620019ac57620019ac62003d48565b6001600160e01b031990921660209283029190910190910152805163a9059cbb60e01b9082906004908110620019e657620019e662003d48565b6001600160e01b03199092166020928302919091019091015280516323b872dd60e01b908290600590811062001a205762001a2062003d48565b6001600160e01b0319909216602092830291909101909101528051633950935160e01b908290600690811062001a5a5762001a5a62003d48565b6001600160e01b031990921660209283029190910190910152805163a457c2d760e01b908290600790811062001a945762001a9462003d48565b6001600160e01b03199092166020928302919091019091015280516306fdde0360e01b908290600890811062001ace5762001ace62003d48565b6001600160e01b03199092166020928302919091019091015280516395d89b4160e01b908290600990811062001b085762001b0862003d48565b6001600160e01b031990921660209283029190910190910152805163313ce56760e01b908290600a90811062001b425762001b4262003d48565b6001600160e01b0319909216602092830291909101909101528051633644e51560e01b908290600b90811062001b7c5762001b7c62003d48565b6001600160e01b0319909216602092830291909101909101528051623f675f60e91b908290600c90811062001bb55762001bb562003d48565b6001600160e01b031990921660209283029190910190910152805163d505accf60e01b908290600d90811062001bef5762001bef62003d48565b6001600160e01b03199092166020928302919091019091015280516340c10f1960e01b908290600e90811062001c295762001c2962003d48565b6001600160e01b0319909216602092830291909101909101528051631780542160e31b908290600f90811062001c635762001c6362003d48565b6001600160e01b0319909216602092830291909101909101528051637f51bb1f60e01b908290601090811062001c9d5762001c9d62003d48565b6001600160e01b031990921660209283029190910190910152805163c47f002760e01b908290601190811062001cd75762001cd762003d48565b6001600160e01b0319909216602092830291909101909101528051635c26412360e11b908290601290811062001d115762001d1162003d48565b6001600160e01b0319909216602092830291909101909101528051633d09cad560e11b908290601390811062001d4b5762001d4b62003d48565b6001600160e01b0319909216602092830291909101909101528051633cae3f5f60e11b908290601490811062001d855762001d8562003d48565b6001600160e01b0319909216602092830291909101909101528051633aa1d1d560e11b908290601590811062001dbf5762001dbf62003d48565b6001600160e01b031990921660209283029190910190910152805163019cc55360e51b908290601690811062001df95762001df962003d48565b6001600160e01b03199092166020928302919091019091015280516316c0896d60e31b908290601790811062001e335762001e3362003d48565b6001600160e01b031990921660209283029190910190910152805163612881a360e11b908290601890811062001e6d5762001e6d62003d48565b6001600160e01b0319909216602092830291909101909101528051636078c0f960e01b908290601990811062001ea75762001ea762003d48565b6001600160e01b0319909216602092830291909101909101528051631ec70d6760e21b908290601a90811062001ee15762001ee162003d48565b6001600160e01b0319909216602092830291909101909101528051634d78e9ad60e11b908290601b90811062001f1b5762001f1b62003d48565b6001600160e01b0319909216602092830291909101909101528051636addb66360e01b908290601c90811062001f555762001f5562003d48565b6001600160e01b03199092166020928302919091019091015280516311c565df60e01b908290601d90811062001f8f5762001f8f62003d48565b6001600160e01b03199092166020928302919091019091015280516318f60b6960e01b908290601e90811062001fc95762001fc962003d48565b6001600160e01b03199092166020928302919091019091015280516311557f7960e11b908290601f90811062002003576200200362003d48565b6001600160e01b0319909216602092830291909101820152815163997d0feb60e01b918391811062002039576200203962003d48565b6001600160e01b031990921660209283029190910190910152805163029d58c160e11b908290602190811062002073576200207362003d48565b6001600160e01b0319909216602092830291909101909101528051631e59818360e31b9082906022908110620020ad57620020ad62003d48565b6001600160e01b031990921660209283029190910190910152805163f84354f160e01b9082906023908110620020e757620020e762003d48565b6001600160e01b031990921660209283029190910190910152805163045a6e8360e51b908290602490811062002121576200212162003d48565b6001600160e01b031990921660209283029190910190910152805163011424b960e51b90829060259081106200215b576200215b62003d48565b6001600160e01b0319909216602092830291909101909101528051634549b03960e01b908290602690811062002195576200219562003d48565b6001600160e01b0319909216602092830291909101909101528051632d83811960e01b9082906027908110620021cf57620021cf62003d48565b6001600160e01b03199092166020928302919091019091015280516313114a9d60e01b908290602890811062002209576200220962003d48565b6001600160e01b031990921660209283029190910190910152919050565b60408051601880825261032082019092526060916000919060208201610300803683370190505090506301ffc9a760e01b816000815181106200226e576200226e62003d48565b6001600160e01b03199092166020928302919091019091015280516370a0823160e01b9082906001908110620022a857620022a862003d48565b6001600160e01b03199092166020928302919091019091015280516331a9108f60e11b9082906002908110620022e257620022e262003d48565b6001600160e01b03199092166020928302919091019091015280516323b872dd60e01b90829060039081106200231c576200231c62003d48565b6001600160e01b031990921660209283029190910190910152805163095ea7b360e01b908290600490811062002356576200235662003d48565b6001600160e01b031990921660209283029190910190910152805163020604bf60e21b908290600590811062002390576200239062003d48565b6001600160e01b031990921660209283029190910190910152805163a22cb46560e01b9082906006908110620023ca57620023ca62003d48565b6001600160e01b031990921660209283029190910190910152805163e985e9c560e01b908290600790811062002404576200240462003d48565b6001600160e01b03199092166020928302919091019091015280516318160ddd60e01b90829060089081106200243e576200243e62003d48565b6001600160e01b0319909216602092830291909101909101528051632f745c5960e01b908290600990811062002478576200247862003d48565b6001600160e01b0319909216602092830291909101909101528051634f6ccce760e01b908290600a908110620024b257620024b262003d48565b6001600160e01b03199092166020928302919091019091015280516306fdde0360e01b908290600b908110620024ec57620024ec62003d48565b6001600160e01b03199092166020928302919091019091015280516395d89b4160e01b908290600c90811062002526576200252662003d48565b6001600160e01b031990921660209283029190910190910152805163c87b56dd60e01b908290600d90811062002560576200256062003d48565b6001600160e01b0319909216602092830291909101909101528051634bb4ee0760e11b908290600e9081106200259a576200259a62003d48565b6001600160e01b0319909216602092830291909101909101528051637600c26f60e11b908290600f908110620025d457620025d462003d48565b6001600160e01b0319909216602092830291909101909101528051636fe49ad960e01b90829060109081106200260e576200260e62003d48565b6001600160e01b0319909216602092830291909101909101528051632bfbbc4f60e11b908290601190811062002648576200264862003d48565b6001600160e01b031990921660209283029190910190910152805163318c2e2160e11b908290601290811062002682576200268262003d48565b6001600160e01b031990921660209283029190910190910152805163b7b1140160e01b9082906013908110620026bc57620026bc62003d48565b6001600160e01b031990921660209283029190910190910152805163a09b654560e01b9082906014908110620026f657620026f662003d48565b6001600160e01b03199092166020928302919091019091015280516337ef227760e11b908290601590811062002730576200273062003d48565b6001600160e01b0319909216602092830291909101909101528051636addb66360e01b90829060169081106200276a576200276a62003d48565b6001600160e01b0319909216602092830291909101909101528051631850e64b60e11b908290601790811062002209576200220962003d48565b60408051601a80825261036082019092526060916000919060208201610340803683370190505090506301ffc9a760e01b81600081518110620027eb57620027eb62003d48565b6001600160e01b0319909216602092830291909101909101528051627eeac760e11b908290600190811062002824576200282462003d48565b6001600160e01b03199092166020928302919091019091015280516313849cfd60e21b90829060029081106200285e576200285e62003d48565b6001600160e01b031990921660209283029190910190910152805163e985e9c560e01b908290600390811062002898576200289862003d48565b6001600160e01b031990921660209283029190910190910152805163a22cb46560e01b9082906004908110620028d257620028d262003d48565b6001600160e01b0319909216602092830291909101909101528051637921219560e11b90829060059081106200290c576200290c62003d48565b6001600160e01b0319909216602092830291909101909101528051631759616b60e11b908290600690811062002946576200294662003d48565b6001600160e01b031990921660209283029190910190910152805163bd85b03960e01b908290600790811062002980576200298062003d48565b6001600160e01b03199092166020928302919091019091015280516313ba55df60e01b9082906008908110620029ba57620029ba62003d48565b6001600160e01b0319909216602092830291909101909101528051636dcfd84160e01b9082906009908110620029f457620029f462003d48565b6001600160e01b03199092166020928302919091019091015280516385bff2e760e01b908290600a90811062002a2e5762002a2e62003d48565b6001600160e01b03199092166020928302919091019091015280516303a24d0760e21b908290600b90811062002a685762002a6862003d48565b6001600160e01b0319909216602092830291909101909101528051624a84cb60e01b908290600c90811062002aa15762002aa162003d48565b6001600160e01b0319909216602092830291909101909101528051636d487de160e01b908290600d90811062002adb5762002adb62003d48565b6001600160e01b03199092166020928302919091019091015280516307e10c0d60e01b908290600e90811062002b155762002b1562003d48565b6001600160e01b031990921660209283029190910190910152805163eeecf93f60e01b908290600f90811062002b4f5762002b4f62003d48565b6001600160e01b0319909216602092830291909101909101528051632bfbbc4f60e11b908290601090811062002b895762002b8962003d48565b6001600160e01b0319909216602092830291909101909101528051630582268f60e51b908290601190811062002bc35762002bc362003d48565b6001600160e01b031990921660209283029190910190910152805163ddc97a4160e01b908290601290811062002bfd5762002bfd62003d48565b6001600160e01b0319909216602092830291909101909101528051636addb66360e01b908290601390811062002c375762002c3762003d48565b6001600160e01b03199092166020928302919091019091015280516321a7dd6560e21b908290601490811062002c715762002c7162003d48565b6001600160e01b0319909216602092830291909101909101528051631fa3f33160e11b908290601590811062002cab5762002cab62003d48565b6001600160e01b031990921660209283029190910190910152805163fd94616360e01b908290601690811062002ce55762002ce562003d48565b6001600160e01b0319909216602092830291909101909101528051634f558e7960e01b908290601790811062002d1f5762002d1f62003d48565b6001600160e01b0319909216602092830291909101909101528051631969630160e21b908290601890811062002d595762002d5962003d48565b6001600160e01b0319909216602092830291909101909101528051631850e64b60e11b908290601990811062002209576200220962003d48565b60408051600780825261010082019092526060916020820160e0803683370190505090506391d1485460e01b8160008151811062002dd55762002dd562003d48565b6001600160e01b031990921660209283029190910190910152805163248a9ca360e01b908290600190811062002e0f5762002e0f62003d48565b6001600160e01b0319909216602092830291909101909101528051632f2ff15d60e01b908290600290811062002e495762002e4962003d48565b6001600160e01b031990921660209283029190910190910152805163d547741f60e01b908290600390811062002e835762002e8362003d48565b6001600160e01b0319909216602092830291909101909101528051638bb9c5bf60e01b908290600490811062002ebd5762002ebd62003d48565b6001600160e01b0319909216602092830291909101909101528051632404341f60e21b908290600590811062002ef75762002ef762003d48565b6001600160e01b031990921660209283029190910190910152805163ca15c87360e01b908290600690811062002f315762002f3162003d48565b6001600160e01b03199092166020928302919091019091015290565b60408051600380825260808201909252606091602082018380368337019050509050635c975abb60e01b8160008151811062002f8d5762002f8d62003d48565b6001600160e01b0319909216602092830291909101909101528051638456cb5960e01b908290600190811062002fc75762002fc762003d48565b6001600160e01b0319909216602092830291909101909101528051631fa5d41d60e11b908290600290811062002f315762002f3162003d48565b60408051600480825260a082019092526060916020820160808036833701905050905063adfca15e60e01b8160008151811062003042576200304262003d48565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b90829060019081106200307c576200307c62003d48565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b9082906002908110620030b657620030b662003d48565b6001600160e01b0319909216602092830291909101909101528051637a0ed62760e01b908290600390811062002f315762002f3162003d48565b6040805160028082526060808301845292602083019080368337019050509050635c60da1b60e01b816000815181106200312e576200312e62003d48565b6001600160e01b0319909216602092830291909101909101528051636bc26a1360e11b908290600190811062002f315762002f3162003d48565b61120b806200479b83390190565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620031b157620031b162003176565b60405290565b604051608081016001600160401b0381118282101715620031b157620031b162003176565b604051606081016001600160401b0381118282101715620031b157620031b162003176565b60405161014081016001600160401b0381118282101715620031b157620031b162003176565b60405161010081016001600160401b0381118282101715620031b157620031b162003176565b60405160a081016001600160401b0381118282101715620031b157620031b162003176565b60405160e081016001600160401b0381118282101715620031b157620031b162003176565b60405161012081016001600160401b0381118282101715620031b157620031b162003176565b604051601f8201601f191681016001600160401b0381118282101715620032e857620032e862003176565b604052919050565b60006001600160401b038211156200330c576200330c62003176565b50601f01601f191660200190565b6000620033316200332b84620032f0565b620032bd565b90508281528383830111156200334657600080fd5b828260208301376000602084830101529392505050565b600082601f8301126200336f57600080fd5b62000154838335602085016200331a565b803560ff811681146200339257600080fd5b919050565b6001600160a01b0381168114620033ad57600080fd5b50565b8035620033928162003397565b8015158114620033ad57600080fd5b80356200339281620033bd565b600060408284031215620033ec57600080fd5b620033f66200318c565b90508135815260208201356200340c81620033bd565b602082015292915050565b600061010082840312156200342b57600080fd5b62003435620031b7565b9050620034438383620033d9565b8152620034548360408401620033d9565b6020820152620034688360808401620033d9565b60408201526200347c8360c08401620033d9565b606082015292915050565b6000608082840312156200349a57600080fd5b620034a4620031b7565b90508135620034b38162003397565b81526020820135620034c58162003397565b80602083015250604082013560408201526060820135606082015292915050565b600060608284031215620034f957600080fd5b62003503620031dc565b905081356001600160401b03808211156200351d57600080fd5b9083019061028082860312156200353357600080fd5b6200353d62003201565b8235828111156200354d57600080fd5b6200355b878286016200335d565b8252506020830135828111156200357157600080fd5b6200357f878286016200335d565b6020830152506040830135828111156200359857600080fd5b620035a6878286016200335d565b604083015250620035ba6060840162003380565b60608201526080830135608082015260a083013560a0820152620035e160c08401620033b0565b60c0820152620035f460e08401620033b0565b60e082015261010091506200360c8683850162003417565b828201526200362086610200850162003487565b61012082015283525062003639905060208301620033b0565b60208201526200364c60408301620033b0565b604082015292915050565b6000602082840312156200366a57600080fd5b81356001600160401b038111156200368157600080fd5b6200368f84828501620034e6565b949350505050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b600060808284031215620036cb57600080fd5b620036d5620031b7565b9050813581526020820135620034c58162003397565b600060e08284031215620036fe57600080fd5b62003708620031b7565b905081356001600160401b03808211156200372257600080fd5b9083019061010082860312156200373857600080fd5b6200374262003227565b8235828111156200375257600080fd5b62003760878286016200335d565b8252506020830135828111156200377657600080fd5b62003784878286016200335d565b6020830152506040830135828111156200379d57600080fd5b620037ab878286016200335d565b604083015250606083013582811115620037c457600080fd5b620037d2878286016200335d565b60608301525060808301356080820152620037f060a08401620033cc565b60a08201526200380360c08401620033cc565b60c08201526200381660e08401620033b0565b60e08201528352506200382f90508360208401620036b8565b60208201526200384260a08301620033b0565b60408201526200347c60c08301620033b0565b6000608082840312156200386857600080fd5b62003872620031b7565b90508135620038818162003397565b8152602082810135908201526040808301359082015260608201356001600160401b03811115620038b157600080fd5b8201601f81018413620038c357600080fd5b620038d4848235602084016200331a565b60608301525092915050565b60008060408385031215620038f457600080fd5b82356001600160401b03808211156200390c57600080fd5b6200391a86838701620036eb565b935060208501359150808211156200393157600080fd5b50620039408582860162003855565b9150509250929050565b600080604083850312156200395e57600080fd5b82356001600160401b03808211156200397657600080fd5b6200391a86838701620034e6565b6000606082840312156200399757600080fd5b620039a1620031dc565b90508135620039b08162003397565b80825250602082013560208201526040820135604082015292915050565b60006001600160401b03821115620039ea57620039ea62003176565b5060051b60200190565b600082601f83011262003a0657600080fd5b8135602062003a196200332b83620039ce565b82815260059290921b8401810191818101908684111562003a3957600080fd5b8286015b8481101562003aec5780356001600160401b038082111562003a5f5760008081fd5b9088019060a0828b03601f190181131562003a7a5760008081fd5b62003a846200324d565b87840135815260408085013589830152606080860135828401526080915062003aaf82870162003380565b9083015291840135918383111562003ac75760008081fd5b62003ad78d8a858801016200335d565b90820152865250505091830191830162003a3d565b509695505050505050565b600060e0828403121562003b0a57600080fd5b62003b146200324d565b905081356001600160401b038082111562003b2e57600080fd5b9083019060e0828603121562003b4357600080fd5b62003b4d62003272565b82358281111562003b5d57600080fd5b62003b6b878286016200335d565b82525060208301358281111562003b8157600080fd5b62003b8f878286016200335d565b60208301525060408301358281111562003ba857600080fd5b62003bb6878286016200335d565b60408301525060608301358281111562003bcf57600080fd5b62003bdd878286016200335d565b60608301525062003bf160808401620033cc565b608082015262003c0460a08401620033cc565b60a082015262003c1760c08401620033b0565b60c0820152835262003c2d856020860162003984565b6020840152608084013591508082111562003c4757600080fd5b5062003c5684828501620039f4565b60408301525062003c6a60a08301620033b0565b606082015262003c7d60c08301620033b0565b608082015292915050565b60006020828403121562003c9b57600080fd5b81356001600160401b0381111562003cb257600080fd5b6200368f8482850162003af7565b6000806040838503121562003cd457600080fd5b82356001600160401b038082111562003cec57600080fd5b6200391a8683870162003af7565b60006020828403121562003d0d57600080fd5b81356001600160401b0381111562003d2457600080fd5b6200368f84828501620036eb565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008151808452602080850194506020840160005b8381101562003d9757815163ffffffff168752958201959082019060010162003d73565b509495945050505050565b60208152815160208201526000602083015160c0604084015262003dca60e084018262003d5e565b90506040840151601f1984830301606085015262003de9828262003d5e565b915050606084015160018060a01b0380821660808601528060808701511660a08601528060a08701511660c086015250508091505092915050565b60006020828403121562003e3757600080fd5b5051919050565b60005b8381101562003e5b57818101518382015260200162003e41565b50506000910152565b6000815180845262003e7e81602086016020860162003e3e565b601f01601f19169290920160200192915050565b60208152600062000154602083018462003e64565b9182526001600160a01b0316602082015260400190565b600060018060a01b0380861683526060602084015284516060840152602085015161010080608086015262003ef861016086018362003d5e565b91506040870151605f198684030160a087015262003f17838262003d5e565b9250508260608801511660c0860152608087015160e086015260a0870151925062003f458186018462003697565b5060c086015161012085015260e086015161014085015283810360408501526200036c818662003e64565b60609190911b6001600160601b031916815260140190565b600082601f83011262003f9a57600080fd5b815162003fab6200332b82620032f0565b81815284602083860101111562003fc157600080fd5b6200368f82602083016020870162003e3e565b8051620033928162003397565b80516200339281620033bd565b600082601f8301126200400057600080fd5b81516020620040136200332b83620039ce565b82815260059290921b840181019181810190868411156200403357600080fd5b8286015b8481101562003aec5780516001600160401b0380821115620040595760008081fd5b908801906040828b03601f1901811315620040745760008081fd5b6200407e6200318c565b8784015183811115620040915760008081fd5b620040a18d8a8388010162003f88565b8252509201518683015250835291830191830162004037565b600060208284031215620040cd57600080fd5b81516001600160401b0380821115620040e557600080fd5b908301906101208286031215620040fb57600080fd5b6200410562003297565b8251828111156200411557600080fd5b620041238782860162003f88565b825250602083015160208201526200413e6040840162003fd4565b6040820152620041516060840162003fd4565b6060820152608083015160808201526200416e60a0840162003fd4565b60a082015260c083015160c08201526200418b60e0840162003fe1565b60e08201526101008084015183811115620041a557600080fd5b620041b38882870162003fee565b918301919091525095945050505050565b600082825180855260208086019550808260051b84010181860160005b848110156200422957601f198684030189528151604081518186526200420a8287018262003e64565b92870151958701959095525098840198925090830190600101620041e1565b5090979650505050505050565b60208152600082516101208060208501526200425761014085018362003e64565b915060208501516040850152604085015162004277606086018262003697565b5060608501516200428c608086018262003697565b50608085015160a085015260a0850151620042ab60c086018262003697565b5060c085015160e085015260e0850151610100620042cc8187018315159052565b860151858403601f1901838701529050620042e88382620041c4565b9695505050505050565b60208152600082516101008060208501526200431361012085018362003e64565b91506020850151601f198086850301604087015262004333848362003e64565b9350604087015191508086850301606087015262004352848362003e64565b935060608701519150808685030160808701525062004372838262003e64565b925050608085015160a085015260a08501516200439360c086018215159052565b5060c085015180151560e08601525060e0850151620043b58286018262003697565b5090949350505050565b6020815281516020820152602082015160408201526040820151606082015260ff60608301511660808201526000608083015160a0808401526200368f60c084018262003e64565b805182526020908101511515910152565b6200442582825162004407565b602081015162004439604084018262004407565b5060408101516200444e608084018262004407565b5060608101516200446360c084018262004407565b505050565b60208152600082516102806020840152620044886102a084018262003e64565b90506020840151601f1980858403016040860152620044a8838362003e64565b9250604086015191508085840301606086015250620044c8828262003e64565b9150506060840151620044e0608085018260ff169052565b50608084015160a084015260a084015160c084015260c08401516200450960e085018262003697565b5060e0840151610100620045208186018362003697565b8501519050610120620045368582018362004418565b85015180516001600160a01b039081166102208701526020820151166102408601526040810151610260860152606081015161028086015290505b509392505050565b60038110620033ad57634e487b7160e01b600052602160045260246000fd5b60006060808301606084528087518083526080925060808601915060808160051b8701016020808b016000805b858110156200465c578a8503607f19018752825180516001600160a01b03168652848101518a870190620045f98162004579565b878701526040918201519187018b90528151908190529085019083908a8801905b80831015620046465783516001600160e01b03191682529287019260019290920191908701906200461a565b50988601989650505091830191600101620045c5565b5050506200466d8189018b62003697565b50868103604088015262004682818962003e64565b9a9950505050505050505050565b81516001600160a01b0390811682526020808401518216908301526040808401519091169082015260608083015190820152608082015160a0820190620046d78162004579565b8060808401525092915050565b602081526000825160e060208401526200470361010084018262003e64565b90506020840151601f198085840301604086015262004723838362003e64565b9250604086015191508085840301606086015262004742838362003e64565b925060608601519150808584030160808601525062004762828262003e64565b9150506080840151151560a084015260a08401516200478560c085018215159052565b5060c08401516200457160e08501826200369756fe608060405260405161120b38038061120b83398101604081905261002291610dc2565b61002b82610136565b604080516001808252818301909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816100425750506040805160018082528183019092529192506000919060208083019080368337019050509050631f931c1c60e01b816000815181106100b1576100b1610df5565b6001600160e01b031990921660209283029190910182015260408051606081019091526001600160a01b038516815290810160008152602001828152508260008151811061010157610101610df5565b602002602001018190525061012d8260006040518060200160405280600081525061019660201b60201c565b505050506110e0565b60006101406103b4565b6004810180546001600160a01b038581166001600160a01b031983168117909355604051939450169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b60005b83518110156103695760008482815181106101b6576101b6610df5565b6020026020010151602001519050600060028111156101d7576101d7610e0b565b8160028111156101e9576101e9610e0b565b0361023d5761023885838151811061020357610203610df5565b60200260200101516000015186848151811061022157610221610df5565b6020026020010151604001516103d860201b60201c565b610360565b600181600281111561025157610251610e0b565b036102a05761023885838151811061026b5761026b610df5565b60200260200101516000015186848151811061028957610289610df5565b60200260200101516040015161055560201b60201c565b60028160028111156102b4576102b4610e0b565b03610303576102388583815181106102ce576102ce610df5565b6020026020010151600001518684815181106102ec576102ec610df5565b6020026020010151604001516106db60201b60201c565b60405162461bcd60e51b815260206004820152602760248201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756044820152663a20b1ba34b7b760c91b60648201526084015b60405180910390fd5b50600101610199565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161039d93929190610e71565b60405180910390a16103af82826107f2565b505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90565b60008151116103f95760405162461bcd60e51b815260040161035790610f74565b60006104036103b4565b90506001600160a01b03831661042b5760405162461bcd60e51b815260040161035790610fbf565b6001600160a01b0383166000908152600182016020526040812054906001600160601b03821690036104615761046182856108b8565b60005b835181101561054e57600084828151811061048157610481610df5565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b031680156105275760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608401610357565b6105338583868a610922565b8361053d81611021565b945050600190920191506104649050565b5050505050565b60008151116105765760405162461bcd60e51b815260040161035790610f74565b60006105806103b4565b90506001600160a01b0383166105a85760405162461bcd60e51b815260040161035790610fbf565b6001600160a01b0383166000908152600182016020526040812054906001600160601b03821690036105de576105de82856108b8565b60005b835181101561054e5760008482815181106105fe576105fe610df5565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0390811690871681036106a95760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608401610357565b6106b48582846109c2565b6106c08583868a610922565b836106ca81611021565b945050600190920191506105e19050565b60008151116106fc5760405162461bcd60e51b815260040161035790610f74565b60006107066103b4565b90506001600160a01b038316156107855760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608401610357565b60005b82518110156107ec5760008382815181106107a5576107a5610df5565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b03166107e28482846109c2565b5050600101610788565b50505050565b6001600160a01b038216610804575050565b610826826040518060600160405280602881526020016111bf60289139610d85565b600080836001600160a01b031683604051610841919061104f565b600060405180830381855af49150503d806000811461087c576040519150601f19603f3d011682016040523d82523d6000602084013e610881565b606091505b5091509150816107ec5780511561089b5780518082602001fd5b838360405163192105d760e01b815260040161035792919061106b565b6108da816040518060600160405280602481526020016111e760249139610d85565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160e01b0319831660008181526020868152604080832080546001600160601b03909716600160a01b026001600160a01b0397881617815594909516808352600180890183529583208054968701815583528183206008870401805460e09890981c60046007909816979097026101000a96870263ffffffff9097021990971695909517909555529290915281546001600160a01b031916179055565b6001600160a01b038216610a3e5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608401610357565b306001600160a01b03831603610aad5760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201526d3a30b1363290333ab731ba34b7b760911b6064820152608401610357565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046001600160601b03169291610afc91611097565b9050808214610bee576001600160a01b03841660009081526001860160205260408120805483908110610b3157610b31610df5565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b925082919085908110610b8257610b82610df5565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6001600160601b038516021790555b6001600160a01b03841660009081526001860160205260409020805480610c1757610c176110b0565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040812081905581900361054e576002850154600090610c7a90600190611097565b6001600160a01b0386166000908152600180890160205260409091200154909150808214610d29576000876002018381548110610cb957610cb9610df5565b6000918252602090912001546002890180546001600160a01b039092169250829184908110610cea57610cea610df5565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b86600201805480610d3c57610d3c6110b0565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b813b81816107ec5760405162461bcd60e51b815260040161035791906110c6565b80516001600160a01b0381168114610dbd57600080fd5b919050565b60008060408385031215610dd557600080fd5b610dde83610da6565b9150610dec60208401610da6565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b60005b83811015610e3c578181015183820152602001610e24565b50506000910152565b60008151808452610e5d816020860160208601610e21565b601f01601f19169290920160200192915050565b60006060808301606084528087518083526080925060808601915060808160051b8701016020808b0160005b84811015610f4457898403607f19018652815180516001600160a01b03168552838101518986019060038110610ee357634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015610f2f5783516001600160e01b0319168252928601926001929092019190860190610f05565b50978501979550505090820190600101610e9d565b50506001600160a01b038a16908801528681036040880152610f668189610e45565b9a9950505050505050505050565b6020808252602b908201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660408201526a1858d95d081d1bc818dd5d60aa1b606082015260800190565b6020808252602c908201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260408201526b65206164647265737328302960a01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60006001600160601b038281166002600160601b031981016110455761104561100b565b6001019392505050565b60008251611061818460208701610e21565b9190910192915050565b6001600160a01b038316815260406020820181905260009061108f90830184610e45565b949350505050565b818103818111156110aa576110aa61100b565b92915050565b634e487b7160e01b600052603160045260246000fd5b6020815260006110d96020830184610e45565b9392505050565b60d1806110ee6000396000f3fe608060405236600a57005b600080356001600160e01b03191681527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c602081905260409091205481906001600160a01b03168060a15760405162461bcd60e51b815260206004820181905260248201527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f74206578697374604482015260640160405180910390fd5b3660008037600080366000845af43d6000803e80801560bf573d6000f35b3d6000fdfea164736f6c6343000817000a4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465ca16e7727e34eddfd016efc2c74be18308b7e9d9c361f0e67d4167ec00bcb635d7d8b7014b7ed36eb085c9e3e427b642d74cab75ecefda8a757042e63ec59919a164736f6c6343000817000a
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.