Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- EVMFSRegistry
- Optimization enabled
- true
- Compiler version
- v0.8.28+commit.7893614a
- Optimization runs
- 200
- EVM Version
- prague
- Verified at
- 2026-03-10T21:51:56.094864Z
contracts/EVMFSRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./IEVMFSRegistry.sol";
/**
* @title EVMFSRegistry
* @notice On-chain name→CID registry for the evmfs.app subdomain gateway.
*
* Users pay a one-time fee (based on name length) to claim a name.
* The owner of a name can update its CID at any time (enabling site updates)
* and transfer ownership to another address.
*
* Pricing follows a linear-scarcity curve by UTF-8 byte length:
* 1 char → 10 ETH
* 2 chars → 3 ETH
* 3 chars → 1 ETH
* 4 chars → 0.3 ETH
* 5 chars → 0.1 ETH
* 6 chars → 0.03 ETH
* 7+ chars→ 0.015 ETH
*
* On testnets these are testnet ETH — same ratios for integration testing.
*/
contract EVMFSRegistry is Ownable, IEVMFSRegistry {
// ─────────────────────────────────────────────────────
// Storage
// ─────────────────────────────────────────────────────
/// @dev name hash → 32-byte EVMFS CID (raw sha256)
mapping(bytes32 => bytes) private _nameToCid;
/// @dev name hash → owner address
mapping(bytes32 => address) private _nameOwner;
/// @dev name hash → original plaintext name (for enumeration / display)
mapping(bytes32 => string) private _nameLabel;
uint256 private _nameCount;
// ─────────────────────────────────────────────────────
// Events
// ─────────────────────────────────────────────────────
event NameRegistered(string indexed nameHash, string name, address indexed owner, bytes cid);
event CidUpdated(string indexed nameHash, string name, bytes oldCid, bytes newCid);
event NameTransferred(string indexed nameHash, string name, address indexed from, address indexed to);
// ─────────────────────────────────────────────────────
// Errors
// ─────────────────────────────────────────────────────
error NameAlreadyTaken();
error NameNotRegistered();
error NotNameOwner();
error InsufficientFee();
error EmptyName();
error EmptyCid();
error InvalidCidLength();
error TransferToZero();
// ─────────────────────────────────────────────────────
// Constructor
// ─────────────────────────────────────────────────────
constructor() Ownable(msg.sender) {}
// ─────────────────────────────────────────────────────
// Write — Registration
// ─────────────────────────────────────────────────────
/**
* @notice Register a name and bind it to an EVMFS CID.
* @param name Plaintext name (e.g. "myapp"). Must be non-empty.
* @param cid 32-byte EVMFS CID (rolling SHA-256 hash).
*/
function registerApp(string calldata name, bytes calldata cid) external payable {
if (bytes(name).length == 0) revert EmptyName();
if (cid.length == 0) revert EmptyCid();
if (cid.length != 32) revert InvalidCidLength();
bytes32 key = _nameKey(name);
if (_nameOwner[key] != address(0)) revert NameAlreadyTaken();
uint256 price = getPrice(name);
if (msg.value < price) revert InsufficientFee();
_nameOwner[key] = msg.sender;
_nameToCid[key] = cid;
_nameLabel[key] = name;
_nameCount++;
// Refund overpayment
uint256 excess = msg.value - price;
if (excess > 0) {
(bool ok, ) = msg.sender.call{value: excess}("");
require(ok, "Refund failed");
}
emit NameRegistered(name, name, msg.sender, cid);
}
// ─────────────────────────────────────────────────────
// Write — Update CID
// ─────────────────────────────────────────────────────
/**
* @notice Update the CID for a name you own (deploy a new version).
* @param name The registered name.
* @param cid New 32-byte EVMFS CID.
*/
function updateCid(string calldata name, bytes calldata cid) external {
if (cid.length == 0) revert EmptyCid();
if (cid.length != 32) revert InvalidCidLength();
bytes32 key = _nameKey(name);
if (_nameOwner[key] == address(0)) revert NameNotRegistered();
if (_nameOwner[key] != msg.sender) revert NotNameOwner();
bytes memory oldCid = _nameToCid[key];
_nameToCid[key] = cid;
emit CidUpdated(name, name, oldCid, cid);
}
// ─────────────────────────────────────────────────────
// Write — Transfer ownership
// ─────────────────────────────────────────────────────
/**
* @notice Transfer ownership of a name to a new address.
* @param name The registered name.
* @param newOwner The new owner. Cannot be address(0).
*/
function transferName(string calldata name, address newOwner) external {
if (newOwner == address(0)) revert TransferToZero();
bytes32 key = _nameKey(name);
if (_nameOwner[key] == address(0)) revert NameNotRegistered();
if (_nameOwner[key] != msg.sender) revert NotNameOwner();
address oldOwner = _nameOwner[key];
_nameOwner[key] = newOwner;
emit NameTransferred(name, name, oldOwner, newOwner);
}
// ─────────────────────────────────────────────────────
// Write — Admin
// ─────────────────────────────────────────────────────
/**
* @notice Withdraw accumulated registration fees.
*/
function withdraw() external onlyOwner {
uint256 bal = address(this).balance;
require(bal > 0, "Nothing to withdraw");
(bool ok, ) = owner().call{value: bal}("");
require(ok, "Withdraw failed");
}
// ─────────────────────────────────────────────────────
// Read — IEVMFSRegistry
// ─────────────────────────────────────────────────────
/// @inheritdoc IEVMFSRegistry
function getCid(string calldata name) external view returns (bytes memory) {
return _nameToCid[_nameKey(name)];
}
/// @inheritdoc IEVMFSRegistry
function nameOwner(string calldata name) external view returns (address) {
return _nameOwner[_nameKey(name)];
}
/// @inheritdoc IEVMFSRegistry
function isRegistered(string calldata name) external view returns (bool) {
return _nameOwner[_nameKey(name)] != address(0);
}
/**
* @inheritdoc IEVMFSRegistry
* @notice Pricing by UTF-8 byte length (linear scarcity):
* 1 → 10 ether | 2 → 3 ether | 3 → 1 ether
* 4 → 0.3 ether | 5 → 0.1 ether | 6 → 0.03 ether
* 7+ → 0.015 ether
*/
function getPrice(string calldata name) public pure returns (uint256) {
uint256 L = bytes(name).length;
if (L == 0) return type(uint256).max; // Unreachable for valid calls
if (L == 1) return 10 ether;
if (L == 2) return 3 ether;
if (L == 3) return 1 ether;
if (L == 4) return 0.3 ether;
if (L == 5) return 0.1 ether;
if (L == 6) return 0.03 ether;
return 0.015 ether;
}
/// @notice Total number of registered names.
function nameCount() external view returns (uint256) {
return _nameCount;
}
// ─────────────────────────────────────────────────────
// Internal
// ─────────────────────────────────────────────────────
/// @dev Convert a plaintext name to a storage key via keccak256.
function _nameKey(string calldata name) internal pure returns (bytes32) {
return keccak256(bytes(name));
}
}
../../lib/openzeppelin-contracts/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
../../lib/openzeppelin-contracts/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
contracts/IEVMFSRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/**
* @title IEVMFSRegistry
* @notice Interface for the EVMFS name registry.
* Maps human-readable names to EVMFS CIDs for subdomain resolution
* on evmfs.app (contract registry) and evmfs.link (ENS mirror).
*/
interface IEVMFSRegistry {
/// @notice Returns the 32-byte CID bound to a name, or empty bytes if unregistered.
function getCid(string calldata name) external view returns (bytes memory);
/// @notice Returns the owner address of a registered name.
function nameOwner(string calldata name) external view returns (address);
/// @notice Returns the registration fee for a name based on its UTF-8 byte length.
function getPrice(string calldata name) external pure returns (uint256);
/// @notice Returns true if the name has been claimed.
function isRegistered(string calldata name) external view returns (bool);
}
Compiler Settings
{"viaIR":true,"remappings":["@openzeppelin/contracts/=../../lib/openzeppelin-contracts/contracts/","forge-std/=../../lib/forge-std/src/","erc4626-tests/=/Users/Onix.Martinez/BlockProjects/web3-twitter/new_monorepo/lib/openzeppelin-contracts/lib/erc4626-tests/","halmos-cheatcodes/=/Users/Onix.Martinez/BlockProjects/web3-twitter/new_monorepo/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","openzeppelin-contracts/=/Users/Onix.Martinez/BlockProjects/web3-twitter/new_monorepo/lib/openzeppelin-contracts/contracts/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"prague"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"error","name":"EmptyCid","inputs":[]},{"type":"error","name":"EmptyName","inputs":[]},{"type":"error","name":"InsufficientFee","inputs":[]},{"type":"error","name":"InvalidCidLength","inputs":[]},{"type":"error","name":"NameAlreadyTaken","inputs":[]},{"type":"error","name":"NameNotRegistered","inputs":[]},{"type":"error","name":"NotNameOwner","inputs":[]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"error","name":"TransferToZero","inputs":[]},{"type":"event","name":"CidUpdated","inputs":[{"type":"string","name":"nameHash","internalType":"string","indexed":true},{"type":"string","name":"name","internalType":"string","indexed":false},{"type":"bytes","name":"oldCid","internalType":"bytes","indexed":false},{"type":"bytes","name":"newCid","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"NameRegistered","inputs":[{"type":"string","name":"nameHash","internalType":"string","indexed":true},{"type":"string","name":"name","internalType":"string","indexed":false},{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"bytes","name":"cid","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"NameTransferred","inputs":[{"type":"string","name":"nameHash","internalType":"string","indexed":true},{"type":"string","name":"name","internalType":"string","indexed":false},{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"getCid","inputs":[{"type":"string","name":"name","internalType":"string"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPrice","inputs":[{"type":"string","name":"name","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isRegistered","inputs":[{"type":"string","name":"name","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nameCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"nameOwner","inputs":[{"type":"string","name":"name","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"registerApp","inputs":[{"type":"string","name":"name","internalType":"string"},{"type":"bytes","name":"cid","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferName","inputs":[{"type":"string","name":"name","internalType":"string"},{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateCid","inputs":[{"type":"string","name":"name","internalType":"string"},{"type":"bytes","name":"cid","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[]}]
Contract Creation Code
0x608080604052346071573315605e575f8054336001600160a01b0319821681178355916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3610e3490816100768239f35b631e4fbdf760e01b5f525f60045260245ffd5b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c806333e17c6014610a6057806337194d1e146109415780633ccfd60b1461088f57806343c2ee35146105fc578063524f3889146105b9578063715018a61461056257806373ff93a2146105455780638da5cb5b1461051e578063b4970b0f146101d4578063c822d7f014610181578063e18c3a061461012a5763f2fde38b1461009d575f80fd5b34610126576020366003190112610126576004356001600160a01b03811690819003610126576100cb610dd8565b8015610113575f80546001600160a01b03198116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b34610126576020366003190112610126576004356001600160401b0381116101265761015d610163913690600401610b57565b90610d9d565b5f526002602052602060018060a01b0360405f205416604051908152f35b34610126576020366003190112610126576004356001600160401b0381116101265761015d6101b4913690600401610b57565b5f526002602052602060018060a01b0360405f2054161515604051908152f35b6101dd36610ba8565b919092811561050f57821561050057602083036104f2576101fe8282610d9d565b5f818152600260205260409020546001600160a01b03166104e3576102238383610d0a565b908134106104d5575f81815260026020908152604080832080546001600160a01b03191633179055600190915290206001600160401b038611610452576102748661026e8354610bf8565b83610cbb565b5f86601f811160011461047157806102a0925f91610466575b508160011b915f199060031b1c19161790565b90555b5f52600360205260405f206001600160401b038411610452576102ca8461026e8354610bf8565b5f84601f81116001146103ef57806102f5925f916103e457508160011b915f199060031b1c19161790565b90555b6004545f1981146103d057600101600455803403903482116103d057340361037f575b507ffcd420f3c377ac516f77699a9c2a3d4109d0d28c17592854ca16517be96a77489161037a60405182848237808381015f81520390209461036a604051948594604086526040860191610c51565b9083820360208501523397610c51565b0390a3005b5f80808093335af161038f610c8c565b501561039b578461031b565b60405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b6044820152606490fd5b634e487b7160e01b5f52601160045260245ffd5b90508501358961028d565b50601f19851690825f528560205f20925f5b81811061043757501061041e575b5050600184811b0190556102f8565b8401355f19600387901b60f8161c19169055868061040f565b87840135855560019094019360209384019389935001610401565b634e487b7160e01b5f52604160045260245ffd5b90508901358a61028d565b50601f19871690825f528760205f20925f5b8b8282106104bb575050106104a2575b5050600186811b0190556102a3565b8801355f19600389901b60f8161c191690558780610493565b84013585556001909401936020938401938b935001610483565b62976f7560e21b5f5260045ffd5b630d706ecd60e21b5f5260045ffd5b6211911b60e81b5f5260045ffd5b636d91186360e01b5f5260045ffd5b632ef1310560e01b5f5260045ffd5b34610126575f366003190112610126575f546040516001600160a01b039091168152602090f35b34610126575f366003190112610126576020600454604051908152f35b34610126575f3660031901126101265761057a610dd8565b5f80546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b34610126576020366003190112610126576004356001600160401b038111610126576105f46105ee6020923690600401610b57565b90610d0a565b604051908152f35b346101265761060a36610ba8565b929091831561050057602084036104f2576106258183610d9d565b5f818152600260205260409020549093906001600160a01b031615610880575f848152600260205260409020546001600160a01b0316330361087157835f52600160205260405f209360405194855f82549261068084610bf8565b808452936001811690811561084f575060011461080b575b506106a592500386610c30565b5f52600160205260405f20946001600160401b038111610452576106d3816106cd8854610bf8565b88610cbb565b5f95601f82116001146107825790610772929161072782807f821a6365db69c1d64ad11e01534750e7fbbf9777b59caf69ff63371daaf73d72999a5f9161077757508160011b915f199060031b1c19161790565b90555b61076460405185878237808681015f815203902097610756604051978897606089526060890191610c51565b908682036020880152610b84565b918483036040860152610c51565b0390a2005b90508501358b61028d565b601f198216815f5260205f20905f5b8181106107f35750907f821a6365db69c1d64ad11e01534750e7fbbf9777b59caf69ff63371daaf73d7297988461077296959493106107da575b5050600182811b01905561072a565b8401355f19600385901b60f8161c1916905588806107cb565b858a013583556020998a019960019093019201610791565b90505f9291925260205f20905f915b8183106108335750509060206106a59282010189610698565b6020919350806001915483858c0101520191019091879261081a565b9050602092506106a594915060ff191682840152151560051b82010189610698565b6310bc162d60e21b5f5260045ffd5b6331aef0e560e01b5f5260045ffd5b34610126575f366003190112610126576108a7610dd8565b478015610906575f8080809360018060a01b038254165af16108c7610c8c565b50156108cf57005b60405162461bcd60e51b815260206004820152600f60248201526e15da5d1a191c985dc819985a5b1959608a1b6044820152606490fd5b60405162461bcd60e51b81526020600482015260136024820152724e6f7468696e6720746f20776974686472617760681b6044820152606490fd5b34610126576040366003190112610126576004356001600160401b03811161012657610971903690600401610b57565b6024356001600160a01b038116929190839003610126578215610a51576109988183610d9d565b5f818152600260205260409020549092906001600160a01b031615610880575f838152600260205260409020546001600160a01b03163303610871575f928352600260205260409283902080546001600160a01b03198116861790915592516001600160a01b03909316927fdf23d51f1260be237fa4088ead0c088c053d59be34359b0f2aadf45d8b7a5f3b919083828237808481015f815203902092610a4c604051928392602084526020840191610c51565b0390a4005b63a38ca3d960e01b5f5260045ffd5b34610126576020366003190112610126576004356001600160401b0381116101265761015d610a93913690600401610b57565b5f52600160205260405f20604051905f90805490610ab082610bf8565b8085529160018116908115610b305750600114610af0575b610aec84610ad881860382610c30565b604051918291602083526020830190610b84565b0390f35b5f90815260208120939250905b808210610b1657509091508101602001610ad882610ac8565b919260018160209254838588010152019101909291610afd565b60ff191660208087019190915292151560051b85019092019250610ad89150839050610ac8565b9181601f84011215610126578235916001600160401b038311610126576020838186019501011161012657565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b6040600319820112610126576004356001600160401b0381116101265781610bd291600401610b57565b92909291602435906001600160401b03821161012657610bf491600401610b57565b9091565b90600182811c92168015610c26575b6020831014610c1257565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610c07565b90601f801991011681019081106001600160401b0382111761045257604052565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160401b03811161045257601f01601f191660200190565b3d15610cb6573d90610c9d82610c71565b91610cab6040519384610c30565b82523d5f602084013e565b606090565b601f8211610cc857505050565b5f5260205f20906020601f840160051c83019310610d00575b601f0160051c01905b818110610cf5575050565b5f8155600101610cea565b9091508190610ce1565b508015610d975760018114610d8a5760028114610d7d5760038114610d705760048114610d635760058114610d5657600614610d4b5766354a6ba7a1800090565b666a94d74f43000090565b5067016345785d8a000090565b50670429d069189e000090565b50670de0b6b3a764000090565b506729a2241af62c000090565b50678ac7230489e8000090565b505f1990565b90610da781610c71565b90610db56040519283610c30565b8082526020820192368282011161012657815f9260209286378301015251902090565b5f546001600160a01b03163303610deb57565b63118cdaa760e01b5f523360045260245ffdfea2646970667358221220b56021b22a60b11a60f0d8c20f8f7e98abfea3b44fafc6901bd27949557489cb64736f6c634300081c0033
Deployed ByteCode
0x60806040526004361015610011575f80fd5b5f3560e01c806333e17c6014610a6057806337194d1e146109415780633ccfd60b1461088f57806343c2ee35146105fc578063524f3889146105b9578063715018a61461056257806373ff93a2146105455780638da5cb5b1461051e578063b4970b0f146101d4578063c822d7f014610181578063e18c3a061461012a5763f2fde38b1461009d575f80fd5b34610126576020366003190112610126576004356001600160a01b03811690819003610126576100cb610dd8565b8015610113575f80546001600160a01b03198116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b34610126576020366003190112610126576004356001600160401b0381116101265761015d610163913690600401610b57565b90610d9d565b5f526002602052602060018060a01b0360405f205416604051908152f35b34610126576020366003190112610126576004356001600160401b0381116101265761015d6101b4913690600401610b57565b5f526002602052602060018060a01b0360405f2054161515604051908152f35b6101dd36610ba8565b919092811561050f57821561050057602083036104f2576101fe8282610d9d565b5f818152600260205260409020546001600160a01b03166104e3576102238383610d0a565b908134106104d5575f81815260026020908152604080832080546001600160a01b03191633179055600190915290206001600160401b038611610452576102748661026e8354610bf8565b83610cbb565b5f86601f811160011461047157806102a0925f91610466575b508160011b915f199060031b1c19161790565b90555b5f52600360205260405f206001600160401b038411610452576102ca8461026e8354610bf8565b5f84601f81116001146103ef57806102f5925f916103e457508160011b915f199060031b1c19161790565b90555b6004545f1981146103d057600101600455803403903482116103d057340361037f575b507ffcd420f3c377ac516f77699a9c2a3d4109d0d28c17592854ca16517be96a77489161037a60405182848237808381015f81520390209461036a604051948594604086526040860191610c51565b9083820360208501523397610c51565b0390a3005b5f80808093335af161038f610c8c565b501561039b578461031b565b60405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b6044820152606490fd5b634e487b7160e01b5f52601160045260245ffd5b90508501358961028d565b50601f19851690825f528560205f20925f5b81811061043757501061041e575b5050600184811b0190556102f8565b8401355f19600387901b60f8161c19169055868061040f565b87840135855560019094019360209384019389935001610401565b634e487b7160e01b5f52604160045260245ffd5b90508901358a61028d565b50601f19871690825f528760205f20925f5b8b8282106104bb575050106104a2575b5050600186811b0190556102a3565b8801355f19600389901b60f8161c191690558780610493565b84013585556001909401936020938401938b935001610483565b62976f7560e21b5f5260045ffd5b630d706ecd60e21b5f5260045ffd5b6211911b60e81b5f5260045ffd5b636d91186360e01b5f5260045ffd5b632ef1310560e01b5f5260045ffd5b34610126575f366003190112610126575f546040516001600160a01b039091168152602090f35b34610126575f366003190112610126576020600454604051908152f35b34610126575f3660031901126101265761057a610dd8565b5f80546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b34610126576020366003190112610126576004356001600160401b038111610126576105f46105ee6020923690600401610b57565b90610d0a565b604051908152f35b346101265761060a36610ba8565b929091831561050057602084036104f2576106258183610d9d565b5f818152600260205260409020549093906001600160a01b031615610880575f848152600260205260409020546001600160a01b0316330361087157835f52600160205260405f209360405194855f82549261068084610bf8565b808452936001811690811561084f575060011461080b575b506106a592500386610c30565b5f52600160205260405f20946001600160401b038111610452576106d3816106cd8854610bf8565b88610cbb565b5f95601f82116001146107825790610772929161072782807f821a6365db69c1d64ad11e01534750e7fbbf9777b59caf69ff63371daaf73d72999a5f9161077757508160011b915f199060031b1c19161790565b90555b61076460405185878237808681015f815203902097610756604051978897606089526060890191610c51565b908682036020880152610b84565b918483036040860152610c51565b0390a2005b90508501358b61028d565b601f198216815f5260205f20905f5b8181106107f35750907f821a6365db69c1d64ad11e01534750e7fbbf9777b59caf69ff63371daaf73d7297988461077296959493106107da575b5050600182811b01905561072a565b8401355f19600385901b60f8161c1916905588806107cb565b858a013583556020998a019960019093019201610791565b90505f9291925260205f20905f915b8183106108335750509060206106a59282010189610698565b6020919350806001915483858c0101520191019091879261081a565b9050602092506106a594915060ff191682840152151560051b82010189610698565b6310bc162d60e21b5f5260045ffd5b6331aef0e560e01b5f5260045ffd5b34610126575f366003190112610126576108a7610dd8565b478015610906575f8080809360018060a01b038254165af16108c7610c8c565b50156108cf57005b60405162461bcd60e51b815260206004820152600f60248201526e15da5d1a191c985dc819985a5b1959608a1b6044820152606490fd5b60405162461bcd60e51b81526020600482015260136024820152724e6f7468696e6720746f20776974686472617760681b6044820152606490fd5b34610126576040366003190112610126576004356001600160401b03811161012657610971903690600401610b57565b6024356001600160a01b038116929190839003610126578215610a51576109988183610d9d565b5f818152600260205260409020549092906001600160a01b031615610880575f838152600260205260409020546001600160a01b03163303610871575f928352600260205260409283902080546001600160a01b03198116861790915592516001600160a01b03909316927fdf23d51f1260be237fa4088ead0c088c053d59be34359b0f2aadf45d8b7a5f3b919083828237808481015f815203902092610a4c604051928392602084526020840191610c51565b0390a4005b63a38ca3d960e01b5f5260045ffd5b34610126576020366003190112610126576004356001600160401b0381116101265761015d610a93913690600401610b57565b5f52600160205260405f20604051905f90805490610ab082610bf8565b8085529160018116908115610b305750600114610af0575b610aec84610ad881860382610c30565b604051918291602083526020830190610b84565b0390f35b5f90815260208120939250905b808210610b1657509091508101602001610ad882610ac8565b919260018160209254838588010152019101909291610afd565b60ff191660208087019190915292151560051b85019092019250610ad89150839050610ac8565b9181601f84011215610126578235916001600160401b038311610126576020838186019501011161012657565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b6040600319820112610126576004356001600160401b0381116101265781610bd291600401610b57565b92909291602435906001600160401b03821161012657610bf491600401610b57565b9091565b90600182811c92168015610c26575b6020831014610c1257565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610c07565b90601f801991011681019081106001600160401b0382111761045257604052565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160401b03811161045257601f01601f191660200190565b3d15610cb6573d90610c9d82610c71565b91610cab6040519384610c30565b82523d5f602084013e565b606090565b601f8211610cc857505050565b5f5260205f20906020601f840160051c83019310610d00575b601f0160051c01905b818110610cf5575050565b5f8155600101610cea565b9091508190610ce1565b508015610d975760018114610d8a5760028114610d7d5760038114610d705760048114610d635760058114610d5657600614610d4b5766354a6ba7a1800090565b666a94d74f43000090565b5067016345785d8a000090565b50670429d069189e000090565b50670de0b6b3a764000090565b506729a2241af62c000090565b50678ac7230489e8000090565b505f1990565b90610da781610c71565b90610db56040519283610c30565b8082526020820192368282011161012657815f9260209286378301015251902090565b5f546001600160a01b03163303610deb57565b63118cdaa760e01b5f523360045260245ffdfea2646970667358221220b56021b22a60b11a60f0d8c20f8f7e98abfea3b44fafc6901bd27949557489cb64736f6c634300081c0033