More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 7 from a total of 7 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Buy Tokens | 20464291 | 35 days ago | IN | 0.01 ETH | 0.00157984 | ||||
Buy Tokens | 20383324 | 46 days ago | IN | 0.00001 ETH | 0.00098641 | ||||
Set Peer | 20328843 | 54 days ago | IN | 0 ETH | 0.00053325 | ||||
Set Peer | 20328842 | 54 days ago | IN | 0 ETH | 0.00052254 | ||||
Set Peer | 20328840 | 54 days ago | IN | 0 ETH | 0.00046241 | ||||
Set Peer | 20328838 | 54 days ago | IN | 0 ETH | 0.0005292 | ||||
0x600b8054 | 20328282 | 54 days ago | IN | 0 ETH | 0.03634947 |
Latest 14 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
20464291 | 35 days ago | 1 wei | ||||
20464291 | 35 days ago | 0.00099999 ETH | ||||
20464291 | 35 days ago | 0.00299999 ETH | ||||
20464291 | 35 days ago | 0.00249999 ETH | ||||
20464291 | 35 days ago | 0.00199999 ETH | ||||
20464291 | 35 days ago | 0.00049999 ETH | ||||
20464291 | 35 days ago | 0.00099999 ETH | ||||
20383324 | 46 days ago | 1 wei | ||||
20383324 | 46 days ago | 0.00000099 ETH | ||||
20383324 | 46 days ago | 0.00000299 ETH | ||||
20383324 | 46 days ago | 0.00000249 ETH | ||||
20383324 | 46 days ago | 0.00000199 ETH | ||||
20383324 | 46 days ago | 0.00000049 ETH | ||||
20383324 | 46 days ago | 0.00000099 ETH |
Loading...
Loading
Contract Name:
GAIA
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.22; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { OFT } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFT.sol"; import { AggregatorV3Interface } from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; contract GAIA is OFT { mapping(uint256 => address) public chainlinkPriceFeedAddresses; uint256 public constant TOTAL_SUPPLY = 20_000_000_000 * 10 ** 18; uint256 public constant REWARD_SUPPLY = 2_000_000_000 * 10 ** 18; uint256 public constant STAKING_SUPPLY = 8_000_000_000 * 10 ** 18; address public reward = 0x8789ceC3967A64D78b28c4f71B16BdD01D48b6c9; address public staking = 0xCaDc2B1bD1124BFb65A2fe05a948aa23303f353d; address public communityWallet = 0xA87c43167e08C5Bd6Ae089153371b5cf72706d10; address public exchangesWallet = 0x3e3Cc7e2956674e334f695E34B2DD37B8449B16e; address public liquidityWallet = 0x2C7A0dd1aba8f972C6E87451c33D4629749d5966; address public devWallet = 0x00e28Dc9537316e0C279bf2a2E272a3e9A6752Dc; address public marketingWallet = 0xFb557DC3a559bcebAF38Fe3d77EEA2Dd518fecB1; address public teamWallet = 0x97a563bbcF6aAFA207fDA301E8d399D22aCeC03E; address public supportWallet = 0xA47924C6b3F5841F43Ff6e487247485505Fa3f1e; address public constructionWallet = 0xE3d784c80fBa7d773ec8D56c509c59B6E408a3Fa; address public tresorieWallet = 0x21cEb4150d5605C73a1Ef1e9801E87432c492fdB; uint256[5] public tierPrices = [0.005 ether, 0.009 ether, 0.019 ether, 0.028 ether, 0.037 ether]; uint256[5] public tierAmounts = [ 2_000_000_000 * 10 ** 18, 2_000_000_000 * 10 ** 18, 2_000_000_000 * 10 ** 18, 2_000_000_000 * 10 ** 18, 2_000_000_000 * 10 ** 18 ]; mapping(address => uint256) public staked; mapping(address => uint256) private stakedFromTS; mapping(uint256 => uint256) public tokensSoldPerTier; uint256 public constant TRANSACTION_FEE_PERCENT = 2; uint256 public reserve = 0; uint256 public totalStakers; constructor( string memory _name, string memory _symbol, address _lzEndpoint, address _delegate ) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) { _mint(address(this), TOTAL_SUPPLY); _transfer(address(this), reward, REWARD_SUPPLY); _transfer(address(this), staking, STAKING_SUPPLY); chainlinkPriceFeedAddresses[11155111] = 0x694AA1769357215DE4FAC081bf1f309aDC325306; chainlinkPriceFeedAddresses[80002] = 0x001382149eBa3441043c1c66972b4772963f5D43; chainlinkPriceFeedAddresses[43113] = 0x5498BB86BC934c8D34FDA08E81D444153d0D06aD; chainlinkPriceFeedAddresses[97] = 0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526; chainlinkPriceFeedAddresses[84532] = 0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1; chainlinkPriceFeedAddresses[1] = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; chainlinkPriceFeedAddresses[137] = 0xAB594600376Ec9fD91F8e885dADF0CE036862dE0; chainlinkPriceFeedAddresses[43114] = 0x0A77230d17318075983913bC2145DB16C7366156; chainlinkPriceFeedAddresses[8453] = 0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70; chainlinkPriceFeedAddresses[56] = 0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE; } function getChainId() public view returns (uint256) { uint256 chainId; assembly { chainId := chainid() } return chainId; } function getChainlinkDataFeedLatestAnswer() public view returns (int) { uint256 chainId = getChainId(); address priceFeedAddress = chainlinkPriceFeedAddresses[chainId]; require(priceFeedAddress != address(0), "Price feed not available for this chain"); AggregatorV3Interface dataFeed = AggregatorV3Interface(priceFeedAddress); (, int answer, , , ) = dataFeed.latestRoundData(); return answer; } function calculateCost(uint256 amount, uint256 tier) public view returns (uint256) { require(tier < 5, "Invalid tier"); uint256 tierPriceUSD = tierPrices[tier]; int ethPriceUSD = getChainlinkDataFeedLatestAnswer(); require(ethPriceUSD > 0, "Invalid ETH price"); uint256 ethPrice = uint256(ethPriceUSD); uint256 costInETH = (tierPriceUSD * amount * 10 ** 8) / ethPrice; return costInETH; } function buyTokens(uint256 tier) external payable { uint256 costInETH = calculateCost(1, tier); uint256 amount = (msg.value * 10 ** 18) / costInETH; uint256 availableTokens = tierAmounts[tier] - tokensSoldPerTier[tier]; require(amount <= availableTokens, "Not enough tokens in this tier"); uint256 totalCost = (amount * costInETH) / 10 ** 18; require(msg.value >= totalCost, "Insufficient ETH sent"); tokensSoldPerTier[tier] += amount; _transfer(address(this), msg.sender, amount); uint256 totalCostShare = (totalCost * 100) / 100; payable(communityWallet).transfer((totalCostShare * 10) / 100); payable(exchangesWallet).transfer((totalCostShare * 5) / 100); payable(liquidityWallet).transfer((totalCostShare * 20) / 100); payable(devWallet).transfer((totalCostShare * 25) / 100); payable(marketingWallet).transfer((totalCostShare * 30) / 100); payable(teamWallet).transfer((totalCostShare * 10) / 100); if (msg.value > totalCost) { payable(msg.sender).transfer(msg.value - totalCost); } } event Stakedd(address indexed user, uint256 amount, uint256 timestamp); function getAvailableTokensPerTier() external view returns (uint256[5] memory) { uint256[5] memory availableTokens; for (uint256 tier = 0; tier < 5; tier++) { availableTokens[tier] = tierAmounts[tier] - tokensSoldPerTier[tier]; } return availableTokens; } function stake(uint256 amount) external { require(amount > 0, "Amount must be greater than 0"); require(balanceOf(msg.sender) >= amount, "Le solde est inferieur au montant"); require(balanceOf(staking) > 0, "Le staking est actuellement indisponible"); uint256 maxPossibleRewards = (amount * 365) / 1000; require( balanceOf(staking) >= reserve + maxPossibleRewards, "Le solde du contrat de staking est insuffisant pour couvrir les recompenses" ); reserve += maxPossibleRewards; _transfer(msg.sender, staking, amount); if (staked[msg.sender] == 0) { totalStakers++; } if (staked[msg.sender] > 0) { claim(); } stakedFromTS[msg.sender] = block.timestamp; staked[msg.sender] += amount; emit Stakedd(msg.sender, amount, block.timestamp); } event Unstaked(address indexed user, uint256 amount, uint256 timestamp); function unstake(uint256 amount) external { require(amount > 0, "Le montant doit etre superieur a 0"); require(staked[msg.sender] >= amount, "Solde de staking insuffisant"); claim(); uint256 maxPossibleRewards = (amount * 365) / 1000; reserve -= maxPossibleRewards; _transfer(staking, msg.sender, amount); staked[msg.sender] -= amount; if (staked[msg.sender] == 0) { totalStakers--; stakedFromTS[msg.sender] = 0; } emit Unstaked(msg.sender, amount, block.timestamp); } event Claimed(address indexed user, uint256 rewards, uint256 timestamp); function claim() public { require(staked[msg.sender] > 0, "Aucun jeton n'est stake"); uint256 secondsStaked = block.timestamp - stakedFromTS[msg.sender]; uint256 daysStaked = secondsStaked / 86400; require(daysStaked > 0, "Staking period must be at least one day"); if (daysStaked > 365) { daysStaked = 365; } uint256 rewards = (staked[msg.sender] * daysStaked) / 1000; _transfer(staking, msg.sender, rewards); stakedFromTS[msg.sender] = block.timestamp; emit Claimed(msg.sender, rewards, block.timestamp); } function isStakingAvailable() public view returns (bool) { return balanceOf(staking) >= reserve; } event TransferWithFee( address indexed sender, address indexed recipient, uint256 amount, uint256 fee, uint256 timestamp ); function getStakedAmount(address user) external view returns (uint256) { return staked[user]; } function transferWithFee(address recipient, uint256 amount) public { require(amount > 0, "Le montant doit etre superieur a 0"); uint256 fee = (amount * TRANSACTION_FEE_PERCENT) / 100; uint256 supportFee = fee / 4; uint256 constructionFee = fee / 4; uint256 tresorieFee = fee / 4; uint256 burnFee = fee / 4; uint256 amountAfterFee = amount - fee; _transfer(_msgSender(), supportWallet, supportFee); _transfer(_msgSender(), constructionWallet, constructionFee); _transfer(_msgSender(), tresorieWallet, tresorieFee); _burn(_msgSender(), burnFee); _transfer(_msgSender(), recipient, amountAfterFee); emit TransferWithFee(_msgSender(), recipient, amount, fee, block.timestamp); } function getTotalStakers() external view returns (uint256) { return totalStakers; } function getAvailableTokensForStaking() external view returns (uint256) { return balanceOf(staking) - reserve; } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // solhint-disable-next-line interface-starts-with-i interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); function getRoundData( uint80 _roundId ) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { ILayerZeroEndpointV2 } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; /** * @title IOAppCore */ interface IOAppCore { // Custom error messages error OnlyPeer(uint32 eid, bytes32 sender); error NoPeer(uint32 eid); error InvalidEndpointCall(); error InvalidDelegate(); // Event emitted when a peer (OApp) is set for a corresponding endpoint event PeerSet(uint32 eid, bytes32 peer); /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. */ function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion); /** * @notice Retrieves the LayerZero endpoint associated with the OApp. * @return iEndpoint The LayerZero endpoint as an interface. */ function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint); /** * @notice Retrieves the peer (OApp) associated with a corresponding endpoint. * @param _eid The endpoint ID. * @return peer The peer address (OApp instance) associated with the corresponding endpoint. */ function peers(uint32 _eid) external view returns (bytes32 peer); /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. */ function setPeer(uint32 _eid, bytes32 _peer) external; /** * @notice Sets the delegate address for the OApp Core. * @param _delegate The address of the delegate to be set. */ function setDelegate(address _delegate) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title IOAppMsgInspector * @dev Interface for the OApp Message Inspector, allowing examination of message and options contents. */ interface IOAppMsgInspector { // Custom error message for inspection failure error InspectionFailed(bytes message, bytes options); /** * @notice Allows the inspector to examine LayerZero message contents and optionally throw a revert if invalid. * @param _message The message payload to be inspected. * @param _options Additional options or parameters for inspection. * @return valid A boolean indicating whether the inspection passed (true) or failed (false). * * @dev Optionally done as a revert, OR use the boolean provided to handle the failure. */ function inspect(bytes calldata _message, bytes calldata _options) external view returns (bool valid); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Struct representing enforced option parameters. */ struct EnforcedOptionParam { uint32 eid; // Endpoint ID uint16 msgType; // Message Type bytes options; // Additional options } /** * @title IOAppOptionsType3 * @dev Interface for the OApp with Type 3 Options, allowing the setting and combining of enforced options. */ interface IOAppOptionsType3 { // Custom error message for invalid options error InvalidOptions(bytes options); // Event emitted when enforced options are set event EnforcedOptionSet(EnforcedOptionParam[] _enforcedOptions); /** * @notice Sets enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) external; /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OApp message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) external view returns (bytes memory options); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { ILayerZeroReceiver, Origin } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol"; interface IOAppReceiver is ILayerZeroReceiver { /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata _origin, bytes calldata _message, address _sender ) external view returns (bool isSender); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IOAppOptionsType3, EnforcedOptionParam } from "../interfaces/IOAppOptionsType3.sol"; /** * @title OAppOptionsType3 * @dev Abstract contract implementing the IOAppOptionsType3 interface with type 3 options. */ abstract contract OAppOptionsType3 is IOAppOptionsType3, Ownable { uint16 internal constant OPTION_TYPE_3 = 3; // @dev The "msgType" should be defined in the child contract. mapping(uint32 eid => mapping(uint16 msgType => bytes enforcedOption)) public enforcedOptions; /** * @dev Sets the enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc. * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType. * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose(). */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) public virtual onlyOwner { _setEnforcedOptions(_enforcedOptions); } /** * @dev Sets the enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. * * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc. * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType. * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose(). */ function _setEnforcedOptions(EnforcedOptionParam[] memory _enforcedOptions) internal virtual { for (uint256 i = 0; i < _enforcedOptions.length; i++) { // @dev Enforced options are only available for optionType 3, as type 1 and 2 dont support combining. _assertOptionsType3(_enforcedOptions[i].options); enforcedOptions[_enforcedOptions[i].eid][_enforcedOptions[i].msgType] = _enforcedOptions[i].options; } emit EnforcedOptionSet(_enforcedOptions); } /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OAPP message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. * * @dev If there is an enforced lzReceive option: * - {gasLimit: 200k, msg.value: 1 ether} AND a caller supplies a lzReceive option: {gasLimit: 100k, msg.value: 0.5 ether} * - The resulting options will be {gasLimit: 300k, msg.value: 1.5 ether} when the message is executed on the remote lzReceive() function. * @dev This presence of duplicated options is handled off-chain in the verifier/executor. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) public view virtual returns (bytes memory) { bytes memory enforced = enforcedOptions[_eid][_msgType]; // No enforced options, pass whatever the caller supplied, even if it's empty or legacy type 1/2 options. if (enforced.length == 0) return _extraOptions; // No caller options, return enforced if (_extraOptions.length == 0) return enforced; // @dev If caller provided _extraOptions, must be type 3 as its the ONLY type that can be combined. if (_extraOptions.length >= 2) { _assertOptionsType3(_extraOptions); // @dev Remove the first 2 bytes containing the type from the _extraOptions and combine with enforced. return bytes.concat(enforced, _extraOptions[2:]); } // No valid set of options was found. revert InvalidOptions(_extraOptions); } /** * @dev Internal function to assert that options are of type 3. * @param _options The options to be checked. */ function _assertOptionsType3(bytes memory _options) internal pure virtual { uint16 optionsType; assembly { optionsType := mload(add(_options, 2)) } if (optionsType != OPTION_TYPE_3) revert InvalidOptions(_options); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; // @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import import { OAppSender, MessagingFee, MessagingReceipt } from "./OAppSender.sol"; // @dev Import the 'Origin' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import import { OAppReceiver, Origin } from "./OAppReceiver.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OApp * @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver functionality. */ abstract contract OApp is OAppSender, OAppReceiver { /** * @dev Constructor to initialize the OApp with the provided endpoint and owner. * @param _endpoint The address of the LOCAL LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(address _endpoint, address _delegate) OAppCore(_endpoint, _delegate) {} /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol implementation. * @return receiverVersion The version of the OAppReceiver.sol implementation. */ function oAppVersion() public pure virtual override(OAppSender, OAppReceiver) returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, RECEIVER_VERSION); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IOAppCore, ILayerZeroEndpointV2 } from "./interfaces/IOAppCore.sol"; /** * @title OAppCore * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations. */ abstract contract OAppCore is IOAppCore, Ownable { // The LayerZero endpoint associated with the given OApp ILayerZeroEndpointV2 public immutable endpoint; // Mapping to store peers associated with corresponding endpoints mapping(uint32 eid => bytes32 peer) public peers; /** * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate. * @param _endpoint The address of the LOCAL Layer Zero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. * * @dev The delegate typically should be set as the owner of the contract. */ constructor(address _endpoint, address _delegate) { endpoint = ILayerZeroEndpointV2(_endpoint); if (_delegate == address(0)) revert InvalidDelegate(); endpoint.setDelegate(_delegate); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Only the owner/admin of the OApp can call this function. * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner { _setPeer(_eid, _peer); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function _setPeer(uint32 _eid, bytes32 _peer) internal virtual { peers[_eid] = _peer; emit PeerSet(_eid, _peer); } /** * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set. * ie. the peer is set to bytes32(0). * @param _eid The endpoint ID. * @return peer The address of the peer associated with the specified endpoint. */ function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) { bytes32 peer = peers[_eid]; if (peer == bytes32(0)) revert NoPeer(_eid); return peer; } /** * @notice Sets the delegate address for the OApp. * @param _delegate The address of the delegate to be set. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract. */ function setDelegate(address _delegate) public onlyOwner { endpoint.setDelegate(_delegate); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { IOAppReceiver, Origin } from "./interfaces/IOAppReceiver.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OAppReceiver * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers. */ abstract contract OAppReceiver is IOAppReceiver, OAppCore { // Custom error message for when the caller is not the registered endpoint/ error OnlyEndpoint(address addr); // @dev The version of the OAppReceiver implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant RECEIVER_VERSION = 2; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented. * ie. this is a RECEIVE only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions. */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (0, RECEIVER_VERSION); } /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @dev _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @dev _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement separate composeMsg senders that are NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata /*_origin*/, bytes calldata /*_message*/, address _sender ) public view virtual returns (bool) { return _sender == address(this); } /** * @notice Checks if the path initialization is allowed based on the provided origin. * @param origin The origin information containing the source endpoint and sender address. * @return Whether the path has been initialized. * * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received. * @dev This defaults to assuming if a peer has been set, its initialized. * Can be overridden by the OApp if there is other logic to determine this. */ function allowInitializePath(Origin calldata origin) public view virtual returns (bool) { return peers[origin.srcEid] == origin.sender; } /** * @notice Retrieves the next nonce for a given source endpoint and sender address. * @dev _srcEid The source endpoint ID. * @dev _sender The sender address. * @return nonce The next nonce. * * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement. * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered. * @dev This is also enforced by the OApp. * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0. */ function nextNonce(uint32 /*_srcEid*/, bytes32 /*_sender*/) public view virtual returns (uint64 nonce) { return 0; } /** * @dev Entry point for receiving messages or packets from the endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The payload of the received message. * @param _executor The address of the executor for the received message. * @param _extraData Additional arbitrary data provided by the corresponding executor. * * @dev Entry point for receiving msg/packet from the LayerZero endpoint. */ function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) public payable virtual { // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp. if (address(endpoint) != msg.sender) revert OnlyEndpoint(msg.sender); // Ensure that the sender matches the expected peer for the source endpoint. if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) revert OnlyPeer(_origin.srcEid, _origin.sender); // Call the internal OApp implementation of lzReceive. _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { MessagingParams, MessagingFee, MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OAppSender * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint. */ abstract contract OAppSender is OAppCore { using SafeERC20 for IERC20; // Custom error messages error NotEnoughNative(uint256 msgValue); error LzTokenUnavailable(); // @dev The version of the OAppSender implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant SENDER_VERSION = 1; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented. * ie. this is a SEND only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, 0); } /** * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens. * @return fee The calculated MessagingFee for the message. * - nativeFee: The native fee for the message. * - lzTokenFee: The LZ token fee for the message. */ function _quote( uint32 _dstEid, bytes memory _message, bytes memory _options, bool _payInLzToken ) internal view virtual returns (MessagingFee memory fee) { return endpoint.quote( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), address(this) ); } /** * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _fee The calculated LayerZero fee for the message. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess fee values sent to the endpoint. * @return receipt The receipt for the sent message. * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function _lzSend( uint32 _dstEid, bytes memory _message, bytes memory _options, MessagingFee memory _fee, address _refundAddress ) internal virtual returns (MessagingReceipt memory receipt) { // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint. uint256 messageValue = _payNative(_fee.nativeFee); if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee); return // solhint-disable-next-line check-send-result endpoint.send{ value: messageValue }( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0), _refundAddress ); } /** * @dev Internal function to pay the native fee associated with the message. * @param _nativeFee The native fee to be paid. * @return nativeFee The amount of native currency paid. * * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction, * this will need to be overridden because msg.value would contain multiple lzFees. * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency. * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees. * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time. */ function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) { if (msg.value != _nativeFee) revert NotEnoughNative(msg.value); return _nativeFee; } /** * @dev Internal function to pay the LZ token fee associated with the message. * @param _lzTokenFee The LZ token fee to be paid. * * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint. * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend(). */ function _payLzToken(uint256 _lzTokenFee) internal virtual { // @dev Cannot cache the token because it is not immutable in the endpoint. address lzToken = endpoint.lzToken(); if (lzToken == address(0)) revert LzTokenUnavailable(); // Pay LZ token fee by sending tokens to the endpoint. IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { MessagingReceipt, MessagingFee } from "../../oapp/OAppSender.sol"; /** * @dev Struct representing token parameters for the OFT send() operation. */ struct SendParam { uint32 dstEid; // Destination endpoint ID. bytes32 to; // Recipient address. uint256 amountLD; // Amount to send in local decimals. uint256 minAmountLD; // Minimum amount to send in local decimals. bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message. bytes composeMsg; // The composed message for the send() operation. bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations. } /** * @dev Struct representing OFT limit information. * @dev These amounts can change dynamically and are up the the specific oft implementation. */ struct OFTLimit { uint256 minAmountLD; // Minimum amount in local decimals that can be sent to the recipient. uint256 maxAmountLD; // Maximum amount in local decimals that can be sent to the recipient. } /** * @dev Struct representing OFT receipt information. */ struct OFTReceipt { uint256 amountSentLD; // Amount of tokens ACTUALLY debited from the sender in local decimals. // @dev In non-default implementations, the amountReceivedLD COULD differ from this value. uint256 amountReceivedLD; // Amount of tokens to be received on the remote side. } /** * @dev Struct representing OFT fee details. * @dev Future proof mechanism to provide a standardized way to communicate fees to things like a UI. */ struct OFTFeeDetail { int256 feeAmountLD; // Amount of the fee in local decimals. string description; // Description of the fee. } /** * @title IOFT * @dev Interface for the OftChain (OFT) token. * @dev Does not inherit ERC20 to accommodate usage by OFTAdapter as well. * @dev This specific interface ID is '0x02e49c2c'. */ interface IOFT { // Custom error messages error InvalidLocalDecimals(); error SlippageExceeded(uint256 amountLD, uint256 minAmountLD); // Events event OFTSent( bytes32 indexed guid, // GUID of the OFT message. uint32 dstEid, // Destination Endpoint ID. address indexed fromAddress, // Address of the sender on the src chain. uint256 amountSentLD, // Amount of tokens sent in local decimals. uint256 amountReceivedLD // Amount of tokens received in local decimals. ); event OFTReceived( bytes32 indexed guid, // GUID of the OFT message. uint32 srcEid, // Source Endpoint ID. address indexed toAddress, // Address of the recipient on the dst chain. uint256 amountReceivedLD // Amount of tokens received in local decimals. ); /** * @notice Retrieves interfaceID and the version of the OFT. * @return interfaceId The interface ID. * @return version The version. * * @dev interfaceId: This specific interface ID is '0x02e49c2c'. * @dev version: Indicates a cross-chain compatible msg encoding with other OFTs. * @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented. * ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1) */ function oftVersion() external view returns (bytes4 interfaceId, uint64 version); /** * @notice Retrieves the address of the token associated with the OFT. * @return token The address of the ERC20 token implementation. */ function token() external view returns (address); /** * @notice Indicates whether the OFT contract requires approval of the 'token()' to send. * @return requiresApproval Needs approval of the underlying token implementation. * * @dev Allows things like wallet implementers to determine integration requirements, * without understanding the underlying token implementation. */ function approvalRequired() external view returns (bool); /** * @notice Retrieves the shared decimals of the OFT. * @return sharedDecimals The shared decimals of the OFT. */ function sharedDecimals() external view returns (uint8); /** * @notice Provides a quote for OFT-related operations. * @param _sendParam The parameters for the send operation. * @return limit The OFT limit information. * @return oftFeeDetails The details of OFT fees. * @return receipt The OFT receipt information. */ function quoteOFT( SendParam calldata _sendParam ) external view returns (OFTLimit memory, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory); /** * @notice Provides a quote for the send() operation. * @param _sendParam The parameters for the send() operation. * @param _payInLzToken Flag indicating whether the caller is paying in the LZ token. * @return fee The calculated LayerZero messaging fee from the send() operation. * * @dev MessagingFee: LayerZero msg fee * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. */ function quoteSend(SendParam calldata _sendParam, bool _payInLzToken) external view returns (MessagingFee memory); /** * @notice Executes the send() operation. * @param _sendParam The parameters for the send operation. * @param _fee The fee information supplied by the caller. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds from fees etc. on the src. * @return receipt The LayerZero messaging receipt from the send() operation. * @return oftReceipt The OFT receipt information. * * @dev MessagingReceipt: LayerZero msg receipt * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) external payable returns (MessagingReceipt memory, OFTReceipt memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; library OFTComposeMsgCodec { // Offset constants for decoding composed messages uint8 private constant NONCE_OFFSET = 8; uint8 private constant SRC_EID_OFFSET = 12; uint8 private constant AMOUNT_LD_OFFSET = 44; uint8 private constant COMPOSE_FROM_OFFSET = 76; /** * @dev Encodes a OFT composed message. * @param _nonce The nonce value. * @param _srcEid The source endpoint ID. * @param _amountLD The amount in local decimals. * @param _composeMsg The composed message. * @return _msg The encoded Composed message. */ function encode( uint64 _nonce, uint32 _srcEid, uint256 _amountLD, bytes memory _composeMsg // 0x[composeFrom][composeMsg] ) internal pure returns (bytes memory _msg) { _msg = abi.encodePacked(_nonce, _srcEid, _amountLD, _composeMsg); } /** * @dev Retrieves the nonce from the composed message. * @param _msg The message. * @return The nonce value. */ function nonce(bytes calldata _msg) internal pure returns (uint64) { return uint64(bytes8(_msg[:NONCE_OFFSET])); } /** * @dev Retrieves the source endpoint ID from the composed message. * @param _msg The message. * @return The source endpoint ID. */ function srcEid(bytes calldata _msg) internal pure returns (uint32) { return uint32(bytes4(_msg[NONCE_OFFSET:SRC_EID_OFFSET])); } /** * @dev Retrieves the amount in local decimals from the composed message. * @param _msg The message. * @return The amount in local decimals. */ function amountLD(bytes calldata _msg) internal pure returns (uint256) { return uint256(bytes32(_msg[SRC_EID_OFFSET:AMOUNT_LD_OFFSET])); } /** * @dev Retrieves the composeFrom value from the composed message. * @param _msg The message. * @return The composeFrom value. */ function composeFrom(bytes calldata _msg) internal pure returns (bytes32) { return bytes32(_msg[AMOUNT_LD_OFFSET:COMPOSE_FROM_OFFSET]); } /** * @dev Retrieves the composed message. * @param _msg The message. * @return The composed message. */ function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) { return _msg[COMPOSE_FROM_OFFSET:]; } /** * @dev Converts an address to bytes32. * @param _addr The address to convert. * @return The bytes32 representation of the address. */ function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } /** * @dev Converts bytes32 to an address. * @param _b The bytes32 value to convert. * @return The address representation of bytes32. */ function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; library OFTMsgCodec { // Offset constants for encoding and decoding OFT messages uint8 private constant SEND_TO_OFFSET = 32; uint8 private constant SEND_AMOUNT_SD_OFFSET = 40; /** * @dev Encodes an OFT LayerZero message. * @param _sendTo The recipient address. * @param _amountShared The amount in shared decimals. * @param _composeMsg The composed message. * @return _msg The encoded message. * @return hasCompose A boolean indicating whether the message has a composed payload. */ function encode( bytes32 _sendTo, uint64 _amountShared, bytes memory _composeMsg ) internal view returns (bytes memory _msg, bool hasCompose) { hasCompose = _composeMsg.length > 0; // @dev Remote chains will want to know the composed function caller ie. msg.sender on the src. _msg = hasCompose ? abi.encodePacked(_sendTo, _amountShared, addressToBytes32(msg.sender), _composeMsg) : abi.encodePacked(_sendTo, _amountShared); } /** * @dev Checks if the OFT message is composed. * @param _msg The OFT message. * @return A boolean indicating whether the message is composed. */ function isComposed(bytes calldata _msg) internal pure returns (bool) { return _msg.length > SEND_AMOUNT_SD_OFFSET; } /** * @dev Retrieves the recipient address from the OFT message. * @param _msg The OFT message. * @return The recipient address. */ function sendTo(bytes calldata _msg) internal pure returns (bytes32) { return bytes32(_msg[:SEND_TO_OFFSET]); } /** * @dev Retrieves the amount in shared decimals from the OFT message. * @param _msg The OFT message. * @return The amount in shared decimals. */ function amountSD(bytes calldata _msg) internal pure returns (uint64) { return uint64(bytes8(_msg[SEND_TO_OFFSET:SEND_AMOUNT_SD_OFFSET])); } /** * @dev Retrieves the composed message from the OFT message. * @param _msg The OFT message. * @return The composed message. */ function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) { return _msg[SEND_AMOUNT_SD_OFFSET:]; } /** * @dev Converts an address to bytes32. * @param _addr The address to convert. * @return The bytes32 representation of the address. */ function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } /** * @dev Converts bytes32 to an address. * @param _b The bytes32 value to convert. * @return The address representation of bytes32. */ function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { IOFT, OFTCore } from "./OFTCore.sol"; /** * @title OFT Contract * @dev OFT is an ERC-20 token that extends the functionality of the OFTCore contract. */ abstract contract OFT is OFTCore, ERC20 { /** * @dev Constructor for the OFT contract. * @param _name The name of the OFT. * @param _symbol The symbol of the OFT. * @param _lzEndpoint The LayerZero endpoint address. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor( string memory _name, string memory _symbol, address _lzEndpoint, address _delegate ) ERC20(_name, _symbol) OFTCore(decimals(), _lzEndpoint, _delegate) {} /** * @dev Retrieves the address of the underlying ERC20 implementation. * @return The address of the OFT token. * * @dev In the case of OFT, address(this) and erc20 are the same contract. */ function token() public view returns (address) { return address(this); } /** * @notice Indicates whether the OFT contract requires approval of the 'token()' to send. * @return requiresApproval Needs approval of the underlying token implementation. * * @dev In the case of OFT where the contract IS the token, approval is NOT required. */ function approvalRequired() external pure virtual returns (bool) { return false; } /** * @dev Burns tokens from the sender's specified balance. * @param _from The address to debit the tokens from. * @param _amountLD The amount of tokens to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @param _dstEid The destination chain ID. * @return amountSentLD The amount sent in local decimals. * @return amountReceivedLD The amount received in local decimals on the remote. */ function _debit( address _from, uint256 _amountLD, uint256 _minAmountLD, uint32 _dstEid ) internal virtual override returns (uint256 amountSentLD, uint256 amountReceivedLD) { (amountSentLD, amountReceivedLD) = _debitView(_amountLD, _minAmountLD, _dstEid); // @dev In NON-default OFT, amountSentLD could be 100, with a 10% fee, the amountReceivedLD amount is 90, // therefore amountSentLD CAN differ from amountReceivedLD. // @dev Default OFT burns on src. _burn(_from, amountSentLD); } /** * @dev Credits tokens to the specified address. * @param _to The address to credit the tokens to. * @param _amountLD The amount of tokens to credit in local decimals. * @dev _srcEid The source chain ID. * @return amountReceivedLD The amount of tokens ACTUALLY received in local decimals. */ function _credit( address _to, uint256 _amountLD, uint32 /*_srcEid*/ ) internal virtual override returns (uint256 amountReceivedLD) { if (_to == address(0x0)) _to = address(0xdead); // _mint(...) does not support address(0x0) // @dev Default OFT mints on dst. _mint(_to, _amountLD); // @dev In the case of NON-default OFT, the _amountLD MIGHT not be == amountReceivedLD. return _amountLD; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { OApp, Origin } from "../oapp/OApp.sol"; import { OAppOptionsType3 } from "../oapp/libs/OAppOptionsType3.sol"; import { IOAppMsgInspector } from "../oapp/interfaces/IOAppMsgInspector.sol"; import { OAppPreCrimeSimulator } from "../precrime/OAppPreCrimeSimulator.sol"; import { IOFT, SendParam, OFTLimit, OFTReceipt, OFTFeeDetail, MessagingReceipt, MessagingFee } from "./interfaces/IOFT.sol"; import { OFTMsgCodec } from "./libs/OFTMsgCodec.sol"; import { OFTComposeMsgCodec } from "./libs/OFTComposeMsgCodec.sol"; /** * @title OFTCore * @dev Abstract contract for the OftChain (OFT) token. */ abstract contract OFTCore is IOFT, OApp, OAppPreCrimeSimulator, OAppOptionsType3 { using OFTMsgCodec for bytes; using OFTMsgCodec for bytes32; // @notice Provides a conversion rate when swapping between denominations of SD and LD // - shareDecimals == SD == shared Decimals // - localDecimals == LD == local decimals // @dev Considers that tokens have different decimal amounts on various chains. // @dev eg. // For a token // - locally with 4 decimals --> 1.2345 => uint(12345) // - remotely with 2 decimals --> 1.23 => uint(123) // - The conversion rate would be 10 ** (4 - 2) = 100 // @dev If you want to send 1.2345 -> (uint 12345), you CANNOT represent that value on the remote, // you can only display 1.23 -> uint(123). // @dev To preserve the dust that would otherwise be lost on that conversion, // we need to unify a denomination that can be represented on ALL chains inside of the OFT mesh uint256 public immutable decimalConversionRate; // @notice Msg types that are used to identify the various OFT operations. // @dev This can be extended in child contracts for non-default oft operations // @dev These values are used in things like combineOptions() in OAppOptionsType3.sol. uint16 public constant SEND = 1; uint16 public constant SEND_AND_CALL = 2; // Address of an optional contract to inspect both 'message' and 'options' address public msgInspector; event MsgInspectorSet(address inspector); /** * @dev Constructor. * @param _localDecimals The decimals of the token on the local chain (this chain). * @param _endpoint The address of the LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(uint8 _localDecimals, address _endpoint, address _delegate) OApp(_endpoint, _delegate) { if (_localDecimals < sharedDecimals()) revert InvalidLocalDecimals(); decimalConversionRate = 10 ** (_localDecimals - sharedDecimals()); } /** * @notice Retrieves interfaceID and the version of the OFT. * @return interfaceId The interface ID. * @return version The version. * * @dev interfaceId: This specific interface ID is '0x02e49c2c'. * @dev version: Indicates a cross-chain compatible msg encoding with other OFTs. * @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented. * ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1) */ function oftVersion() external pure virtual returns (bytes4 interfaceId, uint64 version) { return (type(IOFT).interfaceId, 1); } /** * @dev Retrieves the shared decimals of the OFT. * @return The shared decimals of the OFT. * * @dev Sets an implicit cap on the amount of tokens, over uint64.max() will need some sort of outbound cap / totalSupply cap * Lowest common decimal denominator between chains. * Defaults to 6 decimal places to provide up to 18,446,744,073,709.551615 units (max uint64). * For tokens exceeding this totalSupply(), they will need to override the sharedDecimals function with something smaller. * ie. 4 sharedDecimals would be 1,844,674,407,370,955.1615 */ function sharedDecimals() public view virtual returns (uint8) { return 6; } /** * @dev Sets the message inspector address for the OFT. * @param _msgInspector The address of the message inspector. * * @dev This is an optional contract that can be used to inspect both 'message' and 'options'. * @dev Set it to address(0) to disable it, or set it to a contract address to enable it. */ function setMsgInspector(address _msgInspector) public virtual onlyOwner { msgInspector = _msgInspector; emit MsgInspectorSet(_msgInspector); } /** * @notice Provides a quote for OFT-related operations. * @param _sendParam The parameters for the send operation. * @return oftLimit The OFT limit information. * @return oftFeeDetails The details of OFT fees. * @return oftReceipt The OFT receipt information. */ function quoteOFT( SendParam calldata _sendParam ) external view virtual returns (OFTLimit memory oftLimit, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory oftReceipt) { uint256 minAmountLD = 0; // Unused in the default implementation. uint256 maxAmountLD = type(uint64).max; // Unused in the default implementation. oftLimit = OFTLimit(minAmountLD, maxAmountLD); // Unused in the default implementation; reserved for future complex fee details. oftFeeDetails = new OFTFeeDetail[](0); // @dev This is the same as the send() operation, but without the actual send. // - amountSentLD is the amount in local decimals that would be sent from the sender. // - amountReceivedLD is the amount in local decimals that will be credited to the recipient on the remote OFT instance. // @dev The amountSentLD MIGHT not equal the amount the user actually receives. HOWEVER, the default does. (uint256 amountSentLD, uint256 amountReceivedLD) = _debitView( _sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid ); oftReceipt = OFTReceipt(amountSentLD, amountReceivedLD); } /** * @notice Provides a quote for the send() operation. * @param _sendParam The parameters for the send() operation. * @param _payInLzToken Flag indicating whether the caller is paying in the LZ token. * @return msgFee The calculated LayerZero messaging fee from the send() operation. * * @dev MessagingFee: LayerZero msg fee * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. */ function quoteSend( SendParam calldata _sendParam, bool _payInLzToken ) external view virtual returns (MessagingFee memory msgFee) { // @dev mock the amount to receive, this is the same operation used in the send(). // The quote is as similar as possible to the actual send() operation. (, uint256 amountReceivedLD) = _debitView(_sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid); // @dev Builds the options and OFT message to quote in the endpoint. (bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam, amountReceivedLD); // @dev Calculates the LayerZero fee for the send() operation. return _quote(_sendParam.dstEid, message, options, _payInLzToken); } /** * @dev Executes the send operation. * @param _sendParam The parameters for the send operation. * @param _fee The calculated fee for the send() operation. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds. * @return msgReceipt The receipt for the send operation. * @return oftReceipt The OFT receipt information. * * @dev MessagingReceipt: LayerZero msg receipt * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) external payable virtual returns (MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) { // @dev Applies the token transfers regarding this send() operation. // - amountSentLD is the amount in local decimals that was ACTUALLY sent/debited from the sender. // - amountReceivedLD is the amount in local decimals that will be received/credited to the recipient on the remote OFT instance. (uint256 amountSentLD, uint256 amountReceivedLD) = _debit( msg.sender, _sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid ); // @dev Builds the options and OFT message to quote in the endpoint. (bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam, amountReceivedLD); // @dev Sends the message to the LayerZero endpoint and returns the LayerZero msg receipt. msgReceipt = _lzSend(_sendParam.dstEid, message, options, _fee, _refundAddress); // @dev Formulate the OFT receipt. oftReceipt = OFTReceipt(amountSentLD, amountReceivedLD); emit OFTSent(msgReceipt.guid, _sendParam.dstEid, msg.sender, amountSentLD, amountReceivedLD); } /** * @dev Internal function to build the message and options. * @param _sendParam The parameters for the send() operation. * @param _amountLD The amount in local decimals. * @return message The encoded message. * @return options The encoded options. */ function _buildMsgAndOptions( SendParam calldata _sendParam, uint256 _amountLD ) internal view virtual returns (bytes memory message, bytes memory options) { bool hasCompose; // @dev This generated message has the msg.sender encoded into the payload so the remote knows who the caller is. (message, hasCompose) = OFTMsgCodec.encode( _sendParam.to, _toSD(_amountLD), // @dev Must be include a non empty bytes if you want to compose, EVEN if you dont need it on the remote. // EVEN if you dont require an arbitrary payload to be sent... eg. '0x01' _sendParam.composeMsg ); // @dev Change the msg type depending if its composed or not. uint16 msgType = hasCompose ? SEND_AND_CALL : SEND; // @dev Combine the callers _extraOptions with the enforced options via the OAppOptionsType3. options = combineOptions(_sendParam.dstEid, msgType, _sendParam.extraOptions); // @dev Optionally inspect the message and options depending if the OApp owner has set a msg inspector. // @dev If it fails inspection, needs to revert in the implementation. ie. does not rely on return boolean if (msgInspector != address(0)) IOAppMsgInspector(msgInspector).inspect(message, options); } /** * @dev Internal function to handle the receive on the LayerZero endpoint. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The encoded message. * @dev _executor The address of the executor. * @dev _extraData Additional data. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address /*_executor*/, // @dev unused in the default implementation. bytes calldata /*_extraData*/ // @dev unused in the default implementation. ) internal virtual override { // @dev The src sending chain doesnt know the address length on this chain (potentially non-evm) // Thus everything is bytes32() encoded in flight. address toAddress = _message.sendTo().bytes32ToAddress(); // @dev Credit the amountLD to the recipient and return the ACTUAL amount the recipient received in local decimals uint256 amountReceivedLD = _credit(toAddress, _toLD(_message.amountSD()), _origin.srcEid); if (_message.isComposed()) { // @dev Proprietary composeMsg format for the OFT. bytes memory composeMsg = OFTComposeMsgCodec.encode( _origin.nonce, _origin.srcEid, amountReceivedLD, _message.composeMsg() ); // @dev Stores the lzCompose payload that will be executed in a separate tx. // Standardizes functionality for executing arbitrary contract invocation on some non-evm chains. // @dev The off-chain executor will listen and process the msg based on the src-chain-callers compose options passed. // @dev The index is used when a OApp needs to compose multiple msgs on lzReceive. // For default OFT implementation there is only 1 compose msg per lzReceive, thus its always 0. endpoint.sendCompose(toAddress, _guid, 0 /* the index of the composed message*/, composeMsg); } emit OFTReceived(_guid, _origin.srcEid, toAddress, amountReceivedLD); } /** * @dev Internal function to handle the OAppPreCrimeSimulator simulated receive. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The LayerZero message. * @param _executor The address of the off-chain executor. * @param _extraData Arbitrary data passed by the msg executor. * * @dev Enables the preCrime simulator to mock sending lzReceive() messages, * routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver. */ function _lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual override { _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Check if the peer is considered 'trusted' by the OApp. * @param _eid The endpoint ID to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. * * @dev Enables OAppPreCrimeSimulator to check whether a potential Inbound Packet is from a trusted source. */ function isPeer(uint32 _eid, bytes32 _peer) public view virtual override returns (bool) { return peers[_eid] == _peer; } /** * @dev Internal function to remove dust from the given local decimal amount. * @param _amountLD The amount in local decimals. * @return amountLD The amount after removing dust. * * @dev Prevents the loss of dust when moving amounts between chains with different decimals. * @dev eg. uint(123) with a conversion rate of 100 becomes uint(100). */ function _removeDust(uint256 _amountLD) internal view virtual returns (uint256 amountLD) { return (_amountLD / decimalConversionRate) * decimalConversionRate; } /** * @dev Internal function to convert an amount from shared decimals into local decimals. * @param _amountSD The amount in shared decimals. * @return amountLD The amount in local decimals. */ function _toLD(uint64 _amountSD) internal view virtual returns (uint256 amountLD) { return _amountSD * decimalConversionRate; } /** * @dev Internal function to convert an amount from local decimals into shared decimals. * @param _amountLD The amount in local decimals. * @return amountSD The amount in shared decimals. */ function _toSD(uint256 _amountLD) internal view virtual returns (uint64 amountSD) { return uint64(_amountLD / decimalConversionRate); } /** * @dev Internal function to mock the amount mutation from a OFT debit() operation. * @param _amountLD The amount to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @dev _dstEid The destination endpoint ID. * @return amountSentLD The amount sent, in local decimals. * @return amountReceivedLD The amount to be received on the remote chain, in local decimals. * * @dev This is where things like fees would be calculated and deducted from the amount to be received on the remote. */ function _debitView( uint256 _amountLD, uint256 _minAmountLD, uint32 /*_dstEid*/ ) internal view virtual returns (uint256 amountSentLD, uint256 amountReceivedLD) { // @dev Remove the dust so nothing is lost on the conversion between chains with different decimals for the token. amountSentLD = _removeDust(_amountLD); // @dev The amount to send is the same as amount received in the default implementation. amountReceivedLD = amountSentLD; // @dev Check for slippage. if (amountReceivedLD < _minAmountLD) { revert SlippageExceeded(amountReceivedLD, _minAmountLD); } } /** * @dev Internal function to perform a debit operation. * @param _from The address to debit. * @param _amountLD The amount to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @param _dstEid The destination endpoint ID. * @return amountSentLD The amount sent in local decimals. * @return amountReceivedLD The amount received in local decimals on the remote. * * @dev Defined here but are intended to be overriden depending on the OFT implementation. * @dev Depending on OFT implementation the _amountLD could differ from the amountReceivedLD. */ function _debit( address _from, uint256 _amountLD, uint256 _minAmountLD, uint32 _dstEid ) internal virtual returns (uint256 amountSentLD, uint256 amountReceivedLD); /** * @dev Internal function to perform a credit operation. * @param _to The address to credit. * @param _amountLD The amount to credit in local decimals. * @param _srcEid The source endpoint ID. * @return amountReceivedLD The amount ACTUALLY received in local decimals. * * @dev Defined here but are intended to be overriden depending on the OFT implementation. * @dev Depending on OFT implementation the _amountLD could differ from the amountReceivedLD. */ function _credit( address _to, uint256 _amountLD, uint32 _srcEid ) internal virtual returns (uint256 amountReceivedLD); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; // @dev Import the Origin so it's exposed to OAppPreCrimeSimulator implementers. // solhint-disable-next-line no-unused-import import { InboundPacket, Origin } from "../libs/Packet.sol"; /** * @title IOAppPreCrimeSimulator Interface * @dev Interface for the preCrime simulation functionality in an OApp. */ interface IOAppPreCrimeSimulator { // @dev simulation result used in PreCrime implementation error SimulationResult(bytes result); error OnlySelf(); /** * @dev Emitted when the preCrime contract address is set. * @param preCrimeAddress The address of the preCrime contract. */ event PreCrimeSet(address preCrimeAddress); /** * @dev Retrieves the address of the preCrime contract implementation. * @return The address of the preCrime contract. */ function preCrime() external view returns (address); /** * @dev Retrieves the address of the OApp contract. * @return The address of the OApp contract. */ function oApp() external view returns (address); /** * @dev Sets the preCrime contract address. * @param _preCrime The address of the preCrime contract. */ function setPreCrime(address _preCrime) external; /** * @dev Mocks receiving a packet, then reverts with a series of data to infer the state/result. * @param _packets An array of LayerZero InboundPacket objects representing received packets. */ function lzReceiveAndRevert(InboundPacket[] calldata _packets) external payable; /** * @dev checks if the specified peer is considered 'trusted' by the OApp. * @param _eid The endpoint Id to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. */ function isPeer(uint32 _eid, bytes32 _peer) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; struct PreCrimePeer { uint32 eid; bytes32 preCrime; bytes32 oApp; } // TODO not done yet interface IPreCrime { error OnlyOffChain(); // for simulate() error PacketOversize(uint256 max, uint256 actual); error PacketUnsorted(); error SimulationFailed(bytes reason); // for preCrime() error SimulationResultNotFound(uint32 eid); error InvalidSimulationResult(uint32 eid, bytes reason); error CrimeFound(bytes crime); function getConfig(bytes[] calldata _packets, uint256[] calldata _packetMsgValues) external returns (bytes memory); function simulate( bytes[] calldata _packets, uint256[] calldata _packetMsgValues ) external payable returns (bytes memory); function buildSimulationResult() external view returns (bytes memory); function preCrime( bytes[] calldata _packets, uint256[] calldata _packetMsgValues, bytes[] calldata _simulations ) external; function version() external view returns (uint64 major, uint8 minor); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Origin } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { PacketV1Codec } from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.sol"; /** * @title InboundPacket * @dev Structure representing an inbound packet received by the contract. */ struct InboundPacket { Origin origin; // Origin information of the packet. uint32 dstEid; // Destination endpointId of the packet. address receiver; // Receiver address for the packet. bytes32 guid; // Unique identifier of the packet. uint256 value; // msg.value of the packet. address executor; // Executor address for the packet. bytes message; // Message payload of the packet. bytes extraData; // Additional arbitrary data for the packet. } /** * @title PacketDecoder * @dev Library for decoding LayerZero packets. */ library PacketDecoder { using PacketV1Codec for bytes; /** * @dev Decode an inbound packet from the given packet data. * @param _packet The packet data to decode. * @return packet An InboundPacket struct representing the decoded packet. */ function decode(bytes calldata _packet) internal pure returns (InboundPacket memory packet) { packet.origin = Origin(_packet.srcEid(), _packet.sender(), _packet.nonce()); packet.dstEid = _packet.dstEid(); packet.receiver = _packet.receiverB20(); packet.guid = _packet.guid(); packet.message = _packet.message(); } /** * @dev Decode multiple inbound packets from the given packet data and associated message values. * @param _packets An array of packet data to decode. * @param _packetMsgValues An array of associated message values for each packet. * @return packets An array of InboundPacket structs representing the decoded packets. */ function decode( bytes[] calldata _packets, uint256[] memory _packetMsgValues ) internal pure returns (InboundPacket[] memory packets) { packets = new InboundPacket[](_packets.length); for (uint256 i = 0; i < _packets.length; i++) { bytes calldata packet = _packets[i]; packets[i] = PacketDecoder.decode(packet); // @dev Allows the verifier to specify the msg.value that gets passed in lzReceive. packets[i].value = _packetMsgValues[i]; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IPreCrime } from "./interfaces/IPreCrime.sol"; import { IOAppPreCrimeSimulator, InboundPacket, Origin } from "./interfaces/IOAppPreCrimeSimulator.sol"; /** * @title OAppPreCrimeSimulator * @dev Abstract contract serving as the base for preCrime simulation functionality in an OApp. */ abstract contract OAppPreCrimeSimulator is IOAppPreCrimeSimulator, Ownable { // The address of the preCrime implementation. address public preCrime; /** * @dev Retrieves the address of the OApp contract. * @return The address of the OApp contract. * * @dev The simulator contract is the base contract for the OApp by default. * @dev If the simulator is a separate contract, override this function. */ function oApp() external view virtual returns (address) { return address(this); } /** * @dev Sets the preCrime contract address. * @param _preCrime The address of the preCrime contract. */ function setPreCrime(address _preCrime) public virtual onlyOwner { preCrime = _preCrime; emit PreCrimeSet(_preCrime); } /** * @dev Interface for pre-crime simulations. Always reverts at the end with the simulation results. * @param _packets An array of InboundPacket objects representing received packets to be delivered. * * @dev WARNING: MUST revert at the end with the simulation results. * @dev Gives the preCrime implementation the ability to mock sending packets to the lzReceive function, * WITHOUT actually executing them. */ function lzReceiveAndRevert(InboundPacket[] calldata _packets) public payable virtual { for (uint256 i = 0; i < _packets.length; i++) { InboundPacket calldata packet = _packets[i]; // Ignore packets that are not from trusted peers. if (!isPeer(packet.origin.srcEid, packet.origin.sender)) continue; // @dev Because a verifier is calling this function, it doesnt have access to executor params: // - address _executor // - bytes calldata _extraData // preCrime will NOT work for OApps that rely on these two parameters inside of their _lzReceive(). // They are instead stubbed to default values, address(0) and bytes("") // @dev Calling this.lzReceiveSimulate removes ability for assembly return 0 callstack exit, // which would cause the revert to be ignored. this.lzReceiveSimulate{ value: packet.value }( packet.origin, packet.guid, packet.message, packet.executor, packet.extraData ); } // @dev Revert with the simulation results. msg.sender must implement IPreCrime.buildSimulationResult(). revert SimulationResult(IPreCrime(msg.sender).buildSimulationResult()); } /** * @dev Is effectively an internal function because msg.sender must be address(this). * Allows resetting the call stack for 'internal' calls. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier of the packet. * @param _message The message payload of the packet. * @param _executor The executor address for the packet. * @param _extraData Additional data for the packet. */ function lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable virtual { // @dev Ensure ONLY can be called 'internally'. if (msg.sender != address(this)) revert OnlySelf(); _lzReceiveSimulate(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to handle the OAppPreCrimeSimulator simulated receive. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The GUID of the LayerZero message. * @param _message The LayerZero message. * @param _executor The address of the off-chain executor. * @param _extraData Arbitrary data passed by the msg executor. * * @dev Enables the preCrime simulator to mock sending lzReceive() messages, * routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver. */ function _lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; /** * @dev checks if the specified peer is considered 'trusted' by the OApp. * @param _eid The endpoint Id to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. */ function isPeer(uint32 _eid, bytes32 _peer) public view virtual returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { IMessageLibManager } from "./IMessageLibManager.sol"; import { IMessagingComposer } from "./IMessagingComposer.sol"; import { IMessagingChannel } from "./IMessagingChannel.sol"; import { IMessagingContext } from "./IMessagingContext.sol"; struct MessagingParams { uint32 dstEid; bytes32 receiver; bytes message; bytes options; bool payInLzToken; } struct MessagingReceipt { bytes32 guid; uint64 nonce; MessagingFee fee; } struct MessagingFee { uint256 nativeFee; uint256 lzTokenFee; } struct Origin { uint32 srcEid; bytes32 sender; uint64 nonce; } interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext { event PacketSent(bytes encodedPayload, bytes options, address sendLibrary); event PacketVerified(Origin origin, address receiver, bytes32 payloadHash); event PacketDelivered(Origin origin, address receiver); event LzReceiveAlert( address indexed receiver, address indexed executor, Origin origin, bytes32 guid, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); event LzTokenSet(address token); event DelegateSet(address sender, address delegate); function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory); function send( MessagingParams calldata _params, address _refundAddress ) external payable returns (MessagingReceipt memory); function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external; function verifiable(Origin calldata _origin, address _receiver) external view returns (bool); function initializable(Origin calldata _origin, address _receiver) external view returns (bool); function lzReceive( Origin calldata _origin, address _receiver, bytes32 _guid, bytes calldata _message, bytes calldata _extraData ) external payable; // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external; function setLzToken(address _lzToken) external; function lzToken() external view returns (address); function nativeToken() external view returns (address); function setDelegate(address _delegate) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { Origin } from "./ILayerZeroEndpointV2.sol"; interface ILayerZeroReceiver { function allowInitializePath(Origin calldata _origin) external view returns (bool); function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64); function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { SetConfigParam } from "./IMessageLibManager.sol"; enum MessageLibType { Send, Receive, SendAndReceive } interface IMessageLib is IERC165 { function setConfig(address _oapp, SetConfigParam[] calldata _config) external; function getConfig(uint32 _eid, address _oapp, uint32 _configType) external view returns (bytes memory config); function isSupportedEid(uint32 _eid) external view returns (bool); // message libs of same major version are compatible function version() external view returns (uint64 major, uint8 minor, uint8 endpointVersion); function messageLibType() external view returns (MessageLibType); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; struct SetConfigParam { uint32 eid; uint32 configType; bytes config; } interface IMessageLibManager { struct Timeout { address lib; uint256 expiry; } event LibraryRegistered(address newLib); event DefaultSendLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry); event SendLibrarySet(address sender, uint32 eid, address newLib); event ReceiveLibrarySet(address receiver, uint32 eid, address newLib); event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout); function registerLibrary(address _lib) external; function isRegisteredLibrary(address _lib) external view returns (bool); function getRegisteredLibraries() external view returns (address[] memory); function setDefaultSendLibrary(uint32 _eid, address _newLib) external; function defaultSendLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external; function defaultReceiveLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external; function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry); function isSupportedEid(uint32 _eid) external view returns (bool); function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool); /// ------------------- OApp interfaces ------------------- function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external; function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib); function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool); function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external; function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault); function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external; function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry); function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external; function getConfig( address _oapp, address _lib, uint32 _eid, uint32 _configType ) external view returns (bytes memory config); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingChannel { event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce); event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); function eid() external view returns (uint32); // this is an emergency function if a message cannot be verified for some reasons // required to provide _nextNonce to avoid race condition function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external; function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32); function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64); function inboundPayloadHash( address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce ) external view returns (bytes32); function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingComposer { event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message); event ComposeDelivered(address from, address to, bytes32 guid, uint16 index); event LzComposeAlert( address indexed from, address indexed to, address indexed executor, bytes32 guid, uint16 index, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); function composeQueue( address _from, address _to, bytes32 _guid, uint16 _index ) external view returns (bytes32 messageHash); function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external; function lzCompose( address _from, address _to, bytes32 _guid, uint16 _index, bytes calldata _message, bytes calldata _extraData ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingContext { function isSendingMessage() external view returns (bool); function getSendContext() external view returns (uint32 dstEid, address sender); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { MessagingFee } from "./ILayerZeroEndpointV2.sol"; import { IMessageLib } from "./IMessageLib.sol"; struct Packet { uint64 nonce; uint32 srcEid; address sender; uint32 dstEid; bytes32 receiver; bytes32 guid; bytes message; } interface ISendLib is IMessageLib { function send( Packet calldata _packet, bytes calldata _options, bool _payInLzToken ) external returns (MessagingFee memory, bytes memory encodedPacket); function quote( Packet calldata _packet, bytes calldata _options, bool _payInLzToken ) external view returns (MessagingFee memory); function setTreasury(address _treasury) external; function withdrawFee(address _to, uint256 _amount) external; function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external; }
// SPDX-License-Identifier: LZBL-1.2 pragma solidity ^0.8.20; library AddressCast { error AddressCast_InvalidSizeForAddress(); error AddressCast_InvalidAddress(); function toBytes32(bytes calldata _addressBytes) internal pure returns (bytes32 result) { if (_addressBytes.length > 32) revert AddressCast_InvalidAddress(); result = bytes32(_addressBytes); unchecked { uint256 offset = 32 - _addressBytes.length; result = result >> (offset * 8); } } function toBytes32(address _address) internal pure returns (bytes32 result) { result = bytes32(uint256(uint160(_address))); } function toBytes(bytes32 _addressBytes32, uint256 _size) internal pure returns (bytes memory result) { if (_size == 0 || _size > 32) revert AddressCast_InvalidSizeForAddress(); result = new bytes(_size); unchecked { uint256 offset = 256 - _size * 8; assembly { mstore(add(result, 32), shl(offset, _addressBytes32)) } } } function toAddress(bytes32 _addressBytes32) internal pure returns (address result) { result = address(uint160(uint256(_addressBytes32))); } function toAddress(bytes calldata _addressBytes) internal pure returns (address result) { if (_addressBytes.length != 20) revert AddressCast_InvalidAddress(); result = address(bytes20(_addressBytes)); } }
// SPDX-License-Identifier: LZBL-1.2 pragma solidity ^0.8.20; import { Packet } from "../../interfaces/ISendLib.sol"; import { AddressCast } from "../../libs/AddressCast.sol"; library PacketV1Codec { using AddressCast for address; using AddressCast for bytes32; uint8 internal constant PACKET_VERSION = 1; // header (version + nonce + path) // version uint256 private constant PACKET_VERSION_OFFSET = 0; // nonce uint256 private constant NONCE_OFFSET = 1; // path uint256 private constant SRC_EID_OFFSET = 9; uint256 private constant SENDER_OFFSET = 13; uint256 private constant DST_EID_OFFSET = 45; uint256 private constant RECEIVER_OFFSET = 49; // payload (guid + message) uint256 private constant GUID_OFFSET = 81; // keccak256(nonce + path) uint256 private constant MESSAGE_OFFSET = 113; function encode(Packet memory _packet) internal pure returns (bytes memory encodedPacket) { encodedPacket = abi.encodePacked( PACKET_VERSION, _packet.nonce, _packet.srcEid, _packet.sender.toBytes32(), _packet.dstEid, _packet.receiver, _packet.guid, _packet.message ); } function encodePacketHeader(Packet memory _packet) internal pure returns (bytes memory) { return abi.encodePacked( PACKET_VERSION, _packet.nonce, _packet.srcEid, _packet.sender.toBytes32(), _packet.dstEid, _packet.receiver ); } function encodePayload(Packet memory _packet) internal pure returns (bytes memory) { return abi.encodePacked(_packet.guid, _packet.message); } function header(bytes calldata _packet) internal pure returns (bytes calldata) { return _packet[0:GUID_OFFSET]; } function version(bytes calldata _packet) internal pure returns (uint8) { return uint8(bytes1(_packet[PACKET_VERSION_OFFSET:NONCE_OFFSET])); } function nonce(bytes calldata _packet) internal pure returns (uint64) { return uint64(bytes8(_packet[NONCE_OFFSET:SRC_EID_OFFSET])); } function srcEid(bytes calldata _packet) internal pure returns (uint32) { return uint32(bytes4(_packet[SRC_EID_OFFSET:SENDER_OFFSET])); } function sender(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[SENDER_OFFSET:DST_EID_OFFSET]); } function senderAddressB20(bytes calldata _packet) internal pure returns (address) { return sender(_packet).toAddress(); } function dstEid(bytes calldata _packet) internal pure returns (uint32) { return uint32(bytes4(_packet[DST_EID_OFFSET:RECEIVER_OFFSET])); } function receiver(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[RECEIVER_OFFSET:GUID_OFFSET]); } function receiverB20(bytes calldata _packet) internal pure returns (address) { return receiver(_packet).toAddress(); } function guid(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[GUID_OFFSET:MESSAGE_OFFSET]); } function message(bytes calldata _packet) internal pure returns (bytes calldata) { return bytes(_packet[MESSAGE_OFFSET:]); } function payload(bytes calldata _packet) internal pure returns (bytes calldata) { return bytes(_packet[GUID_OFFSET:]); } function payloadHash(bytes calldata _packet) internal pure returns (bytes32) { return keccak256(payload(_packet)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC20Metadata} from "./extensions/IERC20Metadata.sol"; import {Context} from "../../utils/Context.sol"; import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` amount of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * ``` * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC20Permit} from "../extensions/IERC20Permit.sol"; import {Address} from "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_lzEndpoint","type":"address"},{"internalType":"address","name":"_delegate","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[],"name":"InvalidLocalDecimals","type":"error"},{"inputs":[{"internalType":"bytes","name":"options","type":"bytes"}],"name":"InvalidOptions","type":"error"},{"inputs":[],"name":"LzTokenUnavailable","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"NotEnoughNative","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"OnlyEndpoint","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"}],"name":"OnlyPeer","type":"error"},{"inputs":[],"name":"OnlySelf","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"name":"SimulationResult","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"}],"name":"SlippageExceeded","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"indexed":false,"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"EnforcedOptionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"inspector","type":"address"}],"name":"MsgInspectorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"srcEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"name":"OFTReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"dstEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"name":"OFTSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"peer","type":"bytes32"}],"name":"PeerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"preCrimeAddress","type":"address"}],"name":"PreCrimeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Stakedd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TransferWithFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Unstaked","type":"event"},{"inputs":[],"name":"REWARD_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND_AND_CALL","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANSACTION_FEE_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"}],"name":"allowInitializePath","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvalRequired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"buyTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"calculateCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"chainlinkPriceFeedAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"uint16","name":"_msgType","type":"uint16"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"}],"name":"combineOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"communityWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"constructionWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimalConversionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"}],"name":"enforcedOptions","outputs":[{"internalType":"bytes","name":"enforcedOption","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exchangesWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAvailableTokensForStaking","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAvailableTokensPerTier","outputs":[{"internalType":"uint256[5]","name":"","type":"uint256[5]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainlinkDataFeedLatestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getStakedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalStakers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"_sender","type":"address"}],"name":"isComposeMsgSender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"isPeer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isStakingAvailable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"},{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct InboundPacket[]","name":"_packets","type":"tuple[]"}],"name":"lzReceiveAndRevert","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceiveSimulate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"marketingWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"msgInspector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nextNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oApp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oAppVersion","outputs":[{"internalType":"uint64","name":"senderVersion","type":"uint64"},{"internalType":"uint64","name":"receiverVersion","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"oftVersion","outputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"},{"internalType":"uint64","name":"version","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"peer","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"preCrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"}],"name":"quoteOFT","outputs":[{"components":[{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"uint256","name":"maxAmountLD","type":"uint256"}],"internalType":"struct OFTLimit","name":"oftLimit","type":"tuple"},{"components":[{"internalType":"int256","name":"feeAmountLD","type":"int256"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct OFTFeeDetail[]","name":"oftFeeDetails","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"internalType":"struct OFTReceipt","name":"oftReceipt","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"internalType":"bool","name":"_payInLzToken","type":"bool"}],"name":"quoteSend","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"msgFee","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reward","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"_fee","type":"tuple"},{"internalType":"address","name":"_refundAddress","type":"address"}],"name":"send","outputs":[{"components":[{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt","name":"msgReceipt","type":"tuple"},{"components":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"internalType":"struct OFTReceipt","name":"oftReceipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"setEnforcedOptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_msgInspector","type":"address"}],"name":"setMsgInspector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_preCrime","type":"address"}],"name":"setPreCrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sharedDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"staked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"staking","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supportWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tierAmounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tierPrices","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokensSoldPerTier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferWithFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tresorieWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
600b80546001600160a01b0319908116738789cec3967a64d78b28c4f71b16bdd01d48b6c917909155600c8054821673cadc2b1bd1124bfb65a2fe05a948aa23303f353d179055600d8054821673a87c43167e08c5bd6ae089153371b5cf72706d10179055600e80548216733e3cc7e2956674e334f695e34b2dd37b8449b16e179055600f80548216732c7a0dd1aba8f972c6e87451c33d4629749d596617905560108054821672e28dc9537316e0c279bf2a2e272a3e9a6752dc17905560118054821673fb557dc3a559bcebaf38fe3d77eea2dd518fecb11790556012805482167397a563bbcf6aafa207fda301e8d399d22acec03e17905560138054821673a47924c6b3f5841f43ff6e487247485505fa3f1e17905560148054821673e3d784c80fba7d773ec8d56c509c59b6e408a3fa179055601580549091167321ceb4150d5605c73a1ef1e9801e87432c492fdb1790556101606040526611c37937e0800060c0908152661ff973cafa800060e052664380663abb800061010052666379da05b60000610120526683734dd0b0800061014052620001a690601690600562000898565b506040805160a0810182526b06765c793fa10079d000000080825260208201819052918101829052606081018290526080810191909152620001ed90601b906005620008e6565b5060006023553480156200020057600080fd5b506040516200538138038062005381833981016040819052620002239162000a1e565b83838383838360128484818181818d6001600160a01b0381166200026257604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200026d8162000668565b506001600160a01b0380831660805281166200029c57604051632d618d8160e21b815260040160405180910390fd5b60805160405163ca5eb5e160e01b81526001600160a01b0383811660048301529091169063ca5eb5e190602401600060405180830381600087803b158015620002e457600080fd5b505af1158015620002f9573d6000803e3d6000fd5b505050505050505062000311620006b860201b60201c565b60ff168360ff16101562000338576040516301e9714b60e41b815260040160405180910390fd5b6200034560068462000ac3565b6200035290600a62000be2565b60a0525060089150620003689050838262000c8a565b50600962000377828262000c8a565b505050505050506200039c306b409f9cbc7c4a04c220000000620006bd60201b60201c565b600b54620003c29030906001600160a01b03166b06765c793fa10079d0000000620006fb565b600c54620003e89030906001600160a01b03166b19d971e4fe8401e740000000620006fb565b5050600a60205250507fe83b91319e3f46f3ba062f193930de6f9faf8e204728cf91fd240c66011cbcaa80546001600160a01b031990811673694aa1769357215de4fac081bf1f309adc325306179091557f1d60cdf71a1f477f621ad5acf08f96e351d98654a431242c20fe531a8bcca81780548216721382149eba3441043c1c66972b4772963f5d431790557f97c0a3f1a746153e9beec6a228a79e1f9746d3eedbb48b1d5a59c86935501e9b80548216735498bb86bc934c8d34fda08e81d444153d0d06ad1790557fae935ea5ea6af79732e9ead178ce437ddd0fd99e3c49fd2d8f430db45d6d464480548216732514895c72f50d8bd4b4f9b1110f0d6bd2c975261790557f906bb7cb453c5064096ad334ad7cab636b005ef912a5d053f219a1db0d59038980548216734adc67696ba383f43dd60a9e78f2c97fbbfc7cb11790557fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bc780548216735f4ec3df9cbd43714fe2740f5e3616155c5b84191790557f96e5f151d91e68f2b0cb31facab59746b0abcb367b84e7107ff091d0866070468054821673ab594600376ec9fd91f8e885dadf0ce036862de01790557e2633598644698f511fcc8568bd00764973fec93b7b926384d6b16fe053d20580548216730a77230d17318075983913bc2145db16c73661561790557ffc9e5241f826c99f828d87d1ead41d4defb360616105640ba96e3c7be41aa24c805482167371041dddad3595f9ced3dccfbe3d1f4b0a16bb7017905560386000527f0d66487a4fd51dd587b2804aa978e27509d1f975a58951d636cb4c8aad7c71e18054909116730567f2323251f0aab15c8dfb1967e4e8a7d42aee17905562000d6c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600690565b6001600160a01b038216620006e95760405163ec442f0560e01b81526000600482015260240162000259565b620006f76000838362000765565b5050565b6001600160a01b0383166200072757604051634b637e8f60e11b81526000600482015260240162000259565b6001600160a01b038216620007535760405163ec442f0560e01b81526000600482015260240162000259565b6200076083838362000765565b505050565b6001600160a01b0383166200079457806007600082825462000788919062000d56565b90915550620008089050565b6001600160a01b03831660009081526005602052604090205481811015620007e95760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640162000259565b6001600160a01b03841660009081526005602052604090209082900390555b6001600160a01b038216620008265760078054829003905562000845565b6001600160a01b03821660009081526005602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200088b91815260200190565b60405180910390a3505050565b8260058101928215620008d4579160200282015b82811115620008d4578251829066ffffffffffffff16905591602001919060010190620008ac565b50620008e292915062000922565b5090565b8260058101928215620008d4579160200282015b82811115620008d457825182906001600160601b0316905591602001919060010190620008fa565b5b80821115620008e2576000815560010162000923565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200096157600080fd5b81516001600160401b03808211156200097e576200097e62000939565b604051601f8301601f19908116603f01168101908282118183101715620009a957620009a962000939565b8160405283815260209250866020858801011115620009c757600080fd5b600091505b83821015620009eb5785820183015181830184015290820190620009cc565b6000602085830101528094505050505092915050565b80516001600160a01b038116811462000a1957600080fd5b919050565b6000806000806080858703121562000a3557600080fd5b84516001600160401b038082111562000a4d57600080fd5b62000a5b888389016200094f565b9550602087015191508082111562000a7257600080fd5b5062000a81878288016200094f565b93505062000a926040860162000a01565b915062000aa26060860162000a01565b905092959194509250565b634e487b7160e01b600052601160045260246000fd5b60ff828116828216039081111562000adf5762000adf62000aad565b92915050565b600181815b8085111562000b2657816000190482111562000b0a5762000b0a62000aad565b8085161562000b1857918102915b93841c939080029062000aea565b509250929050565b60008262000b3f5750600162000adf565b8162000b4e5750600062000adf565b816001811462000b67576002811462000b725762000b92565b600191505062000adf565b60ff84111562000b865762000b8662000aad565b50506001821b62000adf565b5060208310610133831016604e8410600b841016171562000bb7575081810a62000adf565b62000bc3838362000ae5565b806000190482111562000bda5762000bda62000aad565b029392505050565b600062000bf360ff84168362000b2e565b9392505050565b600181811c9082168062000c0f57607f821691505b60208210810362000c3057634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000760576000816000526020600020601f850160051c8101602086101562000c615750805b601f850160051c820191505b8181101562000c825782815560010162000c6d565b505050505050565b81516001600160401b0381111562000ca65762000ca662000939565b62000cbe8162000cb7845462000bfa565b8462000c36565b602080601f83116001811462000cf6576000841562000cdd5750858301515b600019600386901b1c1916600185901b17855562000c82565b600085815260208120601f198616915b8281101562000d275788860151825594840194600190910190840162000d06565b508582101562000d465787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b8082018082111562000adf5762000adf62000aad565b60805160a0516145a962000dd860003960008181610ace01528181612fb80152818161302d015261310701526000818161088001528181611127015281816123180152818161273501528181612a4101528181612ce8015281816131d2015261328b01526145a96000f3fe6080604052600436106104565760003560e01c806376a6367f1161023f578063bb0b6a5311610139578063d045a0dc116100b6578063d46980161161007a578063d469801614610dc7578063dd62ed3e14610de7578063f2fde38b14610e2d578063fc0c546a146107e4578063ff7bd03d14610e4d57600080fd5b8063d045a0dc14610d29578063d0c43a5614610d3c578063d2b7dcfd14610d5c578063d2ce702214610d71578063d424388514610da757600080fd5b8063c7c7f5b3116100fd578063c7c7f5b314610c92578063ca5eb5e114610cb3578063cc0aca9a14610cd3578063cd3293de14610cf3578063ce39469614610d0957600080fd5b8063bb0b6a5314610bfd578063bc70b35414610c2a578063bd815db014610c4a578063bea4dfb514610c5d578063c757483914610c7257600080fd5b806395d89b41116101c7578063a694fc3a1161018b578063a694fc3a14610b5d578063a9059cbb14610b7d578063b60eaaaa14610b9d578063b731ea0a14610bbd578063b98bd07014610bdd57600080fd5b806395d89b4114610aa7578063963efcaa14610abc57806397ca379c14610af057806398807d8414610b1d5780639f68b96414610b4957600080fd5b8063869890381161020e5780638698903814610a1e5780638da5cb5b14610a345780638e7bdb9b14610a525780638ea5220f14610a67578063902d55a514610a8757600080fd5b806376a6367f1461098f5780637d25a05e146109af57806382413eac146109ea578063857749b014610a0a57600080fd5b80633408e4701161035057806359927044116102d85780636fc1b31e1161029c5780636fc1b31e146108e457806370a0823114610904578063715018a61461093a57806373e40ed41461094f57806375f0a8741461096f57600080fd5b806359927044146108175780635a0dfe4d146108375780635e280f111461086e5780635e9d2e7b146108a257806362dab32b146108c257600080fd5b80634cf088d91161031f5780634cf088d91461077a5780634da6a5561461079a5780634e71d92d146107cf57806352ae2879146107e45780635535d461146107f757600080fd5b80633408e4701461070757806335771fe01461071a5780633610724e1461073a5780633b6f743b1461074d57600080fd5b806317442b70116103de5780632e17de78116103a25780632e17de7814610670578063300eccab14610690578063313ce567146106b057806331ed0db4146106d25780633400288b146106e757600080fd5b806317442b70146105da57806318160ddd146105fc5780631f5e13341461061b578063228cb7331461063057806323b872dd1461065057600080fd5b80630dea2d5c116104255780630dea2d5c1461050e578063111ecdad1461054057806313137d6514610578578063134d4f251461058b578063156a0d0f146105b357600080fd5b806306fdde031461046257806308acece21461048d578063095ea7b3146104af5780630d35b415146104df57600080fd5b3661045d57005b600080fd5b34801561046e57600080fd5b50610477610e6d565b6040516104849190613547565b60405180910390f35b34801561049957600080fd5b506104ad6104a836600461356f565b610eff565b005b3480156104bb57600080fd5b506104cf6104ca36600461356f565b61103a565b6040519015158152602001610484565b3480156104eb57600080fd5b506104ff6104fa3660046135ad565b611054565b604051610484939291906135e1565b34801561051a57600080fd5b50602354600c546001600160a01b031660009081526005602052604090205410156104cf565b34801561054c57600080fd5b50600454610560906001600160a01b031681565b6040516001600160a01b039091168152602001610484565b6104ad6105863660046136d4565b611125565b34801561059757600080fd5b506105a0600281565b60405161ffff9091168152602001610484565b3480156105bf57600080fd5b506040805162b9270b60e21b81526001602082015201610484565b3480156105e657600080fd5b5060408051600181526002602082015201610484565b34801561060857600080fd5b506007545b604051908152602001610484565b34801561062757600080fd5b506105a0600181565b34801561063c57600080fd5b50600b54610560906001600160a01b031681565b34801561065c57600080fd5b506104cf61066b366004613773565b6111e0565b34801561067c57600080fd5b506104ad61068b3660046137b4565b611206565b34801561069c57600080fd5b5061060d6106ab3660046137b4565b611374565b3480156106bc57600080fd5b5060125b60405160ff9091168152602001610484565b3480156106de57600080fd5b5060245461060d565b3480156106f357600080fd5b506104ad6107023660046137e6565b61138b565b34801561071357600080fd5b504661060d565b34801561072657600080fd5b5061060d6107353660046137b4565b6113a1565b6104ad6107483660046137b4565b6113b1565b34801561075957600080fd5b5061076d610768366004613810565b611736565b6040516104849190613861565b34801561078657600080fd5b50600c54610560906001600160a01b031681565b3480156107a657600080fd5b5061060d6107b5366004613878565b6001600160a01b0316600090815260208052604090205490565b3480156107db57600080fd5b506104ad61179d565b3480156107f057600080fd5b5030610560565b34801561080357600080fd5b506104776108123660046138a7565b611927565b34801561082357600080fd5b50601254610560906001600160a01b031681565b34801561084357600080fd5b506104cf6108523660046137e6565b63ffffffff919091166000908152600160205260409020541490565b34801561087a57600080fd5b506105607f000000000000000000000000000000000000000000000000000000000000000081565b3480156108ae57600080fd5b50600e54610560906001600160a01b031681565b3480156108ce57600080fd5b506108d76119cc565b60405161048491906138da565b3480156108f057600080fd5b506104ad6108ff366004613878565b611a3b565b34801561091057600080fd5b5061060d61091f366004613878565b6001600160a01b031660009081526005602052604090205490565b34801561094657600080fd5b506104ad611a98565b34801561095b57600080fd5b5061060d6b06765c793fa10079d000000081565b34801561097b57600080fd5b50601154610560906001600160a01b031681565b34801561099b57600080fd5b50601454610560906001600160a01b031681565b3480156109bb57600080fd5b506109d26109ca3660046137e6565b600092915050565b6040516001600160401b039091168152602001610484565b3480156109f657600080fd5b506104cf610a0536600461390b565b611aac565b348015610a1657600080fd5b5060066106c0565b348015610a2a57600080fd5b5061060d60245481565b348015610a4057600080fd5b506000546001600160a01b0316610560565b348015610a5e57600080fd5b5061060d600281565b348015610a7357600080fd5b50601054610560906001600160a01b031681565b348015610a9357600080fd5b5061060d6b409f9cbc7c4a04c22000000081565b348015610ab357600080fd5b50610477611ac1565b348015610ac857600080fd5b5061060d7f000000000000000000000000000000000000000000000000000000000000000081565b348015610afc57600080fd5b5061060d610b0b3660046137b4565b60226020526000908152604090205481565b348015610b2957600080fd5b5061060d610b38366004613878565b602080526000908152604090205481565b348015610b5557600080fd5b5060006104cf565b348015610b6957600080fd5b506104ad610b783660046137b4565b611ad0565b348015610b8957600080fd5b506104cf610b9836600461356f565b611dac565b348015610ba957600080fd5b50601354610560906001600160a01b031681565b348015610bc957600080fd5b50600254610560906001600160a01b031681565b348015610be957600080fd5b506104ad610bf83660046139b5565b611dba565b348015610c0957600080fd5b5061060d610c183660046139f6565b60016020526000908152604090205481565b348015610c3657600080fd5b50610477610c45366004613a11565b611dd4565b6104ad610c583660046139b5565b611f7c565b348015610c6957600080fd5b5061060d612106565b348015610c7e57600080fd5b50600d54610560906001600160a01b031681565b610ca5610ca0366004613a71565b6121f6565b604051610484929190613ade565b348015610cbf57600080fd5b506104ad610cce366004613878565b6122f1565b348015610cdf57600080fd5b5061060d6b19d971e4fe8401e74000000081565b348015610cff57600080fd5b5061060d60235481565b348015610d1557600080fd5b5061060d610d24366004613b30565b612377565b6104ad610d373660046136d4565b612452565b348015610d4857600080fd5b50601554610560906001600160a01b031681565b348015610d6857600080fd5b5061060d612481565b348015610d7d57600080fd5b50610560610d8c3660046137b4565b600a602052600090815260409020546001600160a01b031681565b348015610db357600080fd5b506104ad610dc2366004613878565b6124af565b348015610dd357600080fd5b50600f54610560906001600160a01b031681565b348015610df357600080fd5b5061060d610e02366004613b52565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b348015610e3957600080fd5b506104ad610e48366004613878565b612505565b348015610e5957600080fd5b506104cf610e68366004613b80565b612543565b606060088054610e7c90613b9c565b80601f0160208091040260200160405190810160405280929190818152602001828054610ea890613b9c565b8015610ef55780601f10610eca57610100808354040283529160200191610ef5565b820191906000526020600020905b815481529060010190602001808311610ed857829003601f168201915b5050505050905090565b60008111610f285760405162461bcd60e51b8152600401610f1f90613bd0565b60405180910390fd5b60006064610f37600284613c28565b610f419190613c3f565b90506000610f50600483613c3f565b90506000610f5f600484613c3f565b90506000610f6e600485613c3f565b90506000610f7d600486613c3f565b90506000610f8b8688613c61565b9050610fa3336013546001600160a01b031687612579565b610fb9336014546001600160a01b031686612579565b610fcf336015546001600160a01b031685612579565b610fd933836125dd565b610fe4338983612579565b6040805188815260208101889052428183015290516001600160a01b038a169133917f7e1b4577399017960fc6a1284e846e5682b112a94c7c1e28afa6dc3031324a299181900360600190a35050505050505050565b600033611048818585612613565b60019150505b92915050565b60408051808201909152600080825260208201526060611087604051806040016040528060008152602001600081525090565b60408051808201825260008082526001600160401b036020808401829052845183815290810190945291955091826110e2565b6040805180820190915260008152606060208201528152602001906001900390816110ba5790505b509350600080611107604089013560608a013561110260208c018c6139f6565b612620565b60408051808201909152918252602082015296989597505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314611170576040516391ac5e4f60e01b8152336004820152602401610f1f565b6020870180359061118a90611185908a6139f6565b612664565b146111c85761119c60208801886139f6565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610f1f565b6111d7878787878787876126a0565b50505050505050565b6000336111ee858285612807565b6111f9858585612579565b60019150505b9392505050565b600081116112265760405162461bcd60e51b8152600401610f1f90613bd0565b3360009081526020805260409020548111156112845760405162461bcd60e51b815260206004820152601c60248201527f536f6c6465206465207374616b696e6720696e737566666973616e74000000006044820152606401610f1f565b61128c61179d565b60006103e861129d8361016d613c28565b6112a79190613c3f565b905080602360008282546112bb9190613c61565b9091555050600c546112d7906001600160a01b03163384612579565b336000908152602080526040812080548492906112f5908490613c61565b90915550503360009081526020805260408120549003611335576024805490600061131f83613c8a565b9091555050336000908152602160205260408120555b6040805183815242602082015233917f7fc4727e062e336010f2c282598ef5f14facb3de68cf8195c2f23e1454b2b74e91015b60405180910390a25050565b6016816005811061138457600080fd5b0154905081565b611393612885565b61139d82826128b2565b5050565b601b816005811061138457600080fd5b60006113be600183612377565b90506000816113d534670de0b6b3a7640000613c28565b6113df9190613c3f565b60008481526022602052604081205491925090601b856005811061140557611405613ca1565b01546114119190613c61565b9050808211156114635760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f75676820746f6b656e7320696e2074686973207469657200006044820152606401610f1f565b6000670de0b6b3a76400006114788585613c28565b6114829190613c3f565b9050803410156114cc5760405162461bcd60e51b8152602060048201526015602482015274125b9cdd59999a58da595b9d08115512081cd95b9d605a1b6044820152606401610f1f565b600085815260226020526040812080548592906114ea908490613cb7565b909155506114fb9050303385612579565b600060646115098382613c28565b6115139190613c3f565b600d549091506001600160a01b03166108fc606461153284600a613c28565b61153c9190613c3f565b6040518115909202916000818181858888f19350505050158015611564573d6000803e3d6000fd5b50600e546001600160a01b03166108fc6064611581846005613c28565b61158b9190613c3f565b6040518115909202916000818181858888f193505050501580156115b3573d6000803e3d6000fd5b50600f546001600160a01b03166108fc60646115d0846014613c28565b6115da9190613c3f565b6040518115909202916000818181858888f19350505050158015611602573d6000803e3d6000fd5b506010546001600160a01b03166108fc606461161f846019613c28565b6116299190613c3f565b6040518115909202916000818181858888f19350505050158015611651573d6000803e3d6000fd5b506011546001600160a01b03166108fc606461166e84601e613c28565b6116789190613c3f565b6040518115909202916000818181858888f193505050501580156116a0573d6000803e3d6000fd5b506012546001600160a01b03166108fc60646116bd84600a613c28565b6116c79190613c3f565b6040518115909202916000818181858888f193505050501580156116ef573d6000803e3d6000fd5b508134111561172e57336108fc6117068434613c61565b6040518115909202916000818181858888f193505050501580156111d7573d6000803e3d6000fd5b505050505050565b604080518082019091526000808252602082015260006117666040850135606086013561110260208801886139f6565b9150506000806117768684612907565b909250905061179361178b60208801886139f6565b838388612a2b565b9695505050505050565b3360009081526020805260409020546117f85760405162461bcd60e51b815260206004820152601760248201527f417563756e206a65746f6e206e27657374207374616b650000000000000000006044820152606401610f1f565b336000908152602160205260408120546118129042613c61565b905060006118236201518083613c3f565b9050600081116118855760405162461bcd60e51b815260206004820152602760248201527f5374616b696e6720706572696f64206d757374206265206174206c65617374206044820152666f6e652064617960c81b6064820152608401610f1f565b61016d811115611894575061016d5b3360009081526020805260408120546103e8906118b2908490613c28565b6118bc9190613c3f565b600c549091506118d6906001600160a01b03163383612579565b3360008181526021602090815260409182902042908190558251858152918201527f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a910160405180910390a2505050565b60036020908152600092835260408084209091529082529020805461194b90613b9c565b80601f016020809104026020016040519081016040528092919081815260200182805461197790613b9c565b80156119c45780601f10611999576101008083540402835291602001916119c4565b820191906000526020600020905b8154815290600101906020018083116119a757829003601f168201915b505050505081565b6119d4613492565b6119dc613492565b60005b6005811015611a3557600081815260226020526040902054601b8260058110611a0a57611a0a613ca1565b0154611a169190613c61565b828260058110611a2857611a28613ca1565b60200201526001016119df565b50919050565b611a43612885565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b611aa0612885565b611aaa6000612b0c565b565b6001600160a01b03811630145b949350505050565b606060098054610e7c90613b9c565b60008111611b205760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e20300000006044820152606401610f1f565b33600090815260056020526040902054811115611b895760405162461bcd60e51b815260206004820152602160248201527f4c6520736f6c64652065737420696e66657269657572206175206d6f6e74616e6044820152601d60fa1b6064820152608401610f1f565b600c546001600160a01b031660009081526005602052604081205411611c025760405162461bcd60e51b815260206004820152602860248201527f4c65207374616b696e67206573742061637475656c6c656d656e7420696e646960448201526773706f6e69626c6560c01b6064820152608401610f1f565b60006103e8611c138361016d613c28565b611c1d9190613c3f565b905080602354611c2d9190613cb7565b600c546001600160a01b03166000908152600560205260409020541015611cd05760405162461bcd60e51b815260206004820152604b60248201527f4c6520736f6c646520647520636f6e74726174206465207374616b696e67206560448201527f737420696e737566666973616e7420706f757220636f7576726972206c65732060648201526a7265636f6d70656e73657360a81b608482015260a401610f1f565b8060236000828254611ce29190613cb7565b9091555050600c54611cff9033906001600160a01b031684612579565b3360009081526020805260408120549003611d2a5760248054906000611d2483613cca565b91905055505b33600090815260208052604090205415611d4657611d4661179d565b33600090815260216020908152604080832042905590805281208054849290611d70908490613cb7565b90915550506040805183815242602082015233917f54487bf6784eb8093b2c4d57918a67e7b19b91057e918117ed95da9ed2f4caad9101611368565b600033611048818585612579565b611dc2612885565b61139d611dcf8284613d84565b612b5c565b63ffffffff8416600090815260036020908152604080832061ffff87168452909152812080546060929190611e0890613b9c565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3490613b9c565b8015611e815780601f10611e5657610100808354040283529160200191611e81565b820191906000526020600020905b815481529060010190602001808311611e6457829003601f168201915b505050505090508051600003611ed15783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929450611ab99350505050565b6000839003611ee1579050611ab9565b60028310611f5f57611f2884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c6392505050565b80611f368460028188613e99565b604051602001611f4893929190613ec3565b604051602081830303815290604052915050611ab9565b8383604051639a6d49cd60e01b8152600401610f1f929190613f14565b60005b818110156120855736838383818110611f9a57611f9a613ca1565b9050602002810190611fac9190613f28565b9050611fdf611fbe60208301836139f6565b602083013563ffffffff919091166000908152600160205260409020541490565b611fe9575061207d565b3063d045a0dc60c08301358360a0810135612008610100830183613f49565b612019610100890160e08a01613878565b6120276101208a018a613f49565b6040518963ffffffff1660e01b81526004016120499796959493929190613fa4565b6000604051808303818588803b15801561206257600080fd5b505af1158015612076573d6000803e3d6000fd5b5050505050505b600101611f7f565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa1580156120c4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120ec919081019061402a565b604051638351eea760e01b8152600401610f1f9190613547565b466000818152600a60205260408120549091906001600160a01b03168061217f5760405162461bcd60e51b815260206004820152602760248201527f50726963652066656564206e6f7420617661696c61626c6520666f7220746869604482015266399031b430b4b760c91b6064820152608401610f1f565b60008190506000816001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156121c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e891906140b1565b509198975050505050505050565b6121fe6134b0565b604080518082019091526000808252602082015260008061223533604089013560608a013561223060208c018c6139f6565b612c8f565b915091506000806122468984612907565b909250905061227261225b60208b018b6139f6565b838361226c368d90038d018d614101565b8b612cb5565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a906122c0908d018d6139f6565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b6122f9612885565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e190602401600060405180830381600087803b15801561235c57600080fd5b505af1158015612370573d6000803e3d6000fd5b5050505050565b6000600582106123b85760405162461bcd60e51b815260206004820152600c60248201526b24b73b30b634b2103a34b2b960a11b6044820152606401610f1f565b6000601683600581106123cd576123cd613ca1565b0154905060006123db612106565b9050600081136124215760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642045544820707269636560781b6044820152606401610f1f565b8060008161242f8886613c28565b61243d906305f5e100613c28565b6124479190613c3f565b979650505050505050565b3330146124725760405163029a949d60e31b815260040160405180910390fd5b6111d7878787878787876111c8565b602354600c546001600160a01b031660009081526005602052604081205490916124aa91613c61565b905090565b6124b7612885565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c242776090602001611a8d565b61250d612885565b6001600160a01b03811661253757604051631e4fbdf760e01b815260006004820152602401610f1f565b61254081612b0c565b50565b600060208201803590600190839061255b90866139f6565b63ffffffff1681526020810191909152604001600020541492915050565b6001600160a01b0383166125a357604051634b637e8f60e11b815260006004820152602401610f1f565b6001600160a01b0382166125cd5760405163ec442f0560e01b815260006004820152602401610f1f565b6125d8838383612db5565b505050565b6001600160a01b03821661260757604051634b637e8f60e11b815260006004820152602401610f1f565b61139d82600083612db5565b6125d88383836001612edf565b60008061262c85612fb4565b91508190508381101561265c576040516371c4efed60e01b81526004810182905260248101859052604401610f1f565b935093915050565b63ffffffff81166000908152600160205260408120548061104e5760405163f6ff4fb760e01b815263ffffffff84166004820152602401610f1f565b60006126b26126af8787612feb565b90565b905060006126de826126cc6126c78a8a613003565b613026565b6126d960208d018d6139f6565b61305b565b905060288611156127a557600061271b6126fe60608c0160408d01614133565b61270b60208d018d6139f6565b846127168c8c613083565b6130ce565b604051633e5ac80960e11b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637cb59012906127719086908d906000908790600401614150565b600060405180830381600087803b15801561278b57600080fd5b505af115801561279f573d6000803e3d6000fd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c6127de60208d018d6139f6565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6001600160a01b03838116600090815260066020908152604080832093861683529290522054600019811461287f578181101561287057604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610f1f565b61287f84848484036000612edf565b50505050565b6000546001600160a01b03163314611aaa5760405163118cdaa760e01b8152336004820152602401610f1f565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b6060806000612964856020013561291d86613100565b61292a60a0890189613f49565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061312c92505050565b909350905060008161297757600161297a565b60025b905061299a61298c60208801886139f6565b82610c4560808a018a613f49565b6004549093506001600160a01b031615612a22576004805460405163043a78eb60e01b81526001600160a01b039091169163043a78eb916129df918891889101614181565b602060405180830381865afa1580156129fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a2091906141a6565b505b50509250929050565b60408051808201909152600080825260208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddc28c586040518060a001604052808863ffffffff168152602001612a8e89612664565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b8152600401612ac39291906141c3565b6040805180830381865afa158015612adf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b03919061426c565b95945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b8151811015612c3357612b8e828281518110612b7d57612b7d613ca1565b602002602001015160400151612c63565b818181518110612ba057612ba0613ca1565b60200260200101516040015160036000848481518110612bc257612bc2613ca1565b60200260200101516000015163ffffffff1663ffffffff1681526020019081526020016000206000848481518110612bfc57612bfc613ca1565b60200260200101516020015161ffff1661ffff1681526020019081526020016000209081612c2a91906142d0565b50600101612b5f565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b67481604051611a8d919061438f565b600281015161ffff811660031461139d5781604051639a6d49cd60e01b8152600401610f1f9190613547565b600080612c9d858585612620565b9092509050612cac86836125dd565b94509492505050565b612cbd6134b0565b6000612ccc84600001516131a6565b602085015190915015612ce657612ce684602001516131ce565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632637a450826040518060a001604052808b63ffffffff168152602001612d368c612664565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b8152600401612d729291906141c3565b60806040518083038185885af1158015612d90573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612447919061441a565b6001600160a01b038316612de0578060076000828254612dd59190613cb7565b90915550612e529050565b6001600160a01b03831660009081526005602052604090205481811015612e335760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610f1f565b6001600160a01b03841660009081526005602052604090209082900390555b6001600160a01b038216612e6e57600780548290039055612e8d565b6001600160a01b03821660009081526005602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612ed291815260200190565b60405180910390a3505050565b6001600160a01b038416612f095760405163e602df0560e01b815260006004820152602401610f1f565b6001600160a01b038316612f3357604051634a1406b160e11b815260006004820152602401610f1f565b6001600160a01b038085166000908152600660209081526040808320938716835292905220829055801561287f57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051612fa691815260200190565b60405180910390a350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000612fe18184613c3f565b61104e9190613c28565b6000612ffa6020828486613e99565b6111ff91614464565b6000613013602860208486613e99565b61301c91614482565b60c01c9392505050565b600061104e7f00000000000000000000000000000000000000000000000000000000000000006001600160401b038416613c28565b60006001600160a01b0384166130715761dead93505b61307b84846132b0565b509092915050565b60606130928260288186613e99565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b6060848484846040516020016130e794939291906144b2565b6040516020818303038152906040529050949350505050565b600061104e7f000000000000000000000000000000000000000000000000000000000000000083613c3f565b805160609015158061317557848460405160200161316192919091825260c01b6001600160c01b031916602082015260280190565b60405160208183030381529060405261319c565b8484338560405160200161318c9493929190614501565b6040516020818303038152906040525b9150935093915050565b60008134146131ca576040516304fb820960e51b8152346004820152602401610f1f565b5090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa15801561322e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132529190614544565b90506001600160a01b03811661327b576040516329b99a9560e11b815260040160405180910390fd5b61139d6001600160a01b038216337f0000000000000000000000000000000000000000000000000000000000000000856132e6565b6001600160a01b0382166132da5760405163ec442f0560e01b815260006004820152602401610f1f565b61139d60008383612db5565b604080516001600160a01b038581166024830152848116604483015260648083018590528351808403909101815260849092019092526020810180516001600160e01b03166323b872dd60e01b17905261287f9186919060009061334c9084168361339a565b9050805160001415801561337157508080602001905181019061336f91906141a6565b155b156125d857604051635274afe760e01b81526001600160a01b0384166004820152602401610f1f565b60606111ff8383600084600080856001600160a01b031684866040516133c09190614561565b60006040518083038185875af1925050503d80600081146133fd576040519150601f19603f3d011682016040523d82523d6000602084013e613402565b606091505b50915091506117938683836060826134225761341d82613469565b6111ff565b815115801561343957506001600160a01b0384163b155b1561346257604051639996b31560e01b81526001600160a01b0385166004820152602401610f1f565b50806111ff565b8051156134795780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6040518060a001604052806005906020820280368337509192915050565b60405180606001604052806000801916815260200160006001600160401b031681526020016134f2604051806040016040528060008152602001600081525090565b905290565b60005b838110156135125781810151838201526020016134fa565b50506000910152565b600081518084526135338160208601602086016134f7565b601f01601f19169290920160200192915050565b6020815260006111ff602083018461351b565b6001600160a01b038116811461254057600080fd5b6000806040838503121561358257600080fd5b823561358d8161355a565b946020939093013593505050565b600060e08284031215611a3557600080fd5b6000602082840312156135bf57600080fd5b81356001600160401b038111156135d557600080fd5b611ab98482850161359b565b8351815260208085015190820152600060a08201604060a0604085015281865180845260c08601915060c08160051b8701019350602080890160005b8381101561365c5788870360bf190185528151805188528301518388018790526136498789018261351b565b975050938201939082019060010161361d565b50508751606088015250505060208501516080850152509050611ab9565b600060608284031215611a3557600080fd5b60008083601f84011261369e57600080fd5b5081356001600160401b038111156136b557600080fd5b6020830191508360208285010111156136cd57600080fd5b9250929050565b600080600080600080600060e0888a0312156136ef57600080fd5b6136f9898961367a565b96506060880135955060808801356001600160401b038082111561371c57600080fd5b6137288b838c0161368c565b909750955060a08a0135915061373d8261355a565b90935060c0890135908082111561375357600080fd5b506137608a828b0161368c565b989b979a50959850939692959293505050565b60008060006060848603121561378857600080fd5b83356137938161355a565b925060208401356137a38161355a565b929592945050506040919091013590565b6000602082840312156137c657600080fd5b5035919050565b803563ffffffff811681146137e157600080fd5b919050565b600080604083850312156137f957600080fd5b61358d836137cd565b801515811461254057600080fd5b6000806040838503121561382357600080fd5b82356001600160401b0381111561383957600080fd5b6138458582860161359b565b925050602083013561385681613802565b809150509250929050565b81518152602080830151908201526040810161104e565b60006020828403121561388a57600080fd5b81356111ff8161355a565b803561ffff811681146137e157600080fd5b600080604083850312156138ba57600080fd5b6138c3836137cd565b91506138d160208401613895565b90509250929050565b60a08101818360005b60058110156139025781518352602092830192909101906001016138e3565b50505092915050565b60008060008060a0858703121561392157600080fd5b61392b868661367a565b935060608501356001600160401b0381111561394657600080fd5b6139528782880161368c565b90945092505060808501356139668161355a565b939692955090935050565b60008083601f84011261398357600080fd5b5081356001600160401b0381111561399a57600080fd5b6020830191508360208260051b85010111156136cd57600080fd5b600080602083850312156139c857600080fd5b82356001600160401b038111156139de57600080fd5b6139ea85828601613971565b90969095509350505050565b600060208284031215613a0857600080fd5b6111ff826137cd565b60008060008060608587031215613a2757600080fd5b613a30856137cd565b9350613a3e60208601613895565b925060408501356001600160401b03811115613a5957600080fd5b613a658782880161368c565b95989497509550505050565b60008060008385036080811215613a8757600080fd5b84356001600160401b03811115613a9d57600080fd5b613aa98782880161359b565b9450506040601f1982011215613abe57600080fd5b506020840191506060840135613ad38161355a565b809150509250925092565b600060c082019050835182526001600160401b0360208501511660208301526040840151613b19604084018280518252602090810151910152565b5082516080830152602083015160a08301526111ff565b60008060408385031215613b4357600080fd5b50508035926020909101359150565b60008060408385031215613b6557600080fd5b8235613b708161355a565b915060208301356138568161355a565b600060608284031215613b9257600080fd5b6111ff838361367a565b600181811c90821680613bb057607f821691505b602082108103611a3557634e487b7160e01b600052602260045260246000fd5b60208082526022908201527f4c65206d6f6e74616e7420646f69742065747265207375706572696575722061604082015261020360f41b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761104e5761104e613c12565b600082613c5c57634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561104e5761104e613c12565b634e487b7160e01b600052604160045260246000fd5b600081613c9957613c99613c12565b506000190190565b634e487b7160e01b600052603260045260246000fd5b8082018082111561104e5761104e613c12565b600060018201613cdc57613cdc613c12565b5060010190565b604051606081016001600160401b0381118282101715613d0557613d05613c74565b60405290565b604080519081016001600160401b0381118282101715613d0557613d05613c74565b604051601f8201601f191681016001600160401b0381118282101715613d5557613d55613c74565b604052919050565b60006001600160401b03821115613d7657613d76613c74565b50601f01601f191660200190565b60006001600160401b0380841115613d9e57613d9e613c74565b8360051b6020613daf818301613d2d565b868152918501918181019036841115613dc757600080fd5b865b84811015613e8d57803586811115613de15760008081fd5b88016060368290031215613df55760008081fd5b613dfd613ce3565b613e06826137cd565b8152613e13868301613895565b8682015260408083013589811115613e2b5760008081fd5b929092019136601f840112613e405760008081fd5b8235613e53613e4e82613d5d565b613d2d565b8181523689838701011115613e685760008081fd5b818986018a830137600091810189019190915290820152845250918301918301613dc9565b50979650505050505050565b60008085851115613ea957600080fd5b83861115613eb657600080fd5b5050820193919092039150565b60008451613ed58184602089016134f7565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000611ab9602083018486613eeb565b6000823561013e19833603018112613f3f57600080fd5b9190910192915050565b6000808335601e19843603018112613f6057600080fd5b8301803591506001600160401b03821115613f7a57600080fd5b6020019150368190038213156136cd57600080fd5b6001600160401b038116811461254057600080fd5b63ffffffff613fb2896137cd565b1681526020880135602082015260006040890135613fcf81613f8f565b6001600160401b03811660408401525087606083015260e06080830152613ffa60e083018789613eeb565b6001600160a01b03861660a084015282810360c084015261401c818587613eeb565b9a9950505050505050505050565b60006020828403121561403c57600080fd5b81516001600160401b0381111561405257600080fd5b8201601f8101841361406357600080fd5b8051614071613e4e82613d5d565b81815285602083850101111561408657600080fd5b612b038260208301602086016134f7565b805169ffffffffffffffffffff811681146137e157600080fd5b600080600080600060a086880312156140c957600080fd5b6140d286614097565b94506020860151935060408601519250606086015191506140f560808701614097565b90509295509295909350565b60006040828403121561411357600080fd5b61411b613d0b565b82358152602083013560208201528091505092915050565b60006020828403121561414557600080fd5b81356111ff81613f8f565b60018060a01b038516815283602082015261ffff83166040820152608060608201526000611793608083018461351b565b604081526000614194604083018561351b565b8281036020840152612b03818561351b565b6000602082840312156141b857600080fd5b81516111ff81613802565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a060808401526141f960e084018261351b565b90506060850151603f198483030160a0850152614216828261351b565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b60006040828403121561424e57600080fd5b614256613d0b565b9050815181526020820151602082015292915050565b60006040828403121561427e57600080fd5b6111ff838361423c565b601f8211156125d8576000816000526020600020601f850160051c810160208610156142b15750805b601f850160051c820191505b8181101561172e578281556001016142bd565b81516001600160401b038111156142e9576142e9613c74565b6142fd816142f78454613b9c565b84614288565b602080601f831160018114614332576000841561431a5750858301515b600019600386901b1c1916600185901b17855561172e565b600085815260208120601f198616915b8281101561436157888601518255948401946001909101908401614342565b508582101561437f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561440c57888303603f190185528151805163ffffffff1684528781015161ffff168885015286015160608785018190526143f88186018361351b565b9689019694505050908601906001016143b8565b509098975050505050505050565b60006080828403121561442c57600080fd5b614434613ce3565b82518152602083015161444681613f8f565b6020820152614458846040850161423c565b60408201529392505050565b8035602083101561104e57600019602084900360031b1b1692915050565b6001600160c01b031981358181169160088510156144aa5780818660080360031b1b83161692505b505092915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c820152600082516144f181602c8501602087016134f7565b91909101602c0195945050505050565b8481526001600160401b0360c01b8460c01b166020820152826028820152600082516145348160488501602087016134f7565b9190910160480195945050505050565b60006020828403121561455657600080fd5b81516111ff8161355a565b60008251613f3f8184602087016134f756fea2646970667358221220cc1e72e3ccd4b6c2f54520d82e4a7920e210d586462c09b48f890f1374c5ea1664736f6c63430008160033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000001a44076050125825900e736c501f859c50fe728c0000000000000000000000004bf48c86416fd22624bb3edd3407f51f2943b69b0000000000000000000000000000000000000000000000000000000000000004474149410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044741494100000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106104565760003560e01c806376a6367f1161023f578063bb0b6a5311610139578063d045a0dc116100b6578063d46980161161007a578063d469801614610dc7578063dd62ed3e14610de7578063f2fde38b14610e2d578063fc0c546a146107e4578063ff7bd03d14610e4d57600080fd5b8063d045a0dc14610d29578063d0c43a5614610d3c578063d2b7dcfd14610d5c578063d2ce702214610d71578063d424388514610da757600080fd5b8063c7c7f5b3116100fd578063c7c7f5b314610c92578063ca5eb5e114610cb3578063cc0aca9a14610cd3578063cd3293de14610cf3578063ce39469614610d0957600080fd5b8063bb0b6a5314610bfd578063bc70b35414610c2a578063bd815db014610c4a578063bea4dfb514610c5d578063c757483914610c7257600080fd5b806395d89b41116101c7578063a694fc3a1161018b578063a694fc3a14610b5d578063a9059cbb14610b7d578063b60eaaaa14610b9d578063b731ea0a14610bbd578063b98bd07014610bdd57600080fd5b806395d89b4114610aa7578063963efcaa14610abc57806397ca379c14610af057806398807d8414610b1d5780639f68b96414610b4957600080fd5b8063869890381161020e5780638698903814610a1e5780638da5cb5b14610a345780638e7bdb9b14610a525780638ea5220f14610a67578063902d55a514610a8757600080fd5b806376a6367f1461098f5780637d25a05e146109af57806382413eac146109ea578063857749b014610a0a57600080fd5b80633408e4701161035057806359927044116102d85780636fc1b31e1161029c5780636fc1b31e146108e457806370a0823114610904578063715018a61461093a57806373e40ed41461094f57806375f0a8741461096f57600080fd5b806359927044146108175780635a0dfe4d146108375780635e280f111461086e5780635e9d2e7b146108a257806362dab32b146108c257600080fd5b80634cf088d91161031f5780634cf088d91461077a5780634da6a5561461079a5780634e71d92d146107cf57806352ae2879146107e45780635535d461146107f757600080fd5b80633408e4701461070757806335771fe01461071a5780633610724e1461073a5780633b6f743b1461074d57600080fd5b806317442b70116103de5780632e17de78116103a25780632e17de7814610670578063300eccab14610690578063313ce567146106b057806331ed0db4146106d25780633400288b146106e757600080fd5b806317442b70146105da57806318160ddd146105fc5780631f5e13341461061b578063228cb7331461063057806323b872dd1461065057600080fd5b80630dea2d5c116104255780630dea2d5c1461050e578063111ecdad1461054057806313137d6514610578578063134d4f251461058b578063156a0d0f146105b357600080fd5b806306fdde031461046257806308acece21461048d578063095ea7b3146104af5780630d35b415146104df57600080fd5b3661045d57005b600080fd5b34801561046e57600080fd5b50610477610e6d565b6040516104849190613547565b60405180910390f35b34801561049957600080fd5b506104ad6104a836600461356f565b610eff565b005b3480156104bb57600080fd5b506104cf6104ca36600461356f565b61103a565b6040519015158152602001610484565b3480156104eb57600080fd5b506104ff6104fa3660046135ad565b611054565b604051610484939291906135e1565b34801561051a57600080fd5b50602354600c546001600160a01b031660009081526005602052604090205410156104cf565b34801561054c57600080fd5b50600454610560906001600160a01b031681565b6040516001600160a01b039091168152602001610484565b6104ad6105863660046136d4565b611125565b34801561059757600080fd5b506105a0600281565b60405161ffff9091168152602001610484565b3480156105bf57600080fd5b506040805162b9270b60e21b81526001602082015201610484565b3480156105e657600080fd5b5060408051600181526002602082015201610484565b34801561060857600080fd5b506007545b604051908152602001610484565b34801561062757600080fd5b506105a0600181565b34801561063c57600080fd5b50600b54610560906001600160a01b031681565b34801561065c57600080fd5b506104cf61066b366004613773565b6111e0565b34801561067c57600080fd5b506104ad61068b3660046137b4565b611206565b34801561069c57600080fd5b5061060d6106ab3660046137b4565b611374565b3480156106bc57600080fd5b5060125b60405160ff9091168152602001610484565b3480156106de57600080fd5b5060245461060d565b3480156106f357600080fd5b506104ad6107023660046137e6565b61138b565b34801561071357600080fd5b504661060d565b34801561072657600080fd5b5061060d6107353660046137b4565b6113a1565b6104ad6107483660046137b4565b6113b1565b34801561075957600080fd5b5061076d610768366004613810565b611736565b6040516104849190613861565b34801561078657600080fd5b50600c54610560906001600160a01b031681565b3480156107a657600080fd5b5061060d6107b5366004613878565b6001600160a01b0316600090815260208052604090205490565b3480156107db57600080fd5b506104ad61179d565b3480156107f057600080fd5b5030610560565b34801561080357600080fd5b506104776108123660046138a7565b611927565b34801561082357600080fd5b50601254610560906001600160a01b031681565b34801561084357600080fd5b506104cf6108523660046137e6565b63ffffffff919091166000908152600160205260409020541490565b34801561087a57600080fd5b506105607f0000000000000000000000001a44076050125825900e736c501f859c50fe728c81565b3480156108ae57600080fd5b50600e54610560906001600160a01b031681565b3480156108ce57600080fd5b506108d76119cc565b60405161048491906138da565b3480156108f057600080fd5b506104ad6108ff366004613878565b611a3b565b34801561091057600080fd5b5061060d61091f366004613878565b6001600160a01b031660009081526005602052604090205490565b34801561094657600080fd5b506104ad611a98565b34801561095b57600080fd5b5061060d6b06765c793fa10079d000000081565b34801561097b57600080fd5b50601154610560906001600160a01b031681565b34801561099b57600080fd5b50601454610560906001600160a01b031681565b3480156109bb57600080fd5b506109d26109ca3660046137e6565b600092915050565b6040516001600160401b039091168152602001610484565b3480156109f657600080fd5b506104cf610a0536600461390b565b611aac565b348015610a1657600080fd5b5060066106c0565b348015610a2a57600080fd5b5061060d60245481565b348015610a4057600080fd5b506000546001600160a01b0316610560565b348015610a5e57600080fd5b5061060d600281565b348015610a7357600080fd5b50601054610560906001600160a01b031681565b348015610a9357600080fd5b5061060d6b409f9cbc7c4a04c22000000081565b348015610ab357600080fd5b50610477611ac1565b348015610ac857600080fd5b5061060d7f000000000000000000000000000000000000000000000000000000e8d4a5100081565b348015610afc57600080fd5b5061060d610b0b3660046137b4565b60226020526000908152604090205481565b348015610b2957600080fd5b5061060d610b38366004613878565b602080526000908152604090205481565b348015610b5557600080fd5b5060006104cf565b348015610b6957600080fd5b506104ad610b783660046137b4565b611ad0565b348015610b8957600080fd5b506104cf610b9836600461356f565b611dac565b348015610ba957600080fd5b50601354610560906001600160a01b031681565b348015610bc957600080fd5b50600254610560906001600160a01b031681565b348015610be957600080fd5b506104ad610bf83660046139b5565b611dba565b348015610c0957600080fd5b5061060d610c183660046139f6565b60016020526000908152604090205481565b348015610c3657600080fd5b50610477610c45366004613a11565b611dd4565b6104ad610c583660046139b5565b611f7c565b348015610c6957600080fd5b5061060d612106565b348015610c7e57600080fd5b50600d54610560906001600160a01b031681565b610ca5610ca0366004613a71565b6121f6565b604051610484929190613ade565b348015610cbf57600080fd5b506104ad610cce366004613878565b6122f1565b348015610cdf57600080fd5b5061060d6b19d971e4fe8401e74000000081565b348015610cff57600080fd5b5061060d60235481565b348015610d1557600080fd5b5061060d610d24366004613b30565b612377565b6104ad610d373660046136d4565b612452565b348015610d4857600080fd5b50601554610560906001600160a01b031681565b348015610d6857600080fd5b5061060d612481565b348015610d7d57600080fd5b50610560610d8c3660046137b4565b600a602052600090815260409020546001600160a01b031681565b348015610db357600080fd5b506104ad610dc2366004613878565b6124af565b348015610dd357600080fd5b50600f54610560906001600160a01b031681565b348015610df357600080fd5b5061060d610e02366004613b52565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b348015610e3957600080fd5b506104ad610e48366004613878565b612505565b348015610e5957600080fd5b506104cf610e68366004613b80565b612543565b606060088054610e7c90613b9c565b80601f0160208091040260200160405190810160405280929190818152602001828054610ea890613b9c565b8015610ef55780601f10610eca57610100808354040283529160200191610ef5565b820191906000526020600020905b815481529060010190602001808311610ed857829003601f168201915b5050505050905090565b60008111610f285760405162461bcd60e51b8152600401610f1f90613bd0565b60405180910390fd5b60006064610f37600284613c28565b610f419190613c3f565b90506000610f50600483613c3f565b90506000610f5f600484613c3f565b90506000610f6e600485613c3f565b90506000610f7d600486613c3f565b90506000610f8b8688613c61565b9050610fa3336013546001600160a01b031687612579565b610fb9336014546001600160a01b031686612579565b610fcf336015546001600160a01b031685612579565b610fd933836125dd565b610fe4338983612579565b6040805188815260208101889052428183015290516001600160a01b038a169133917f7e1b4577399017960fc6a1284e846e5682b112a94c7c1e28afa6dc3031324a299181900360600190a35050505050505050565b600033611048818585612613565b60019150505b92915050565b60408051808201909152600080825260208201526060611087604051806040016040528060008152602001600081525090565b60408051808201825260008082526001600160401b036020808401829052845183815290810190945291955091826110e2565b6040805180820190915260008152606060208201528152602001906001900390816110ba5790505b509350600080611107604089013560608a013561110260208c018c6139f6565b612620565b60408051808201909152918252602082015296989597505050505050565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b03163314611170576040516391ac5e4f60e01b8152336004820152602401610f1f565b6020870180359061118a90611185908a6139f6565b612664565b146111c85761119c60208801886139f6565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610f1f565b6111d7878787878787876126a0565b50505050505050565b6000336111ee858285612807565b6111f9858585612579565b60019150505b9392505050565b600081116112265760405162461bcd60e51b8152600401610f1f90613bd0565b3360009081526020805260409020548111156112845760405162461bcd60e51b815260206004820152601c60248201527f536f6c6465206465207374616b696e6720696e737566666973616e74000000006044820152606401610f1f565b61128c61179d565b60006103e861129d8361016d613c28565b6112a79190613c3f565b905080602360008282546112bb9190613c61565b9091555050600c546112d7906001600160a01b03163384612579565b336000908152602080526040812080548492906112f5908490613c61565b90915550503360009081526020805260408120549003611335576024805490600061131f83613c8a565b9091555050336000908152602160205260408120555b6040805183815242602082015233917f7fc4727e062e336010f2c282598ef5f14facb3de68cf8195c2f23e1454b2b74e91015b60405180910390a25050565b6016816005811061138457600080fd5b0154905081565b611393612885565b61139d82826128b2565b5050565b601b816005811061138457600080fd5b60006113be600183612377565b90506000816113d534670de0b6b3a7640000613c28565b6113df9190613c3f565b60008481526022602052604081205491925090601b856005811061140557611405613ca1565b01546114119190613c61565b9050808211156114635760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f75676820746f6b656e7320696e2074686973207469657200006044820152606401610f1f565b6000670de0b6b3a76400006114788585613c28565b6114829190613c3f565b9050803410156114cc5760405162461bcd60e51b8152602060048201526015602482015274125b9cdd59999a58da595b9d08115512081cd95b9d605a1b6044820152606401610f1f565b600085815260226020526040812080548592906114ea908490613cb7565b909155506114fb9050303385612579565b600060646115098382613c28565b6115139190613c3f565b600d549091506001600160a01b03166108fc606461153284600a613c28565b61153c9190613c3f565b6040518115909202916000818181858888f19350505050158015611564573d6000803e3d6000fd5b50600e546001600160a01b03166108fc6064611581846005613c28565b61158b9190613c3f565b6040518115909202916000818181858888f193505050501580156115b3573d6000803e3d6000fd5b50600f546001600160a01b03166108fc60646115d0846014613c28565b6115da9190613c3f565b6040518115909202916000818181858888f19350505050158015611602573d6000803e3d6000fd5b506010546001600160a01b03166108fc606461161f846019613c28565b6116299190613c3f565b6040518115909202916000818181858888f19350505050158015611651573d6000803e3d6000fd5b506011546001600160a01b03166108fc606461166e84601e613c28565b6116789190613c3f565b6040518115909202916000818181858888f193505050501580156116a0573d6000803e3d6000fd5b506012546001600160a01b03166108fc60646116bd84600a613c28565b6116c79190613c3f565b6040518115909202916000818181858888f193505050501580156116ef573d6000803e3d6000fd5b508134111561172e57336108fc6117068434613c61565b6040518115909202916000818181858888f193505050501580156111d7573d6000803e3d6000fd5b505050505050565b604080518082019091526000808252602082015260006117666040850135606086013561110260208801886139f6565b9150506000806117768684612907565b909250905061179361178b60208801886139f6565b838388612a2b565b9695505050505050565b3360009081526020805260409020546117f85760405162461bcd60e51b815260206004820152601760248201527f417563756e206a65746f6e206e27657374207374616b650000000000000000006044820152606401610f1f565b336000908152602160205260408120546118129042613c61565b905060006118236201518083613c3f565b9050600081116118855760405162461bcd60e51b815260206004820152602760248201527f5374616b696e6720706572696f64206d757374206265206174206c65617374206044820152666f6e652064617960c81b6064820152608401610f1f565b61016d811115611894575061016d5b3360009081526020805260408120546103e8906118b2908490613c28565b6118bc9190613c3f565b600c549091506118d6906001600160a01b03163383612579565b3360008181526021602090815260409182902042908190558251858152918201527f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a910160405180910390a2505050565b60036020908152600092835260408084209091529082529020805461194b90613b9c565b80601f016020809104026020016040519081016040528092919081815260200182805461197790613b9c565b80156119c45780601f10611999576101008083540402835291602001916119c4565b820191906000526020600020905b8154815290600101906020018083116119a757829003601f168201915b505050505081565b6119d4613492565b6119dc613492565b60005b6005811015611a3557600081815260226020526040902054601b8260058110611a0a57611a0a613ca1565b0154611a169190613c61565b828260058110611a2857611a28613ca1565b60200201526001016119df565b50919050565b611a43612885565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b611aa0612885565b611aaa6000612b0c565b565b6001600160a01b03811630145b949350505050565b606060098054610e7c90613b9c565b60008111611b205760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e20300000006044820152606401610f1f565b33600090815260056020526040902054811115611b895760405162461bcd60e51b815260206004820152602160248201527f4c6520736f6c64652065737420696e66657269657572206175206d6f6e74616e6044820152601d60fa1b6064820152608401610f1f565b600c546001600160a01b031660009081526005602052604081205411611c025760405162461bcd60e51b815260206004820152602860248201527f4c65207374616b696e67206573742061637475656c6c656d656e7420696e646960448201526773706f6e69626c6560c01b6064820152608401610f1f565b60006103e8611c138361016d613c28565b611c1d9190613c3f565b905080602354611c2d9190613cb7565b600c546001600160a01b03166000908152600560205260409020541015611cd05760405162461bcd60e51b815260206004820152604b60248201527f4c6520736f6c646520647520636f6e74726174206465207374616b696e67206560448201527f737420696e737566666973616e7420706f757220636f7576726972206c65732060648201526a7265636f6d70656e73657360a81b608482015260a401610f1f565b8060236000828254611ce29190613cb7565b9091555050600c54611cff9033906001600160a01b031684612579565b3360009081526020805260408120549003611d2a5760248054906000611d2483613cca565b91905055505b33600090815260208052604090205415611d4657611d4661179d565b33600090815260216020908152604080832042905590805281208054849290611d70908490613cb7565b90915550506040805183815242602082015233917f54487bf6784eb8093b2c4d57918a67e7b19b91057e918117ed95da9ed2f4caad9101611368565b600033611048818585612579565b611dc2612885565b61139d611dcf8284613d84565b612b5c565b63ffffffff8416600090815260036020908152604080832061ffff87168452909152812080546060929190611e0890613b9c565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3490613b9c565b8015611e815780601f10611e5657610100808354040283529160200191611e81565b820191906000526020600020905b815481529060010190602001808311611e6457829003601f168201915b505050505090508051600003611ed15783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929450611ab99350505050565b6000839003611ee1579050611ab9565b60028310611f5f57611f2884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c6392505050565b80611f368460028188613e99565b604051602001611f4893929190613ec3565b604051602081830303815290604052915050611ab9565b8383604051639a6d49cd60e01b8152600401610f1f929190613f14565b60005b818110156120855736838383818110611f9a57611f9a613ca1565b9050602002810190611fac9190613f28565b9050611fdf611fbe60208301836139f6565b602083013563ffffffff919091166000908152600160205260409020541490565b611fe9575061207d565b3063d045a0dc60c08301358360a0810135612008610100830183613f49565b612019610100890160e08a01613878565b6120276101208a018a613f49565b6040518963ffffffff1660e01b81526004016120499796959493929190613fa4565b6000604051808303818588803b15801561206257600080fd5b505af1158015612076573d6000803e3d6000fd5b5050505050505b600101611f7f565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa1580156120c4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120ec919081019061402a565b604051638351eea760e01b8152600401610f1f9190613547565b466000818152600a60205260408120549091906001600160a01b03168061217f5760405162461bcd60e51b815260206004820152602760248201527f50726963652066656564206e6f7420617661696c61626c6520666f7220746869604482015266399031b430b4b760c91b6064820152608401610f1f565b60008190506000816001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156121c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e891906140b1565b509198975050505050505050565b6121fe6134b0565b604080518082019091526000808252602082015260008061223533604089013560608a013561223060208c018c6139f6565b612c8f565b915091506000806122468984612907565b909250905061227261225b60208b018b6139f6565b838361226c368d90038d018d614101565b8b612cb5565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a906122c0908d018d6139f6565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b6122f9612885565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c169063ca5eb5e190602401600060405180830381600087803b15801561235c57600080fd5b505af1158015612370573d6000803e3d6000fd5b5050505050565b6000600582106123b85760405162461bcd60e51b815260206004820152600c60248201526b24b73b30b634b2103a34b2b960a11b6044820152606401610f1f565b6000601683600581106123cd576123cd613ca1565b0154905060006123db612106565b9050600081136124215760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642045544820707269636560781b6044820152606401610f1f565b8060008161242f8886613c28565b61243d906305f5e100613c28565b6124479190613c3f565b979650505050505050565b3330146124725760405163029a949d60e31b815260040160405180910390fd5b6111d7878787878787876111c8565b602354600c546001600160a01b031660009081526005602052604081205490916124aa91613c61565b905090565b6124b7612885565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c242776090602001611a8d565b61250d612885565b6001600160a01b03811661253757604051631e4fbdf760e01b815260006004820152602401610f1f565b61254081612b0c565b50565b600060208201803590600190839061255b90866139f6565b63ffffffff1681526020810191909152604001600020541492915050565b6001600160a01b0383166125a357604051634b637e8f60e11b815260006004820152602401610f1f565b6001600160a01b0382166125cd5760405163ec442f0560e01b815260006004820152602401610f1f565b6125d8838383612db5565b505050565b6001600160a01b03821661260757604051634b637e8f60e11b815260006004820152602401610f1f565b61139d82600083612db5565b6125d88383836001612edf565b60008061262c85612fb4565b91508190508381101561265c576040516371c4efed60e01b81526004810182905260248101859052604401610f1f565b935093915050565b63ffffffff81166000908152600160205260408120548061104e5760405163f6ff4fb760e01b815263ffffffff84166004820152602401610f1f565b60006126b26126af8787612feb565b90565b905060006126de826126cc6126c78a8a613003565b613026565b6126d960208d018d6139f6565b61305b565b905060288611156127a557600061271b6126fe60608c0160408d01614133565b61270b60208d018d6139f6565b846127168c8c613083565b6130ce565b604051633e5ac80960e11b81529091506001600160a01b037f0000000000000000000000001a44076050125825900e736c501f859c50fe728c1690637cb59012906127719086908d906000908790600401614150565b600060405180830381600087803b15801561278b57600080fd5b505af115801561279f573d6000803e3d6000fd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c6127de60208d018d6139f6565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6001600160a01b03838116600090815260066020908152604080832093861683529290522054600019811461287f578181101561287057604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610f1f565b61287f84848484036000612edf565b50505050565b6000546001600160a01b03163314611aaa5760405163118cdaa760e01b8152336004820152602401610f1f565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b6060806000612964856020013561291d86613100565b61292a60a0890189613f49565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061312c92505050565b909350905060008161297757600161297a565b60025b905061299a61298c60208801886139f6565b82610c4560808a018a613f49565b6004549093506001600160a01b031615612a22576004805460405163043a78eb60e01b81526001600160a01b039091169163043a78eb916129df918891889101614181565b602060405180830381865afa1580156129fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a2091906141a6565b505b50509250929050565b60408051808201909152600080825260208201527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663ddc28c586040518060a001604052808863ffffffff168152602001612a8e89612664565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b8152600401612ac39291906141c3565b6040805180830381865afa158015612adf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b03919061426c565b95945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b8151811015612c3357612b8e828281518110612b7d57612b7d613ca1565b602002602001015160400151612c63565b818181518110612ba057612ba0613ca1565b60200260200101516040015160036000848481518110612bc257612bc2613ca1565b60200260200101516000015163ffffffff1663ffffffff1681526020019081526020016000206000848481518110612bfc57612bfc613ca1565b60200260200101516020015161ffff1661ffff1681526020019081526020016000209081612c2a91906142d0565b50600101612b5f565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b67481604051611a8d919061438f565b600281015161ffff811660031461139d5781604051639a6d49cd60e01b8152600401610f1f9190613547565b600080612c9d858585612620565b9092509050612cac86836125dd565b94509492505050565b612cbd6134b0565b6000612ccc84600001516131a6565b602085015190915015612ce657612ce684602001516131ce565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b0316632637a450826040518060a001604052808b63ffffffff168152602001612d368c612664565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b8152600401612d729291906141c3565b60806040518083038185885af1158015612d90573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190612447919061441a565b6001600160a01b038316612de0578060076000828254612dd59190613cb7565b90915550612e529050565b6001600160a01b03831660009081526005602052604090205481811015612e335760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610f1f565b6001600160a01b03841660009081526005602052604090209082900390555b6001600160a01b038216612e6e57600780548290039055612e8d565b6001600160a01b03821660009081526005602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612ed291815260200190565b60405180910390a3505050565b6001600160a01b038416612f095760405163e602df0560e01b815260006004820152602401610f1f565b6001600160a01b038316612f3357604051634a1406b160e11b815260006004820152602401610f1f565b6001600160a01b038085166000908152600660209081526040808320938716835292905220829055801561287f57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051612fa691815260200190565b60405180910390a350505050565b60007f000000000000000000000000000000000000000000000000000000e8d4a51000612fe18184613c3f565b61104e9190613c28565b6000612ffa6020828486613e99565b6111ff91614464565b6000613013602860208486613e99565b61301c91614482565b60c01c9392505050565b600061104e7f000000000000000000000000000000000000000000000000000000e8d4a510006001600160401b038416613c28565b60006001600160a01b0384166130715761dead93505b61307b84846132b0565b509092915050565b60606130928260288186613e99565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b6060848484846040516020016130e794939291906144b2565b6040516020818303038152906040529050949350505050565b600061104e7f000000000000000000000000000000000000000000000000000000e8d4a5100083613c3f565b805160609015158061317557848460405160200161316192919091825260c01b6001600160c01b031916602082015260280190565b60405160208183030381529060405261319c565b8484338560405160200161318c9493929190614501565b6040516020818303038152906040525b9150935093915050565b60008134146131ca576040516304fb820960e51b8152346004820152602401610f1f565b5090565b60007f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa15801561322e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132529190614544565b90506001600160a01b03811661327b576040516329b99a9560e11b815260040160405180910390fd5b61139d6001600160a01b038216337f0000000000000000000000001a44076050125825900e736c501f859c50fe728c856132e6565b6001600160a01b0382166132da5760405163ec442f0560e01b815260006004820152602401610f1f565b61139d60008383612db5565b604080516001600160a01b038581166024830152848116604483015260648083018590528351808403909101815260849092019092526020810180516001600160e01b03166323b872dd60e01b17905261287f9186919060009061334c9084168361339a565b9050805160001415801561337157508080602001905181019061336f91906141a6565b155b156125d857604051635274afe760e01b81526001600160a01b0384166004820152602401610f1f565b60606111ff8383600084600080856001600160a01b031684866040516133c09190614561565b60006040518083038185875af1925050503d80600081146133fd576040519150601f19603f3d011682016040523d82523d6000602084013e613402565b606091505b50915091506117938683836060826134225761341d82613469565b6111ff565b815115801561343957506001600160a01b0384163b155b1561346257604051639996b31560e01b81526001600160a01b0385166004820152602401610f1f565b50806111ff565b8051156134795780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6040518060a001604052806005906020820280368337509192915050565b60405180606001604052806000801916815260200160006001600160401b031681526020016134f2604051806040016040528060008152602001600081525090565b905290565b60005b838110156135125781810151838201526020016134fa565b50506000910152565b600081518084526135338160208601602086016134f7565b601f01601f19169290920160200192915050565b6020815260006111ff602083018461351b565b6001600160a01b038116811461254057600080fd5b6000806040838503121561358257600080fd5b823561358d8161355a565b946020939093013593505050565b600060e08284031215611a3557600080fd5b6000602082840312156135bf57600080fd5b81356001600160401b038111156135d557600080fd5b611ab98482850161359b565b8351815260208085015190820152600060a08201604060a0604085015281865180845260c08601915060c08160051b8701019350602080890160005b8381101561365c5788870360bf190185528151805188528301518388018790526136498789018261351b565b975050938201939082019060010161361d565b50508751606088015250505060208501516080850152509050611ab9565b600060608284031215611a3557600080fd5b60008083601f84011261369e57600080fd5b5081356001600160401b038111156136b557600080fd5b6020830191508360208285010111156136cd57600080fd5b9250929050565b600080600080600080600060e0888a0312156136ef57600080fd5b6136f9898961367a565b96506060880135955060808801356001600160401b038082111561371c57600080fd5b6137288b838c0161368c565b909750955060a08a0135915061373d8261355a565b90935060c0890135908082111561375357600080fd5b506137608a828b0161368c565b989b979a50959850939692959293505050565b60008060006060848603121561378857600080fd5b83356137938161355a565b925060208401356137a38161355a565b929592945050506040919091013590565b6000602082840312156137c657600080fd5b5035919050565b803563ffffffff811681146137e157600080fd5b919050565b600080604083850312156137f957600080fd5b61358d836137cd565b801515811461254057600080fd5b6000806040838503121561382357600080fd5b82356001600160401b0381111561383957600080fd5b6138458582860161359b565b925050602083013561385681613802565b809150509250929050565b81518152602080830151908201526040810161104e565b60006020828403121561388a57600080fd5b81356111ff8161355a565b803561ffff811681146137e157600080fd5b600080604083850312156138ba57600080fd5b6138c3836137cd565b91506138d160208401613895565b90509250929050565b60a08101818360005b60058110156139025781518352602092830192909101906001016138e3565b50505092915050565b60008060008060a0858703121561392157600080fd5b61392b868661367a565b935060608501356001600160401b0381111561394657600080fd5b6139528782880161368c565b90945092505060808501356139668161355a565b939692955090935050565b60008083601f84011261398357600080fd5b5081356001600160401b0381111561399a57600080fd5b6020830191508360208260051b85010111156136cd57600080fd5b600080602083850312156139c857600080fd5b82356001600160401b038111156139de57600080fd5b6139ea85828601613971565b90969095509350505050565b600060208284031215613a0857600080fd5b6111ff826137cd565b60008060008060608587031215613a2757600080fd5b613a30856137cd565b9350613a3e60208601613895565b925060408501356001600160401b03811115613a5957600080fd5b613a658782880161368c565b95989497509550505050565b60008060008385036080811215613a8757600080fd5b84356001600160401b03811115613a9d57600080fd5b613aa98782880161359b565b9450506040601f1982011215613abe57600080fd5b506020840191506060840135613ad38161355a565b809150509250925092565b600060c082019050835182526001600160401b0360208501511660208301526040840151613b19604084018280518252602090810151910152565b5082516080830152602083015160a08301526111ff565b60008060408385031215613b4357600080fd5b50508035926020909101359150565b60008060408385031215613b6557600080fd5b8235613b708161355a565b915060208301356138568161355a565b600060608284031215613b9257600080fd5b6111ff838361367a565b600181811c90821680613bb057607f821691505b602082108103611a3557634e487b7160e01b600052602260045260246000fd5b60208082526022908201527f4c65206d6f6e74616e7420646f69742065747265207375706572696575722061604082015261020360f41b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761104e5761104e613c12565b600082613c5c57634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561104e5761104e613c12565b634e487b7160e01b600052604160045260246000fd5b600081613c9957613c99613c12565b506000190190565b634e487b7160e01b600052603260045260246000fd5b8082018082111561104e5761104e613c12565b600060018201613cdc57613cdc613c12565b5060010190565b604051606081016001600160401b0381118282101715613d0557613d05613c74565b60405290565b604080519081016001600160401b0381118282101715613d0557613d05613c74565b604051601f8201601f191681016001600160401b0381118282101715613d5557613d55613c74565b604052919050565b60006001600160401b03821115613d7657613d76613c74565b50601f01601f191660200190565b60006001600160401b0380841115613d9e57613d9e613c74565b8360051b6020613daf818301613d2d565b868152918501918181019036841115613dc757600080fd5b865b84811015613e8d57803586811115613de15760008081fd5b88016060368290031215613df55760008081fd5b613dfd613ce3565b613e06826137cd565b8152613e13868301613895565b8682015260408083013589811115613e2b5760008081fd5b929092019136601f840112613e405760008081fd5b8235613e53613e4e82613d5d565b613d2d565b8181523689838701011115613e685760008081fd5b818986018a830137600091810189019190915290820152845250918301918301613dc9565b50979650505050505050565b60008085851115613ea957600080fd5b83861115613eb657600080fd5b5050820193919092039150565b60008451613ed58184602089016134f7565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000611ab9602083018486613eeb565b6000823561013e19833603018112613f3f57600080fd5b9190910192915050565b6000808335601e19843603018112613f6057600080fd5b8301803591506001600160401b03821115613f7a57600080fd5b6020019150368190038213156136cd57600080fd5b6001600160401b038116811461254057600080fd5b63ffffffff613fb2896137cd565b1681526020880135602082015260006040890135613fcf81613f8f565b6001600160401b03811660408401525087606083015260e06080830152613ffa60e083018789613eeb565b6001600160a01b03861660a084015282810360c084015261401c818587613eeb565b9a9950505050505050505050565b60006020828403121561403c57600080fd5b81516001600160401b0381111561405257600080fd5b8201601f8101841361406357600080fd5b8051614071613e4e82613d5d565b81815285602083850101111561408657600080fd5b612b038260208301602086016134f7565b805169ffffffffffffffffffff811681146137e157600080fd5b600080600080600060a086880312156140c957600080fd5b6140d286614097565b94506020860151935060408601519250606086015191506140f560808701614097565b90509295509295909350565b60006040828403121561411357600080fd5b61411b613d0b565b82358152602083013560208201528091505092915050565b60006020828403121561414557600080fd5b81356111ff81613f8f565b60018060a01b038516815283602082015261ffff83166040820152608060608201526000611793608083018461351b565b604081526000614194604083018561351b565b8281036020840152612b03818561351b565b6000602082840312156141b857600080fd5b81516111ff81613802565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a060808401526141f960e084018261351b565b90506060850151603f198483030160a0850152614216828261351b565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b60006040828403121561424e57600080fd5b614256613d0b565b9050815181526020820151602082015292915050565b60006040828403121561427e57600080fd5b6111ff838361423c565b601f8211156125d8576000816000526020600020601f850160051c810160208610156142b15750805b601f850160051c820191505b8181101561172e578281556001016142bd565b81516001600160401b038111156142e9576142e9613c74565b6142fd816142f78454613b9c565b84614288565b602080601f831160018114614332576000841561431a5750858301515b600019600386901b1c1916600185901b17855561172e565b600085815260208120601f198616915b8281101561436157888601518255948401946001909101908401614342565b508582101561437f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561440c57888303603f190185528151805163ffffffff1684528781015161ffff168885015286015160608785018190526143f88186018361351b565b9689019694505050908601906001016143b8565b509098975050505050505050565b60006080828403121561442c57600080fd5b614434613ce3565b82518152602083015161444681613f8f565b6020820152614458846040850161423c565b60408201529392505050565b8035602083101561104e57600019602084900360031b1b1692915050565b6001600160c01b031981358181169160088510156144aa5780818660080360031b1b83161692505b505092915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c820152600082516144f181602c8501602087016134f7565b91909101602c0195945050505050565b8481526001600160401b0360c01b8460c01b166020820152826028820152600082516145348160488501602087016134f7565b9190910160480195945050505050565b60006020828403121561455657600080fd5b81516111ff8161355a565b60008251613f3f8184602087016134f756fea2646970667358221220cc1e72e3ccd4b6c2f54520d82e4a7920e210d586462c09b48f890f1374c5ea1664736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000001a44076050125825900e736c501f859c50fe728c0000000000000000000000004bf48c86416fd22624bb3edd3407f51f2943b69b0000000000000000000000000000000000000000000000000000000000000004474149410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044741494100000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): GAIA
Arg [1] : _symbol (string): GAIA
Arg [2] : _lzEndpoint (address): 0x1a44076050125825900e736c501f859c50fE728c
Arg [3] : _delegate (address): 0x4bF48C86416Fd22624BB3edD3407f51f2943b69B
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 0000000000000000000000001a44076050125825900e736c501f859c50fe728c
Arg [3] : 0000000000000000000000004bf48c86416fd22624bb3edd3407f51f2943b69b
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [5] : 4741494100000000000000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 4741494100000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
333:9540:39:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2074:89:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8802:796:39;;;;;;;;;;-1:-1:-1;8802:796:39;;;;;:::i;:::-;;:::i;:::-;;4293:186:31;;;;;;;;;;-1:-1:-1;4293:186:31;;;;;:::i;:::-;;:::i;:::-;;;1391:14:40;;1384:22;1366:41;;1354:2;1339:18;4293:186:31;1226:187:40;4928:1258:11;;;;;;;;;;-1:-1:-1;4928:1258:11;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;8388:112:39:-;;;;;;;;;;-1:-1:-1;8485:7:39;;8473;;-1:-1:-1;;;;;8473:7:39;8439:4;3390:18:31;;;:9;:18;;;;;;-1:-1:-1;8463:29:39;8388:112;;2132:27:11;;;;;;;;;;-1:-1:-1;2132:27:11;;;;-1:-1:-1;;;;;2132:27:11;;;;;;-1:-1:-1;;;;;3605:32:40;;;3587:51;;3575:2;3560:18;2132:27:11;3441:203:40;4368:708:3;;;;;;:::i;:::-;;:::i;2006:40:11:-;;;;;;;;;;;;2045:1;2006:40;;;;;5387:6:40;5375:19;;;5357:38;;5345:2;5330:18;2006:40:11;5213:188:40;3277:140:11;;;;;;;;;;-1:-1:-1;3277:140:11;;;-1:-1:-1;;;5576:52:40;;3408:1:11;5659:2:40;5644:18;;5637:59;5549:18;3277:140:11;5406:296:40;1287:235:1;;;;;;;;;;-1:-1:-1;1287:235:1;;;843:1:4;5914:34:40;;678:1:3;5979:2:40;5964:18;;5957:43;5850:18;1287:235:1;5707:299:40;3144:97:31;;;;;;;;;;-1:-1:-1;3222:12:31;;3144:97;;;6157:25:40;;;6145:2;6130:18;3144:97:31;6011:177:40;1969:31:11;;;;;;;;;;;;1999:1;1969:31;;644:66:39;;;;;;;;;;-1:-1:-1;644:66:39;;;;-1:-1:-1;;;;;644:66:39;;;5039:244:31;;;;;;;;;;-1:-1:-1;5039:244:31;;;;;:::i;:::-;;:::i;7091:589:39:-;;;;;;;;;;-1:-1:-1;7091:589:39;;;;;:::i;:::-;;:::i;1520:96::-;;;;;;;;;;-1:-1:-1;1520:96:39;;;;;:::i;:::-;;:::i;3002:82:31:-;;;;;;;;;;-1:-1:-1;3075:2:31;3002:82;;;7011:4:40;6999:17;;;6981:36;;6969:2;6954:18;3002:82:31;6839:184:40;9604:97:39;;;;;;;;;;-1:-1:-1;9681:12:39;;9604:97;;1724:108:2;;;;;;;;;;-1:-1:-1;1724:108:2;;;;;:::i;:::-;;:::i;3408:176:39:-;;;;;;;;;;-1:-1:-1;3532:9:39;3408:176;;1625:214;;;;;;;;;;-1:-1:-1;1625:214:39;;;;;:::i;:::-;;:::i;4517:1161::-;;;;;;:::i;:::-;;:::i;6637:774:11:-;;;;;;;;;;-1:-1:-1;6637:774:11;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;717:67:39:-;;;;;;;;;;-1:-1:-1;717:67:39;;;;-1:-1:-1;;;;;717:67:39;;;8685:109;;;;;;;;;;-1:-1:-1;8685:109:39;;;;;:::i;:::-;-1:-1:-1;;;;;8774:12:39;8747:7;8774:12;;;:6;:12;;;;;;;8685:109;7766:616;;;;;;;;;;;;;:::i;875:93:15:-;;;;;;;;;;-1:-1:-1;956:4:15;875:93;;538::9;;;;;;;;;;-1:-1:-1;538:93:9;;;;;:::i;:::-;;:::i;1195:70:39:-;;;;;;;;;;-1:-1:-1;1195:70:39;;;;-1:-1:-1;;;;;1195:70:39;;;14792:132:11;;;;;;;;;;-1:-1:-1;14792:132:11;;;;;:::i;:::-;14897:11;;;;;14874:4;14897:11;;;:5;:11;;;;;;:20;;14792:132;446:46:2;;;;;;;;;;;;;;;873:75:39;;;;;;;;;;-1:-1:-1;873:75:39;;;;-1:-1:-1;;;;;873:75:39;;;5763:309;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;4459:163:11:-;;;;;;;;;;-1:-1:-1;4459:163:11;;;;;:::i;:::-;;:::i;3299:116:31:-;;;;;;;;;;-1:-1:-1;3299:116:31;;;;;:::i;:::-;-1:-1:-1;;;;;3390:18:31;3364:7;3390:18;;;:9;:18;;;;;;;3299:116;2293:101:29;;;;;;;;;;;;;:::i;501:64:39:-;;;;;;;;;;;;541:24;501:64;;1113:75;;;;;;;;;;-1:-1:-1;1113:75:39;;;;-1:-1:-1;;;;;1113:75:39;;;1352:78;;;;;;;;;;-1:-1:-1;1352:78:39;;;;-1:-1:-1;;;;;1352:78:39;;;3507:128:3;;;;;;;;;;-1:-1:-1;3507:128:3;;;;;:::i;:::-;3596:12;3507:128;;;;;;;;-1:-1:-1;;;;;10131:31:40;;;10113:50;;10101:2;10086:18;3507:128:3;9969:200:40;2013:216:3;;;;;;;;;;-1:-1:-1;2013:216:3;;;;;:::i;:::-;;:::i;4024:87:11:-;;;;;;;;;;-1:-1:-1;4103:1:11;4024:87;;2101:27:39;;;;;;;;;;;;;;;;1638:85:29;;;;;;;;;;-1:-1:-1;1684:7:29;1710:6;-1:-1:-1;;;;;1710:6:29;1638:85;;2010:51:39;;;;;;;;;;;;2060:1;2010:51;;1037:69;;;;;;;;;;-1:-1:-1;1037:69:39;;;;-1:-1:-1;;;;;1037:69:39;;;430:64;;;;;;;;;;;;469:25;430:64;;2276:93:31;;;;;;;;;;;;;:::i;1663:46:11:-;;;;;;;;;;;;;;;1949:52:39;;;;;;;;;;-1:-1:-1;1949:52:39;;;;;:::i;:::-;;;;;;;;;;;;;;1846:41;;;;;;;;;;-1:-1:-1;1846:41:39;;;;;:::i;:::-;;;;;;;;;;;;;;1460:94:10;;;;;;;;;;-1:-1:-1;1519:4:10;1460:94;;6080:925:39;;;;;;;;;;-1:-1:-1;6080:925:39;;;;;:::i;:::-;;:::i;3610:178:31:-;;;;;;;;;;-1:-1:-1;3610:178:31;;;;;:::i;:::-;;:::i;1272:73:39:-;;;;;;;;;;-1:-1:-1;1272:73:39;;;;-1:-1:-1;;;;;1272:73:39;;;559:23:15;;;;;;;;;;-1:-1:-1;559:23:15;;;;-1:-1:-1;;;;;559:23:15;;;1391:156:9;;;;;;;;;;-1:-1:-1;1391:156:9;;;;;:::i;:::-;;:::i;569:48:2:-;;;;;;;;;;-1:-1:-1;569:48:2;;;;;:::i;:::-;;;;;;;;;;;;;;3510:981:9;;;;;;;;;;-1:-1:-1;3510:981:9;;;;;:::i;:::-;;:::i;1698:1333:15:-;;;;;;:::i;:::-;;:::i;3592:453:39:-;;;;;;;;;;;;;:::i;791:75::-;;;;;;;;;;-1:-1:-1;791:75:39;;;;-1:-1:-1;;;;;791:75:39;;;8099:1340:11;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;3252:105:2:-;;;;;;;;;;-1:-1:-1;3252:105:2;;;;;:::i;:::-;;:::i;572:65:39:-;;;;;;;;;;;;613:24;572:65;;2068:26;;;;;;;;;;;;;;;;4053:456;;;;;;;;;;-1:-1:-1;4053:456:39;;;;;:::i;:::-;;:::i;3679:409:15:-;;;;;;:::i;:::-;;:::i;1437:74:39:-;;;;;;;;;;-1:-1:-1;1437:74:39;;;;-1:-1:-1;;;;;1437:74:39;;;9707:126;;;;;;;;;;;;;:::i;361:62::-;;;;;;;;;;-1:-1:-1;361:62:39;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;361:62:39;;;1100:139:15;;;;;;;;;;-1:-1:-1;1100:139:15;;;;;:::i;:::-;;:::i;955:75:39:-;;;;;;;;;;-1:-1:-1;955:75:39;;;;-1:-1:-1;;;;;955:75:39;;;3846:140:31;;;;;;;;;;-1:-1:-1;3846:140:31;;;;;:::i;:::-;-1:-1:-1;;;;;3952:18:31;;;3926:7;3952:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3846:140;2543:215:29;;;;;;;;;;-1:-1:-1;2543:215:29;;;;;:::i;:::-;;:::i;2771:149:3:-;;;;;;;;;;-1:-1:-1;2771:149:3;;;;;:::i;:::-;;:::i;2074:89:31:-;2119:13;2151:5;2144:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2074:89;:::o;8802:796:39:-;8897:1;8888:6;:10;8880:57;;;;-1:-1:-1;;;8880:57:39;;;;;;;:::i;:::-;;;;;;;;;8948:11;8999:3;8963:32;2060:1;8963:6;:32;:::i;:::-;8962:40;;;;:::i;:::-;8948:54;-1:-1:-1;9013:18:39;9034:7;9040:1;8948:54;9034:7;:::i;:::-;9013:28;-1:-1:-1;9052:23:39;9078:7;9084:1;9078:3;:7;:::i;:::-;9052:33;-1:-1:-1;9096:19:39;9118:7;9124:1;9118:3;:7;:::i;:::-;9096:29;-1:-1:-1;9136:15:39;9154:7;9160:1;9154:3;:7;:::i;:::-;9136:25;-1:-1:-1;9172:22:39;9197:12;9206:3;9197:6;:12;:::i;:::-;9172:37;-1:-1:-1;9220:50:39;735:10:37;9244:13:39;;-1:-1:-1;;;;;9244:13:39;9259:10;9220:9;:50::i;:::-;9281:60;735:10:37;9305:18:39;;-1:-1:-1;;;;;9305:18:39;9325:15;9281:9;:60::i;:::-;9352:52;735:10:37;9376:14:39;;-1:-1:-1;;;;;9376:14:39;9392:11;9352:9;:52::i;:::-;9415:28;735:10:37;9435:7:39;9415:5;:28::i;:::-;9454:50;735:10:37;9478:9:39;9489:14;9454:9;:50::i;:::-;9520:70;;;17186:25:40;;;17242:2;17227:18;;17220:34;;;9574:15:39;17270:18:40;;;17263:34;9520:70:39;;-1:-1:-1;;;;;9520:70:39;;;735:10:37;;9520:70:39;;;;;17174:2:40;9520:70:39;;;8869:729;;;;;;8802:796;;:::o;4293:186:31:-;4366:4;735:10:37;4420:31:31;735:10:37;4436:7:31;4445:5;4420:8;:31::i;:::-;4468:4;4461:11;;;4293:186;;;;;:::o;4928:1258:11:-;-1:-1:-1;;;;;;;;;;;;;;;;;5080:35:11;5117:28;-1:-1:-1;;;;;;;;;;;;;;;;;;;5117:28:11;5335:34;;;;;;;;-1:-1:-1;5335:34:11;;;-1:-1:-1;;;;;5335:34:11;;;;;;;5486:21;;;;;;;;;;;5335:34;;-1:-1:-1;;;5486:21:11;;;-1:-1:-1;;;;;;;;;;;;;;;;;5486:21:11;;;;;;;;;;;;;;;-1:-1:-1;5470:37:11;-1:-1:-1;5944:20:11;;5994:120;6018:19;;;;6051:22;;;;6087:17;;;;6018:10;6087:17;:::i;:::-;5994:10;:120::i;:::-;6137:42;;;;;;;;;;;;;;;;4928:1258;;;;-1:-1:-1;;;;;;4928:1258:11:o;4368:708:3:-;4681:8;-1:-1:-1;;;;;4673:31:3;4694:10;4673:31;4669:68;;4713:24;;-1:-1:-1;;;4713:24:3;;4726:10;4713:24;;;3587:51:40;3560:18;;4713:24:3;3441:203:40;4669:68:3;4873:14;;;;;;4837:32;;4854:14;;4873:7;4854:14;:::i;:::-;4837:16;:32::i;:::-;:50;4833:103;;4905:14;;;;:7;:14;:::i;:::-;4896:40;;-1:-1:-1;;;4896:40:3;;17642:10:40;17630:23;;;4896:40:3;;;17612:42:40;4921:14:3;;;;17670:18:40;;;17663:34;17585:18;;4896:40:3;17440:263:40;4833:103:3;5010:59;5021:7;5030:5;5037:8;;5047:9;5058:10;;5010;:59::i;:::-;4368:708;;;;;;;:::o;5039:244:31:-;5126:4;735:10:37;5182:37:31;5198:4;735:10:37;5213:5:31;5182:15;:37::i;:::-;5229:26;5239:4;5245:2;5249:5;5229:9;:26::i;:::-;5272:4;5265:11;;;5039:244;;;;;;:::o;7091:589:39:-;7161:1;7152:6;:10;7144:57;;;;-1:-1:-1;;;7144:57:39;;;;;;;:::i;:::-;7227:10;7220:18;;;;:6;:18;;;;;;:28;-1:-1:-1;7220:28:39;7212:69;;;;-1:-1:-1;;;7212:69:39;;17910:2:40;7212:69:39;;;17892:21:40;17949:2;17929:18;;;17922:30;17988;17968:18;;;17961:58;18036:18;;7212:69:39;17708:352:40;7212:69:39;7292:7;:5;:7::i;:::-;7310:26;7356:4;7340:12;:6;7349:3;7340:12;:::i;:::-;7339:21;;;;:::i;:::-;7310:50;;7382:18;7371:7;;:29;;;;;;;:::i;:::-;;;;-1:-1:-1;;7421:7:39;;7411:38;;-1:-1:-1;;;;;7421:7:39;7430:10;7442:6;7411:9;:38::i;:::-;7467:10;7460:18;;;;:6;:18;;;;;:28;;7482:6;;7460:18;:28;;7482:6;;7460:28;:::i;:::-;;;;-1:-1:-1;;7510:10:39;7503:18;;;;:6;:18;;;;;;:23;;7499:113;;7543:12;:14;;;:12;:14;;;:::i;:::-;;;;-1:-1:-1;;7585:10:39;7599:1;7572:24;;;:12;:24;;;;;:28;7499:113;7627:45;;;18380:25:40;;;7656:15:39;18436:2:40;18421:18;;18414:34;7636:10:39;;7627:45;;18353:18:40;7627:45:39;;;;;;;;7133:547;7091:589;:::o;1520:96::-;;;;;;;;;;;;;;;-1:-1:-1;1520:96:39;:::o;1724:108:2:-;1531:13:29;:11;:13::i;:::-;1804:21:2::1;1813:4;1819:5;1804:8;:21::i;:::-;1724:108:::0;;:::o;1625:214:39:-;;;;;;;;;;;4517:1161;4578:17;4598:22;4612:1;4615:4;4598:13;:22::i;:::-;4578:42;-1:-1:-1;4631:14:39;4578:42;4649:20;:9;4661:8;4649:20;:::i;:::-;4648:34;;;;:::i;:::-;4693:23;4739;;;:17;:23;;;;;;4631:51;;-1:-1:-1;4693:23:39;4719:11;4757:4;4719:17;;;;;;;:::i;:::-;;;:43;;;;:::i;:::-;4693:69;;4791:15;4781:6;:25;;4773:68;;;;-1:-1:-1;;;4773:68:39;;18793:2:40;4773:68:39;;;18775:21:40;18832:2;18812:18;;;18805:30;18871:32;18851:18;;;18844:60;18921:18;;4773:68:39;18591:354:40;4773:68:39;4853:17;4896:8;4874:18;4883:9;4874:6;:18;:::i;:::-;4873:31;;;;:::i;:::-;4853:51;;4936:9;4923;:22;;4915:56;;;;-1:-1:-1;;;4915:56:39;;19152:2:40;4915:56:39;;;19134:21:40;19191:2;19171:18;;;19164:30;-1:-1:-1;;;19210:18:40;;;19203:51;19271:18;;4915:56:39;18950:345:40;4915:56:39;4982:23;;;;:17;:23;;;;;:33;;5009:6;;4982:23;:33;;5009:6;;4982:33;:::i;:::-;;;;-1:-1:-1;5026:44:39;;-1:-1:-1;5044:4:39;5051:10;5063:6;5026:9;:44::i;:::-;5081:22;5126:3;5107:15;:9;5126:3;5107:15;:::i;:::-;5106:23;;;;:::i;:::-;5148:15;;5081:48;;-1:-1:-1;;;;;;5148:15:39;5140:62;5198:3;5175:19;5081:48;5192:2;5175:19;:::i;:::-;5174:27;;;;:::i;:::-;5140:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5221:15:39;;-1:-1:-1;;;;;5221:15:39;5213:61;5270:3;5248:18;:14;5265:1;5248:18;:::i;:::-;5247:26;;;;:::i;:::-;5213:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5293:15:39;;-1:-1:-1;;;;;5293:15:39;5285:62;5343:3;5320:19;:14;5337:2;5320:19;:::i;:::-;5319:27;;;;:::i;:::-;5285:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5366:9:39;;-1:-1:-1;;;;;5366:9:39;5358:56;5410:3;5387:19;:14;5404:2;5387:19;:::i;:::-;5386:27;;;;:::i;:::-;5358:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5433:15:39;;-1:-1:-1;;;;;5433:15:39;5425:62;5483:3;5460:19;:14;5477:2;5460:19;:::i;:::-;5459:27;;;;:::i;:::-;5425:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5506:10:39;;-1:-1:-1;;;;;5506:10:39;5498:57;5551:3;5528:19;:14;5545:2;5528:19;:::i;:::-;5527:27;;;;:::i;:::-;5498:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5582:9;5570;:21;5566:105;;;5616:10;5608:51;5637:21;5649:9;5637;:21;:::i;:::-;5608:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5566:105;4567:1111;;;;;4517:1161;:::o;6637:774:11:-;-1:-1:-1;;;;;;;;;;;;;;;;;6971:24:11;6999:74;7010:19;;;;7031:22;;;;7055:17;;;;7010:10;7055:17;:::i;6999:74::-;6968:105;;;7162:20;7184;7208:49;7228:10;7240:16;7208:19;:49::i;:::-;7161:96;;-1:-1:-1;7161:96:11;-1:-1:-1;7346:58:11;7353:17;;;;:10;:17;:::i;:::-;7372:7;7381;7390:13;7346:6;:58::i;:::-;7339:65;6637:774;-1:-1:-1;;;;;;6637:774:11:o;7766:616:39:-;7816:10;7830:1;7809:18;;;:6;:18;;;;;;7801:58;;;;-1:-1:-1;;;7801:58:39;;19632:2:40;7801:58:39;;;19614:21:40;19671:2;19651:18;;;19644:30;19710:25;19690:18;;;19683:53;19753:18;;7801:58:39;19430:347:40;7801:58:39;7925:10;7870:21;7912:24;;;:12;:24;;;;;;7894:42;;:15;:42;:::i;:::-;7870:66;-1:-1:-1;7947:18:39;7968:21;7984:5;7870:66;7968:21;:::i;:::-;7947:42;;8021:1;8008:10;:14;8000:66;;;;-1:-1:-1;;;8000:66:39;;19984:2:40;8000:66:39;;;19966:21:40;20023:2;20003:18;;;19996:30;20062:34;20042:18;;;20035:62;-1:-1:-1;;;20113:18:40;;;20106:37;20160:19;;8000:66:39;19782:403:40;8000:66:39;8094:3;8081:10;:16;8077:65;;;-1:-1:-1;8127:3:39;8077:65;8178:10;8152:15;8171:18;;;:6;:18;;;;;;8206:4;;8171:31;;8192:10;;8171:31;:::i;:::-;8170:40;;;;:::i;:::-;8231:7;;8152:58;;-1:-1:-1;8221:39:39;;-1:-1:-1;;;;;8231:7:39;8240:10;8152:58;8221:9;:39::i;:::-;8284:10;8271:24;;;;:12;:24;;;;;;;;;8298:15;8271:42;;;;8329:45;;18380:25:40;;;18421:18;;;18414:34;8329:45:39;;18353:18:40;8329:45:39;;;;;;;7790:592;;;7766:616::o;538:93:9:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5763:309:39:-;5823:17;;:::i;:::-;5853:33;;:::i;:::-;5902:12;5897:135;5927:1;5920:4;:8;5897:135;;;5997:23;;;;:17;:23;;;;;;5977:11;6015:4;5977:17;;;;;;;:::i;:::-;;;:43;;;;:::i;:::-;5953:15;5969:4;5953:21;;;;;;;:::i;:::-;;;;:67;5930:6;;5897:135;;;-1:-1:-1;6049:15:39;5763:309;-1:-1:-1;5763:309:39:o;4459:163:11:-;1531:13:29;:11;:13::i;:::-;4542:12:11::1;:28:::0;;-1:-1:-1;;;;;;4542:28:11::1;-1:-1:-1::0;;;;;4542:28:11;::::1;::::0;;::::1;::::0;;;4585:30:::1;::::0;3587:51:40;;;4585:30:11::1;::::0;3575:2:40;3560:18;4585:30:11::1;;;;;;;;4459:163:::0;:::o;2293:101:29:-;1531:13;:11;:13::i;:::-;2357:30:::1;2384:1;2357:18;:30::i;:::-;2293:101::o:0;2013:216:3:-;-1:-1:-1;;;;;2198:24:3;;2217:4;2198:24;2013:216;;;;;;;:::o;2276:93:31:-;2323:13;2355:7;2348:14;;;;;:::i;6080:925:39:-;6148:1;6139:6;:10;6131:52;;;;-1:-1:-1;;;6131:52:39;;20392:2:40;6131:52:39;;;20374:21:40;20431:2;20411:18;;;20404:30;20470:31;20450:18;;;20443:59;20519:18;;6131:52:39;20190:353:40;6131:52:39;6212:10;3364:7:31;3390:18;;;:9;:18;;;;;;6227:6:39;-1:-1:-1;6202:31:39;6194:77;;;;-1:-1:-1;;;6194:77:39;;20750:2:40;6194:77:39;;;20732:21:40;20789:2;20769:18;;;20762:30;20828:34;20808:18;;;20801:62;-1:-1:-1;;;20879:18:40;;;20872:31;20920:19;;6194:77:39;20548:397:40;6194:77:39;6300:7;;-1:-1:-1;;;;;6300:7:39;6311:1;3390:18:31;;;:9;:18;;;;;;6290:22:39;6282:75;;;;-1:-1:-1;;;6282:75:39;;21152:2:40;6282:75:39;;;21134:21:40;21191:2;21171:18;;;21164:30;21230:34;21210:18;;;21203:62;-1:-1:-1;;;21281:18:40;;;21274:38;21329:19;;6282:75:39;20950:404:40;6282:75:39;6368:26;6414:4;6398:12;:6;6407:3;6398:12;:::i;:::-;6397:21;;;;:::i;:::-;6368:50;;6483:18;6473:7;;:28;;;;:::i;:::-;6461:7;;-1:-1:-1;;;;;6461:7:39;3364::31;3390:18;;;:9;:18;;;;;;6451:50:39;;6429:175;;;;-1:-1:-1;;;6429:175:39;;21561:2:40;6429:175:39;;;21543:21:40;21600:2;21580:18;;;21573:30;21639:34;21619:18;;;21612:62;21710:34;21690:18;;;21683:62;-1:-1:-1;;;21761:19:40;;;21754:42;21813:19;;6429:175:39;21359:479:40;6429:175:39;6626:18;6615:7;;:29;;;;;;;:::i;:::-;;;;-1:-1:-1;;6677:7:39;;6655:38;;6665:10;;-1:-1:-1;;;;;6677:7:39;6686:6;6655:9;:38::i;:::-;6715:10;6708:18;;;;:6;:18;;;;;;:23;;6704:70;;6748:12;:14;;;:12;:14;;;:::i;:::-;;;;;;6704:70;6795:10;6809:1;6788:18;;;:6;:18;;;;;;:22;6784:62;;6827:7;:5;:7::i;:::-;6869:10;6856:24;;;;:12;:24;;;;;;;;6883:15;6856:42;;6909:18;;;;;:28;;6931:6;;6856:24;6909:28;;6931:6;;6909:28;:::i;:::-;;;;-1:-1:-1;;6953:44:39;;;18380:25:40;;;6981:15:39;18436:2:40;18421:18;;18414:34;6961:10:39;;6953:44;;18353:18:40;6953:44:39;18206:248:40;3610:178:31;3679:4;735:10:37;3733:27:31;735:10:37;3750:2:31;3754:5;3733:9;:27::i;1391:156:9:-;1531:13:29;:11;:13::i;:::-;1503:37:9::1;;1523:16:::0;;1503:37:::1;:::i;:::-;:19;:37::i;3510:981::-:0;3701:21;;;3677;3701;;;:15;:21;;;;;;;;:31;;;;;;;;;;3677:55;;3653:12;;3677:21;3701:31;3677:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3861:8;:15;3880:1;3861:20;3857:46;;3890:13;;3883:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3883:20:9;;-1:-1:-1;3883:20:9;;-1:-1:-1;;;;3883:20:9;3857:46;3988:1;3964:25;;;3960:46;;3998:8;-1:-1:-1;3991:15:9;;3960:46;4153:1;4129:25;;4125:267;;4170:34;4190:13;;4170:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4170:19:9;;-1:-1:-1;;;4170:34:9:i;:::-;4353:8;4363:17;:13;4377:1;4363:13;;:17;:::i;:::-;4340:41;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4333:48;;;;;4125:267;4470:13;;4455:29;;-1:-1:-1;;;4455:29:9;;;;;;;;;:::i;1698:1333:15:-;1799:9;1794:1037;1814:19;;;1794:1037;;;1854:29;1886:8;;1895:1;1886:11;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1854:43;-1:-1:-1;1980:50:15;1987:20;;;;1854:43;1987:20;:::i;:::-;2009;;;;14897:11:11;;;;;14874:4;14897:11;;;:5;:11;;;;;;:20;;14792:132;1980:50:15;1975:65;;2032:8;;;1975:65;2602:4;:22;2633:12;;;;:6;2696:11;;;;2725:14;;;;2633:6;2725:14;:::i;:::-;2757:15;;;;;;;;:::i;:::-;2790:16;;;;:6;:16;:::i;:::-;2602:218;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1840:991;1794:1037;1835:3;;1794:1037;;;;2988:10;-1:-1:-1;;;;;2978:43:15;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2978:45:15;;;;;;;;;;;;:::i;:::-;2961:63;;-1:-1:-1;;;2961:63:15;;;;;;;;:::i;3592:453:39:-;3532:9;3657:3;3741:36;;;:27;:36;;;;;;3657:3;;3532:9;-1:-1:-1;;;;;3741:36:39;;3788:82;;;;-1:-1:-1;;;3788:82:39;;29272:2:40;3788:82:39;;;29254:21:40;29311:2;29291:18;;;29284:30;29350:34;29330:18;;;29323:62;-1:-1:-1;;;29401:18:40;;;29394:37;29448:19;;3788:82:39;29070:403:40;3788:82:39;3881:30;3936:16;3881:72;;3967:10;3987:8;-1:-1:-1;;;;;3987:24:39;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;3964:49:39;;3592:453;-1:-1:-1;;;;;;;;3592:453:39:o;8099:1340:11:-;8260:34;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;8658:20:11;;8708:140;8728:10;8752:19;;;;8785:22;;;;8821:17;;;;8752:10;8821:17;:::i;:::-;8708:6;:140::i;:::-;8657:191;;;;8937:20;8959;8983:49;9003:10;9015:16;8983:19;:49::i;:::-;8936:96;;-1:-1:-1;8936:96:11;-1:-1:-1;9155:66:11;9163:17;;;;:10;:17;:::i;:::-;9182:7;9191;9155:66;;;;;;;9200:4;9155:66;:::i;:::-;9206:14;9155:7;:66::i;:::-;9287:42;;;;;;;;;;;;;;;;;;;9353:15;;9142:79;;-1:-1:-1;9287:42:11;;-1:-1:-1;9389:10:11;;9353:15;9345:87;;9370:17;;;;:10;:17;:::i;:::-;9345:87;;;30723:10:40;30711:23;;;30693:42;;30766:2;30751:18;;30744:34;;;30794:18;;30787:34;;;30681:2;30666:18;9345:87:11;;;;;;;8326:1113;;;;8099:1340;;;;;;:::o;3252:105:2:-;1531:13:29;:11;:13::i;:::-;3319:31:2::1;::::0;-1:-1:-1;;;3319:31:2;;-1:-1:-1;;;;;3605:32:40;;;3319:31:2::1;::::0;::::1;3587:51:40::0;3319:8:2::1;:20;::::0;::::1;::::0;3560:18:40;;3319:31:2::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;3252:105:::0;:::o;4053:456:39:-;4127:7;4162:1;4155:4;:8;4147:33;;;;-1:-1:-1;;;4147:33:39;;31034:2:40;4147:33:39;;;31016:21:40;31073:2;31053:18;;;31046:30;-1:-1:-1;;;31092:18:40;;;31085:42;31144:18;;4147:33:39;30832:336:40;4147:33:39;4191:20;4214:10;4225:4;4214:16;;;;;;;:::i;:::-;;;4191:39;;4241:15;4259:34;:32;:34::i;:::-;4241:52;;4326:1;4312:11;:15;4304:45;;;;-1:-1:-1;;;4304:45:39;;31375:2:40;4304:45:39;;;31357:21:40;31414:2;31394:18;;;31387:30;-1:-1:-1;;;31433:18:40;;;31426:47;31490:18;;4304:45:39;31173:341:40;4304:45:39;4387:11;4360:16;4387:11;4431:21;4446:6;4431:12;:21;:::i;:::-;:31;;4455:7;4431:31;:::i;:::-;4430:44;;;;:::i;:::-;4410:64;4053:456;-1:-1:-1;;;;;;;4053:456:39:o;3679:409:15:-;3958:10;3980:4;3958:27;3954:50;;3994:10;;-1:-1:-1;;;3994:10:15;;;;;;;;;;;3954:50;4014:67;4033:7;4042:5;4049:8;;4059:9;4070:10;;4014:18;:67::i;9707:126:39:-;9818:7;;9807;;-1:-1:-1;;;;;9807:7:39;9770;3390:18:31;;;:9;:18;;;;;;9770:7:39;;9797:28;;;:::i;:::-;9790:35;;9707:126;:::o;1100:139:15:-;1531:13:29;:11;:13::i;:::-;1175:8:15::1;:20:::0;;-1:-1:-1;;;;;;1175:20:15::1;-1:-1:-1::0;;;;;1175:20:15;::::1;::::0;;::::1;::::0;;;1210:22:::1;::::0;3587:51:40;;;1210:22:15::1;::::0;3575:2:40;3560:18;1210:22:15::1;3441:203:40::0;2543:215:29;1531:13;:11;:13::i;:::-;-1:-1:-1;;;;;2627:22:29;::::1;2623:91;;2672:31;::::0;-1:-1:-1;;;2672:31:29;;2700:1:::1;2672:31;::::0;::::1;3587:51:40::0;3560:18;;2672:31:29::1;3441:203:40::0;2623:91:29::1;2723:28;2742:8;2723:18;:28::i;:::-;2543:215:::0;:::o;2771:149:3:-;2853:4;2900:13;;;;;;2876:5;;2853:4;;2882:13;;2900:6;2882:13;:::i;:::-;2876:20;;;;;;;;;;;;;-1:-1:-1;2876:20:3;;:37;;2771:149;-1:-1:-1;;2771:149:3:o;5656:300:31:-;-1:-1:-1;;;;;5739:18:31;;5735:86;;5780:30;;-1:-1:-1;;;5780:30:31;;5807:1;5780:30;;;3587:51:40;3560:18;;5780:30:31;3441:203:40;5735:86:31;-1:-1:-1;;;;;5834:16:31;;5830:86;;5873:32;;-1:-1:-1;;;5873:32:31;;5902:1;5873:32;;;3587:51:40;3560:18;;5873:32:31;3441:203:40;5830:86:31;5925:24;5933:4;5939:2;5943:5;5925:7;:24::i;:::-;5656:300;;;:::o;8247:206::-;-1:-1:-1;;;;;8317:21:31;;8313:89;;8361:30;;-1:-1:-1;;;8361:30:31;;8388:1;8361:30;;;3587:51:40;3560:18;;8361:30:31;3441:203:40;8313:89:31;8411:35;8419:7;8436:1;8440:5;8411:7;:35::i;8989:128::-;9073:37;9082:5;9089:7;9098:5;9105:4;9073:8;:37::i;16809:668:11:-;16951:20;16973:24;17147:22;17159:9;17147:11;:22::i;:::-;17132:37;;17295:12;17276:31;;17377:12;17358:16;:31;17354:117;;;17412:48;;-1:-1:-1;;;17412:48:11;;;;;18380:25:40;;;18421:18;;;18414:34;;;18353:18;;17412:48:11;18206:248:40;17354:117:11;16809:668;;;;;;:::o;2718:196:2:-;2822:11;;;2788:7;2822:11;;;:5;:11;;;;;;;2843:43;;2874:12;;-1:-1:-1;;;2874:12:2;;31693:10:40;31681:23;;2874:12:2;;;31663:42:40;31636:18;;2874:12:2;31519:192:40;11585:1806:11;12062:17;12082:36;:17;:8;;:15;:17::i;:::-;2891:2:14;2780:123;12082:36:11;12062:56;;12251:24;12278:62;12286:9;12297:26;12303:19;:8;;:17;:19::i;:::-;12297:5;:26::i;:::-;12325:14;;;;:7;:14;:::i;:::-;12278:7;:62::i;:::-;12251:89;-1:-1:-1;243:2:14;-1:-1:-1;;12351:955:11;;;12455:23;12481:175;12524:13;;;;;;;;:::i;:::-;12555:14;;;;:7;:14;:::i;:::-;12587:16;12621:21;:8;;:19;:21::i;:::-;12481:25;:175::i;:::-;13203:92;;-1:-1:-1;;;13203:92:11;;12455:201;;-1:-1:-1;;;;;;13203:8:11;:20;;;;:92;;13224:9;;13235:5;;13242:1;;12455:201;;13203:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12378:928;12351:955;-1:-1:-1;;;;;13321:63:11;;13333:5;13321:63;13340:14;;;;:7;:14;:::i;:::-;13321:63;;;17642:10:40;17630:23;;;17612:42;;17685:2;17670:18;;17663:34;;;17585:18;13321:63:11;;;;;;;11888:1503;;11585:1806;;;;;;;:::o;10663:477:31:-;-1:-1:-1;;;;;3952:18:31;;;10762:24;3952:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;10828:37:31;;10824:310;;10904:5;10885:16;:24;10881:130;;;10936:60;;-1:-1:-1;;;10936:60:31;;-1:-1:-1;;;;;32938:32:40;;10936:60:31;;;32920:51:40;32987:18;;;32980:34;;;33030:18;;;33023:34;;;32893:18;;10936:60:31;32718:345:40;10881:130:31;11052:57;11061:5;11068:7;11096:5;11077:16;:24;11103:5;11052:8;:57::i;:::-;10752:388;10663:477;;;:::o;1796:162:29:-;1684:7;1710:6;-1:-1:-1;;;;;1710:6:29;735:10:37;1855:23:29;1851:101;;1901:40;;-1:-1:-1;;;1901:40:29;;735:10:37;1901:40:29;;;3587:51:40;3560:18;;1901:40:29;3441:203:40;2286:134:2;2359:11;;;;;;;:5;:11;;;;;;;;;:19;;;2393:20;;17612:42:40;;;17670:18;;17663:34;;;2393:20:2;;17585:18:40;2393:20:2;;;;;;;2286:134;;:::o;9733:1334:11:-;9865:20;9887;9919:15;10090:324;10122:10;:13;;;10149:16;10155:9;10149:5;:16::i;:::-;10383:21;;;;:10;:21;:::i;:::-;10090:324;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10090:18:11;;-1:-1:-1;;;10090:324:11:i;:::-;10066:348;;-1:-1:-1;10066:348:11;-1:-1:-1;10494:14:11;10066:348;10511:33;;1999:1;10511:33;;;2045:1;10511:33;10494:50;-1:-1:-1;10666:67:11;10681:17;;;;:10;:17;:::i;:::-;10700:7;10709:23;;;;:10;:23;:::i;10666:67::-;10975:12;;10656:77;;-1:-1:-1;;;;;;10975:12:11;:26;10971:89;;11021:12;;;11003:57;;-1:-1:-1;;;11003:57:11;;-1:-1:-1;;;;;11021:12:11;;;;11003:39;;:57;;11043:7;;11052;;11003:57;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;10971:89;9909:1158;;9733:1334;;;;;:::o;2038:391:4:-;-1:-1:-1;;;;;;;;;;;;;;;;;2259:8:4;-1:-1:-1;;;;;2259:14:4;;2291:86;;;;;;;;2307:7;2291:86;;;;;;2316:25;2333:7;2316:16;:25::i;:::-;2291:86;;;;2343:8;2291:86;;;;2353:8;2291:86;;;;2363:13;2291:86;;;;;2403:4;2259:163;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2240:182;2038:391;-1:-1:-1;;;;;2038:391:4:o;2912:187:29:-;2985:16;3004:6;;-1:-1:-1;;;;;3020:17:29;;;-1:-1:-1;;;;;;3020:17:29;;;;;;3052:40;;3004:6;;;;;;;3052:40;;2985:16;3052:40;2975:124;2912:187;:::o;2237:514:9:-;2345:9;2340:354;2364:16;:23;2360:1;:27;2340:354;;;2522:48;2542:16;2559:1;2542:19;;;;;;;;:::i;:::-;;;;;;;:27;;;2522:19;:48::i;:::-;2656:16;2673:1;2656:19;;;;;;;;:::i;:::-;;;;;;;:27;;;2584:15;:40;2600:16;2617:1;2600:19;;;;;;;;:::i;:::-;;;;;;;:23;;;2584:40;;;;;;;;;;;;;;;:69;2625:16;2642:1;2625:19;;;;;;;;:::i;:::-;;;;;;;:27;;;2584:69;;;;;;;;;;;;;;;:99;;;;;;:::i;:::-;-1:-1:-1;2389:3:9;;2340:354;;;;2709:35;2727:16;2709:35;;;;;;:::i;4631:264::-;4801:1;4787:16;;4781:23;4827:28;;;463:1;4827:28;4823:65;;4879:8;4864:24;;-1:-1:-1;;;4864:24:9;;;;;;;;:::i;2037:567:10:-;2198:20;2220:24;2291:44;2302:9;2313:12;2327:7;2291:10;:44::i;:::-;2256:79;;-1:-1:-1;2256:79:10;-1:-1:-1;2571:26:10;2577:5;2256:79;2571:5;:26::i;:::-;2037:567;;;;;;;:::o;3188:766:4:-;3389:31;;:::i;:::-;3554:20;3577:26;3588:4;:14;;;3577:10;:26::i;:::-;3617:15;;;;3554:49;;-1:-1:-1;3617:19:4;3613:53;;3638:28;3650:4;:15;;;3638:11;:28::i;:::-;3755:8;-1:-1:-1;;;;;3755:13:4;;3777:12;3809:92;;;;;;;;3825:7;3809:92;;;;;;3834:25;3851:7;3834:16;:25::i;:::-;3809:92;;;;3861:8;3809:92;;;;3871:8;3809:92;;;;3899:1;3881:4;:15;;;:19;3809:92;;;;;3919:14;3755:192;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;6271:1107:31:-;-1:-1:-1;;;;;6360:18:31;;6356:540;;6512:5;6496:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;6356:540:31;;-1:-1:-1;6356:540:31;;-1:-1:-1;;;;;6570:15:31;;6548:19;6570:15;;;:9;:15;;;;;;6603:19;;;6599:115;;;6649:50;;-1:-1:-1;;;6649:50:31;;-1:-1:-1;;;;;32938:32:40;;6649:50:31;;;32920:51:40;32987:18;;;32980:34;;;33030:18;;;33023:34;;;32893:18;;6649:50:31;32718:345:40;6599:115:31;-1:-1:-1;;;;;6834:15:31;;;;;;:9;:15;;;;;6852:19;;;;6834:37;;6356:540;-1:-1:-1;;;;;6910:16:31;;6906:425;;7073:12;:21;;;;;;;6906:425;;;-1:-1:-1;;;;;7284:13:31;;;;;;:9;:13;;;;;:22;;;;;;6906:425;7361:2;-1:-1:-1;;;;;7346:25:31;7355:4;-1:-1:-1;;;;;7346:25:31;;7365:5;7346:25;;;;6157::40;;6145:2;6130:18;;6011:177;7346:25:31;;;;;;;;6271:1107;;;:::o;9949:432::-;-1:-1:-1;;;;;10061:19:31;;10057:89;;10103:32;;-1:-1:-1;;;10103:32:31;;10132:1;10103:32;;;3587:51:40;3560:18;;10103:32:31;3441:203:40;10057:89:31;-1:-1:-1;;;;;10159:21:31;;10155:90;;10203:31;;-1:-1:-1;;;10203:31:31;;10231:1;10203:31;;;3587:51:40;3560:18;;10203:31:31;3441:203:40;10155:90:31;-1:-1:-1;;;;;10254:18:31;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;10299:76;;;;10349:7;-1:-1:-1;;;;;10333:31:31;10342:5;-1:-1:-1;;;;;10333:31:31;;10358:5;10333:31;;;;6157:25:40;;6145:2;6130:18;;6011:177;10333:31:31;;;;;;;;9949:432;;;;:::o;15318:172:11:-;15389:16;15462:21;15425:33;15462:21;15425:9;:33;:::i;:::-;15424:59;;;;:::i;1573:123:14:-;1633:7;1667:21;188:2;1633:7;1667:4;;:21;:::i;:::-;1659:30;;;:::i;1874:152::-;1936:6;1975:42;243:2;188;1975:4;;:42;:::i;:::-;1968:50;;;:::i;:::-;1961:58;;;1874:152;-1:-1:-1;;;1874:152:14:o;15714:139:11:-;15778:16;15813:33;15825:21;-1:-1:-1;;;;;15813:33:11;;;:::i;2939:462:10:-;3073:24;-1:-1:-1;;;;;3113:19:10;;3109:46;;3148:6;3134:21;;3109:46;3251:21;3257:3;3262:9;3251:5;:21::i;:::-;-1:-1:-1;3385:9:10;;2939:462;-1:-1:-1;;2939:462:10:o;2186:130:14:-;2250:12;2281:28;:4;243:2;2281:4;;:28;:::i;:::-;2274:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2274:35:14;;2186:130;-1:-1:-1;;;;;;2186:130:14:o;640:284:13:-;824:17;877:6;885:7;894:9;905:11;860:57;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;853:64;;640:284;;;;;;:::o;16077:147:11:-;16142:15;16183:33;16195:21;16183:9;:33;:::i;598:506:14:-;791:18;;732:17;;791:22;;;934:163;;1074:7;1083:13;1057:40;;;;;;;;40361:19:40;;;40436:3;40414:16;-1:-1:-1;;;;;;40410:51:40;40405:2;40396:12;;40389:73;40487:2;40478:12;;40206:290;1057:40:14;;;;;;;;;;;;;934:163;;;976:7;985:13;1017:10;1030:11;959:83;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;934:163;927:170;;598:506;;;;;;:::o;4650:191:4:-;4716:17;4762:10;4749:9;:23;4745:62;;4781:26;;-1:-1:-1;;;4781:26:4;;4797:9;4781:26;;;6157:25:40;6130:18;;4781:26:4;6011:177:40;4745:62:4;-1:-1:-1;4824:10:4;4650:191::o;5218:410::-;5371:15;5389:8;-1:-1:-1;;;;;5389:16:4;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5371:36;-1:-1:-1;;;;;;5421:21:4;;5417:54;;5451:20;;-1:-1:-1;;;5451:20:4;;;;;;;;;;;5417:54;5545:76;-1:-1:-1;;;;;5545:32:4;;5578:10;5598:8;5609:11;5545:32;:76::i;7721:208:31:-;-1:-1:-1;;;;;7791:21:31;;7787:91;;7835:32;;-1:-1:-1;;;7835:32:31;;7864:1;7835:32;;;3587:51:40;3560:18;;7835:32:31;3441:203:40;7787:91:31;7887:35;7903:1;7907:7;7916:5;7887:7;:35::i;1702:188:35:-;1829:53;;;-1:-1:-1;;;;;41552:15:40;;;1829:53:35;;;41534:34:40;41604:15;;;41584:18;;;41577:43;41636:18;;;;41629:34;;;1829:53:35;;;;;;;;;;41469:18:40;;;;1829:53:35;;;;;;;;-1:-1:-1;;;;;1829:53:35;-1:-1:-1;;;1829:53:35;;;1802:81;;1822:5;;1829:53;-1:-1:-1;;4504:33:35;;1844:18;;1829:53;4504:27;:33::i;:::-;4478:59;;4551:10;:17;4572:1;4551:22;;:57;;;;;4589:10;4578:30;;;;;;;;;;;;:::i;:::-;4577:31;4551:57;4547:135;;;4631:40;;-1:-1:-1;;;4631:40:35;;-1:-1:-1;;;;;3605:32:40;;4631:40:35;;;3587:51:40;3560:18;;4631:40:35;3441:203:40;2705:151:36;2780:12;2811:38;2833:6;2841:4;2847:1;2780:12;3421;3435:23;3462:6;-1:-1:-1;;;;;3462:11:36;3481:5;3488:4;3462:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3420:73;;;;3510:55;3537:6;3545:7;3554:10;4769:12;4798:7;4793:408;;4821:19;4829:10;4821:7;:19::i;:::-;4793:408;;;5045:17;;:22;:49;;;;-1:-1:-1;;;;;;5071:18:36;;;:23;5045:49;5041:119;;;5121:24;;-1:-1:-1;;;5121:24:36;;-1:-1:-1;;;;;3605:32:40;;5121:24:36;;;3587:51:40;3560:18;;5121:24:36;3441:203:40;5041:119:36;-1:-1:-1;5180:10:36;5173:17;;5743:516;5874:17;;:21;5870:383;;6102:10;6096:17;6158:15;6145:10;6141:2;6137:19;6130:44;5870:383;6225:17;;-1:-1:-1;;;6225:17:36;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:250:40:-;99:1;109:113;123:6;120:1;117:13;109:113;;;199:11;;;193:18;180:11;;;173:39;145:2;138:10;109:113;;;-1:-1:-1;;256:1:40;238:16;;231:27;14:250::o;269:271::-;311:3;349:5;343:12;376:6;371:3;364:19;392:76;461:6;454:4;449:3;445:14;438:4;431:5;427:16;392:76;:::i;:::-;522:2;501:15;-1:-1:-1;;497:29:40;488:39;;;;529:4;484:50;;269:271;-1:-1:-1;;269:271:40:o;545:220::-;694:2;683:9;676:21;657:4;714:45;755:2;744:9;740:18;732:6;714:45;:::i;770:131::-;-1:-1:-1;;;;;845:31:40;;835:42;;825:70;;891:1;888;881:12;906:315;974:6;982;1035:2;1023:9;1014:7;1010:23;1006:32;1003:52;;;1051:1;1048;1041:12;1003:52;1090:9;1077:23;1109:31;1134:5;1109:31;:::i;:::-;1159:5;1211:2;1196:18;;;;1183:32;;-1:-1:-1;;;906:315:40:o;1418:158::-;1480:5;1525:3;1516:6;1511:3;1507:16;1503:26;1500:46;;;1542:1;1539;1532:12;1581:360;1669:6;1722:2;1710:9;1701:7;1697:23;1693:32;1690:52;;;1738:1;1735;1728:12;1690:52;1778:9;1765:23;-1:-1:-1;;;;;1803:6:40;1800:30;1797:50;;;1843:1;1840;1833:12;1797:50;1866:69;1927:7;1918:6;1907:9;1903:22;1866:69;:::i;2100:1336::-;2020:12;;2008:25;;2082:4;2071:16;;;2065:23;2049:14;;;2042:47;2466:4;2514:3;2499:19;;2591:2;2629:3;2624:2;2613:9;2609:18;2602:31;2653:6;2688;2682:13;2719:6;2711;2704:22;2757:3;2746:9;2742:19;2735:26;;2820:3;2810:6;2807:1;2803:14;2792:9;2788:30;2784:40;2770:54;;2843:4;2882;2874:6;2870:17;2905:1;2915:429;2929:6;2926:1;2923:13;2915:429;;;2994:22;;;-1:-1:-1;;2990:37:40;2978:50;;3051:13;;3092:9;;3077:25;;3141:11;;3135:18;3173:15;;;3166:27;;;3216:48;3248:15;;;3135:18;3216:48;:::i;:::-;3206:58;-1:-1:-1;;3322:12:40;;;;3287:15;;;;2951:1;2944:9;2915:429;;;-1:-1:-1;;2020:12:40;;3426:2;3411:18;;2008:25;-1:-1:-1;;;2082:4:40;2071:16;;2065:23;2049:14;;;2042:47;-1:-1:-1;3361:6:40;-1:-1:-1;3376:54:40;1946:149;3649:154;3708:5;3753:2;3744:6;3739:3;3735:16;3731:25;3728:45;;;3769:1;3766;3759:12;3808:347;3859:8;3869:6;3923:3;3916:4;3908:6;3904:17;3900:27;3890:55;;3941:1;3938;3931:12;3890:55;-1:-1:-1;3964:20:40;;-1:-1:-1;;;;;3996:30:40;;3993:50;;;4039:1;4036;4029:12;3993:50;4076:4;4068:6;4064:17;4052:29;;4128:3;4121:4;4112:6;4104;4100:19;4096:30;4093:39;4090:59;;;4145:1;4142;4135:12;4090:59;3808:347;;;;;:::o;4160:1048::-;4303:6;4311;4319;4327;4335;4343;4351;4404:3;4392:9;4383:7;4379:23;4375:33;4372:53;;;4421:1;4418;4411:12;4372:53;4444;4489:7;4478:9;4444:53;:::i;:::-;4434:63;;4544:2;4533:9;4529:18;4516:32;4506:42;;4599:3;4588:9;4584:19;4571:33;-1:-1:-1;;;;;4664:2:40;4656:6;4653:14;4650:34;;;4680:1;4677;4670:12;4650:34;4719:58;4769:7;4760:6;4749:9;4745:22;4719:58;:::i;:::-;4796:8;;-1:-1:-1;4693:84:40;-1:-1:-1;4881:3:40;4866:19;;4853:33;;-1:-1:-1;4895:31:40;4853:33;4895:31;:::i;:::-;4945:5;;-1:-1:-1;5003:3:40;4988:19;;4975:33;;5020:16;;;5017:36;;;5049:1;5046;5039:12;5017:36;;5088:60;5140:7;5129:8;5118:9;5114:24;5088:60;:::i;:::-;4160:1048;;;;-1:-1:-1;4160:1048:40;;-1:-1:-1;4160:1048:40;;;;5062:86;;-1:-1:-1;;;4160:1048:40:o;6193:456::-;6270:6;6278;6286;6339:2;6327:9;6318:7;6314:23;6310:32;6307:52;;;6355:1;6352;6345:12;6307:52;6394:9;6381:23;6413:31;6438:5;6413:31;:::i;:::-;6463:5;-1:-1:-1;6520:2:40;6505:18;;6492:32;6533:33;6492:32;6533:33;:::i;:::-;6193:456;;6585:7;;-1:-1:-1;;;6639:2:40;6624:18;;;;6611:32;;6193:456::o;6654:180::-;6713:6;6766:2;6754:9;6745:7;6741:23;6737:32;6734:52;;;6782:1;6779;6772:12;6734:52;-1:-1:-1;6805:23:40;;6654:180;-1:-1:-1;6654:180:40:o;7028:163::-;7095:20;;7155:10;7144:22;;7134:33;;7124:61;;7181:1;7178;7171:12;7124:61;7028:163;;;:::o;7196:252::-;7263:6;7271;7324:2;7312:9;7303:7;7299:23;7295:32;7292:52;;;7340:1;7337;7330:12;7292:52;7363:28;7381:9;7363:28;:::i;7453:118::-;7539:5;7532:13;7525:21;7518:5;7515:32;7505:60;;7561:1;7558;7551:12;7576:489;7670:6;7678;7731:2;7719:9;7710:7;7706:23;7702:32;7699:52;;;7747:1;7744;7737:12;7699:52;7787:9;7774:23;-1:-1:-1;;;;;7812:6:40;7809:30;7806:50;;;7852:1;7849;7842:12;7806:50;7875:69;7936:7;7927:6;7916:9;7912:22;7875:69;:::i;:::-;7865:79;;;7994:2;7983:9;7979:18;7966:32;8007:28;8029:5;8007:28;:::i;:::-;8054:5;8044:15;;;7576:489;;;;;:::o;8070:257::-;2020:12;;2008:25;;2082:4;2071:16;;;2065:23;2049:14;;;2042:47;8264:2;8249:18;;8276:45;1946:149;8332:247;8391:6;8444:2;8432:9;8423:7;8419:23;8415:32;8412:52;;;8460:1;8457;8450:12;8412:52;8499:9;8486:23;8518:31;8543:5;8518:31;:::i;8584:159::-;8651:20;;8711:6;8700:18;;8690:29;;8680:57;;8733:1;8730;8723:12;8748:256;8814:6;8822;8875:2;8863:9;8854:7;8850:23;8846:32;8843:52;;;8891:1;8888;8881:12;8843:52;8914:28;8932:9;8914:28;:::i;:::-;8904:38;;8961:37;8994:2;8983:9;8979:18;8961:37;:::i;:::-;8951:47;;8748:256;;;;;:::o;9469:495::-;9649:3;9634:19;;9638:9;9730:6;9607:4;9764:194;9778:4;9775:1;9772:11;9764:194;;;9837:13;;9825:26;;9874:4;9898:12;;;;9933:15;;;;9798:1;9791:9;9764:194;;;9768:3;;;9469:495;;;;:::o;10174:670::-;10288:6;10296;10304;10312;10365:3;10353:9;10344:7;10340:23;10336:33;10333:53;;;10382:1;10379;10372:12;10333:53;10405;10450:7;10439:9;10405:53;:::i;:::-;10395:63;;10509:2;10498:9;10494:18;10481:32;-1:-1:-1;;;;;10528:6:40;10525:30;10522:50;;;10568:1;10565;10558:12;10522:50;10607:58;10657:7;10648:6;10637:9;10633:22;10607:58;:::i;:::-;10684:8;;-1:-1:-1;10581:84:40;-1:-1:-1;;10769:3:40;10754:19;;10741:33;10783:31;10741:33;10783:31;:::i;:::-;10174:670;;;;-1:-1:-1;10174:670:40;;-1:-1:-1;;10174:670:40:o;10849:395::-;10940:8;10950:6;11004:3;10997:4;10989:6;10985:17;10981:27;10971:55;;11022:1;11019;11012:12;10971:55;-1:-1:-1;11045:20:40;;-1:-1:-1;;;;;11077:30:40;;11074:50;;;11120:1;11117;11110:12;11074:50;11157:4;11149:6;11145:17;11133:29;;11217:3;11210:4;11200:6;11197:1;11193:14;11185:6;11181:27;11177:38;11174:47;11171:67;;;11234:1;11231;11224:12;11249:503;11373:6;11381;11434:2;11422:9;11413:7;11409:23;11405:32;11402:52;;;11450:1;11447;11440:12;11402:52;11490:9;11477:23;-1:-1:-1;;;;;11515:6:40;11512:30;11509:50;;;11555:1;11552;11545:12;11509:50;11594:98;11684:7;11675:6;11664:9;11660:22;11594:98;:::i;:::-;11711:8;;11568:124;;-1:-1:-1;11249:503:40;-1:-1:-1;;;;11249:503:40:o;11757:184::-;11815:6;11868:2;11856:9;11847:7;11843:23;11839:32;11836:52;;;11884:1;11881;11874:12;11836:52;11907:28;11925:9;11907:28;:::i;12128:553::-;12214:6;12222;12230;12238;12291:2;12279:9;12270:7;12266:23;12262:32;12259:52;;;12307:1;12304;12297:12;12259:52;12330:28;12348:9;12330:28;:::i;:::-;12320:38;;12377:37;12410:2;12399:9;12395:18;12377:37;:::i;:::-;12367:47;;12465:2;12454:9;12450:18;12437:32;-1:-1:-1;;;;;12484:6:40;12481:30;12478:50;;;12524:1;12521;12514:12;12478:50;12563:58;12613:7;12604:6;12593:9;12589:22;12563:58;:::i;:::-;12128:553;;;;-1:-1:-1;12640:8:40;-1:-1:-1;;;;12128:553:40:o;13369:657::-;13507:6;13515;13523;13567:9;13558:7;13554:23;13597:3;13593:2;13589:12;13586:32;;;13614:1;13611;13604:12;13586:32;13654:9;13641:23;-1:-1:-1;;;;;13679:6:40;13676:30;13673:50;;;13719:1;13716;13709:12;13673:50;13742:69;13803:7;13794:6;13783:9;13779:22;13742:69;:::i;:::-;13732:79;-1:-1:-1;;13845:2:40;-1:-1:-1;;13827:16:40;;13823:25;13820:45;;;13861:1;13858;13851:12;13820:45;;13899:2;13888:9;13884:18;13874:28;;13952:2;13941:9;13937:18;13924:32;13965:31;13990:5;13965:31;:::i;:::-;14015:5;14005:15;;;13369:657;;;;;:::o;14031:613::-;14275:4;14317:3;14306:9;14302:19;14294:27;;14354:6;14348:13;14337:9;14330:32;-1:-1:-1;;;;;14422:4:40;14414:6;14410:17;14404:24;14400:49;14393:4;14382:9;14378:20;14371:79;14497:4;14489:6;14485:17;14479:24;14512:62;14568:4;14557:9;14553:20;14539:12;2020;;2008:25;;2082:4;2071:16;;;2065:23;2049:14;;2042:47;1946:149;14512:62;-1:-1:-1;2020:12:40;;14633:3;14618:19;;2008:25;2082:4;2071:16;;2065:23;2049:14;;;2042:47;14583:55;1946:149;14649:248;14717:6;14725;14778:2;14766:9;14757:7;14753:23;14749:32;14746:52;;;14794:1;14791;14784:12;14746:52;-1:-1:-1;;14817:23:40;;;14887:2;14872:18;;;14859:32;;-1:-1:-1;14649:248:40:o;14902:388::-;14970:6;14978;15031:2;15019:9;15010:7;15006:23;15002:32;14999:52;;;15047:1;15044;15037:12;14999:52;15086:9;15073:23;15105:31;15130:5;15105:31;:::i;:::-;15155:5;-1:-1:-1;15212:2:40;15197:18;;15184:32;15225:33;15184:32;15225:33;:::i;15295:236::-;15380:6;15433:2;15421:9;15412:7;15408:23;15404:32;15401:52;;;15449:1;15446;15439:12;15401:52;15472:53;15517:7;15506:9;15472:53;:::i;15536:380::-;15615:1;15611:12;;;;15658;;;15679:61;;15733:4;15725:6;15721:17;15711:27;;15679:61;15786:2;15778:6;15775:14;15755:18;15752:38;15749:161;;15832:10;15827:3;15823:20;15820:1;15813:31;15867:4;15864:1;15857:15;15895:4;15892:1;15885:15;15921:398;16123:2;16105:21;;;16162:2;16142:18;;;16135:30;16201:34;16196:2;16181:18;;16174:62;-1:-1:-1;;;16267:2:40;16252:18;;16245:32;16309:3;16294:19;;15921:398::o;16324:127::-;16385:10;16380:3;16376:20;16373:1;16366:31;16416:4;16413:1;16406:15;16440:4;16437:1;16430:15;16456:168;16529:9;;;16560;;16577:15;;;16571:22;;16557:37;16547:71;;16598:18;;:::i;16629:217::-;16669:1;16695;16685:132;;16739:10;16734:3;16730:20;16727:1;16720:31;16774:4;16771:1;16764:15;16802:4;16799:1;16792:15;16685:132;-1:-1:-1;16831:9:40;;16629:217::o;16851:128::-;16918:9;;;16939:11;;;16936:37;;;16953:18;;:::i;17308:127::-;17369:10;17364:3;17360:20;17357:1;17350:31;17400:4;17397:1;17390:15;17424:4;17421:1;17414:15;18065:136;18104:3;18132:5;18122:39;;18141:18;;:::i;:::-;-1:-1:-1;;;18177:18:40;;18065:136::o;18459:127::-;18520:10;18515:3;18511:20;18508:1;18501:31;18551:4;18548:1;18541:15;18575:4;18572:1;18565:15;19300:125;19365:9;;;19386:10;;;19383:36;;;19399:18;;:::i;21843:135::-;21882:3;21903:17;;;21900:43;;21923:18;;:::i;:::-;-1:-1:-1;21970:1:40;21959:13;;21843:135::o;21983:253::-;22055:2;22049:9;22097:4;22085:17;;-1:-1:-1;;;;;22117:34:40;;22153:22;;;22114:62;22111:88;;;22179:18;;:::i;:::-;22215:2;22208:22;21983:253;:::o;22241:251::-;22313:2;22307:9;;;22343:15;;-1:-1:-1;;;;;22373:34:40;;22409:22;;;22370:62;22367:88;;;22435:18;;:::i;22497:275::-;22568:2;22562:9;22633:2;22614:13;;-1:-1:-1;;22610:27:40;22598:40;;-1:-1:-1;;;;;22653:34:40;;22689:22;;;22650:62;22647:88;;;22715:18;;:::i;:::-;22751:2;22744:22;22497:275;;-1:-1:-1;22497:275:40:o;22777:186::-;22825:4;-1:-1:-1;;;;;22850:6:40;22847:30;22844:56;;;22880:18;;:::i;:::-;-1:-1:-1;22946:2:40;22925:15;-1:-1:-1;;22921:29:40;22952:4;22917:40;;22777:186::o;22968:2115::-;23158:9;-1:-1:-1;;;;;23233:2:40;23225:6;23222:14;23219:40;;;23239:18;;:::i;:::-;23285:6;23282:1;23278:14;23311:4;23335:28;23359:2;23355;23351:11;23335:28;:::i;:::-;23397:19;;;23467:14;;;;23432:12;;;;23504:14;23493:26;;23490:46;;;23532:1;23529;23522:12;23490:46;23556:5;23570:1480;23586:6;23581:3;23578:15;23570:1480;;;23672:3;23659:17;23708:2;23695:11;23692:19;23689:109;;;23752:1;23781:2;23777;23770:14;23689:109;23821:23;;23889:4;23868:14;23864:23;;;23860:34;23857:124;;;23935:1;23964:2;23960;23953:14;23857:124;24009:22;;:::i;:::-;24060:21;24078:2;24060:21;:::i;:::-;24051:7;24044:38;24120:30;24146:2;24142;24138:11;24120:30;:::i;:::-;24115:2;24106:7;24102:16;24095:56;24174:2;24224;24220;24216:11;24203:25;24255:2;24247:6;24244:14;24241:104;;;24299:1;24328:2;24324;24317:14;24241:104;24368:15;;;;;24425:14;24418:4;24410:13;;24406:34;24396:135;;24483:1;24513:3;24508;24501:16;24396:135;24568:2;24555:16;24597:49;24613:32;24641:3;24613:32;:::i;:::-;24597:49;:::i;:::-;24673:3;24666:5;24659:18;24719:14;24714:2;24708:3;24704:2;24700:12;24696:21;24693:41;24690:134;;;24776:1;24806:3;24801;24794:16;24690:134;24879:3;24874:2;24870;24866:11;24861:2;24854:5;24850:14;24837:46;24929:1;24907:15;;;24903:24;;24896:35;;;;24951:16;;;24944:31;24988:20;;-1:-1:-1;25028:12:40;;;;23603;;23570:1480;;;-1:-1:-1;25072:5:40;22968:2115;-1:-1:-1;;;;;;;22968:2115:40:o;25088:331::-;25193:9;25204;25246:8;25234:10;25231:24;25228:44;;;25268:1;25265;25258:12;25228:44;25297:6;25287:8;25284:20;25281:40;;;25317:1;25314;25307:12;25281:40;-1:-1:-1;;25343:23:40;;;25388:25;;;;;-1:-1:-1;25088:331:40:o;25424:476::-;25615:3;25653:6;25647:13;25669:66;25728:6;25723:3;25716:4;25708:6;25704:17;25669:66;:::i;:::-;25757:16;;25810:6;25802;25757:16;25782:35;25874:1;25836:18;;25863:13;;;-1:-1:-1;25836:18:40;;25424:476;-1:-1:-1;;;25424:476:40:o;25905:266::-;25993:6;25988:3;25981:19;26045:6;26038:5;26031:4;26026:3;26022:14;26009:43;-1:-1:-1;26097:1:40;26072:16;;;26090:4;26068:27;;;26061:38;;;;26153:2;26132:15;;;-1:-1:-1;;26128:29:40;26119:39;;;26115:50;;25905:266::o;26176:244::-;26333:2;26322:9;26315:21;26296:4;26353:61;26410:2;26399:9;26395:18;26387:6;26379;26353:61;:::i;26425:331::-;26524:4;26582:11;26569:25;26676:3;26672:8;26661;26645:14;26641:29;26637:44;26617:18;26613:69;26603:97;;26696:1;26693;26686:12;26603:97;26717:33;;;;;26425:331;-1:-1:-1;;26425:331:40:o;26761:521::-;26838:4;26844:6;26904:11;26891:25;26998:2;26994:7;26983:8;26967:14;26963:29;26959:43;26939:18;26935:68;26925:96;;27017:1;27014;27007:12;26925:96;27044:33;;27096:20;;;-1:-1:-1;;;;;;27128:30:40;;27125:50;;;27171:1;27168;27161:12;27125:50;27204:4;27192:17;;-1:-1:-1;27235:14:40;27231:27;;;27221:38;;27218:58;;;27272:1;27269;27262:12;27287:129;-1:-1:-1;;;;;27365:5:40;27361:30;27354:5;27351:41;27341:69;;27406:1;27403;27396:12;27421:992;27799:10;27772:25;27790:6;27772:25;:::i;:::-;27768:42;27757:9;27750:61;27874:4;27866:6;27862:17;27849:31;27842:4;27831:9;27827:20;27820:61;27731:4;27928;27920:6;27916:17;27903:31;27943:30;27967:5;27943:30;:::i;:::-;-1:-1:-1;;;;;28015:5:40;28011:30;28004:4;27993:9;27989:20;27982:60;;28078:6;28073:2;28062:9;28058:18;28051:34;28122:3;28116;28105:9;28101:19;28094:32;28149:62;28206:3;28195:9;28191:19;28183:6;28175;28149:62;:::i;:::-;-1:-1:-1;;;;;28248:32:40;;28268:3;28227:19;;28220:61;28318:22;;;28312:3;28297:19;;28290:51;28358:49;28322:6;28392;28384;28358:49;:::i;:::-;28350:57;27421:992;-1:-1:-1;;;;;;;;;;27421:992:40:o;28418:647::-;28497:6;28550:2;28538:9;28529:7;28525:23;28521:32;28518:52;;;28566:1;28563;28556:12;28518:52;28599:9;28593:16;-1:-1:-1;;;;;28624:6:40;28621:30;28618:50;;;28664:1;28661;28654:12;28618:50;28687:22;;28740:4;28732:13;;28728:27;-1:-1:-1;28718:55:40;;28769:1;28766;28759:12;28718:55;28798:2;28792:9;28823:48;28839:31;28867:2;28839:31;:::i;28823:48::-;28894:2;28887:5;28880:17;28934:7;28929:2;28924;28920;28916:11;28912:20;28909:33;28906:53;;;28955:1;28952;28945:12;28906:53;28968:67;29032:2;29027;29020:5;29016:14;29011:2;29007;29003:11;28968:67;:::i;29478:179::-;29556:13;;29609:22;29598:34;;29588:45;;29578:73;;29647:1;29644;29637:12;29662:473;29765:6;29773;29781;29789;29797;29850:3;29838:9;29829:7;29825:23;29821:33;29818:53;;;29867:1;29864;29857:12;29818:53;29890:39;29919:9;29890:39;:::i;:::-;29880:49;;29969:2;29958:9;29954:18;29948:25;29938:35;;30013:2;30002:9;29998:18;29992:25;29982:35;;30057:2;30046:9;30042:18;30036:25;30026:35;;30080:49;30124:3;30113:9;30109:19;30080:49;:::i;:::-;30070:59;;29662:473;;;;;;;;:::o;30140:348::-;30229:6;30282:2;30270:9;30261:7;30257:23;30253:32;30250:52;;;30298:1;30295;30288:12;30250:52;30324:22;;:::i;:::-;30382:9;30369:23;30362:5;30355:38;30453:2;30442:9;30438:18;30425:32;30420:2;30413:5;30409:14;30402:56;30477:5;30467:15;;;30140:348;;;;:::o;31716:245::-;31774:6;31827:2;31815:9;31806:7;31802:23;31798:32;31795:52;;;31843:1;31840;31833:12;31795:52;31882:9;31869:23;31901:30;31925:5;31901:30;:::i;31966:479::-;32233:1;32229;32224:3;32220:11;32216:19;32208:6;32204:32;32193:9;32186:51;32273:6;32268:2;32257:9;32253:18;32246:34;32328:6;32320;32316:19;32311:2;32300:9;32296:18;32289:47;32372:3;32367:2;32356:9;32352:18;32345:31;32167:4;32393:46;32434:3;32423:9;32419:19;32411:6;32393:46;:::i;33068:379::-;33261:2;33250:9;33243:21;33224:4;33287:45;33328:2;33317:9;33313:18;33305:6;33287:45;:::i;:::-;33380:9;33372:6;33368:22;33363:2;33352:9;33348:18;33341:50;33408:33;33434:6;33426;33408:33;:::i;33452:245::-;33519:6;33572:2;33560:9;33551:7;33547:23;33543:32;33540:52;;;33588:1;33585;33578:12;33540:52;33620:9;33614:16;33639:28;33661:5;33639:28;:::i;33702:891::-;33925:2;33914:9;33907:21;33983:10;33974:6;33968:13;33964:30;33959:2;33948:9;33944:18;33937:58;34049:4;34041:6;34037:17;34031:24;34026:2;34015:9;34011:18;34004:52;33888:4;34103:2;34095:6;34091:15;34085:22;34144:4;34138:3;34127:9;34123:19;34116:33;34172:52;34219:3;34208:9;34204:19;34190:12;34172:52;:::i;:::-;34158:66;;34273:2;34265:6;34261:15;34255:22;34347:2;34343:7;34331:9;34323:6;34319:22;34315:36;34308:4;34297:9;34293:20;34286:66;34375:41;34409:6;34393:14;34375:41;:::i;:::-;34485:3;34473:16;;;;34467:23;34460:31;34453:39;34447:3;34432:19;;34425:68;-1:-1:-1;;;;;;;;34554:32:40;;;;34547:4;34532:20;;;34525:62;34361:55;33702:891::o;34598:284::-;34668:5;34716:4;34704:9;34699:3;34695:19;34691:30;34688:50;;;34734:1;34731;34724:12;34688:50;34756:22;;:::i;:::-;34747:31;;34807:9;34801:16;34794:5;34787:31;34871:2;34860:9;34856:18;34850:25;34845:2;34838:5;34834:14;34827:49;34598:284;;;;:::o;34887:259::-;34987:6;35040:2;35028:9;35019:7;35015:23;35011:32;35008:52;;;35056:1;35053;35046:12;35008:52;35079:61;35132:7;35121:9;35079:61;:::i;35276:542::-;35377:2;35372:3;35369:11;35366:446;;;35413:1;35437:5;35434:1;35427:16;35481:4;35478:1;35468:18;35551:2;35539:10;35535:19;35532:1;35528:27;35522:4;35518:38;35587:4;35575:10;35572:20;35569:47;;;-1:-1:-1;35610:4:40;35569:47;35665:2;35660:3;35656:12;35653:1;35649:20;35643:4;35639:31;35629:41;;35720:82;35738:2;35731:5;35728:13;35720:82;;;35783:17;;;35764:1;35753:13;35720:82;;35994:1341;36118:3;36112:10;-1:-1:-1;;;;;36137:6:40;36134:30;36131:56;;;36167:18;;:::i;:::-;36196:96;36285:6;36245:38;36277:4;36271:11;36245:38;:::i;:::-;36239:4;36196:96;:::i;:::-;36347:4;;36404:2;36393:14;;36421:1;36416:662;;;;37122:1;37139:6;37136:89;;;-1:-1:-1;37191:19:40;;;37185:26;37136:89;-1:-1:-1;;35951:1:40;35947:11;;;35943:24;35939:29;35929:40;35975:1;35971:11;;;35926:57;37238:81;;36386:943;;36416:662;35223:1;35216:14;;;35260:4;35247:18;;-1:-1:-1;;36452:20:40;;;36569:236;36583:7;36580:1;36577:14;36569:236;;;36672:19;;;36666:26;36651:42;;36764:27;;;;36732:1;36720:14;;;;36599:19;;36569:236;;;36573:3;36833:6;36824:7;36821:19;36818:201;;;36894:19;;;36888:26;-1:-1:-1;;36977:1:40;36973:14;;;36989:3;36969:24;36965:37;36961:42;36946:58;36931:74;;36818:201;-1:-1:-1;;;;;37065:1:40;37049:14;;;37045:22;37032:36;;-1:-1:-1;35994:1341:40:o;37340:1162::-;37554:4;37583:2;37623;37612:9;37608:18;37653:2;37642:9;37635:21;37676:6;37711;37705:13;37742:6;37734;37727:22;37768:2;37758:12;;37801:2;37790:9;37786:18;37779:25;;37863:2;37853:6;37850:1;37846:14;37835:9;37831:30;37827:39;37901:2;37893:6;37889:15;37922:1;37932:541;37946:6;37943:1;37940:13;37932:541;;;38011:22;;;-1:-1:-1;;38007:36:40;37995:49;;38067:13;;38139:9;;38150:10;38135:26;38120:42;;38209:11;;;38203:18;38223:6;38199:31;38182:15;;;38175:56;38270:11;;38264:18;38103:4;38302:15;;;38295:27;;;38345:48;38377:15;;;38264:18;38345:48;:::i;:::-;38451:12;;;;38335:58;-1:-1:-1;;;38416:15:40;;;;37968:1;37961:9;37932:541;;;-1:-1:-1;38490:6:40;;37340:1162;-1:-1:-1;;;;;;;;37340:1162:40:o;38507:525::-;38611:6;38664:3;38652:9;38643:7;38639:23;38635:33;38632:53;;;38681:1;38678;38671:12;38632:53;38707:22;;:::i;:::-;38758:9;38752:16;38745:5;38738:31;38814:2;38803:9;38799:18;38793:25;38827:32;38851:7;38827:32;:::i;:::-;38886:2;38875:14;;38868:31;38931:70;38993:7;38988:2;38973:18;;38931:70;:::i;:::-;38926:2;38915:14;;38908:94;38919:5;38507:525;-1:-1:-1;;;38507:525:40:o;39037:255::-;39157:19;;39196:2;39188:11;;39185:101;;;-1:-1:-1;;39257:2:40;39253:12;;;39250:1;39246:20;39242:33;39231:45;39037:255;;;;:::o;39297:331::-;-1:-1:-1;;;;;;39417:19:40;;39501:11;;;;39532:1;39524:10;;39521:101;;;39609:2;39603;39596:3;39593:1;39589:11;39586:1;39582:19;39578:28;39574:2;39570:37;39566:46;39557:55;;39521:101;;;39297:331;;;;:::o;39633:568::-;-1:-1:-1;;;;;39898:3:40;39894:28;39885:6;39880:3;39876:16;39872:51;39867:3;39860:64;39984:10;39979:3;39975:20;39966:6;39961:3;39957:16;39953:43;39949:1;39944:3;39940:11;39933:64;40027:6;40022:2;40017:3;40013:12;40006:28;39842:3;40063:6;40057:13;40079:75;40147:6;40142:2;40137:3;40133:12;40126:4;40118:6;40114:17;40079:75;:::i;:::-;40174:16;;;;40192:2;40170:25;;39633:568;-1:-1:-1;;;;;39633:568:40:o;40501:532::-;40742:6;40737:3;40730:19;-1:-1:-1;;;;;40805:3:40;40801:28;40792:6;40787:3;40783:16;40779:51;40774:2;40769:3;40765:12;40758:73;40861:6;40856:2;40851:3;40847:12;40840:28;40712:3;40897:6;40891:13;40913:73;40979:6;40974:2;40969:3;40965:12;40960:2;40952:6;40948:15;40913:73;:::i;:::-;41006:16;;;;41024:2;41002:25;;40501:532;-1:-1:-1;;;;;40501:532:40:o;41038:251::-;41108:6;41161:2;41149:9;41140:7;41136:23;41132:32;41129:52;;;41177:1;41174;41167:12;41129:52;41209:9;41203:16;41228:31;41253:5;41228:31;:::i;41674:287::-;41803:3;41841:6;41835:13;41857:66;41916:6;41911:3;41904:4;41896:6;41892:17;41857:66;:::i
Swarm Source
ipfs://cc1e72e3ccd4b6c2f54520d82e4a7920e210d586462c09b48f890f1374c5ea16
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $2,346.03 | 0.00000000000000001 | <$0.000001 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.