| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| no token transfers for this address yet | |||||||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x120fd8…f08178 | 22 days agoSat, 25 Jul 2026 22:16:07 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…160bf65b [2] 0x000000000000…00000006 |
| 0x49c791…e5f0c4 | 22 days agoSat, 25 Jul 2026 21:38:57 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…0f9c28db [2] 0x000000000000…00000005 |
| 0x36e3ea…7b0f7b | 22 days agoSat, 25 Jul 2026 21:23:01 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…0f9c28db [2] 0x000000000000…00000004 |
| 0xd07cb1…bc8174 | 24 days agoThu, 23 Jul 2026 20:54:44 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…b6254310 [2] 0x000000000000…00000003 |
| 0xd4e5b8…054319 | 25 days agoThu, 23 Jul 2026 11:09:46 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…1b478779 [2] 0x000000000000…00000002 |
| 0x1e4cb7…150960 | 26 days agoWed, 22 Jul 2026 18:48:04 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…0f9c28db [2] 0x000000000000…00000001 |
| 0x0f696b…9ea397 | 28 days agoMon, 20 Jul 2026 18:24:05 UTC | 0x8be007…57e0 | [0] 0x000000000000…7763872b [1] 0x000000000000…07e881df |
| 0xe18baa…bf867d | 28 days agoMon, 20 Jul 2026 18:10:48 UTC | 0xc7f505…81d2 | data: 0x000000000000000000…00000001 |
| 0x868cbb…4be245 | 28 days agoMon, 20 Jul 2026 18:10:08 UTC | 0x8be007…57e0 | [0] 0x000000000000…00000000 [1] 0x000000000000…7763872b |
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x0f696b…9ea397 | transferOwnership | 14,914,061 | 28 days agoMon, 20 Jul 2026 18:24:05 UTC | 0x6e47…872b | IN | Flaunch Revenue Streams | $0.000 ETH | 0.00000157 | |
| 0xe18baa…bf867d | initialize | 14,906,107 | 28 days agoMon, 20 Jul 2026 18:10:48 UTC | 0x6e47…872b | IN | Flaunch Revenue Streams | $0.000 ETH | 0.00000496 |
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 19,361,279 | 22 days agoSat, 25 Jul 2026 22:16:07 UTC | 0x120fd8…f08178 | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0xda8b…4c16 | 0 ETH |
| 19,361,279 | 22 days agoSat, 25 Jul 2026 22:16:07 UTC | 0x120fd8…f08178 | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0x426f…58b8 | 0 ETH |
| 19,357,062 | 22 days agoSat, 25 Jul 2026 22:09:03 UTC | 0x016789…7aaf6d | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0xda8b…4c16 | 0 ETH |
| 19,357,062 | 22 days agoSat, 25 Jul 2026 22:09:03 UTC | 0x016789…7aaf6d | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0x426f…58b8 | 0 ETH |
| 19,339,042 | 22 days agoSat, 25 Jul 2026 21:38:57 UTC | 0x49c791…e5f0c4 | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0xf5b4…2354 | 0 ETH |
| 19,339,042 | 22 days agoSat, 25 Jul 2026 21:38:57 UTC | 0x49c791…e5f0c4 | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0x4f98…48f5 | 0 ETH |
| 19,329,493 | 22 days agoSat, 25 Jul 2026 21:23:01 UTC | 0x36e3ea…7b0f7b | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0x204a…452e | 0 ETH |
| 19,329,493 | 22 days agoSat, 25 Jul 2026 21:23:01 UTC | 0x36e3ea…7b0f7b | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0x887a…968d | 0 ETH |
| 17,590,620 | 24 days agoThu, 23 Jul 2026 20:54:44 UTC | 0xd07cb1…bc8174 | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0x746f…dd8d | 0 ETH |
| 17,590,620 | 24 days agoThu, 23 Jul 2026 20:54:44 UTC | 0xd07cb1…bc8174 | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0xfb11…8a11 | 0 ETH |
| 17,240,404 | 25 days agoThu, 23 Jul 2026 11:09:46 UTC | 0xd4e5b8…054319 | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0xedd3…91d1 | 0 ETH |
| 17,240,404 | 25 days agoThu, 23 Jul 2026 11:09:46 UTC | 0xd4e5b8…054319 | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0xff0f…6719 | 0 ETH |
| 16,652,870 | 26 days agoWed, 22 Jul 2026 18:48:04 UTC | 0x1e4cb7…150960 | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0xa526…3fc4 | 0 ETH |
| 16,652,870 | 26 days agoWed, 22 Jul 2026 18:48:04 UTC | 0x1e4cb7…150960 | CREATE2 | flaunch | 0x2c8d…c192 | OUT | 0xb24d…527e | 0 ETH |
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {IL2ToL2CrossDomainMessenger} from '@optimism/interfaces/L2/IL2ToL2CrossDomainMessenger.sol';
import {Predeploys} from '@optimism/src/libraries/Predeploys.sol';
import {Initializable} from '@solady/utils/Initializable.sol';
import {ERC721} from '@solady/tokens/ERC721.sol';
import {LibClone} from '@solady/utils/LibClone.sol';
import {LibString} from '@solady/utils/LibString.sol';
import {Ownable} from '@solady/auth/Ownable.sol';
import {PoolId} from '@uniswap/v4-core/src/types/PoolId.sol';
import {PositionManager} from '@flaunch/PositionManager.sol';
import {TokenSupply} from '@flaunch/libraries/TokenSupply.sol';
import {IFlaunch} from '@flaunch-interfaces/IFlaunch.sol';
import {IMemecoin} from '@flaunch-interfaces/IMemecoin.sol';
/**
* The Flaunch ERC721 NFT that is created when a new position is by the {PositionManager} flaunched.
* This is used to prove ownership of a pool, so transferring this token would result in a new
* pool creator being assigned.
*/
contract Flaunch is ERC721, IFlaunch, Initializable, Ownable {
error CallerNotL2ToL2CrossDomainMessenger();
error CallerIsNotPositionManager();
error CreatorFeeAllocationInvalid(uint24 _allocation, uint _maxAllocation);
error InvalidCrossDomainSender();
error InvalidDestinationChain();
error InvalidFlaunchSchedule();
error InvalidInitialSupply(uint _initialSupply);
error PremineExceedsInitialAmount(uint _buyAmount, uint _initialSupply);
error TokenAlreadyBridging();
error TokenAlreadyBridged();
error UnknownMemecoin();
event TokenBridging(uint _tokenId, uint _chainId, address _memecoin);
event TokenBridged(uint _tokenId, uint _chainId, address _memecoin, uint _messageSource);
event BaseURIUpdated(string _newBaseURI);
event MemecoinImplementationUpdated(address _newImplementation);
event MemecoinTreasuryImplementationUpdated(address _newImplementation);
/**
* Stores related memecoin contract implementation addresses.
*
* @member memecoin The ERC20 {Memecoin} address
* @member memecoinTreasury The {MemecoinTreasury} address
*/
struct TokenInfo {
address memecoin;
address payable memecoinTreasury;
}
/**
* Stores the metadata for a memecoin for bridging.
*
* @member name The name of the memecoin
* @member symbol The symbol of the memecoin
* @member tokenUri The token URI for the memecoin
*/
struct MemecoinMetadata {
string name;
string symbol;
string tokenUri;
}
/// The L2 to L2 cross domain messenger predeploy to handle message passing
IL2ToL2CrossDomainMessenger internal messenger = IL2ToL2CrossDomainMessenger(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER);
/// The maximum amount of tokens that can be attributed to the Fair Launch
uint public constant MAX_FAIR_LAUNCH_TOKENS = TokenSupply.INITIAL_SUPPLY;
/// The maximum value of a creator's fee allocation
uint public constant MAX_CREATOR_ALLOCATION = 100_00;
/// The maximum duration of a flaunch schedule
uint public constant MAX_SCHEDULE_DURATION = 30 days;
/// The maximum amount of time to allow for a bridging finalization before allowing a retry
uint public constant MAX_BRIDGING_WINDOW = 1 hours;
/// Our basic token information
string internal _name = 'Flaunch Revenue Streams';
string internal _symbol = 'FLAUNCH';
/// The base URI to represent the metadata
string public baseURI;
/// Stores the next tokenId that will be minted. This can be used as an indication of how
/// many tokens currently exist in the protocol.
uint public nextTokenId = 1;
/// The Flaunch {PositionManager} contract
PositionManager public positionManager;
/// Our token implementations that will be deployed when a new token is flaunched
address public memecoinImplementation;
address public memecoinTreasuryImplementation;
/// Maps `TokenInfo` for each token ID
mapping (uint _tokenId => TokenInfo _tokenInfo) internal tokenInfo;
/// Maps a {Memecoin} ERC20 address to it's token ID
mapping (address _memecoin => uint _tokenId) public tokenId;
/// Maps our ERC20 bridging statuses
mapping (uint _tokenId => mapping (uint _chainId => uint _startedAt)) public bridgingStarted;
mapping (uint _tokenId => mapping (uint _chainId => bool _finalized)) public bridgingFinalized;
/**
* References the contract addresses for the Flaunch protocol.
*
* @param _memecoinImplementation The {Memecoin} implementation address
* @param _baseURI The default baseUri for the ERC721
*/
constructor (address _memecoinImplementation, string memory _baseURI) {
memecoinImplementation = _memecoinImplementation;
baseURI = _baseURI;
_initializeOwner(msg.sender);
}
/**
* Adds the {PositionManager} and {MemecoinTreasury} implementation addresses required to
* actually flaunch tokens, converting the contract from a satellite contract into a fully
* fledged Flaunch protocol implementation.
*
* @param _positionManager The Flaunch {PositionManager}
* @param _memecoinTreasuryImplementation The {MemecoinTreasury} implementation address
*/
function initialize(PositionManager _positionManager, address _memecoinTreasuryImplementation) external onlyOwner initializer {
positionManager = _positionManager;
memecoinTreasuryImplementation = _memecoinTreasuryImplementation;
}
/**
* Flaunches a new token, deploying the required implementations and creating a new ERC721. The
* tokens are sent to the `_creator` to prove ownership of the pool.
*/
function flaunch(
PositionManager.FlaunchParams calldata _params
) external override onlyPositionManager returns (
address memecoin_,
address payable memecoinTreasury_,
uint tokenId_
) {
// Check if the flaunch timestamp surpasses the max schedule duration
if (_params.flaunchAt > block.timestamp + MAX_SCHEDULE_DURATION) revert InvalidFlaunchSchedule();
// Ensure that the initial supply falls within an accepted range
if (_params.initialTokenFairLaunch > MAX_FAIR_LAUNCH_TOKENS) revert InvalidInitialSupply(_params.initialTokenFairLaunch);
// Check that user isn't trying to premine too many tokens
if (_params.premineAmount > _params.initialTokenFairLaunch) revert PremineExceedsInitialAmount(_params.premineAmount, _params.initialTokenFairLaunch);
// A creator cannot set their allocation above a threshold
if (_params.creatorFeeAllocation > MAX_CREATOR_ALLOCATION) revert CreatorFeeAllocationInvalid(_params.creatorFeeAllocation, MAX_CREATOR_ALLOCATION);
// Store the current token ID and increment the next token ID
tokenId_ = nextTokenId;
unchecked { nextTokenId++; }
// Mint ownership token to the creator
_mint(_params.creator, tokenId_);
// Deploy the memecoin
memecoin_ = LibClone.cloneDeterministic(memecoinImplementation, bytes32(tokenId_));
// Store the token ID
tokenId[memecoin_] = tokenId_;
// Initialize the memecoin with the metadata
IMemecoin _memecoin = IMemecoin(memecoin_);
_memecoin.initialize(_params.name, _params.symbol, _params.tokenUri);
// Deploy the memecoin treasury
memecoinTreasury_ = payable(
LibClone.cloneDeterministic(memecoinTreasuryImplementation, bytes32(tokenId_))
);
// Store the token info
tokenInfo[tokenId_] = TokenInfo(memecoin_, memecoinTreasury_);
// Mint our initial supply to the {PositionManager}
_memecoin.mint(address(positionManager), TokenSupply.INITIAL_SUPPLY);
}
/**
* Allows a contract owner to update the name and symbol of the ERC20 token so
* that if one is created with malformed, unintelligible or offensive data then
* we can replace it.
*
* @param _memecoin The memecoin address
* @param name_ The new name for the token
* @param symbol_ The new symbol for the token
*/
function setMemecoinMetadata(
address _memecoin,
string calldata name_,
string calldata symbol_
) external onlyOwner {
IMemecoin(_memecoin).setMetadata(name_, symbol_);
}
/**
* Allows a contract owner to update the base URI for the creator ERC721 tokens.
*
* @param _baseURI The new base URI
*/
function setBaseURI(string memory _baseURI) external onlyOwner {
baseURI = _baseURI;
emit BaseURIUpdated(_baseURI);
}
/**
* Allows the contract owner to update the memecoin implementation address.
*
* @param _memecoinImplementation The new memecoin implementation address
*/
function setMemecoinImplementation(address _memecoinImplementation) external onlyOwner {
memecoinImplementation = _memecoinImplementation;
emit MemecoinImplementationUpdated(_memecoinImplementation);
}
/**
* Allows the contract owner to update the memecoin treasury implementation address.
*
* @param _memecoinTreasuryImplementation The new memecoin treasury implementation address
*/
function setMemecoinTreasuryImplementation(address _memecoinTreasuryImplementation) external onlyOwner {
memecoinTreasuryImplementation = _memecoinTreasuryImplementation;
emit MemecoinTreasuryImplementationUpdated(_memecoinTreasuryImplementation);
}
/**
* Returns the ERC721 name.
*/
function name() public view override returns (string memory) {
return _name;
}
/**
* Returns the ERC721 symbol.
*/
function symbol() public view override returns (string memory) {
return _symbol;
}
/**
* Returns the Uniform Resource Identifier (URI) for token id.
*
* @dev We prevent the token from erroring if it was burned, and instead we just check against
* the current tokenId iteration we have stored.
*
* @param _tokenId The token ID to get the URI for
*/
function tokenURI(uint _tokenId) public view override returns (string memory) {
// If we are ahead of our tracked tokenIds, then revert
if (_tokenId == 0 || _tokenId >= nextTokenId) revert TokenDoesNotExist();
// If the base URI is empty, return the memecoin token URI
if (bytes(baseURI).length == 0) {
return IMemecoin(tokenInfo[_tokenId].memecoin).tokenURI();
}
// Otherwise, concatenate the base URI and the token ID
return LibString.concat(baseURI, LibString.toString(_tokenId));
}
/**
* Helper to show the {Memecoin} address for the ERC721.
*
* @param _tokenId The token ID to get the {Memecoin} for
*
* @return address {Memecoin} address
*/
function memecoin(uint _tokenId) public view returns (address) {
return tokenInfo[_tokenId].memecoin;
}
/**
* Helper to show the {MemecoinTreasury} address for the ERC721.
*
* @param _tokenId The token ID to get the {MemecoinTreasury} for
*
* @return address {MemecoinTreasury} address
*/
function memecoinTreasury(uint _tokenId) public view returns (address payable) {
return tokenInfo[_tokenId].memecoinTreasury;
}
/**
* Helper to show the {PoolId} address for the ERC721 token.
*
* @param _tokenId The token ID to get the {PoolId} for
*
* @return PoolId The {PoolId} for the token
*/
function poolId(uint _tokenId) public view returns (PoolId) {
return positionManager.poolKey(tokenInfo[_tokenId].memecoin).toId();
}
/**
* Burns `tokenId` by sending it to `address(0)`.
*
* @dev The caller must own `tokenId` or be an approved operator.
*
* @param _tokenId The token ID to check
*/
function burn(uint _tokenId) public {
_burn(msg.sender, _tokenId);
}
/**
* Allows anyone to trigger their token to be bridged to another L2. This will then relay the
* message to the other L2 which will complete the bridging flow in the `finalizeBridge`
* function call.
*
* The token contract will be created with the same salt as the initial token, so the address
* will persist, but won't mint an initial supply like the `flaunch` function call does.
*
* @dev More information regarding Superchain Interoperability can be found
* [here](https://supersim.pages.dev/guides/interop/).
*
* @param _tokenId The ERC721 memestream tokenId to bridge the memecoin of
* @param _chainId The destination L2 chainId
*/
function initializeBridge(uint _tokenId, uint _chainId) public {
// Ensure that we are not calling the same chain
if (_chainId == block.chainid) {
revert InvalidDestinationChain();
}
// Ensure that the bridge has not already been finalized
if (bridgingFinalized[_tokenId][_chainId]) {
revert TokenAlreadyBridged();
}
// If the token bridging process has already been started, then we don't allow this
// to be triggered again for a set window of time.
if (
bridgingStarted[_tokenId][_chainId] != 0 &&
block.timestamp < bridgingStarted[_tokenId][_chainId] + MAX_BRIDGING_WINDOW
) {
revert TokenAlreadyBridging();
}
// Update our bridging status to show it has started
bridgingStarted[_tokenId][_chainId] = block.timestamp;
// Find the memecoin for metadata discovery
address memecoinAddress = memecoin(_tokenId);
// If we were unable to discover the memecoin, then there is nothing to bridge
if (memecoinAddress == address(0)) {
revert UnknownMemecoin();
}
// Send the memecoin data to another L2. On previous versions of Superchain Interoperability
// this would revert in the `sendMessage` call if the target contract did not exist. However,
// in recent updates this is no longer the case, so we need to allow for this to be retried
// at a later date.
IMemecoin _memecoin = IMemecoin(memecoinAddress);
messenger.sendMessage(
_chainId,
address(this),
abi.encodeCall(
this.finalizeBridge,
(
_tokenId,
MemecoinMetadata({
name: _memecoin.name(),
symbol: _memecoin.symbol(),
tokenUri: _memecoin.tokenURI()
})
)
)
);
emit TokenBridging(_tokenId, _chainId, memecoinAddress);
}
/**
* Called after the `initializeBridge` function to validate the bridging request and subsequently
* deploy the memecoin contract code onto the L2 chain.
*
* @param _tokenId The ERC721 memestream tokenId that is being bridged
* @param _metadata Memecoin token metadata to initialize with
*/
function finalizeBridge(uint _tokenId, MemecoinMetadata memory _metadata) public onlyCrossDomainCallback {
// Map our bridging as being finalized
bridgingFinalized[_tokenId][block.chainid] = true;
// Deploy the token on this chain
address memecoin_ = LibClone.cloneDeterministic(memecoinImplementation, bytes32(_tokenId));
// Initialize the memecoin with the metadata
IMemecoin(memecoin_).initialize(_metadata.name, _metadata.symbol, _metadata.tokenUri);
// Update our bridging status
emit TokenBridged(_tokenId, block.chainid, memecoin_, messenger.crossDomainMessageSource());
}
/**
* Ensures that only the immutable {PositionManager} can call the function.
*/
modifier onlyPositionManager() {
if (msg.sender != address(positionManager)) {
revert CallerIsNotPositionManager();
}
_;
}
/**
* Modifier to restrict a function to only be a cross-domain callback into this contract.
*/
modifier onlyCrossDomainCallback() {
if (msg.sender != address(messenger)) revert CallerNotL2ToL2CrossDomainMessenger();
if (messenger.crossDomainMessageSender() != address(this)) revert InvalidCrossDomainSender();
_;
}
/**
* Override to return true to make `_initializeOwner` prevent double-initialization.
*
* @return bool Set to `true` to prevent owner being reinitialized.
*/
function _guardInitializeOwner() internal pure override returns (bool) {
return true;
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "_memecoinImplementation",
"type": "address",
"internalType": "address"
},
{
"name": "_baseURI",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "nonpayable"
},
{
"name": "AccountBalanceOverflow",
"type": "error",
"inputs": []
},
{
"name": "AlreadyInitialized",
"type": "error",
"inputs": []
},
{
"name": "BalanceQueryForZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "CallerIsNotPositionManager",
"type": "error",
"inputs": []
},
{
"name": "CallerNotL2ToL2CrossDomainMessenger",
"type": "error",
"inputs": []
},
{
"name": "CreatorFeeAllocationInvalid",
"type": "error",
"inputs": [
{
"name": "_allocation",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "_maxAllocation",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "InvalidCrossDomainSender",
"type": "error",
"inputs": []
},
{
"name": "InvalidDestinationChain",
"type": "error",
"inputs": []
},
{
"name": "InvalidFlaunchSchedule",
"type": "error",
"inputs": []
},
{
"name": "InvalidInitialSupply",
"type": "error",
"inputs": [
{
"name": "_initialSupply",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "InvalidInitialization",
"type": "error",
"inputs": []
},
{
"name": "NewOwnerIsZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "NoHandoverRequest",
"type": "error",
"inputs": []
},
{
"name": "NotInitializing",
"type": "error",
"inputs": []
},
{
"name": "NotOwnerNorApproved",
"type": "error",
"inputs": []
},
{
"name": "PremineExceedsInitialAmount",
"type": "error",
"inputs": [
{
"name": "_buyAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_initialSupply",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "TokenAlreadyBridged",
"type": "error",
"inputs": []
},
{
"name": "TokenAlreadyBridging",
"type": "error",
"inputs": []
},
{
"name": "TokenAlreadyExists",
"type": "error",
"inputs": []
},
{
"name": "TokenDoesNotExist",
"type": "error",
"inputs": []
},
{
"name": "TransferFromIncorrectOwner",
"type": "error",
"inputs": []
},
{
"name": "TransferToNonERC721ReceiverImplementer",
"type": "error",
"inputs": []
},
{
"name": "TransferToZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "Unauthorized",
"type": "error",
"inputs": []
},
{
"name": "UnknownMemecoin",
"type": "error",
"inputs": []
},
{
"name": "Approval",
"type": "event",
"inputs": [
{
"name": "owner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "account",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "id",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "ApprovalForAll",
"type": "event",
"inputs": [
{
"name": "owner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "operator",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "isApproved",
"type": "bool",
"indexed": false,
"internalType": "bool"
}
],
"anonymous": false
},
{
"name": "BaseURIUpdated",
"type": "event",
"inputs": [
{
"name": "_newBaseURI",
"type": "string",
"indexed": false,
"internalType": "string"
}
],
"anonymous": false
},
{
"name": "Initialized",
"type": "event",
"inputs": [
{
"name": "version",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "MemecoinImplementationUpdated",
"type": "event",
"inputs": [
{
"name": "_newImplementation",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "MemecoinTreasuryImplementationUpdated",
"type": "event",
"inputs": [
{
"name": "_newImplementation",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipHandoverCanceled",
"type": "event",
"inputs": [
{
"name": "pendingOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipHandoverRequested",
"type": "event",
"inputs": [
{
"name": "pendingOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "oldOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "TokenBridged",
"type": "event",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "_chainId",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "_memecoin",
"type": "address",
"indexed": false,
"internalType": "address"
},
{
"name": "_messageSource",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "TokenBridging",
"type": "event",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "_chainId",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "_memecoin",
"type": "address",
"indexed": false,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "Transfer",
"type": "event",
"inputs": [
{
"name": "from",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "id",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "MAX_BRIDGING_WINDOW",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MAX_CREATOR_ALLOCATION",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MAX_FAIR_LAUNCH_TOKENS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MAX_SCHEDULE_DURATION",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "approve",
"type": "function",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
},
{
"name": "id",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "balanceOf",
"type": "function",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "result",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "baseURI",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "bridgingFinalized",
"type": "function",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_chainId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "_finalized",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "bridgingStarted",
"type": "function",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_chainId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "_startedAt",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "burn",
"type": "function",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "cancelOwnershipHandover",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "completeOwnershipHandover",
"type": "function",
"inputs": [
{
"name": "pendingOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "finalizeBridge",
"type": "function",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_metadata",
"type": "tuple",
"components": [
{
"name": "name",
"type": "string",
"internalType": "string"
},
{
"name": "symbol",
"type": "string",
"internalType": "string"
},
{
"name": "tokenUri",
"type": "string",
"internalType": "string"
}
],
"internalType": "struct Flaunch.MemecoinMetadata"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "flaunch",
"type": "function",
"inputs": [
{
"name": "_params",
"type": "tuple",
"components": [
{
"name": "name",
"type": "string",
"internalType": "string"
},
{
"name": "symbol",
"type": "string",
"internalType": "string"
},
{
"name": "tokenUri",
"type": "string",
"internalType": "string"
},
{
"name": "initialTokenFairLaunch",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "fairLaunchDuration",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "premineAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "creator",
"type": "address",
"internalType": "address"
},
{
"name": "creatorFeeAllocation",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "flaunchAt",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "initialPriceParams",
"type": "bytes",
"internalType": "bytes"
},
{
"name": "feeCalculatorParams",
"type": "bytes",
"internalType": "bytes"
}
],
"internalType": "struct PositionManager.FlaunchParams"
}
],
"outputs": [
{
"name": "memecoin_",
"type": "address",
"internalType": "address"
},
{
"name": "memecoinTreasury_",
"type": "address",
"internalType": "address payable"
},
{
"name": "tokenId_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "getApproved",
"type": "function",
"inputs": [
{
"name": "id",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "result",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "initialize",
"type": "function",
"inputs": [
{
"name": "_positionManager",
"type": "address",
"internalType": "contract PositionManager"
},
{
"name": "_memecoinTreasuryImplementation",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "initializeBridge",
"type": "function",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "_chainId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "isApprovedForAll",
"type": "function",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
},
{
"name": "operator",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "result",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "memecoin",
"type": "function",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "memecoinImplementation",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "memecoinTreasury",
"type": "function",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address payable"
}
],
"stateMutability": "view"
},
{
"name": "memecoinTreasuryImplementation",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "name",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "nextTokenId",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "result",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "ownerOf",
"type": "function",
"inputs": [
{
"name": "id",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "result",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "ownershipHandoverExpiresAt",
"type": "function",
"inputs": [
{
"name": "pendingOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "result",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "poolId",
"type": "function",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "PoolId"
}
],
"stateMutability": "view"
},
{
"name": "positionManager",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract PositionManager"
}
],
"stateMutability": "view"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "requestOwnershipHandover",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "safeTransferFrom",
"type": "function",
"inputs": [
{
"name": "from",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "id",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "safeTransferFrom",
"type": "function",
"inputs": [
{
"name": "from",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "id",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "data",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "setApprovalForAll",
"type": "function",
"inputs": [
{
"name": "operator",
"type": "address",
"internalType": "address"
},
{
"name": "isApproved",
"type": "bool",
"internalType": "bool"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setBaseURI",
"type": "function",
"inputs": [
{
"name": "_baseURI",
"type": "string",
"internalType": "string"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setMemecoinImplementation",
"type": "function",
"inputs": [
{
"name": "_memecoinImplementation",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setMemecoinMetadata",
"type": "function",
"inputs": [
{
"name": "_memecoin",
"type": "address",
"internalType": "address"
},
{
"name": "name_",
"type": "string",
"internalType": "string"
},
{
"name": "symbol_",
"type": "string",
"internalType": "string"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setMemecoinTreasuryImplementation",
"type": "function",
"inputs": [
{
"name": "_memecoinTreasuryImplementation",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "supportsInterface",
"type": "function",
"inputs": [
{
"name": "interfaceId",
"type": "bytes4",
"internalType": "bytes4"
}
],
"outputs": [
{
"name": "result",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "symbol",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "tokenId",
"type": "function",
"inputs": [
{
"name": "_memecoin",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "_tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "tokenURI",
"type": "function",
"inputs": [
{
"name": "_tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "transferFrom",
"type": "function",
"inputs": [
{
"name": "from",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "id",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "payable"
}
]0x5f80546001600160a01b03191673420000000000000000000000000000000000002317905560c0604052601760809081527f466c61756e636820526576656e75652053747265616d7300000000000000000060a05260019061006190826101e5565b5060408051808201909152600781526608c9882aa9c86960cb1b602082015260029061008d90826101e5565b50600160045534801561009e575f80fd5b506040516129993803806129998339810160408190526100bd9161029f565b600680546001600160a01b0319166001600160a01b03841617905560036100e482826101e5565b506100ee336100f5565b505061036e565b638b78c6d81980541561010f57630dc149f05f526004601cfd5b6001600160a01b03909116801560ff1b8117909155805f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061017557607f821691505b60208210810361019357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156101e057805f5260205f20601f840160051c810160208510156101be5750805b601f840160051c820191505b818110156101dd575f81556001016101ca565b50505b505050565b81516001600160401b038111156101fe576101fe61014d565b6102128161020c8454610161565b84610199565b6020601f821160018114610244575f831561022d5750848201515b5f19600385901b1c1916600184901b1784556101dd565b5f84815260208120601f198516915b828110156102735787850151825560209485019460019092019101610253565b508482101561029057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f80604083850312156102b0575f80fd5b82516001600160a01b03811681146102c6575f80fd5b60208401519092506001600160401b038111156102e1575f80fd5b8301601f810185136102f1575f80fd5b80516001600160401b0381111561030a5761030a61014d565b604051601f8201601f19908116603f011681016001600160401b03811182821017156103385761033861014d565b60405281815282820160200187101561034f575f80fd5b8160208401602083015e5f602083830101528093505050509250929050565b61261e8061037b5f395ff3fe6080604052600436106101f6575f3560e01c806301ffc9a7146101fa57806305f77c6f1461024b57806306fdde0314610290578063081812fc146102b1578063095ea7b3146102dd5780630a57aaf5146102f25780631a5de1df1461032b57806323b872dd1461034a57806324f9bbb81461035d578063256929621461037c5780632b31d94a1461038457806342842e0e146103a357806342966c68146103b657806346ce21f8146103d5578063485cc955146103f457806354d1f13d1461041357806355f804b31461041b5780635a3617fc1461043a5780635b7426be146104675780635f1514751461047d5780636352211e146104925780636c0360eb146104b157806370a08231146104c5578063715018a6146104e457806375794a3c146104ec578063791b98bc146105015780637ca3172414610520578063829f042a1461054b5780638da5cb5b1461056a57806395d89b411461058257806397cd41a8146105965780639dab7831146105b5578063a22cb465146105eb578063b88d4fde1461060a578063bb100a1a1461061d578063bf989c7814610632578063c87b56dd14610651578063e49c185414610670578063e4b47c0b1461068f578063e985e9c5146106ae578063f04e283e146106e1578063f2fde38b146106f4578063f38f955014610707578063fee81cf41461073e575b5f80fd5b348015610205575f80fd5b50610236610214366004611c70565b6301ffc9a760e09190911c9081146380ac58cd821417635b5e139f9091141790565b60405190151581526020015b60405180910390f35b348015610256575f80fd5b5061026a610265366004611c97565b61076f565b604080516001600160a01b03948516815293909216602084015290820152606001610242565b34801561029b575f80fd5b506102a4610a50565b6040516102429190611cfc565b3480156102bc575f80fd5b506102d06102cb366004611d0e565b610ae0565b6040516102429190611d25565b6102f06102eb366004611d4d565b610b1b565b005b3480156102fd575f80fd5b5061023661030c366004611d77565b600b60209081525f928352604080842090915290825290205460ff1681565b348015610336575f80fd5b506007546102d0906001600160a01b031681565b6102f0610358366004611d97565b610b2a565b348015610368575f80fd5b506102f0610377366004611dd5565b610c11565b6102f0610c6f565b34801561038f575f80fd5b506102f061039e366004611ed4565b610cbb565b6102f06103b1366004611d97565b610eea565b3480156103c1575f80fd5b506102f06103d0366004611d0e565b610f16565b3480156103e0575f80fd5b506102f06103ef366004611dd5565b610f23565b3480156103ff575f80fd5b506102f061040e366004611f9e565b610f76565b6102f061101e565b348015610426575f80fd5b506102f0610435366004611fd5565b611057565b348015610445575f80fd5b50610459610454366004611d0e565b61109b565b604051908152602001610242565b348015610472575f80fd5b5061045962278d0081565b348015610488575f80fd5b5061045961271081565b34801561049d575f80fd5b506102d06104ac366004611d0e565b61112c565b3480156104bc575f80fd5b506102a4611168565b3480156104d0575f80fd5b506104596104df366004611dd5565b6111f4565b6102f061122c565b3480156104f7575f80fd5b5061045960045481565b34801561050c575f80fd5b506005546102d0906001600160a01b031681565b34801561052b575f80fd5b5061045961053a366004611dd5565b60096020525f908152604090205481565b348015610556575f80fd5b506102f0610565366004612052565b61123f565b348015610575575f80fd5b50638b78c6d819546102d0565b34801561058d575f80fd5b506102a46112ad565b3480156105a1575f80fd5b50610459680a18f07d736b90be55601d1b81565b3480156105c0575f80fd5b506104596105cf366004611d77565b600a60209081525f928352604080842090915290825290205481565b3480156105f6575f80fd5b506102f06106053660046120d2565b6112bc565b6102f0610618366004612102565b61130e565b348015610628575f80fd5b50610459610e1081565b34801561063d575f80fd5b506006546102d0906001600160a01b031681565b34801561065c575f80fd5b506102a461066b366004611d0e565b611368565b34801561067b575f80fd5b506102d061068a366004611d0e565b6114ba565b34801561069a575f80fd5b506102f06106a9366004611d77565b6114d4565b3480156106b9575f80fd5b506102366106c8366004611f9e565b601c5263052d173d60211b6008525f526030600c205490565b6102f06106ef366004611dd5565b611842565b6102f0610702366004611dd5565b61187c565b348015610712575f80fd5b506102d0610721366004611d0e565b5f908152600860205260409020600101546001600160a01b031690565b348015610749575f80fd5b50610459610758366004611dd5565b63389a75e1600c9081525f91909152602090205490565b6005545f90819081906001600160a01b031633146107a057604051630a2840f360e01b815260040160405180910390fd5b6107ad62278d0042612152565b84610100013511156107d257604051630f0ffca560e41b815260040160405180910390fd5b680a18f07d736b90be55601d1b8460600135111561080e57604051631554010f60e01b8152606085013560048201526024015b60405180910390fd5b83606001358460a00135111561084757604051639f68473d60e01b815260a0850135600482015260608501356024820152604401610805565b61271061085b610100860160e08701612181565b62ffffff1611156108a057610877610100850160e08601612181565b604051633707e93960e21b815262ffffff90911660048201526127106024820152604401610805565b5060048054600181019091556108c56108bf60e0860160c08701611dd5565b826118a2565b6006546108db906001600160a01b03168261192b565b6001600160a01b0381165f818152600960205260409020839055909350839063a6487c53610909878061219c565b61091660208a018a61219c565b61092360408c018c61219c565b6040518763ffffffff1660e01b815260040161094496959493929190612206565b5f604051808303815f87803b15801561095b575f80fd5b505af115801561096d573d5f803e3d5ffd5b505060075461098892506001600160a01b031690508361192b565b6040805180820182526001600160a01b03878116825283811660208084019182525f8881526008909152849020925183549083166001600160a01b0319918216178455905160019093018054938316939091169290921790915560055491516340c10f1960e01b81529181166004830152680a18f07d736b90be55601d1b6024830152919450908216906340c10f19906044015f604051808303815f87803b158015610a32575f80fd5b505af1158015610a44573d5f803e3d5ffd5b50505050509193909250565b606060018054610a5f9061224e565b80601f0160208091040260200160405190810160405280929190818152602001828054610a8b9061224e565b8015610ad65780601f10610aad57610100808354040283529160200191610ad6565b820191905f5260205f20905b815481529060010190602001808311610ab957829003601f168201915b5050505050905090565b5f815f52673ec412a9852d173d60c11b601c5260205f2082018201805460601b610b115763ceea21b65f526004601cfd5b6001015492915050565b610b2633838361193e565b5050565b5f818152673ec412a9852d173d60c11b3317601c52602090208101810180546001600160a01b039485169493841693811691908286148302610b7b5767ceea21b6a1148100831560021b526004601cfd5b855f528160010154925082331486331417610ba7576030600c2054610ba757634b6e7f185f526004601cfd5b8215610bb4575f82600101555b85851818905550601c600c81812080545f190190555f84905220805460010163ffffffff81168402610bf55767ea553b3401336cea841560021b526004601cfd5b90558082845f805160206125c98339815191525f38a45b505050565b610c196119d8565b600680546001600160a01b0319166001600160a01b0383161790556040517fbe7d62d85347642e2d9359b1cdd36015e64d5fc54b52bb4be4f23a56aa6f070190610c64908390611d25565b60405180910390a150565b5f6202a3006001600160401b03164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a250565b5f546001600160a01b03163314610ce4576040516265d51560e41b815260040160405180910390fd5b5f546040805163071ffbc360e31b8152905130926001600160a01b0316916338ffde189160048083019260209291908290030181865afa158015610d2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d4e9190612286565b6001600160a01b031614610d7557604051635e11715560e11b815260040160405180910390fd5b5f828152600b602090815260408083204684529091528120805460ff19166001179055600654610dae906001600160a01b03168461192b565b82516020840151604080860151905163a6487c5360e01b81529394506001600160a01b0385169363a6487c5393610deb93909290916004016122a1565b5f604051808303815f87803b158015610e02575f80fd5b505af1158015610e14573d5f803e3d5ffd5b505050507fd953cced6d6de41e29efa3f395f6815b35e5a0bb1bff016cb796b95e34a932548346835f8054906101000a90046001600160a01b03166001600160a01b031663247944626040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eae91906122e3565b604051610edd949392919093845260208401929092526001600160a01b03166040830152606082015260800190565b60405180910390a1505050565b610ef5838383610b2a565b813b15610c0c57610c0c83838360405180602001604052805f8152506119f2565b610f203382611a7b565b50565b610f2b6119d8565b600780546001600160a01b0319166001600160a01b0383161790556040517fcaaf51427c43b5149933a25a5d5506daee532e95fd7a9b406c37db11b8674d3990610c64908390611d25565b610f7e6119d8565b63409feecd198054600382558015610fb45760018160011c14303b10610fab5763f92ee8a95f526004601cfd5b818160ff1b1b91505b50600580546001600160a01b038086166001600160a01b03199283161790925560078054928516929091169190911790558015610c0c576002815560016020527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602080a1505050565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2565b61105f6119d8565b600361106b828261233e565b507f6741b2fc379fad678116fe3d4d4b9a1a184ab53ba36b86ad0fa66340b1ab41ad81604051610c649190611cfc565b6005545f828152600860205260408082205490516302ae8e5b60e51b81529192611126926001600160a01b03918216926355d1cb60926110e092911690600401611d25565b60a060405180830381865afa1580156110fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061111f91906123f8565b60a0902090565b92915050565b5f818152673ec412a9852d173d60c11b601c526020902081018101546001600160a01b0316806111635763ceea21b65f526004601cfd5b919050565b600380546111759061224e565b80601f01602080910402602001604051908101604052809291908181526020018280546111a19061224e565b80156111ec5780601f106111c3576101008083540402835291602001916111ec565b820191905f5260205f20905b8154815290600101906020018083116111cf57829003601f168201915b505050505081565b5f8161120757638f4eb6045f526004601cfd5b673ec412a9852d173d60c11b601c52815f5263ffffffff601c600c2054169050919050565b6112346119d8565b61123d5f611b2e565b565b6112476119d8565b60405163051335b560e41b81526001600160a01b038616906351335b5090611279908790879087908790600401612495565b5f604051808303815f87803b158015611290575f80fd5b505af11580156112a2573d5f803e3d5ffd5b505050505050505050565b606060028054610a5f9061224e565b801515905081601c5263052d173d60211b600852335f52806030600c2055805f528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160205fa35050565b611319858585610b2a565b833b156113615761136185858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506119f292505050565b5050505050565b606081158061137957506004548210155b156113975760405163677510db60e11b815260040160405180910390fd5b600380546113a49061224e565b90505f03611420575f828152600860205260408082205481516303c130d960e41b815291516001600160a01b0390911692633c130d9092600480820193918290030181865afa1580156113f9573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261112691908101906124c6565b611126600380546114309061224e565b80601f016020809104026020016040519081016040528092919081815260200182805461145c9061224e565b80156114a75780601f1061147e576101008083540402835291602001916114a7565b820191905f5260205f20905b81548152906001019060200180831161148a57829003601f168201915b50505050506114b584611b74565b611bb6565b5f908152600860205260409020546001600160a01b031690565b4681036114f45760405163b86ac1ef60e01b815260040160405180910390fd5b5f828152600b6020908152604080832084845290915290205460ff161561152e57604051635314a19160e11b815260040160405180910390fd5b5f828152600a602090815260408083208484529091529020541580159061157957505f828152600a6020908152604080832084845290915290205461157690610e1090612152565b42105b1561159757604051636e4dce4b60e11b815260040160405180910390fd5b5f828152600a6020908152604080832084845290915281204290556115bb836114ba565b90506001600160a01b0381166115e45760405163a4c0139760e01b815260040160405180910390fd5b5f8190505f8054906101000a90046001600160a01b03166001600160a01b0316637056f41f8430306001600160a01b0316632b31d94a896040518060600160405280896001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015611661573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261168891908101906124c6565b8152602001896001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa1580156116c8573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526116ef91908101906124c6565b8152602001896001600160a01b0316633c130d906040518163ffffffff1660e01b81526004015f60405180830381865afa15801561172f573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261175691908101906124c6565b905260405161176992919060240161253a565b60408051808303601f1901815291815260208201805160e094851b6001600160e01b03909116179052519186901b6001600160e01b03191682526117b39493925090600401612596565b6020604051808303815f875af11580156117cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f391906122e3565b5060408051858152602081018590526001600160a01b0384168183015290517ff2a584a2309fee3f807e426ce11328f237b9bc191989cbc6f62cc5fee1d6b46f9181900360600190a150505050565b61184a6119d8565b63389a75e1600c52805f526020600c20805442111561187057636f5e88185f526004601cfd5b5f9055610f2081611b2e565b6118846119d8565b8060601b61189957637448fbae5f526004601cfd5b610f2081611b2e565b8160601b60601c9150805f52673ec412a9852d173d60c11b601c5260205f208101810180548060601b156118dd5763c991cbb15f526004601cfd5b831790555f829052601c600c20805460010163ffffffff811684026119115767ea553b3401336cea841560021b526004601cfd5b905580825f5f805160206125c98339815191528138a45050565b5f6119375f8484611bc2565b9392505050565b5f1960601c82811692508381169350815f5283673ec412a9852d173d60c11b17601c5260205f2082018201805482169150816119815763ceea21b65f526004601cfd5b8185148515176119a557815f526030600c20546119a557634b6e7f185f526004601cfd5b6001018390558183827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f38a450505050565b638b78c6d81954331461123d576382b429005f526004601cfd5b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a08401528015611a39578060c08401826020870160045afa505b60208360a48301601c86015f8a5af1611a5a573d15611a5a573d5f843e3d83fd5b508060e01b825114611a735763d1a57ed65f526004601cfd5b505050505050565b5f611a858261112c565b9050505f8181526001600160a01b03928316673ec412a9852d173d60c11b8117601c526020909120820182018054919382169182611aca5763ceea21b65f526004601cfd5b825f52816001015480861484871417861517611af7576030600c2054611af757634b6e7f185f526004601cfd5b8015611b04575f83600101555b5082189055601c600c2080545f19019055815f825f805160206125c98339815191528238a4505050565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3811560ff1b8217905550565b60606080604051019050602081016040525f8152805f19835b928101926030600a8206018453600a900480611b8d575050819003601f19909101908152919050565b60606119378383611c15565b5f6c5af43d3d93803e602a57fd5bf36021528260145273602c3d8160093d39f33d3d3d3d363d3d37363d735f52816035600c86f5905080611c0a5763301164255f526004601cfd5b5f6021529392505050565b6040518251601f19906020810182165b8581015184820152820180611c25575083518184018360208301165b8681015182820152840180611c415750505f910183810160208101929092528352604090810190525092915050565b5f60208284031215611c80575f80fd5b81356001600160e01b031981168114611937575f80fd5b5f60208284031215611ca7575f80fd5b81356001600160401b03811115611cbc575f80fd5b82016101608185031215611937575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6119376020830184611cce565b5f60208284031215611d1e575f80fd5b5035919050565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114610f20575f80fd5b5f8060408385031215611d5e575f80fd5b8235611d6981611d39565b946020939093013593505050565b5f8060408385031215611d88575f80fd5b50508035926020909101359150565b5f805f60608486031215611da9575f80fd5b8335611db481611d39565b92506020840135611dc481611d39565b929592945050506040919091013590565b5f60208284031215611de5575f80fd5b813561193781611d39565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b0381118282101715611e2657611e26611df0565b60405290565b604051601f8201601f191681016001600160401b0381118282101715611e5457611e54611df0565b604052919050565b5f6001600160401b03821115611e7457611e74611df0565b50601f01601f191660200190565b5f82601f830112611e91575f80fd5b8135611ea4611e9f82611e5c565b611e2c565b818152846020838601011115611eb8575f80fd5b816020850160208301375f918101602001919091529392505050565b5f8060408385031215611ee5575f80fd5b8235915060208301356001600160401b03811115611f01575f80fd5b830160608186031215611f12575f80fd5b611f1a611e04565b81356001600160401b03811115611f2f575f80fd5b611f3b87828501611e82565b82525060208201356001600160401b03811115611f56575f80fd5b611f6287828501611e82565b60208301525060408201356001600160401b03811115611f80575f80fd5b611f8c87828501611e82565b60408301525080925050509250929050565b5f8060408385031215611faf575f80fd5b8235611fba81611d39565b91506020830135611fca81611d39565b809150509250929050565b5f60208284031215611fe5575f80fd5b81356001600160401b03811115611ffa575f80fd5b61200684828501611e82565b949350505050565b5f8083601f84011261201e575f80fd5b5081356001600160401b03811115612034575f80fd5b60208301915083602082850101111561204b575f80fd5b9250929050565b5f805f805f60608688031215612066575f80fd5b853561207181611d39565b945060208601356001600160401b0381111561208b575f80fd5b6120978882890161200e565b90955093505060408601356001600160401b038111156120b5575f80fd5b6120c18882890161200e565b969995985093965092949392505050565b5f80604083850312156120e3575f80fd5b82356120ee81611d39565b915060208301358015158114611fca575f80fd5b5f805f805f60808688031215612116575f80fd5b853561212181611d39565b9450602086013561213181611d39565b93506040860135925060608601356001600160401b038111156120b5575f80fd5b8082018082111561112657634e487b7160e01b5f52601160045260245ffd5b62ffffff81168114610f20575f80fd5b5f60208284031215612191575f80fd5b813561193781612171565b5f808335601e198436030181126121b1575f80fd5b8301803591506001600160401b038211156121ca575f80fd5b60200191503681900382131561204b575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b606081525f61221960608301888a6121de565b828103602084015261222c8187896121de565b905082810360408401526122418185876121de565b9998505050505050505050565b600181811c9082168061226257607f821691505b60208210810361228057634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215612296575f80fd5b815161193781611d39565b606081525f6122b36060830186611cce565b82810360208401526122c58186611cce565b905082810360408401526122d98185611cce565b9695505050505050565b5f602082840312156122f3575f80fd5b5051919050565b601f821115610c0c57805f5260205f20601f840160051c8101602085101561231f5750805b601f840160051c820191505b81811015611361575f815560010161232b565b81516001600160401b0381111561235757612357611df0565b61236b81612365845461224e565b846122fa565b6020601f82116001811461239d575f83156123865750848201515b5f19600385901b1c1916600184901b178455611361565b5f84815260208120601f198516915b828110156123cc57878501518255602094850194600190920191016123ac565b50848210156123e957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60a0828403128015612409575f80fd5b5060405160a081016001600160401b038111828210171561242c5761242c611df0565b604052825161243a81611d39565b8152602083015161244a81611d39565b6020820152604083015161245d81612171565b60408201526060830151600281900b8114612476575f80fd5b6060820152608083015161248981611d39565b60808201529392505050565b604081525f6124a86040830186886121de565b82810360208401526124bb8185876121de565b979650505050505050565b5f602082840312156124d6575f80fd5b81516001600160401b038111156124eb575f80fd5b8201601f810184136124fb575f80fd5b8051612509611e9f82611e5c565b81815285602083850101111561251d575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b828152604060208201525f82516060604084015261255b60a0840182611cce565b90506020840151603f198483030160608501526125788282611cce565b9150506040840151603f198483030160808501526122d98282611cce565b8381526001600160a01b03831660208201526060604082018190525f906125bf90830184611cce565b9594505050505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122059d2e14d0b2e895458de86057601241ae81351ff5d038a0dc80a829b7903713564736f6c634300081a00330000000000000000000000007e0a48a48edb29520e57298964f966df4154930a0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002168747470733a2f2f73706c69746172726f772e66756e2f6170692f746f6b656e2f00000000000000000000000000000000000000000000000000000000000000
0x6080604052600436106101f6575f3560e01c806301ffc9a7146101fa57806305f77c6f1461024b57806306fdde0314610290578063081812fc146102b1578063095ea7b3146102dd5780630a57aaf5146102f25780631a5de1df1461032b57806323b872dd1461034a57806324f9bbb81461035d578063256929621461037c5780632b31d94a1461038457806342842e0e146103a357806342966c68146103b657806346ce21f8146103d5578063485cc955146103f457806354d1f13d1461041357806355f804b31461041b5780635a3617fc1461043a5780635b7426be146104675780635f1514751461047d5780636352211e146104925780636c0360eb146104b157806370a08231146104c5578063715018a6146104e457806375794a3c146104ec578063791b98bc146105015780637ca3172414610520578063829f042a1461054b5780638da5cb5b1461056a57806395d89b411461058257806397cd41a8146105965780639dab7831146105b5578063a22cb465146105eb578063b88d4fde1461060a578063bb100a1a1461061d578063bf989c7814610632578063c87b56dd14610651578063e49c185414610670578063e4b47c0b1461068f578063e985e9c5146106ae578063f04e283e146106e1578063f2fde38b146106f4578063f38f955014610707578063fee81cf41461073e575b5f80fd5b348015610205575f80fd5b50610236610214366004611c70565b6301ffc9a760e09190911c9081146380ac58cd821417635b5e139f9091141790565b60405190151581526020015b60405180910390f35b348015610256575f80fd5b5061026a610265366004611c97565b61076f565b604080516001600160a01b03948516815293909216602084015290820152606001610242565b34801561029b575f80fd5b506102a4610a50565b6040516102429190611cfc565b3480156102bc575f80fd5b506102d06102cb366004611d0e565b610ae0565b6040516102429190611d25565b6102f06102eb366004611d4d565b610b1b565b005b3480156102fd575f80fd5b5061023661030c366004611d77565b600b60209081525f928352604080842090915290825290205460ff1681565b348015610336575f80fd5b506007546102d0906001600160a01b031681565b6102f0610358366004611d97565b610b2a565b348015610368575f80fd5b506102f0610377366004611dd5565b610c11565b6102f0610c6f565b34801561038f575f80fd5b506102f061039e366004611ed4565b610cbb565b6102f06103b1366004611d97565b610eea565b3480156103c1575f80fd5b506102f06103d0366004611d0e565b610f16565b3480156103e0575f80fd5b506102f06103ef366004611dd5565b610f23565b3480156103ff575f80fd5b506102f061040e366004611f9e565b610f76565b6102f061101e565b348015610426575f80fd5b506102f0610435366004611fd5565b611057565b348015610445575f80fd5b50610459610454366004611d0e565b61109b565b604051908152602001610242565b348015610472575f80fd5b5061045962278d0081565b348015610488575f80fd5b5061045961271081565b34801561049d575f80fd5b506102d06104ac366004611d0e565b61112c565b3480156104bc575f80fd5b506102a4611168565b3480156104d0575f80fd5b506104596104df366004611dd5565b6111f4565b6102f061122c565b3480156104f7575f80fd5b5061045960045481565b34801561050c575f80fd5b506005546102d0906001600160a01b031681565b34801561052b575f80fd5b5061045961053a366004611dd5565b60096020525f908152604090205481565b348015610556575f80fd5b506102f0610565366004612052565b61123f565b348015610575575f80fd5b50638b78c6d819546102d0565b34801561058d575f80fd5b506102a46112ad565b3480156105a1575f80fd5b50610459680a18f07d736b90be55601d1b81565b3480156105c0575f80fd5b506104596105cf366004611d77565b600a60209081525f928352604080842090915290825290205481565b3480156105f6575f80fd5b506102f06106053660046120d2565b6112bc565b6102f0610618366004612102565b61130e565b348015610628575f80fd5b50610459610e1081565b34801561063d575f80fd5b506006546102d0906001600160a01b031681565b34801561065c575f80fd5b506102a461066b366004611d0e565b611368565b34801561067b575f80fd5b506102d061068a366004611d0e565b6114ba565b34801561069a575f80fd5b506102f06106a9366004611d77565b6114d4565b3480156106b9575f80fd5b506102366106c8366004611f9e565b601c5263052d173d60211b6008525f526030600c205490565b6102f06106ef366004611dd5565b611842565b6102f0610702366004611dd5565b61187c565b348015610712575f80fd5b506102d0610721366004611d0e565b5f908152600860205260409020600101546001600160a01b031690565b348015610749575f80fd5b50610459610758366004611dd5565b63389a75e1600c9081525f91909152602090205490565b6005545f90819081906001600160a01b031633146107a057604051630a2840f360e01b815260040160405180910390fd5b6107ad62278d0042612152565b84610100013511156107d257604051630f0ffca560e41b815260040160405180910390fd5b680a18f07d736b90be55601d1b8460600135111561080e57604051631554010f60e01b8152606085013560048201526024015b60405180910390fd5b83606001358460a00135111561084757604051639f68473d60e01b815260a0850135600482015260608501356024820152604401610805565b61271061085b610100860160e08701612181565b62ffffff1611156108a057610877610100850160e08601612181565b604051633707e93960e21b815262ffffff90911660048201526127106024820152604401610805565b5060048054600181019091556108c56108bf60e0860160c08701611dd5565b826118a2565b6006546108db906001600160a01b03168261192b565b6001600160a01b0381165f818152600960205260409020839055909350839063a6487c53610909878061219c565b61091660208a018a61219c565b61092360408c018c61219c565b6040518763ffffffff1660e01b815260040161094496959493929190612206565b5f604051808303815f87803b15801561095b575f80fd5b505af115801561096d573d5f803e3d5ffd5b505060075461098892506001600160a01b031690508361192b565b6040805180820182526001600160a01b03878116825283811660208084019182525f8881526008909152849020925183549083166001600160a01b0319918216178455905160019093018054938316939091169290921790915560055491516340c10f1960e01b81529181166004830152680a18f07d736b90be55601d1b6024830152919450908216906340c10f19906044015f604051808303815f87803b158015610a32575f80fd5b505af1158015610a44573d5f803e3d5ffd5b50505050509193909250565b606060018054610a5f9061224e565b80601f0160208091040260200160405190810160405280929190818152602001828054610a8b9061224e565b8015610ad65780601f10610aad57610100808354040283529160200191610ad6565b820191905f5260205f20905b815481529060010190602001808311610ab957829003601f168201915b5050505050905090565b5f815f52673ec412a9852d173d60c11b601c5260205f2082018201805460601b610b115763ceea21b65f526004601cfd5b6001015492915050565b610b2633838361193e565b5050565b5f818152673ec412a9852d173d60c11b3317601c52602090208101810180546001600160a01b039485169493841693811691908286148302610b7b5767ceea21b6a1148100831560021b526004601cfd5b855f528160010154925082331486331417610ba7576030600c2054610ba757634b6e7f185f526004601cfd5b8215610bb4575f82600101555b85851818905550601c600c81812080545f190190555f84905220805460010163ffffffff81168402610bf55767ea553b3401336cea841560021b526004601cfd5b90558082845f805160206125c98339815191525f38a45b505050565b610c196119d8565b600680546001600160a01b0319166001600160a01b0383161790556040517fbe7d62d85347642e2d9359b1cdd36015e64d5fc54b52bb4be4f23a56aa6f070190610c64908390611d25565b60405180910390a150565b5f6202a3006001600160401b03164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a250565b5f546001600160a01b03163314610ce4576040516265d51560e41b815260040160405180910390fd5b5f546040805163071ffbc360e31b8152905130926001600160a01b0316916338ffde189160048083019260209291908290030181865afa158015610d2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d4e9190612286565b6001600160a01b031614610d7557604051635e11715560e11b815260040160405180910390fd5b5f828152600b602090815260408083204684529091528120805460ff19166001179055600654610dae906001600160a01b03168461192b565b82516020840151604080860151905163a6487c5360e01b81529394506001600160a01b0385169363a6487c5393610deb93909290916004016122a1565b5f604051808303815f87803b158015610e02575f80fd5b505af1158015610e14573d5f803e3d5ffd5b505050507fd953cced6d6de41e29efa3f395f6815b35e5a0bb1bff016cb796b95e34a932548346835f8054906101000a90046001600160a01b03166001600160a01b031663247944626040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eae91906122e3565b604051610edd949392919093845260208401929092526001600160a01b03166040830152606082015260800190565b60405180910390a1505050565b610ef5838383610b2a565b813b15610c0c57610c0c83838360405180602001604052805f8152506119f2565b610f203382611a7b565b50565b610f2b6119d8565b600780546001600160a01b0319166001600160a01b0383161790556040517fcaaf51427c43b5149933a25a5d5506daee532e95fd7a9b406c37db11b8674d3990610c64908390611d25565b610f7e6119d8565b63409feecd198054600382558015610fb45760018160011c14303b10610fab5763f92ee8a95f526004601cfd5b818160ff1b1b91505b50600580546001600160a01b038086166001600160a01b03199283161790925560078054928516929091169190911790558015610c0c576002815560016020527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602080a1505050565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2565b61105f6119d8565b600361106b828261233e565b507f6741b2fc379fad678116fe3d4d4b9a1a184ab53ba36b86ad0fa66340b1ab41ad81604051610c649190611cfc565b6005545f828152600860205260408082205490516302ae8e5b60e51b81529192611126926001600160a01b03918216926355d1cb60926110e092911690600401611d25565b60a060405180830381865afa1580156110fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061111f91906123f8565b60a0902090565b92915050565b5f818152673ec412a9852d173d60c11b601c526020902081018101546001600160a01b0316806111635763ceea21b65f526004601cfd5b919050565b600380546111759061224e565b80601f01602080910402602001604051908101604052809291908181526020018280546111a19061224e565b80156111ec5780601f106111c3576101008083540402835291602001916111ec565b820191905f5260205f20905b8154815290600101906020018083116111cf57829003601f168201915b505050505081565b5f8161120757638f4eb6045f526004601cfd5b673ec412a9852d173d60c11b601c52815f5263ffffffff601c600c2054169050919050565b6112346119d8565b61123d5f611b2e565b565b6112476119d8565b60405163051335b560e41b81526001600160a01b038616906351335b5090611279908790879087908790600401612495565b5f604051808303815f87803b158015611290575f80fd5b505af11580156112a2573d5f803e3d5ffd5b505050505050505050565b606060028054610a5f9061224e565b801515905081601c5263052d173d60211b600852335f52806030600c2055805f528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160205fa35050565b611319858585610b2a565b833b156113615761136185858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506119f292505050565b5050505050565b606081158061137957506004548210155b156113975760405163677510db60e11b815260040160405180910390fd5b600380546113a49061224e565b90505f03611420575f828152600860205260408082205481516303c130d960e41b815291516001600160a01b0390911692633c130d9092600480820193918290030181865afa1580156113f9573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261112691908101906124c6565b611126600380546114309061224e565b80601f016020809104026020016040519081016040528092919081815260200182805461145c9061224e565b80156114a75780601f1061147e576101008083540402835291602001916114a7565b820191905f5260205f20905b81548152906001019060200180831161148a57829003601f168201915b50505050506114b584611b74565b611bb6565b5f908152600860205260409020546001600160a01b031690565b4681036114f45760405163b86ac1ef60e01b815260040160405180910390fd5b5f828152600b6020908152604080832084845290915290205460ff161561152e57604051635314a19160e11b815260040160405180910390fd5b5f828152600a602090815260408083208484529091529020541580159061157957505f828152600a6020908152604080832084845290915290205461157690610e1090612152565b42105b1561159757604051636e4dce4b60e11b815260040160405180910390fd5b5f828152600a6020908152604080832084845290915281204290556115bb836114ba565b90506001600160a01b0381166115e45760405163a4c0139760e01b815260040160405180910390fd5b5f8190505f8054906101000a90046001600160a01b03166001600160a01b0316637056f41f8430306001600160a01b0316632b31d94a896040518060600160405280896001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015611661573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261168891908101906124c6565b8152602001896001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa1580156116c8573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526116ef91908101906124c6565b8152602001896001600160a01b0316633c130d906040518163ffffffff1660e01b81526004015f60405180830381865afa15801561172f573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261175691908101906124c6565b905260405161176992919060240161253a565b60408051808303601f1901815291815260208201805160e094851b6001600160e01b03909116179052519186901b6001600160e01b03191682526117b39493925090600401612596565b6020604051808303815f875af11580156117cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117f391906122e3565b5060408051858152602081018590526001600160a01b0384168183015290517ff2a584a2309fee3f807e426ce11328f237b9bc191989cbc6f62cc5fee1d6b46f9181900360600190a150505050565b61184a6119d8565b63389a75e1600c52805f526020600c20805442111561187057636f5e88185f526004601cfd5b5f9055610f2081611b2e565b6118846119d8565b8060601b61189957637448fbae5f526004601cfd5b610f2081611b2e565b8160601b60601c9150805f52673ec412a9852d173d60c11b601c5260205f208101810180548060601b156118dd5763c991cbb15f526004601cfd5b831790555f829052601c600c20805460010163ffffffff811684026119115767ea553b3401336cea841560021b526004601cfd5b905580825f5f805160206125c98339815191528138a45050565b5f6119375f8484611bc2565b9392505050565b5f1960601c82811692508381169350815f5283673ec412a9852d173d60c11b17601c5260205f2082018201805482169150816119815763ceea21b65f526004601cfd5b8185148515176119a557815f526030600c20546119a557634b6e7f185f526004601cfd5b6001018390558183827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f38a450505050565b638b78c6d81954331461123d576382b429005f526004601cfd5b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a08401528015611a39578060c08401826020870160045afa505b60208360a48301601c86015f8a5af1611a5a573d15611a5a573d5f843e3d83fd5b508060e01b825114611a735763d1a57ed65f526004601cfd5b505050505050565b5f611a858261112c565b9050505f8181526001600160a01b03928316673ec412a9852d173d60c11b8117601c526020909120820182018054919382169182611aca5763ceea21b65f526004601cfd5b825f52816001015480861484871417861517611af7576030600c2054611af757634b6e7f185f526004601cfd5b8015611b04575f83600101555b5082189055601c600c2080545f19019055815f825f805160206125c98339815191528238a4505050565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3811560ff1b8217905550565b60606080604051019050602081016040525f8152805f19835b928101926030600a8206018453600a900480611b8d575050819003601f19909101908152919050565b60606119378383611c15565b5f6c5af43d3d93803e602a57fd5bf36021528260145273602c3d8160093d39f33d3d3d3d363d3d37363d735f52816035600c86f5905080611c0a5763301164255f526004601cfd5b5f6021529392505050565b6040518251601f19906020810182165b8581015184820152820180611c25575083518184018360208301165b8681015182820152840180611c415750505f910183810160208101929092528352604090810190525092915050565b5f60208284031215611c80575f80fd5b81356001600160e01b031981168114611937575f80fd5b5f60208284031215611ca7575f80fd5b81356001600160401b03811115611cbc575f80fd5b82016101608185031215611937575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6119376020830184611cce565b5f60208284031215611d1e575f80fd5b5035919050565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114610f20575f80fd5b5f8060408385031215611d5e575f80fd5b8235611d6981611d39565b946020939093013593505050565b5f8060408385031215611d88575f80fd5b50508035926020909101359150565b5f805f60608486031215611da9575f80fd5b8335611db481611d39565b92506020840135611dc481611d39565b929592945050506040919091013590565b5f60208284031215611de5575f80fd5b813561193781611d39565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b0381118282101715611e2657611e26611df0565b60405290565b604051601f8201601f191681016001600160401b0381118282101715611e5457611e54611df0565b604052919050565b5f6001600160401b03821115611e7457611e74611df0565b50601f01601f191660200190565b5f82601f830112611e91575f80fd5b8135611ea4611e9f82611e5c565b611e2c565b818152846020838601011115611eb8575f80fd5b816020850160208301375f918101602001919091529392505050565b5f8060408385031215611ee5575f80fd5b8235915060208301356001600160401b03811115611f01575f80fd5b830160608186031215611f12575f80fd5b611f1a611e04565b81356001600160401b03811115611f2f575f80fd5b611f3b87828501611e82565b82525060208201356001600160401b03811115611f56575f80fd5b611f6287828501611e82565b60208301525060408201356001600160401b03811115611f80575f80fd5b611f8c87828501611e82565b60408301525080925050509250929050565b5f8060408385031215611faf575f80fd5b8235611fba81611d39565b91506020830135611fca81611d39565b809150509250929050565b5f60208284031215611fe5575f80fd5b81356001600160401b03811115611ffa575f80fd5b61200684828501611e82565b949350505050565b5f8083601f84011261201e575f80fd5b5081356001600160401b03811115612034575f80fd5b60208301915083602082850101111561204b575f80fd5b9250929050565b5f805f805f60608688031215612066575f80fd5b853561207181611d39565b945060208601356001600160401b0381111561208b575f80fd5b6120978882890161200e565b90955093505060408601356001600160401b038111156120b5575f80fd5b6120c18882890161200e565b969995985093965092949392505050565b5f80604083850312156120e3575f80fd5b82356120ee81611d39565b915060208301358015158114611fca575f80fd5b5f805f805f60808688031215612116575f80fd5b853561212181611d39565b9450602086013561213181611d39565b93506040860135925060608601356001600160401b038111156120b5575f80fd5b8082018082111561112657634e487b7160e01b5f52601160045260245ffd5b62ffffff81168114610f20575f80fd5b5f60208284031215612191575f80fd5b813561193781612171565b5f808335601e198436030181126121b1575f80fd5b8301803591506001600160401b038211156121ca575f80fd5b60200191503681900382131561204b575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b606081525f61221960608301888a6121de565b828103602084015261222c8187896121de565b905082810360408401526122418185876121de565b9998505050505050505050565b600181811c9082168061226257607f821691505b60208210810361228057634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215612296575f80fd5b815161193781611d39565b606081525f6122b36060830186611cce565b82810360208401526122c58186611cce565b905082810360408401526122d98185611cce565b9695505050505050565b5f602082840312156122f3575f80fd5b5051919050565b601f821115610c0c57805f5260205f20601f840160051c8101602085101561231f5750805b601f840160051c820191505b81811015611361575f815560010161232b565b81516001600160401b0381111561235757612357611df0565b61236b81612365845461224e565b846122fa565b6020601f82116001811461239d575f83156123865750848201515b5f19600385901b1c1916600184901b178455611361565b5f84815260208120601f198516915b828110156123cc57878501518255602094850194600190920191016123ac565b50848210156123e957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60a0828403128015612409575f80fd5b5060405160a081016001600160401b038111828210171561242c5761242c611df0565b604052825161243a81611d39565b8152602083015161244a81611d39565b6020820152604083015161245d81612171565b60408201526060830151600281900b8114612476575f80fd5b6060820152608083015161248981611d39565b60808201529392505050565b604081525f6124a86040830186886121de565b82810360208401526124bb8185876121de565b979650505050505050565b5f602082840312156124d6575f80fd5b81516001600160401b038111156124eb575f80fd5b8201601f810184136124fb575f80fd5b8051612509611e9f82611e5c565b81815285602083850101111561251d575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b828152604060208201525f82516060604084015261255b60a0840182611cce565b90506020840151603f198483030160608501526125788282611cce565b9150506040840151603f198483030160808501526122d98282611cce565b8381526001600160a01b03831660208201526060604082018190525f906125bf90830184611cce565b9594505050505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122059d2e14d0b2e895458de86057601241ae81351ff5d038a0dc80a829b7903713564736f6c634300081a0033