Overview
ETH Balance
0.000000000622020578 ETH
Eth Value
Less Than $0.01 (@ $3,304.45/ETH)More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 202 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Increment Radar ... | 16123288 | 748 days ago | IN | 0 ETH | 0.00186497 | ||||
Increment Radar ... | 16123286 | 748 days ago | IN | 0 ETH | 0.00177358 | ||||
Increment Radar ... | 16123284 | 748 days ago | IN | 0 ETH | 0.00198617 | ||||
Increment Radar ... | 16123282 | 748 days ago | IN | 0 ETH | 0.00221559 | ||||
Increment Radar ... | 16123279 | 748 days ago | IN | 0 ETH | 0.00207352 | ||||
Increment Radar ... | 16123276 | 748 days ago | IN | 0 ETH | 0.00219142 | ||||
Increment Radar ... | 16123274 | 748 days ago | IN | 0 ETH | 0.00208319 | ||||
Increment Radar ... | 16123272 | 748 days ago | IN | 0 ETH | 0.00187604 | ||||
Increment Radar ... | 16123270 | 748 days ago | IN | 0 ETH | 0.00200416 | ||||
Increment Radar ... | 16123268 | 748 days ago | IN | 0 ETH | 0.00189538 | ||||
Increment Radar ... | 16123266 | 748 days ago | IN | 0 ETH | 0.00177364 | ||||
Increment Radar ... | 16123264 | 748 days ago | IN | 0 ETH | 0.00185188 | ||||
Increment Radar ... | 16123262 | 748 days ago | IN | 0 ETH | 0.00200308 | ||||
Increment Radar ... | 16123260 | 748 days ago | IN | 0 ETH | 0.00186731 | ||||
Increment Radar ... | 16123258 | 748 days ago | IN | 0 ETH | 0.00190673 | ||||
Increment Radar ... | 16123256 | 748 days ago | IN | 0 ETH | 0.00173118 | ||||
Increment Radar ... | 16123254 | 748 days ago | IN | 0 ETH | 0.00183984 | ||||
Increment Radar ... | 16123251 | 748 days ago | IN | 0 ETH | 0.00196893 | ||||
Increment Radar ... | 16123249 | 748 days ago | IN | 0 ETH | 0.00182466 | ||||
Increment Radar ... | 16123247 | 748 days ago | IN | 0 ETH | 0.00200291 | ||||
Increment Radar ... | 16123245 | 748 days ago | IN | 0 ETH | 0.00191791 | ||||
Increment Radar ... | 16123242 | 748 days ago | IN | 0 ETH | 0.00209639 | ||||
Increment Radar ... | 16123240 | 748 days ago | IN | 0 ETH | 0.00196323 | ||||
Increment Radar ... | 16123238 | 748 days ago | IN | 0 ETH | 0.00204759 | ||||
Increment Radar ... | 16123236 | 748 days ago | IN | 0 ETH | 0.00182227 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
17381141 | 571 days ago | 0.00637481 ETH | ||||
17380907 | 571 days ago | 6.16842463 ETH | ||||
17368889 | 573 days ago | 0.00684546 ETH | ||||
17366262 | 574 days ago | 0.01152778 ETH | ||||
17365524 | 574 days ago | 0.01557513 ETH | ||||
17363074 | 574 days ago | 0.00786316 ETH | ||||
17360454 | 574 days ago | 0.00977306 ETH | ||||
17356433 | 575 days ago | 0.00721277 ETH | ||||
17355748 | 575 days ago | 0.00852904 ETH | ||||
17355513 | 575 days ago | 0.00798132 ETH | ||||
17352970 | 575 days ago | 0.00692375 ETH | ||||
17351903 | 576 days ago | 0.00686077 ETH | ||||
17350407 | 576 days ago | 0.00658796 ETH | ||||
17350383 | 576 days ago | 0.00658796 ETH | ||||
17350129 | 576 days ago | 0.00724699 ETH | ||||
17350122 | 576 days ago | 0.00792399 ETH | ||||
17350051 | 576 days ago | 0.00719368 ETH | ||||
17349227 | 576 days ago | 0.00796394 ETH | ||||
17348769 | 576 days ago | 0.00722756 ETH | ||||
17343940 | 577 days ago | 0.01174587 ETH | ||||
17342187 | 577 days ago | 0.01037598 ETH | ||||
17341419 | 577 days ago | 0.00761464 ETH | ||||
17339130 | 577 days ago | 0.00868068 ETH | ||||
17337417 | 578 days ago | 0.02487819 ETH | ||||
17320260 | 580 days ago | 0.01364382 ETH |
Loading...
Loading
Contract Name:
UltraLightNodeV2Radar
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "./interfaces/ILayerZeroValidationLibrary.sol"; import "./interfaces/ILayerZeroReceiver.sol"; import "./interfaces/ILayerZeroTreasury.sol"; import "./interfaces/ILayerZeroEndpoint.sol"; // v2 import "./interfaces/ILayerZeroMessagingLibraryV2.sol"; import "./interfaces/ILayerZeroOracleV2.sol"; import "./interfaces/ILayerZeroUltraLightNodeV2.sol"; import "./interfaces/ILayerZeroRelayerV2.sol"; import "./NonceContractRadar.sol"; contract UltraLightNodeV2Radar is ILayerZeroMessagingLibraryV2, ILayerZeroUltraLightNodeV2, ReentrancyGuard, Ownable { using SafeERC20 for IERC20; using SafeMath for uint; // Application config uint public constant CONFIG_TYPE_INBOUND_PROOF_LIBRARY_VERSION = 1; uint public constant CONFIG_TYPE_INBOUND_BLOCK_CONFIRMATIONS = 2; uint public constant CONFIG_TYPE_RELAYER = 3; uint public constant CONFIG_TYPE_OUTBOUND_PROOF_TYPE = 4; uint public constant CONFIG_TYPE_OUTBOUND_BLOCK_CONFIRMATIONS = 5; uint public constant CONFIG_TYPE_ORACLE = 6; // Token and Contracts IERC20 public layerZeroToken; ILayerZeroTreasury public treasuryContract; mapping(address => uint) public nativeFees; uint public treasuryZROFees; // User Application mapping(address => mapping(uint16 => ApplicationConfiguration)) public appConfig; // app address => chainId => config mapping(uint16 => ApplicationConfiguration) public defaultAppConfig; // default UA settings if no version specified mapping(uint16 => mapping(uint16 => bytes)) public defaultAdapterParams; // Validation mapping(uint16 => mapping(uint16 => address)) public inboundProofLibrary; // chainId => library Id => inboundProofLibrary contract mapping(uint16 => uint16) public maxInboundProofLibrary; // chainId => inboundProofLibrary mapping(uint16 => mapping(uint16 => bool)) public supportedOutboundProof; // chainId => outboundProofType => enabled mapping(uint16 => uint) public chainAddressSizeMap; mapping(address => mapping(uint16 => mapping(bytes32 => mapping(bytes32 => uint)))) public hashLookup; //[oracle][srcChainId][blockhash][datahash] -> confirmation mapping(uint16 => bytes32) public ulnLookup; // remote ulns ILayerZeroEndpoint public immutable endpoint; uint16 public immutable localChainId; NonceContractRadar public nonceContract; constructor(address _endpoint, uint16 _localChainId, address _dappRadar) { require(_endpoint != address(0x0), "LayerZero: endpoint cannot be zero address"); ILayerZeroEndpoint lzEndpoint = ILayerZeroEndpoint(_endpoint); localChainId = _localChainId; endpoint = lzEndpoint; // dappRadar dappRadar = _dappRadar; } // only the endpoint can call SEND() and setConfig() modifier onlyEndpoint() { require(address(endpoint) == msg.sender, "LayerZero: only endpoint"); _; } function setNonceContractRadar(address _nonceContractRadar) public onlyOwner { require(address(nonceContract) == address(0x0), "LayerZero: nonceContractRadar can only be set once"); nonceContract = NonceContractRadar(_nonceContractRadar); } // Manual for DappRadar handling. This contract is dappRadar-only (send/receive) // 1. Layerzero deploys UltraLightNodeV2Radar and NonceContractRadar using old chain ID with the local dappRadar address in constructor // 2. Dapp Radar sets the messaging library to UltraLightNodeV2Radar // 3. Dapp Radar sets the trustedRemote to the full path // 4. Layerzero initializes the outboundNonce (1 call) and inboundNonce (batch call) // 5. Test message flows // // 6. after an agree-upon period of time, decommission this contract (one-way trip). // // DappRadar constructs // address immutable public dappRadar; bool public decommissioned; mapping(uint16 => bool) public outboundNonceSet; mapping(address => uint64) public inboundNonceCap; // only dappRadar function initRadarOutboundNonce(uint16 _dstChainId, address _dstRadarAddress) external onlyOwner { // can only inherit the outbound nonce from previous path once // assuming dappRadar has only 1 remote peer at a destination chain. require(!outboundNonceSet[_dstChainId], "LayerZero: dappRadar nonce already set"); uint64 inheritedNonce = endpoint.getOutboundNonce(_dstChainId, dappRadar); outboundNonceSet[_dstChainId] = true; // can only set the path owned by the dappRadar // dappRadar is only deployed on EVM chains so the address is 20 bytes for all bytes memory radarPath = abi.encodePacked(_dstRadarAddress, dappRadar); //// remote + local // insert into the nonce contract nonceContract.initRadarOutboundNonce(_dstChainId, radarPath, inheritedNonce); } // generate a message from the new dappRadar-owned path with now payload // dappRadar needs to first change the trustedRemote // messages will fail locally in the nonBlockingLzApp from the nonce checking // can only increment the nonce till we hit the legacy nonce function incrementRadarInboundNonce(uint16 _srcChainId, address _srcRadarAddress, uint _gasLimitPerCall, uint _steps) external onlyOwner { // initialize the inboundNonceCap, only once if (inboundNonceCap[_srcRadarAddress] == 0) { // check if the _srcRadarAddress is a legacy address by checking the nonce uint64 inheritNonce = endpoint.getInboundNonce(_srcChainId, abi.encodePacked(_srcRadarAddress)); require(inheritNonce > 0, "LayerZero: not legacy radar address"); inboundNonceCap[_srcRadarAddress] = inheritNonce; } // can only set the path owned by the dappRadar // dappRadar is only deployed on EVM chains so the address is 20 bytes for all bytes memory radarPath = abi.encodePacked(_srcRadarAddress, dappRadar); // remote + local uint64 radarPathNonce = endpoint.getInboundNonce(_srcChainId, radarPath); uint64 nonceCap = inboundNonceCap[_srcRadarAddress]; for (uint i = 0; i < _steps; i++) { // ensure that the nonce of the new path is not already at the cap radarPathNonce++; if (radarPathNonce > nonceCap) { break; } // receive the message with null Payload endpoint.receivePayload(_srcChainId, radarPath, dappRadar, radarPathNonce, _gasLimitPerCall, bytes("")); } } // this contract will only serve for a period of time function decommission() external onlyOwner { decommissioned = true; } //---------------------------------------------------------------------------------- // PROTOCOL function validateTransactionProof(uint16 _srcChainId, address _dstAddress, uint _gasLimit, bytes32 _lookupHash, bytes32 _blockData, bytes calldata _transactionProof) external override { require(_dstAddress == dappRadar, "LayerZero: only dappRadar"); require(!decommissioned, "LayerZero: decommissioned"); // retrieve UA's configuration using the _dstAddress from arguments. ApplicationConfiguration memory uaConfig = _getAppConfig(_srcChainId, _dstAddress); // assert that the caller == UA's relayer require(uaConfig.relayer == msg.sender, "LayerZero: invalid relayer"); LayerZeroPacket.Packet memory _packet; uint remoteAddressSize = chainAddressSizeMap[_srcChainId]; require(remoteAddressSize != 0, "LayerZero: incorrect remote address size"); { // assert that the data submitted by UA's oracle have no fewer confirmations than UA's configuration uint storedConfirmations = hashLookup[uaConfig.oracle][_srcChainId][_lookupHash][_blockData]; require(storedConfirmations > 0 && storedConfirmations >= uaConfig.inboundBlockConfirmations, "LayerZero: not enough block confirmations"); // decode address inboundProofLib = inboundProofLibrary[_srcChainId][uaConfig.inboundProofLibraryVersion]; _packet = ILayerZeroValidationLibrary(inboundProofLib).validateProof(_blockData, _transactionProof, remoteAddressSize); } // packet content assertion require(ulnLookup[_srcChainId] == _packet.ulnAddress && _packet.ulnAddress != bytes32(0), "LayerZero: invalid _packet.ulnAddress"); require(_packet.srcChainId == _srcChainId, "LayerZero: invalid srcChain Id"); // failsafe because the remoteAddress size being passed into validateProof trims the address this should not hit require(_packet.srcAddress.length == remoteAddressSize, "LayerZero: invalid srcAddress size"); require(_packet.dstChainId == localChainId, "LayerZero: invalid dstChain Id"); require(_packet.dstAddress == _dstAddress, "LayerZero: invalid dstAddress"); // if the dst is not a contract, then emit and return early. This will break inbound nonces, but this particular // path is already broken and wont ever be able to deliver anyways if (!_isContract(_dstAddress)) { emit InvalidDst(_packet.srcChainId, _packet.srcAddress, _packet.dstAddress, _packet.nonce, keccak256(_packet.payload)); return; } bytes memory pathData = abi.encodePacked(_packet.srcAddress, _packet.dstAddress); emit PacketReceived(_packet.srcChainId, _packet.srcAddress, _packet.dstAddress, _packet.nonce, keccak256(_packet.payload)); endpoint.receivePayload(_srcChainId, pathData, _dstAddress, _packet.nonce, _gasLimit, _packet.payload); } function send(address _ua, uint64, uint16 _dstChainId, bytes calldata _path, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable override onlyEndpoint { require(_ua == dappRadar, "LayerZero: only dappRadar"); require(!decommissioned, "LayerZero: decommissioned"); address ua = _ua; uint16 dstChainId = _dstChainId; require(ulnLookup[dstChainId] != bytes32(0), "LayerZero: dstChainId does not exist"); bytes memory dstAddress; uint64 nonce; // code block for solving 'Stack Too Deep' { uint chainAddressSize = chainAddressSizeMap[dstChainId]; // path = remoteAddress + localAddress require(chainAddressSize != 0 && _path.length == 20 + chainAddressSize, "LayerZero: incorrect remote address size"); address srcInPath; bytes memory path = _path; // copy to memory assembly { srcInPath := mload(add(add(path, 20), chainAddressSize)) // chainAddressSize + 20 } require(ua == srcInPath, "LayerZero: wrong path data"); dstAddress = _path[0:chainAddressSize]; nonce = nonceContract.increment(dstChainId, ua, path); } bytes memory payload = _payload; ApplicationConfiguration memory uaConfig = _getAppConfig(dstChainId, ua); // compute all the fees uint relayerFee = _handleRelayer(dstChainId, uaConfig, ua, payload.length, _adapterParams); uint oracleFee = _handleOracle(dstChainId, uaConfig, ua); uint nativeProtocolFee = _handleProtocolFee(relayerFee, oracleFee, ua, _zroPaymentAddress); // total native fee, does not include ZRO protocol fee uint totalNativeFee = relayerFee.add(oracleFee).add(nativeProtocolFee); // assert the user has attached enough native token for this address require(totalNativeFee <= msg.value, "LayerZero: not enough native for fees"); // refund if they send too much uint amount = msg.value.sub(totalNativeFee); if (amount > 0) { (bool success, ) = _refundAddress.call{value: amount}(""); require(success, "LayerZero: failed to refund"); } // emit the data packet bytes memory encodedPayload = abi.encodePacked(nonce, localChainId, ua, dstChainId, dstAddress, payload); emit Packet(encodedPayload); } function _handleRelayer(uint16 _dstChainId, ApplicationConfiguration memory _uaConfig, address _ua, uint _payloadSize, bytes memory _adapterParams) internal returns (uint relayerFee) { if (_adapterParams.length == 0) { _adapterParams = defaultAdapterParams[_dstChainId][_uaConfig.outboundProofType]; } address relayerAddress = _uaConfig.relayer; ILayerZeroRelayerV2 relayer = ILayerZeroRelayerV2(relayerAddress); relayerFee = relayer.assignJob(_dstChainId, _uaConfig.outboundProofType, _ua, _payloadSize, _adapterParams); _creditNativeFee(relayerAddress, relayerFee); // emit the param events emit RelayerParams(_adapterParams, _uaConfig.outboundProofType); } function _handleOracle(uint16 _dstChainId, ApplicationConfiguration memory _uaConfig, address _ua) internal returns (uint oracleFee) { address oracleAddress = _uaConfig.oracle; oracleFee = ILayerZeroOracleV2(oracleAddress).assignJob(_dstChainId, _uaConfig.outboundProofType, _uaConfig.outboundBlockConfirmations, _ua); _creditNativeFee(oracleAddress, oracleFee); } function _handleProtocolFee(uint _relayerFee, uint _oracleFee, address _ua, address _zroPaymentAddress) internal returns (uint protocolNativeFee) { // if no ZRO token or not specifying a payment address, pay in native token bool payInNative = _zroPaymentAddress == address(0x0) || address(layerZeroToken) == address(0x0); uint protocolFee = treasuryContract.getFees(!payInNative, _relayerFee, _oracleFee); if (protocolFee > 0) { if (payInNative) { address treasuryAddress = address(treasuryContract); _creditNativeFee(treasuryAddress, protocolFee); protocolNativeFee = protocolFee; } else { // zro payment address must equal the ua or the tx.origin otherwise the transaction reverts require(_zroPaymentAddress == _ua || _zroPaymentAddress == tx.origin, "LayerZero: must be paid by sender or origin"); // transfer the LayerZero token to this contract from the payee layerZeroToken.safeTransferFrom(_zroPaymentAddress, address(this), protocolFee); treasuryZROFees = treasuryZROFees.add(protocolFee); } } } function _creditNativeFee(address _receiver, uint _amount) internal { nativeFees[_receiver] = nativeFees[_receiver].add(_amount); } // Can be called by any address to update a block header // can only upload new block data or the same block data with more confirmations function updateHash(uint16 _srcChainId, bytes32 _lookupHash, uint _confirmations, bytes32 _blockData) external override { uint storedConfirmations = hashLookup[msg.sender][_srcChainId][_lookupHash][_blockData]; // if it has a record, requires a larger confirmation. require(storedConfirmations < _confirmations, "LayerZero: oracle data can only update if it has more confirmations"); // set the new information into storage hashLookup[msg.sender][_srcChainId][_lookupHash][_blockData] = _confirmations; emit HashReceived(_srcChainId, msg.sender, _lookupHash, _blockData, _confirmations); } //---------------------------------------------------------------------------------- // Other Library Interfaces // default to DEFAULT setting if ZERO value function getAppConfig(uint16 _remoteChainId, address _ua) external view override returns (ApplicationConfiguration memory) { return _getAppConfig(_remoteChainId, _ua); } function _getAppConfig(uint16 _remoteChainId, address _ua) internal view returns (ApplicationConfiguration memory) { ApplicationConfiguration memory config = appConfig[_ua][_remoteChainId]; ApplicationConfiguration storage defaultConfig = defaultAppConfig[_remoteChainId]; if (config.inboundProofLibraryVersion == 0) { config.inboundProofLibraryVersion = defaultConfig.inboundProofLibraryVersion; } if (config.inboundBlockConfirmations == 0) { config.inboundBlockConfirmations = defaultConfig.inboundBlockConfirmations; } if (config.relayer == address(0x0)) { config.relayer = defaultConfig.relayer; } if (config.outboundProofType == 0) { config.outboundProofType = defaultConfig.outboundProofType; } if (config.outboundBlockConfirmations == 0) { config.outboundBlockConfirmations = defaultConfig.outboundBlockConfirmations; } if (config.oracle == address(0x0)) { config.oracle = defaultConfig.oracle; } return config; } function setConfig(uint16 _remoteChainId, address _ua, uint _configType, bytes calldata _config) external override onlyEndpoint { ApplicationConfiguration storage uaConfig = appConfig[_ua][_remoteChainId]; if (_configType == CONFIG_TYPE_INBOUND_PROOF_LIBRARY_VERSION) { uint16 inboundProofLibraryVersion = abi.decode(_config, (uint16)); require(inboundProofLibraryVersion <= maxInboundProofLibrary[_remoteChainId], "LayerZero: invalid inbound proof library version"); uaConfig.inboundProofLibraryVersion = inboundProofLibraryVersion; } else if (_configType == CONFIG_TYPE_INBOUND_BLOCK_CONFIRMATIONS) { uint64 blockConfirmations = abi.decode(_config, (uint64)); uaConfig.inboundBlockConfirmations = blockConfirmations; } else if (_configType == CONFIG_TYPE_RELAYER) { address relayer = abi.decode(_config, (address)); uaConfig.relayer = relayer; } else if (_configType == CONFIG_TYPE_OUTBOUND_PROOF_TYPE) { uint16 outboundProofType = abi.decode(_config, (uint16)); require(supportedOutboundProof[_remoteChainId][outboundProofType] || outboundProofType == 0, "LayerZero: invalid outbound proof type"); uaConfig.outboundProofType = outboundProofType; } else if (_configType == CONFIG_TYPE_OUTBOUND_BLOCK_CONFIRMATIONS) { uint64 blockConfirmations = abi.decode(_config, (uint64)); uaConfig.outboundBlockConfirmations = blockConfirmations; } else if (_configType == CONFIG_TYPE_ORACLE) { address oracle = abi.decode(_config, (address)); uaConfig.oracle = oracle; } else { revert("LayerZero: Invalid config type"); } emit AppConfigUpdated(_ua, _configType, _config); } function getConfig(uint16 _remoteChainId, address _ua, uint _configType) external view override returns (bytes memory) { ApplicationConfiguration storage uaConfig = appConfig[_ua][_remoteChainId]; if (_configType == CONFIG_TYPE_INBOUND_PROOF_LIBRARY_VERSION) { if (uaConfig.inboundProofLibraryVersion == 0) { return abi.encode(defaultAppConfig[_remoteChainId].inboundProofLibraryVersion); } return abi.encode(uaConfig.inboundProofLibraryVersion); } else if (_configType == CONFIG_TYPE_INBOUND_BLOCK_CONFIRMATIONS) { if (uaConfig.inboundBlockConfirmations == 0) { return abi.encode(defaultAppConfig[_remoteChainId].inboundBlockConfirmations); } return abi.encode(uaConfig.inboundBlockConfirmations); } else if (_configType == CONFIG_TYPE_RELAYER) { if (uaConfig.relayer == address(0x0)) { return abi.encode(defaultAppConfig[_remoteChainId].relayer); } return abi.encode(uaConfig.relayer); } else if (_configType == CONFIG_TYPE_OUTBOUND_PROOF_TYPE) { if (uaConfig.outboundProofType == 0) { return abi.encode(defaultAppConfig[_remoteChainId].outboundProofType); } return abi.encode(uaConfig.outboundProofType); } else if (_configType == CONFIG_TYPE_OUTBOUND_BLOCK_CONFIRMATIONS) { if (uaConfig.outboundBlockConfirmations == 0) { return abi.encode(defaultAppConfig[_remoteChainId].outboundBlockConfirmations); } return abi.encode(uaConfig.outboundBlockConfirmations); } else if (_configType == CONFIG_TYPE_ORACLE) { if (uaConfig.oracle == address(0x0)) { return abi.encode(defaultAppConfig[_remoteChainId].oracle); } return abi.encode(uaConfig.oracle); } else { revert("LayerZero: Invalid config type"); } } // returns the native fee the UA pays to cover fees function estimateFees(uint16 _dstChainId, address _ua, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParams) external view override returns (uint nativeFee, uint zroFee) { ApplicationConfiguration memory uaConfig = _getAppConfig(_dstChainId, _ua); // Relayer Fee bytes memory adapterParams; if (_adapterParams.length > 0) { adapterParams = _adapterParams; } else { adapterParams = defaultAdapterParams[_dstChainId][uaConfig.outboundProofType]; } uint relayerFee = ILayerZeroRelayerV2(uaConfig.relayer).getFee(_dstChainId, uaConfig.outboundProofType, _ua, _payload.length, adapterParams); // Oracle Fee address ua = _ua; // stack too deep uint oracleFee = ILayerZeroOracleV2(uaConfig.oracle).getFee(_dstChainId, uaConfig.outboundProofType, uaConfig.outboundBlockConfirmations, ua); // LayerZero Fee uint protocolFee = treasuryContract.getFees(_payInZRO, relayerFee, oracleFee); _payInZRO ? zroFee = protocolFee : nativeFee = protocolFee; // return the sum of fees nativeFee = nativeFee.add(relayerFee).add(oracleFee); } //--------------------------------------------------------------------------- // Claim Fees // universal withdraw ZRO token function function withdrawZRO(address _to, uint _amount) external override nonReentrant { require(msg.sender == address(treasuryContract), "LayerZero: only treasury"); treasuryZROFees = treasuryZROFees.sub(_amount); layerZeroToken.safeTransfer(_to, _amount); emit WithdrawZRO(msg.sender, _to, _amount); } // universal withdraw native token function. // the source contract should perform all the authentication control function withdrawNative(address payable _to, uint _amount) external override nonReentrant { require(_to != address(0x0), "LayerZero: _to cannot be zero address"); nativeFees[msg.sender] = nativeFees[msg.sender].sub(_amount); (bool success, ) = _to.call{value: _amount}(""); require(success, "LayerZero: withdraw failed"); emit WithdrawNative(msg.sender, _to, _amount); } //--------------------------------------------------------------------------- // Owner calls, configuration only. function setLayerZeroToken(address _layerZeroToken) external onlyOwner { require(_layerZeroToken != address(0x0), "LayerZero: _layerZeroToken cannot be zero address"); layerZeroToken = IERC20(_layerZeroToken); emit SetLayerZeroToken(_layerZeroToken); } function setTreasury(address _treasury) external onlyOwner { require(_treasury != address(0x0), "LayerZero: treasury cannot be zero address"); treasuryContract = ILayerZeroTreasury(_treasury); emit SetTreasury(_treasury); } function addInboundProofLibraryForChain(uint16 _chainId, address _library) external onlyOwner { require(_library != address(0x0), "LayerZero: library cannot be zero address"); uint16 libId = maxInboundProofLibrary[_chainId]; require(libId < 65535, "LayerZero: can not add new library"); maxInboundProofLibrary[_chainId] = ++libId; inboundProofLibrary[_chainId][libId] = _library; emit AddInboundProofLibraryForChain(_chainId, _library); } function enableSupportedOutboundProof(uint16 _chainId, uint16 _proofType) external onlyOwner { supportedOutboundProof[_chainId][_proofType] = true; emit EnableSupportedOutboundProof(_chainId, _proofType); } function setDefaultConfigForChainId(uint16 _chainId, uint16 _inboundProofLibraryVersion, uint64 _inboundBlockConfirmations, address _relayer, uint16 _outboundProofType, uint64 _outboundBlockConfirmations, address _oracle) external onlyOwner { require(_inboundProofLibraryVersion <= maxInboundProofLibrary[_chainId] && _inboundProofLibraryVersion > 0, "LayerZero: invalid inbound proof library version"); require(_inboundBlockConfirmations > 0, "LayerZero: invalid inbound block confirmation"); require(_relayer != address(0x0), "LayerZero: invalid relayer address"); require(supportedOutboundProof[_chainId][_outboundProofType], "LayerZero: invalid outbound proof type"); require(_outboundBlockConfirmations > 0, "LayerZero: invalid outbound block confirmation"); require(_oracle != address(0x0), "LayerZero: invalid oracle address"); defaultAppConfig[_chainId] = ApplicationConfiguration(_inboundProofLibraryVersion, _inboundBlockConfirmations, _relayer, _outboundProofType, _outboundBlockConfirmations, _oracle); emit SetDefaultConfigForChainId(_chainId, _inboundProofLibraryVersion, _inboundBlockConfirmations, _relayer, _outboundProofType, _outboundBlockConfirmations, _oracle); } function setDefaultAdapterParamsForChainId(uint16 _chainId, uint16 _proofType, bytes calldata _adapterParams) external onlyOwner { defaultAdapterParams[_chainId][_proofType] = _adapterParams; emit SetDefaultAdapterParamsForChainId(_chainId, _proofType, _adapterParams); } function setRemoteUln(uint16 _remoteChainId, bytes32 _remoteUln) external onlyOwner { require(ulnLookup[_remoteChainId] == bytes32(0), "LayerZero: remote uln already set"); ulnLookup[_remoteChainId] = _remoteUln; emit SetRemoteUln(_remoteChainId, _remoteUln); } function setChainAddressSize(uint16 _chainId, uint _size) external onlyOwner { require(chainAddressSizeMap[_chainId] == 0, "LayerZero: remote chain address size already set"); chainAddressSizeMap[_chainId] = _size; emit SetChainAddressSize(_chainId, _size); } //---------------------------------------------------------------------------------- // view functions function accruedNativeFee(address _address) external view override returns (uint) { return nativeFees[_address]; } function getOutboundNonce(uint16 _chainId, bytes calldata _path) external view override returns (uint64) { return nonceContract.outboundNonce(_chainId, _path); } function _isContract(address addr) internal view returns (bool) { uint size; assembly { size := extcodesize(addr) } return size != 0; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "../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. * * By default, the owner account will be the one that deploys the contract. 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; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = 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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) 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 `amount` 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 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; import "../../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 SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @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, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; pragma abicoder v2; import "../proof/utility/LayerZeroPacket.sol"; interface ILayerZeroValidationLibrary { function validateProof(bytes32 blockData, bytes calldata _data, uint _remoteAddressSize) external returns (LayerZeroPacket.Packet memory packet); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; interface ILayerZeroTreasury { function getFees(bool payInZro, uint relayerFee, uint oracleFee) external view returns (uint); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send(uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload(uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees(uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam) external view returns (uint nativeFee, uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress(address _userApplication) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress(address _userApplication) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig(uint16 _version, uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion(address _userApplication) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion(address _userApplication) external view returns (uint16); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; import "./ILayerZeroUserApplicationConfig.sol"; import "./ILayerZeroMessagingLibrary.sol"; interface ILayerZeroMessagingLibraryV2 is ILayerZeroMessagingLibrary { function getOutboundNonce(uint16 _chainId, bytes calldata _path) external view returns (uint64); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; interface ILayerZeroOracleV2 { // @notice query price and assign jobs at the same time // @param _dstChainId - the destination endpoint identifier // @param _outboundProofType - the proof type identifier to specify proof to be relayed // @param _outboundBlockConfirmation - block confirmation delay before relaying blocks // @param _userApplication - the source sending contract address function assignJob(uint16 _dstChainId, uint16 _outboundProofType, uint64 _outboundBlockConfirmation, address _userApplication) external returns (uint price); // @notice query the oracle price for relaying block information to the destination chain // @param _dstChainId the destination endpoint identifier // @param _outboundProofType the proof type identifier to specify the data to be relayed // @param _outboundBlockConfirmation - block confirmation delay before relaying blocks // @param _userApplication - the source sending contract address function getFee(uint16 _dstChainId, uint16 _outboundProofType, uint64 _outboundBlockConfirmation, address _userApplication) external view returns (uint price); // @notice withdraw the accrued fee in ultra light node // @param _to - the fee receiver // @param _amount - the withdrawal amount function withdrawFee(address payable _to, uint _amount) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; pragma abicoder v2; interface ILayerZeroUltraLightNodeV2 { // Relayer functions function validateTransactionProof(uint16 _srcChainId, address _dstAddress, uint _gasLimit, bytes32 _lookupHash, bytes32 _blockData, bytes calldata _transactionProof) external; // an Oracle delivers the block data using updateHash() function updateHash(uint16 _srcChainId, bytes32 _lookupHash, uint _confirmations, bytes32 _blockData) external; // can only withdraw the receivable of the msg.sender function withdrawNative(address payable _to, uint _amount) external; function withdrawZRO(address _to, uint _amount) external; // view functions function getAppConfig(uint16 _remoteChainId, address _userApplicationAddress) external view returns (ApplicationConfiguration memory); function accruedNativeFee(address _address) external view returns (uint); struct ApplicationConfiguration { uint16 inboundProofLibraryVersion; uint64 inboundBlockConfirmations; address relayer; uint16 outboundProofType; uint64 outboundBlockConfirmations; address oracle; } event HashReceived(uint16 indexed srcChainId, address indexed oracle, bytes32 lookupHash, bytes32 blockData, uint confirmations); event RelayerParams(bytes adapterParams, uint16 outboundProofType); event Packet(bytes payload); event InvalidDst(uint16 indexed srcChainId, bytes srcAddress, address indexed dstAddress, uint64 nonce, bytes32 payloadHash); event PacketReceived(uint16 indexed srcChainId, bytes srcAddress, address indexed dstAddress, uint64 nonce, bytes32 payloadHash); event AppConfigUpdated(address indexed userApplication, uint indexed configType, bytes newConfig); event AddInboundProofLibraryForChain(uint16 indexed chainId, address lib); event EnableSupportedOutboundProof(uint16 indexed chainId, uint16 proofType); event SetChainAddressSize(uint16 indexed chainId, uint size); event SetDefaultConfigForChainId(uint16 indexed chainId, uint16 inboundProofLib, uint64 inboundBlockConfirm, address relayer, uint16 outboundProofType, uint64 outboundBlockConfirm, address oracle); event SetDefaultAdapterParamsForChainId(uint16 indexed chainId, uint16 indexed proofType, bytes adapterParams); event SetLayerZeroToken(address indexed tokenAddress); event SetRemoteUln(uint16 indexed chainId, bytes32 uln); event SetTreasury(address indexed treasuryAddress); event WithdrawZRO(address indexed msgSender, address indexed to, uint amount); event WithdrawNative(address indexed msgSender, address indexed to, uint amount); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; interface ILayerZeroRelayerV2 { // @notice query price and assign jobs at the same time // @param _dstChainId - the destination endpoint identifier // @param _outboundProofType - the proof type identifier to specify proof to be relayed // @param _userApplication - the source sending contract address. relayers may apply price discrimination to user apps // @param _payloadSize - the length of the payload. it is an indicator of gas usage for relaying cross-chain messages // @param _adapterParams - optional parameters for extra service plugins, e.g. sending dust tokens at the destination chain function assignJob(uint16 _dstChainId, uint16 _outboundProofType, address _userApplication, uint _payloadSize, bytes calldata _adapterParams) external returns (uint price); // @notice query the relayer price for relaying the payload and its proof to the destination chain // @param _dstChainId - the destination endpoint identifier // @param _outboundProofType - the proof type identifier to specify proof to be relayed // @param _userApplication - the source sending contract address. relayers may apply price discrimination to user apps // @param _payloadSize - the length of the payload. it is an indicator of gas usage for relaying cross-chain messages // @param _adapterParams - optional parameters for extra service plugins, e.g. sending dust tokens at the destination chain function getFee(uint16 _dstChainId, uint16 _outboundProofType, address _userApplication, uint _payloadSize, bytes calldata _adapterParams) external view returns (uint price); // @notice withdraw the accrued fee in ultra light node // @param _to - the fee receiver // @param _amount - the withdrawal amount function withdrawFee(address payable _to, uint _amount) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; import "./interfaces/ILayerZeroEndpoint.sol"; contract NonceContractRadar { ILayerZeroEndpoint public immutable endpoint; address public immutable ulnv2Radar; // outboundNonce = [dstChainId][remoteAddress + localAddress] mapping(uint16 => mapping(bytes => uint64)) public outboundNonce; constructor(address _endpoint, address _ulnv2Radar) { endpoint = ILayerZeroEndpoint(_endpoint); ulnv2Radar = _ulnv2Radar; } function increment(uint16 _chainId, address _ua, bytes calldata _path) external returns (uint64) { require(endpoint.getSendLibraryAddress(_ua) == msg.sender, "NonceContract: msg.sender is not valid sendlibrary"); return ++outboundNonce[_chainId][_path]; } // only ulnv2Radar can call this function function initRadarOutboundNonce(uint16 _dstChainId, bytes calldata _path, uint64 _nonce) external { require(msg.sender == ulnv2Radar, "NonceContract: only ulnv2Radar"); outboundNonce[_dstChainId][_path] = _nonce; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @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 GSN 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 payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @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://diligence.consensys.net/posts/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.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @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, it is bubbled up by this * function (like regular Solidity function calls). * * 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. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @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`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; import "./Buffer.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; library LayerZeroPacket { using Buffer for Buffer.buffer; using SafeMath for uint; struct Packet { uint16 srcChainId; uint16 dstChainId; uint64 nonce; address dstAddress; bytes srcAddress; bytes32 ulnAddress; bytes payload; } function getPacket( bytes memory data, uint16 srcChain, uint sizeOfSrcAddress, bytes32 ulnAddress ) internal pure returns (LayerZeroPacket.Packet memory) { uint16 dstChainId; address dstAddress; uint size; uint64 nonce; // The log consists of the destination chain id and then a bytes payload // 0--------------------------------------------31 // 0 | total bytes size // 32 | destination chain id // 64 | bytes offset // 96 | bytes array size // 128 | payload assembly { dstChainId := mload(add(data, 32)) size := mload(add(data, 96)) /// size of the byte array nonce := mload(add(data, 104)) // offset to convert to uint64 128 is index -24 dstAddress := mload(add(data, sub(add(128, sizeOfSrcAddress), 4))) // offset to convert to address 12 -8 } Buffer.buffer memory srcAddressBuffer; srcAddressBuffer.init(sizeOfSrcAddress); srcAddressBuffer.writeRawBytes(0, data, 136, sizeOfSrcAddress); // 128 + 8 uint payloadSize = size.sub(28).sub(sizeOfSrcAddress); Buffer.buffer memory payloadBuffer; payloadBuffer.init(payloadSize); payloadBuffer.writeRawBytes(0, data, sizeOfSrcAddress.add(156), payloadSize); // 148 + 8 return LayerZeroPacket.Packet(srcChain, dstChainId, nonce, dstAddress, srcAddressBuffer.buf, ulnAddress, payloadBuffer.buf); } function getPacketV2( bytes memory data, uint sizeOfSrcAddress, bytes32 ulnAddress ) internal pure returns (LayerZeroPacket.Packet memory) { // packet def: abi.encodePacked(nonce, srcChain, srcAddress, dstChain, dstAddress, payload); // data def: abi.encode(packet) = offset(32) + length(32) + packet // if from EVM // 0 - 31 0 - 31 | total bytes size // 32 - 63 32 - 63 | location // 64 - 95 64 - 95 | size of the packet // 96 - 103 96 - 103 | nonce // 104 - 105 104 - 105 | srcChainId // 106 - P 106 - 125 | srcAddress, where P = 106 + sizeOfSrcAddress - 1, // P+1 - P+2 126 - 127 | dstChainId // P+3 - P+22 128 - 147 | dstAddress // P+23 - END 148 - END | payload // decode the packet uint256 realSize; uint64 nonce; uint16 srcChain; uint16 dstChain; address dstAddress; assembly { realSize := mload(add(data, 64)) nonce := mload(add(data, 72)) // 104 - 32 srcChain := mload(add(data, 74)) // 106 - 32 dstChain := mload(add(data, add(76, sizeOfSrcAddress))) // P + 3 - 32 = 105 + size + 3 - 32 = 76 + size dstAddress := mload(add(data, add(96, sizeOfSrcAddress))) // P + 23 - 32 = 105 + size + 23 - 32 = 96 + size } require(srcChain != 0, "LayerZeroPacket: invalid packet"); Buffer.buffer memory srcAddressBuffer; srcAddressBuffer.init(sizeOfSrcAddress); srcAddressBuffer.writeRawBytes(0, data, 106, sizeOfSrcAddress); uint nonPayloadSize = sizeOfSrcAddress.add(32);// 2 + 2 + 8 + 20, 32 + 20 = 52 if sizeOfSrcAddress == 20 uint payloadSize = realSize.sub(nonPayloadSize); Buffer.buffer memory payloadBuffer; payloadBuffer.init(payloadSize); payloadBuffer.writeRawBytes(0, data, nonPayloadSize.add(96), payloadSize); return LayerZeroPacket.Packet(srcChain, dstChain, nonce, dstAddress, srcAddressBuffer.buf, ulnAddress, payloadBuffer.buf); } function getPacketV3( bytes memory data, uint sizeOfSrcAddress, bytes32 ulnAddress ) internal pure returns (LayerZeroPacket.Packet memory) { // data def: abi.encodePacked(nonce, srcChain, srcAddress, dstChain, dstAddress, payload); // if from EVM // 0 - 31 0 - 31 | total bytes size // 32 - 39 32 - 39 | nonce // 40 - 41 40 - 41 | srcChainId // 42 - P 42 - 61 | srcAddress, where P = 41 + sizeOfSrcAddress, // P+1 - P+2 62 - 63 | dstChainId // P+3 - P+22 64 - 83 | dstAddress // P+23 - END 84 - END | payload // decode the packet uint256 realSize = data.length; uint nonPayloadSize = sizeOfSrcAddress.add(32);// 2 + 2 + 8 + 20, 32 + 20 = 52 if sizeOfSrcAddress == 20 require(realSize >= nonPayloadSize, "LayerZeroPacket: invalid packet"); uint payloadSize = realSize - nonPayloadSize; uint64 nonce; uint16 srcChain; uint16 dstChain; address dstAddress; assembly { nonce := mload(add(data, 8)) // 40 - 32 srcChain := mload(add(data, 10)) // 42 - 32 dstChain := mload(add(data, add(12, sizeOfSrcAddress))) // P + 3 - 32 = 41 + size + 3 - 32 = 12 + size dstAddress := mload(add(data, add(32, sizeOfSrcAddress))) // P + 23 - 32 = 41 + size + 23 - 32 = 32 + size } require(srcChain != 0, "LayerZeroPacket: invalid packet"); Buffer.buffer memory srcAddressBuffer; srcAddressBuffer.init(sizeOfSrcAddress); srcAddressBuffer.writeRawBytes(0, data, 42, sizeOfSrcAddress); Buffer.buffer memory payloadBuffer; if (payloadSize > 0) { payloadBuffer.init(payloadSize); payloadBuffer.writeRawBytes(0, data, nonPayloadSize.add(32), payloadSize); } return LayerZeroPacket.Packet(srcChain, dstChain, nonce, dstAddress, srcAddressBuffer.buf, ulnAddress, payloadBuffer.buf); } }
// SPDX-License-Identifier: BUSL-1.1 // https://github.com/ensdomains/buffer pragma solidity ^0.7.0; /** * @dev A library for working with mutable byte buffers in Solidity. * * Byte buffers are mutable and expandable, and provide a variety of primitives * for writing to them. At any time you can fetch a bytes object containing the * current contents of the buffer. The bytes object should not be stored between * operations, as it may change due to resizing of the buffer. */ library Buffer { /** * @dev Represents a mutable buffer. Buffers have a current value (buf) and * a capacity. The capacity may be longer than the current value, in * which case it can be extended without the need to allocate more memory. */ struct buffer { bytes buf; uint capacity; } /** * @dev Initializes a buffer with an initial capacity.a co * @param buf The buffer to initialize. * @param capacity The number of bytes of space to allocate the buffer. * @return The buffer, for chaining. */ function init(buffer memory buf, uint capacity) internal pure returns (buffer memory) { if (capacity % 32 != 0) { capacity += 32 - (capacity % 32); } // Allocate space for the buffer data buf.capacity = capacity; assembly { let ptr := mload(0x40) mstore(buf, ptr) mstore(ptr, 0) mstore(0x40, add(32, add(ptr, capacity))) } return buf; } /** * @dev Writes a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The start offset to write to. * @param rawData The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function writeRawBytes( buffer memory buf, uint off, bytes memory rawData, uint offData, uint len ) internal pure returns (buffer memory) { if (off + len > buf.capacity) { resize(buf, max(buf.capacity, len + off) * 2); } uint dest; uint src; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Start address = buffer address + offset + sizeof(buffer length) dest := add(add(bufptr, 32), off) // Update buffer length if we're extending it if gt(add(len, off), buflen) { mstore(bufptr, add(len, off)) } src := add(rawData, offData) } // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes uint mask = 256**(32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } return buf; } /** * @dev Writes a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The start offset to write to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns (buffer memory) { require(len <= data.length); if (off + len > buf.capacity) { resize(buf, max(buf.capacity, len + off) * 2); } uint dest; uint src; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Start address = buffer address + offset + sizeof(buffer length) dest := add(add(bufptr, 32), off) // Update buffer length if we're extending it if gt(add(len, off), buflen) { mstore(bufptr, add(len, off)) } src := add(data, 32) } // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes uint mask = 256**(32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } return buf; } function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, data.length); } function resize(buffer memory buf, uint capacity) private pure { bytes memory oldbuf = buf.buf; init(buf, capacity); append(buf, oldbuf); } function max(uint a, uint b) private pure returns (uint) { if (a > b) { return a; } return b; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion(uint16 _version) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion(uint16 _version) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroMessagingLibrary { // send(), messages will be inflight. function send(address _userApplication, uint64 _lastNonce, uint16 _chainId, bytes calldata _destination, bytes calldata _payload, address payable refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable; // estimate native fee at the send side function estimateFees(uint16 _chainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam) external view returns (uint nativeFee, uint zroFee); //--------------------------------------------------------------------------- // setConfig / getConfig are User Application (UA) functions to specify Oracle, Relayer, blockConfirmations, libraryVersion function setConfig(uint16 _chainId, address _userApplication, uint _configType, bytes calldata _config) external; function getConfig(uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_endpoint","type":"address"},{"internalType":"uint16","name":"_localChainId","type":"uint16"},{"internalType":"address","name":"_dappRadar","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"address","name":"lib","type":"address"}],"name":"AddInboundProofLibraryForChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userApplication","type":"address"},{"indexed":true,"internalType":"uint256","name":"configType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newConfig","type":"bytes"}],"name":"AppConfigUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"proofType","type":"uint16"}],"name":"EnableSupportedOutboundProof","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"bytes32","name":"lookupHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"blockData","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"confirmations","type":"uint256"}],"name":"HashReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"dstAddress","type":"address"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"name":"InvalidDst","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":"bytes","name":"payload","type":"bytes"}],"name":"Packet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"dstAddress","type":"address"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"name":"PacketReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"adapterParams","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"outboundProofType","type":"uint16"}],"name":"RelayerParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"size","type":"uint256"}],"name":"SetChainAddressSize","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":true,"internalType":"uint16","name":"proofType","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"adapterParams","type":"bytes"}],"name":"SetDefaultAdapterParamsForChainId","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"inboundProofLib","type":"uint16"},{"indexed":false,"internalType":"uint64","name":"inboundBlockConfirm","type":"uint64"},{"indexed":false,"internalType":"address","name":"relayer","type":"address"},{"indexed":false,"internalType":"uint16","name":"outboundProofType","type":"uint16"},{"indexed":false,"internalType":"uint64","name":"outboundBlockConfirm","type":"uint64"},{"indexed":false,"internalType":"address","name":"oracle","type":"address"}],"name":"SetDefaultConfigForChainId","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"}],"name":"SetLayerZeroToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"bytes32","name":"uln","type":"bytes32"}],"name":"SetRemoteUln","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasuryAddress","type":"address"}],"name":"SetTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"msgSender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawNative","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"msgSender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawZRO","type":"event"},{"inputs":[],"name":"CONFIG_TYPE_INBOUND_BLOCK_CONFIRMATIONS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG_TYPE_INBOUND_PROOF_LIBRARY_VERSION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG_TYPE_ORACLE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG_TYPE_OUTBOUND_BLOCK_CONFIRMATIONS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG_TYPE_OUTBOUND_PROOF_TYPE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIG_TYPE_RELAYER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"accruedNativeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"_library","type":"address"}],"name":"addInboundProofLibraryForChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"appConfig","outputs":[{"internalType":"uint16","name":"inboundProofLibraryVersion","type":"uint16"},{"internalType":"uint64","name":"inboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"uint16","name":"outboundProofType","type":"uint16"},{"internalType":"uint64","name":"outboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"oracle","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainAddressSizeMap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dappRadar","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decommission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decommissioned","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"defaultAdapterParams","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"defaultAppConfig","outputs":[{"internalType":"uint16","name":"inboundProofLibraryVersion","type":"uint16"},{"internalType":"uint64","name":"inboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"uint16","name":"outboundProofType","type":"uint16"},{"internalType":"uint64","name":"outboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"oracle","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint16","name":"_proofType","type":"uint16"}],"name":"enableSupportedOutboundProof","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"address","name":"_ua","type":"address"},{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"bool","name":"_payInZRO","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateFees","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"address","name":"_ua","type":"address"}],"name":"getAppConfig","outputs":[{"components":[{"internalType":"uint16","name":"inboundProofLibraryVersion","type":"uint16"},{"internalType":"uint64","name":"inboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"uint16","name":"outboundProofType","type":"uint16"},{"internalType":"uint64","name":"outboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"oracle","type":"address"}],"internalType":"struct ILayerZeroUltraLightNodeV2.ApplicationConfiguration","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"address","name":"_ua","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"bytes","name":"_path","type":"bytes"}],"name":"getOutboundNonce","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"hashLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"inboundNonceCap","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"inboundProofLibrary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"address","name":"_srcRadarAddress","type":"address"},{"internalType":"uint256","name":"_gasLimitPerCall","type":"uint256"},{"internalType":"uint256","name":"_steps","type":"uint256"}],"name":"incrementRadarInboundNonce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"address","name":"_dstRadarAddress","type":"address"}],"name":"initRadarOutboundNonce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"layerZeroToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"localChainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"maxInboundProofLibrary","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nativeFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonceContract","outputs":[{"internalType":"contract NonceContractRadar","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"outboundNonceSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ua","type":"address"},{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_path","type":"bytes"},{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"send","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"setChainAddressSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"address","name":"_ua","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint16","name":"_proofType","type":"uint16"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"setDefaultAdapterParamsForChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint16","name":"_inboundProofLibraryVersion","type":"uint16"},{"internalType":"uint64","name":"_inboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"_relayer","type":"address"},{"internalType":"uint16","name":"_outboundProofType","type":"uint16"},{"internalType":"uint64","name":"_outboundBlockConfirmations","type":"uint64"},{"internalType":"address","name":"_oracle","type":"address"}],"name":"setDefaultConfigForChainId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_layerZeroToken","type":"address"}],"name":"setLayerZeroToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nonceContractRadar","type":"address"}],"name":"setNonceContractRadar","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes32","name":"_remoteUln","type":"bytes32"}],"name":"setRemoteUln","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"supportedOutboundProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryContract","outputs":[{"internalType":"contract ILayerZeroTreasury","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryZROFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"ulnLookup","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes32","name":"_lookupHash","type":"bytes32"},{"internalType":"uint256","name":"_confirmations","type":"uint256"},{"internalType":"bytes32","name":"_blockData","type":"bytes32"}],"name":"updateHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"address","name":"_dstAddress","type":"address"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"internalType":"bytes32","name":"_lookupHash","type":"bytes32"},{"internalType":"bytes32","name":"_blockData","type":"bytes32"},{"internalType":"bytes","name":"_transactionProof","type":"bytes"}],"name":"validateTransactionProof","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawZRO","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e06040523480156200001157600080fd5b50604051620058b4380380620058b4833981016040819052620000349162000119565b6001600090815562000045620000f8565b600180546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600160a01b038316620000c55760405162461bcd60e51b8152600401620000bc9062000169565b60405180910390fd5b60f09190911b6001600160f01b03191660a052606091821b6001600160601b0319908116608052911b1660c052620001b3565b3390565b80516001600160a01b03811681146200011457600080fd5b919050565b6000806000606084860312156200012e578283fd5b6200013984620000fc565b9250602084015161ffff8116811462000150578283fd5b91506200016060408501620000fc565b90509250925092565b6020808252602a908201527f4c617965725a65726f3a20656e64706f696e742063616e6e6f74206265207a65604082015269726f206164647265737360b01b606082015260800190565b60805160601c60a05160f01c60c05160601c6156806200023460003980610c995280610e1f52806112f45280611edc528061222752806122ce52806128295250806116a15280611b2d5280612ad5525080610b765280610cf35280610dee52806112ac5280611b5152806121f85280612c6252806131fd52506156806000f3fe6080604052600436106102ff5760003560e01c80637f068c0f11610190578063b8e7e3e0116100dc578063eb0d4c3111610095578063f2fde38b1161006f578063f2fde38b146108cd578063f47a5feb146108ed578063f58589a214610902578063f8e1734c14610922576102ff565b8063eb0d4c311461086d578063ed28580a1461088d578063f0f44260146108ad576102ff565b8063b8e7e3e0146107ad578063b9a99bed146107cd578063d543c774146107ed578063db00719b1461080d578063ddfdef5a1461082d578063ea216c211461084d576102ff565b80638da5cb5b11610149578063959f594311610123578063959f59431461072b578063987fa2d51461074b578063a46622221461076b578063b77d22ad14610798576102ff565b80638da5cb5b146106ec578063904d3b8d1461070157806394e17ef914610716576102ff565b80637f068c0f146106425780638140666e146106575780638207f79d1461066c5780638317814a1461068c5780638525b711146106ac57806387078f9f146106cc576102ff565b806352d3b5001161024f5780636a14ac8211610208578063715018a6116101e2578063715018a6146105cd578063759c5b3b146105e25780637728882f146106025780637754537314610622576102ff565b80636a14ac82146105785780636d51012614610598578063704316e5146105ad576102ff565b806352d3b500146104a757806357983548146104c75780635af7956c146104f45780635b056da5146105215780635e280f111461054357806369412bfa14610558576102ff565b80632cfacb06116102bc57806340a7bb101161029657806340a7bb101461043157806349148c371461045f5780634d3a0f7c1461047457806352d2871f14610487576102ff565b80632cfacb06146103c85780632f813464146103ea57806331bd24301461041c576102ff565b806302bd97431461030457806307b18bde1461032f57806307b9ca7c146103515780630fcbae371461036657806318da0011146103865780632a819bbf1461039b575b600080fd5b34801561031057600080fd5b50610319610942565b604051610326919061483b565b60405180910390f35b34801561033b57600080fd5b5061034f61034a36600461401e565b610951565b005b34801561035d57600080fd5b50610319610adb565b34801561037257600080fd5b5061034f6103813660046144b5565b610aea565b34801561039257600080fd5b50610319610e93565b3480156103a757600080fd5b506103bb6103b636600461458e565b610ea2565b60405161032691906148d0565b3480156103d457600080fd5b506103dd610f46565b6040516103269190614872565b3480156103f657600080fd5b5061040a6104053660046142a2565b610f4b565b604051610326969594939291906154bc565b34801561042857600080fd5b506103dd610fa7565b34801561043d57600080fd5b5061045161044c3660046142eb565b610fac565b604051610326929190615504565b34801561046b57600080fd5b506103dd6112a5565b61034f6104823660046140d8565b6112aa565b34801561049357600080fd5b506103bb6104a2366004614395565b61173a565b3480156104b357600080fd5b5061034f6104c2366004614002565b611a29565b3480156104d357600080fd5b506104e76104e2366004614002565b611afb565b6040516103269190615512565b34801561050057600080fd5b5061051461050f3660046142a2565b611b16565b604051610326919061484f565b34801561052d57600080fd5b50610536611b2b565b6040516103269190615315565b34801561054f57600080fd5b50610319611b4f565b34801561056457600080fd5b506103dd610573366004614002565b611b73565b34801561058457600080fd5b5061034f61059336600461460d565b611b92565b3480156105a457600080fd5b50610319611eda565b3480156105b957600080fd5b5061034f6105c8366004614502565b611efe565b3480156105d957600080fd5b5061034f611fc3565b3480156105ee57600080fd5b506103dd6105fd366004614081565b61206f565b34801561060e57600080fd5b5061034f61061d366004614002565b61209b565b34801561062e57600080fd5b5061034f61063d3660046142be565b612148565b34801561064e57600080fd5b5061034f612365565b34801561066357600080fd5b506103dd6123dc565b34801561067857600080fd5b5061034f6106873660046142be565b6123e1565b34801561069857600080fd5b5061034f6106a73660046145ab565b612533565b3480156106b857600080fd5b5061034f6106c73660046140c6565b61260a565b3480156106d857600080fd5b5061034f6106e73660046144e5565b61270c565b3480156106f857600080fd5b506103196127f1565b34801561070d57600080fd5b506103dd612800565b34801561072257600080fd5b50610514612805565b34801561073757600080fd5b506103dd6107463660046142a2565b612815565b34801561075757600080fd5b5061034f6107663660046143d5565b612827565b34801561077757600080fd5b5061078b6107863660046142be565b612cfe565b60405161032691906152ab565b3480156107a457600080fd5b506103dd612d10565b3480156107b957600080fd5b506105366107c83660046142a2565b612d15565b3480156107d957600080fd5b506104e76107e836600461453c565b612d2b565b3480156107f957600080fd5b5061051461080836600461458e565b612db8565b34801561081957600080fd5b5061031961082836600461458e565b612dd8565b34801561083957600080fd5b5061040a610848366004614049565b612dfe565b34801561085957600080fd5b506103dd6108683660046142a2565b612e65565b34801561087957600080fd5b5061034f61088836600461458e565b612e77565b34801561089957600080fd5b5061034f6108a83660046144e5565b612f35565b3480156108b957600080fd5b5061034f6108c8366004614002565b61300e565b3480156108d957600080fd5b5061034f6108e8366004614002565b6130e0565b3480156108f957600080fd5b506103dd6131e3565b34801561090e57600080fd5b506103dd61091d366004614002565b6131e9565b34801561092e57600080fd5b5061034f61093d366004614445565b6131fb565b600f546001600160a01b031681565b600260005414156109a9576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556001600160a01b0382166109dd5760405162461bcd60e51b81526004016109d490614aab565b60405180910390fd5b336000908152600460205260409020546109f790826134c9565b336000908152600460205260408082209290925590516001600160a01b038416908390610a23906147b4565b60006040518083038185875af1925050503d8060008114610a60576040519150601f19603f3d011682016040523d82523d6000602084013e610a65565b606091505b5050905080610a865760405162461bcd60e51b81526004016109d490614a2f565b826001600160a01b0316336001600160a01b03167f3bfd26201736b5cb14a562ab3cfc2bef76901726e3a78483d6288af47131e1d984604051610ac99190614872565b60405180910390a35050600160005550565b6002546001600160a01b031681565b610af2613526565b6001600160a01b0316610b036127f1565b6001600160a01b031614610b4c576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001600160a01b0383166000908152601160205260409020546001600160401b0316610c945760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663fdc07c708686604051602001610bb59190614748565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610be1929190615396565b60206040518083038186803b158015610bf957600080fd5b505afa158015610c0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3191906146d6565b90506000816001600160401b031611610c5c5760405162461bcd60e51b81526004016109d490614fc4565b6001600160a01b0384166000908152601160205260409020805467ffffffffffffffff19166001600160401b03929092169190911790555b6000837f0000000000000000000000000000000000000000000000000000000000000000604051602001610cc9929190614760565b60408051601f1981840301815290829052630fdc07c760e41b825291506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063fdc07c7090610d2a9089908690600401615396565b60206040518083038186803b158015610d4257600080fd5b505afa158015610d56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7a91906146d6565b6001600160a01b0386166000908152601160205260408120549192506001600160401b03909116905b84811015610e89576001909201916001600160401b038083169084161115610dca57610e89565b6040805160208101825260008152905163c2fa481360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163c2fa481391610e4b918c9189917f0000000000000000000000000000000000000000000000000000000000000000918a918e916004016153b3565b600060405180830381600087803b158015610e6557600080fd5b505af1158015610e79573d6000803e3d6000fd5b505060019092019150610da39050565b5050505050505050565b6003546001600160a01b031681565b60086020908152600092835260408084208252918352918190208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015610f3e5780601f10610f1357610100808354040283529160200191610f3e565b820191906000526020600020905b815481529060010190602001808311610f2157829003601f168201915b505050505081565b600381565b6007602052600090815260409020805460019091015461ffff808316926001600160401b036201000082048116936001600160a01b03600160501b8404811694600160f01b9094049093169291811691600160401b9091041686565b600681565b6000806000610fbb8a8a61352a565b9050606084156110045785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293506110b592505050565b61ffff808c166000908152600860209081526040808320606087015190941683529281529082902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156110ad5780601f10611082576101008083540402835291602001916110ad565b820191906000526020600020905b81548152906001019060200180831161109057829003601f168201915b505050505090505b600082604001516001600160a01b031663c03f15298d85606001518e8e8e9050876040518663ffffffff1660e01b81526004016110f695949392919061544a565b60206040518083038186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114691906146a2565b905060008b905060008460a001516001600160a01b0316635553fb8e8f87606001518860800151866040518563ffffffff1660e01b815260040161118d9493929190615487565b60206040518083038186803b1580156111a557600080fd5b505afa1580156111b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111dd91906146a2565b600354604051635cbbbd7560e01b81529192506000916001600160a01b0390911690635cbbbd7590611217908e908890879060040161485a565b60206040518083038186803b15801561122f57600080fd5b505afa158015611243573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126791906146a2565b90508a611277578097508761127c565b809650865b506112918261128b8a876136a2565b906136a2565b975050505050505097509795505050505050565b600281565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146112f25760405162461bcd60e51b81526004016109d4906150c1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168b6001600160a01b0316146113435760405162461bcd60e51b81526004016109d49061518e565b600f54600160a01b900460ff161561136d5760405162461bcd60e51b81526004016109d49061508a565b61ffff89166000908152600e60205260409020548b908a906113a15760405162461bcd60e51b81526004016109d49061497d565b61ffff81166000908152600c60205260408120546060919080158015906113ca5750601481018c145b6113e65760405162461bcd60e51b81526004016109d490615146565b6000808e8e8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505083810160140151925090506001600160a01b03878116908316146114555760405162461bcd60e51b81526004016109d490614d82565b8e8e600090859261146893929190615549565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050600f54604051636fe7b67360e01b81529398506001600160a01b031692636fe7b67392506114d1915089908b908690600401615341565b602060405180830381600087803b1580156114eb57600080fd5b505af11580156114ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152391906146d6565b935050505060008a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093945061156f925087915088905061352a565b905060006115b786838986518d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506136fc92505050565b905060006115c687848a61389f565b905060006115d683838b8f613940565b905060006115e88261128b86866136a2565b90503481111561160a5760405162461bcd60e51b81526004016109d490614a66565b600061161634836134c9565b9050801561169c5760008f6001600160a01b031682604051611637906147b4565b60006040518083038185875af1925050503d8060008114611674576040519150601f19603f3d011682016040523d82523d6000602084013e611679565b606091505b505090508061169a5760405162461bcd60e51b81526004016109d490614b83565b505b6000887f00000000000000000000000000000000000000000000000000000000000000008d8d8d8c6040516020016116d9969594939291906147b7565b60405160208183030381529060405290507fe9bded5f24a4168e4f3bf44e00298c993b22376aad8c58c7dda9718a54cbea828160405161171991906148d0565b60405180910390a15050505050505050505050505050505050505050505050565b6001600160a01b038216600090815260066020908152604080832061ffff87168452909152902060609060018314156117ce57805461ffff166117b85761ffff8086166000908152600760209081526040918290205491516117a193929092169101615315565b604051602081830303815290604052915050611a22565b80546040516117a19161ffff1690602001615315565b60028314156118415780546201000090046001600160401b03166118205761ffff85166000908152600760209081526040918290205491516117a1926201000090046001600160401b03169101615512565b80546040516117a1916201000090046001600160401b031690602001615512565b60038314156118b7578054600160501b90046001600160a01b03166118955761ffff85166000908152600760209081526040918290205491516117a192600160501b90046001600160a01b0316910161483b565b80546040516117a191600160501b90046001600160a01b03169060200161483b565b600483141561191f578054600160f01b900461ffff166119025761ffff8086166000908152600760209081526040918290205491516117a193600160f01b9093049092169101615315565b80546040516117a191600160f01b900461ffff1690602001615315565b60058314156119895760018101546001600160401b031661196b5761ffff85166000908152600760209081526040918290206001015491516117a1926001600160401b03169101615512565b60018101546040516117a1916001600160401b031690602001615512565b6006831415611a08576001810154600160401b90046001600160a01b03166119e35761ffff85166000908152600760209081526040918290206001015491516117a192600160401b90046001600160a01b0316910161483b565b60018101546040516117a191600160401b90046001600160a01b03169060200161483b565b60405162461bcd60e51b81526004016109d4906149f8565b505b9392505050565b611a31613526565b6001600160a01b0316611a426127f1565b6001600160a01b031614611a8b576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001600160a01b038116611ab15760405162461bcd60e51b81526004016109d490614af0565b600280546001600160a01b0319166001600160a01b0383169081179091556040517f33d644987381deff4408951d55afa136f124e22a7810b163b2aaa3ebef770f6490600090a250565b6011602052600090815260409020546001600160401b031681565b60106020526000908152604090205460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001600160a01b0381166000908152600460205260409020545b919050565b611b9a613526565b6001600160a01b0316611bab6127f1565b6001600160a01b031614611bf4576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff8088166000908152600a6020526040902054811690871611801590611c20575060008661ffff16115b611c3c5760405162461bcd60e51b81526004016109d490614ee8565b6000856001600160401b031611611c655760405162461bcd60e51b81526004016109d490615215565b6001600160a01b038416611c8b5760405162461bcd60e51b81526004016109d490614b41565b61ffff8088166000908152600b602090815260408083209387168352929052205460ff16611ccb5760405162461bcd60e51b81526004016109d490614937565b6000826001600160401b031611611cf45760405162461bcd60e51b81526004016109d4906150f8565b6001600160a01b038116611d1a5760405162461bcd60e51b81526004016109d490614c8e565b6040518060c001604052808761ffff168152602001866001600160401b03168152602001856001600160a01b031681526020018461ffff168152602001836001600160401b03168152602001826001600160a01b0316815250600760008961ffff1661ffff16815260200190815260200160002060008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a8154816001600160401b0302191690836001600160401b03160217905550604082015181600001600a6101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600001601e6101000a81548161ffff021916908361ffff16021790555060808201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060a08201518160010160086101000a8154816001600160a01b0302191690836001600160a01b031602179055509050508661ffff167f5a76432853a0871c4e780def7f3ffc7912339b53f022ac31127fe5ff84a36fa1878787878787604051611ec9969594939291906154bc565b60405180910390a250505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b336000908152600d6020908152604080832061ffff8816845282528083208684528252808320848452909152902054828110611f4c5760405162461bcd60e51b81526004016109d490614e48565b336000818152600d6020908152604080832061ffff8a1680855290835281842089855283528184208785529092529182902086905590517f74bbc026808dcba59692d6a8bb20596849ca718e10e2432c6cdf48af865bc5d990611fb49088908790899061487b565b60405180910390a35050505050565b611fcb613526565b6001600160a01b0316611fdc6127f1565b6001600160a01b031614612025576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b600d60209081526000948552604080862082529385528385208152918452828420909152825290205481565b6120a3613526565b6001600160a01b03166120b46127f1565b6001600160a01b0316146120fd576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b600f546001600160a01b0316156121265760405162461bcd60e51b81526004016109d490614c3c565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b612150613526565b6001600160a01b03166121616127f1565b6001600160a01b0316146121aa576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff821660009081526010602052604090205460ff16156121de5760405162461bcd60e51b81526004016109d490614db9565b604051630f428ae960e31b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637a1457489061224f9086907f000000000000000000000000000000000000000000000000000000000000000090600401615324565b60206040518083038186803b15801561226757600080fd5b505afa15801561227b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229f91906146d6565b61ffff84166000908152601060209081526040808320805460ff191660011790555192935090916122f49185917f00000000000000000000000000000000000000000000000000000000000000009101614760565b60408051601f1981840301815290829052600f54631a30ffab60e11b83529092506001600160a01b031690633461ff569061233790879085908790600401615414565b600060405180830381600087803b15801561235157600080fd5b505af1158015610e89573d6000803e3d6000fd5b61236d613526565b6001600160a01b031661237e6127f1565b6001600160a01b0316146123c7576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b600f805460ff60a01b1916600160a01b179055565b600481565b6123e9613526565b6001600160a01b03166123fa6127f1565b6001600160a01b031614612443576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001600160a01b0381166124695760405162461bcd60e51b81526004016109d490614dff565b61ffff8083166000908152600a6020526040902054811690811061249f5760405162461bcd60e51b81526004016109d490615048565b61ffff8381166000818152600a60209081526040808320805461ffff191660019790970195861696871790556009825280832095835294905283902080546001600160a01b0319166001600160a01b03861617905591519091907f802d55279d51813cb7a9a98e8fd2d7bec5346cb830901c11b85d1650cb857e9a9061252690859061483b565b60405180910390a2505050565b61253b613526565b6001600160a01b031661254c6127f1565b6001600160a01b031614612595576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff80851660009081526008602090815260408083209387168352929052206125c0908383613e0b565b508261ffff168461ffff167f4a5695eee2a74d548d5f5c485a3de99ace99e3b664c8e30a90f49be6ebb5493284846040516125fc9291906148bc565b60405180910390a350505050565b60026000541415612662576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556003546001600160a01b031633146126915760405162461bcd60e51b81526004016109d4906149c1565b60055461269e90826134c9565b6005556002546126b8906001600160a01b03168383613a91565b816001600160a01b0316336001600160a01b03167f3a20c8c3cd1848485ae8261a52398bb9b26f195b717306b3cf7f058e62c095d5836040516126fb9190614872565b60405180910390a350506001600055565b612714613526565b6001600160a01b03166127256127f1565b6001600160a01b03161461276e576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff82166000908152600c60205260409020541561279f5760405162461bcd60e51b81526004016109d4906151c5565b61ffff82166000818152600c602052604090819020839055517f0611bb2107e385b79ec826fff8ecc1c1248a7aae3c875c96668f8cfbf1734220906127e5908490614872565b60405180910390a25050565b6001546001600160a01b031690565b600581565b600f54600160a01b900460ff1681565b600c6020526000908152604090205481565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b0316146128785760405162461bcd60e51b81526004016109d49061518e565b600f54600160a01b900460ff16156128a25760405162461bcd60e51b81526004016109d49061508a565b60006128ae888861352a565b60408101519091506001600160a01b031633146128dd5760405162461bcd60e51b81526004016109d490614d4b565b6128e5613e97565b61ffff89166000908152600c6020526040902054806129165760405162461bcd60e51b81526004016109d490615146565b60a08301516001600160a01b03166000908152600d6020908152604080832061ffff8e16845282528083208a84528252808320898452909152902054801580159061296e575083602001516001600160401b03168110155b61298a5760405162461bcd60e51b81526004016109d490615262565b61ffff808c1660009081526009602090815260408083208851909416835292905281902054905163b71e0f7160e01b81526001600160a01b0390911690819063b71e0f71906129e3908b908b908b908990600401614891565b600060405180830381600087803b1580156129fd57600080fd5b505af1158015612a11573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a3991908101906141c7565b60a081015161ffff8e166000908152600e6020526040902054919550149150508015612a68575060a082015115155b612a845760405162461bcd60e51b81526004016109d490614ccf565b8961ffff16826000015161ffff1614612aaf5760405162461bcd60e51b81526004016109d490614d14565b8082608001515114612ad35760405162461bcd60e51b81526004016109d490614f38565b7f000000000000000000000000000000000000000000000000000000000000000061ffff16826020015161ffff1614612b1e5760405162461bcd60e51b81526004016109d490614eb1565b886001600160a01b031682606001516001600160a01b031614612b535760405162461bcd60e51b81526004016109d490614c05565b612b5c89613ae8565b612bcd5781606001516001600160a01b0316826000015161ffff167fa2786598bd84ae4a299103996359e6cb4333404583256079dfc279386baf5832846080015185604001518660c0015180519060200120604051612bbd93929190614909565b60405180910390a3505050612cf5565b600082608001518360600151604051602001612bea929190614782565b604051602081830303815290604052905082606001516001600160a01b0316836000015161ffff167f2bd2d8a84b748439fd50d79a49502b4eb5faa25b864da6a9ab5c150704be9a4d856080015186604001518760c0015180519060200120604051612c5893929190614909565b60405180910390a37f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c2fa48138c838d87604001518e8960c001516040518763ffffffff1660e01b8152600401612cbe969594939291906153b3565b600060405180830381600087803b158015612cd857600080fd5b505af1158015612cec573d6000803e3d6000fd5b50505050505050505b50505050505050565b612d06613ed5565b611a22838361352a565b600181565b600a6020526000908152604090205461ffff1681565b600f5460405163c533338f60e01b81526000916001600160a01b03169063c533338f90612d6090879087908790600401615378565b60206040518083038186803b158015612d7857600080fd5b505afa158015612d8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612db091906146d6565b949350505050565b600b60209081526000928352604080842090915290825290205460ff1681565b60096020908152600092835260408084209091529082529020546001600160a01b031681565b60066020908152600092835260408084209091529082529020805460019091015461ffff808316926001600160401b036201000082048116936001600160a01b03600160501b8404811694600160f01b9094049093169291811691600160401b9091041686565b600e6020526000908152604090205481565b612e7f613526565b6001600160a01b0316612e906127f1565b6001600160a01b031614612ed9576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff8083166000818152600b602090815260408083209486168352939052829020805460ff1916600117905590517fec23bee6f88cfecebb09d6aaaed66f0ce110debc1f61117c8270a7116597df9a906127e5908490615315565b612f3d613526565b6001600160a01b0316612f4e6127f1565b6001600160a01b031614612f97576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff82166000908152600e602052604090205415612fc85760405162461bcd60e51b81526004016109d490615007565b61ffff82166000818152600e602052604090819020839055517f0dad975e1d2fbe771c95cdcc7be9a1e61181de7173abe0a32b8f8f83140873e5906127e5908490614872565b613016613526565b6001600160a01b03166130276127f1565b6001600160a01b031614613070576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001600160a01b0381166130965760405162461bcd60e51b81526004016109d490614f7a565b600380546001600160a01b0319166001600160a01b0383169081179091556040517fcb7ef3e545f5cdb893f5c568ba710fe08f336375a2d9fd66e161033f8fc09ef390600090a250565b6130e8613526565b6001600160a01b03166130f96127f1565b6001600160a01b031614613142576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001600160a01b0381166131875760405162461bcd60e51b81526004018080602001828103825260268152602001806155db6026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b60055481565b60046020526000908152604090205481565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146132435760405162461bcd60e51b81526004016109d4906150c1565b6001600160a01b038416600090815260066020908152604080832061ffff89168452909152902060018414156132d3576000613281838501856142a2565b61ffff8089166000908152600a602052604090205491925090811690821611156132bd5760405162461bcd60e51b81526004016109d490614ee8565b815461ffff191661ffff9190911617815561347d565b60028414156133145760006132ea838501856146ba565b82546001600160401b03909116620100000269ffffffffffffffff0000199091161782555061347d565b600384141561336b57600061332b83850185614002565b82546001600160a01b03909116600160501b027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9091161782555061347d565b60048414156133f3576000613382838501856142a2565b61ffff8089166000908152600b602090815260408083209385168352929052205490915060ff16806133b6575061ffff8116155b6133d25760405162461bcd60e51b81526004016109d490614937565b815461ffff909116600160f01b026001600160f01b0390911617815561347d565b600584141561343357600061340a838501856146ba565b60018301805467ffffffffffffffff19166001600160401b03929092169190911790555061347d565b6006841415611a0857600061344a83850185614002565b6001830180546001600160a01b03909216600160401b0268010000000000000000600160e01b0319909216919091179055505b83856001600160a01b03167ffc01bf86212a14151d51d1be5c2ac64d67d5ec823dfc6f53298d7ce3f3d3d25285856040516134b99291906148bc565b60405180910390a3505050505050565b600082821115613520576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b3390565b613532613ed5565b6001600160a01b03808316600090815260066020908152604080832061ffff808916808652918452828520835160c081018552815480841682526001600160401b03620100008204811683890152600160501b82048a1683880152600160f01b909104841660608301526001909201549182166080820152600160401b90910490961660a0870152908452600790925290912082519091166135d757805461ffff1682525b60208201516001600160401b03166136005780546201000090046001600160401b031660208301525b60408201516001600160a01b031661362a578054600160501b90046001600160a01b031660408301525b606082015161ffff1661364a578054600160f01b900461ffff1660608301525b60808201516001600160401b03166136705760018101546001600160401b031660808301525b60a08201516001600160a01b0316611a205760010154600160401b90046001600160a01b031660a08201529392505050565b600082820183811015611a22576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008151600014156137b95761ffff808716600090815260086020908152604080832060608a015190941683529281529082902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156137b15780601f10613786576101008083540402835291602001916137b1565b820191906000526020600020905b81548152906001019060200180831161379457829003601f168201915b505050505091505b60408086015160608701519151635886ea6560e01b8152909182916001600160a01b03831691635886ea65916137f9918c918b908b908b9060040161544a565b602060405180830381600087803b15801561381357600080fd5b505af1158015613827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061384b91906146a2565b92506138578284613aee565b7fb0c632f55f1e1b3b2c3d82f41ee4716bb4c00f0f5d84cdafc141581bb8757a4f84886060015160405161388c9291906148e3565b60405180910390a1505095945050505050565b60a08201516060830151608084015160405163c5e193cd60e01b8152600093926001600160a01b0384169263c5e193cd926138e2928a9290918990600401615487565b602060405180830381600087803b1580156138fc57600080fd5b505af1158015613910573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061393491906146a2565b9150611a208183613aee565b6000806001600160a01b038316158061396257506002546001600160a01b0316155b600354604051635cbbbd7560e01b81529192506000916001600160a01b0390911690635cbbbd759061399d908515908b908b9060040161485a565b60206040518083038186803b1580156139b557600080fd5b505afa1580156139c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ed91906146a2565b90508015613a87578115613a1a576003546001600160a01b0316613a118183613aee565b81935050613a87565b846001600160a01b0316846001600160a01b03161480613a4257506001600160a01b03841632145b613a5e5760405162461bcd60e51b81526004016109d490614bba565b600254613a76906001600160a01b0316853084613b31565b600554613a8390826136a2565b6005555b5050949350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613ae3908490613b91565b505050565b3b151590565b6001600160a01b038216600090815260046020526040902054613b1190826136a2565b6001600160a01b0390921660009081526004602052604090209190915550565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052613b8b908590613b91565b50505050565b6000613be6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613c429092919063ffffffff16565b805190915015613ae357808060200190516020811015613c0557600080fd5b5051613ae35760405162461bcd60e51b815260040180806020018281038252602a815260200180615621602a913960400191505060405180910390fd5b6060612db0848460008585613c5685613ae8565b613ca7576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b60208310613ce55780518252601f199092019160209182019101613cc6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613d47576040519150601f19603f3d011682016040523d82523d6000602084013e613d4c565b606091505b5091509150613d5c828286613d67565b979650505050505050565b60608315613d76575081611a22565b825115613d865782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613dd0578181015183820152602001613db8565b50505050905090810190601f168015613dfd5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282613e415760008555613e87565b82601f10613e5a5782800160ff19823516178555613e87565b82800160010185558215613e87579182015b82811115613e87578235825591602001919060010190613e6c565b50613e93929150613f0a565b5090565b6040805160e08101825260008082526020820181905291810182905260608082018390526080820181905260a082019290925260c081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b5b80821115613e935760008155600101613f0b565b8035611b8d8161559d565b8051611b8d8161559d565b60008083601f840112613f46578182fd5b5081356001600160401b03811115613f5c578182fd5b602083019150836020828501011115613f7457600080fd5b9250929050565b600082601f830112613f8b578081fd5b81516001600160401b03811115613f9e57fe5b613fb1601f8201601f1916602001615526565b818152846020838601011115613fc5578283fd5b612db0826020830160208701615571565b8035611b8d816155b5565b8051611b8d816155b5565b8035611b8d816155c5565b8051611b8d816155c5565b600060208284031215614013578081fd5b8135611a228161559d565b60008060408385031215614030578081fd5b823561403b8161559d565b946020939093013593505050565b6000806040838503121561405b578182fd5b82356140668161559d565b91506020830135614076816155b5565b809150509250929050565b60008060008060808587031215614096578182fd5b84356140a18161559d565b935060208501356140b1816155b5565b93969395505050506040820135916060013590565b60008060408385031215614030578182fd5b60008060008060008060008060008060006101008c8e0312156140f9578687fd5b6141028c613f1f565b9a5061411060208d01613fec565b995061411e60408d01613fd6565b98506001600160401b038060608e01351115614138578788fd5b6141488e60608f01358f01613f35565b909950975060808d013581101561415d578687fd5b61416d8e60808f01358f01613f35565b909750955061417e60a08e01613f1f565b945061418c60c08e01613f1f565b93508060e08e0135111561419e578283fd5b506141af8d60e08e01358e01613f35565b81935080925050509295989b509295989b9093969950565b6000602082840312156141d8578081fd5b81516001600160401b03808211156141ee578283fd5b9083019060e08286031215614201578283fd5b61420b60e0615526565b61421483613fe1565b815261422260208401613fe1565b602082015261423360408401613ff7565b604082015261424460608401613f2a565b606082015260808301518281111561425a578485fd5b61426687828601613f7b565b60808301525060a083015160a082015260c083015182811115614287578485fd5b61429387828601613f7b565b60c08301525095945050505050565b6000602082840312156142b3578081fd5b8135611a22816155b5565b600080604083850312156142d0578182fd5b82356142db816155b5565b915060208301356140768161559d565b600080600080600080600060a0888a031215614305578081fd5b8735614310816155b5565b965060208801356143208161559d565b955060408801356001600160401b038082111561433b578283fd5b6143478b838c01613f35565b909750955060608a013591508115158214614360578283fd5b90935060808901359080821115614375578283fd5b506143828a828b01613f35565b989b979a50959850939692959293505050565b6000806000606084860312156143a9578081fd5b83356143b4816155b5565b925060208401356143c48161559d565b929592945050506040919091013590565b600080600080600080600060c0888a0312156143ef578081fd5b87356143fa816155b5565b9650602088013561440a8161559d565b955060408801359450606088013593506080880135925060a08801356001600160401b03811115614439578182fd5b6143828a828b01613f35565b60008060008060006080868803121561445c578283fd5b8535614467816155b5565b945060208601356144778161559d565b93506040860135925060608601356001600160401b03811115614498578182fd5b6144a488828901613f35565b969995985093965092949392505050565b600080600080608085870312156144ca578182fd5b84356144d5816155b5565b935060208501356140b18161559d565b600080604083850312156144f7578182fd5b823561403b816155b5565b60008060008060808587031215614517578182fd5b8435614522816155b5565b966020860135965060408601359560600135945092505050565b600080600060408486031215614550578081fd5b833561455b816155b5565b925060208401356001600160401b03811115614575578182fd5b61458186828701613f35565b9497909650939450505050565b600080604083850312156145a0578182fd5b8235614066816155b5565b600080600080606085870312156145c0578182fd5b84356145cb816155b5565b935060208501356145db816155b5565b925060408501356001600160401b038111156145f5578283fd5b61460187828801613f35565b95989497509550505050565b600080600080600080600060e0888a031215614627578081fd5b8735614632816155b5565b96506020880135614642816155b5565b95506040880135614652816155c5565b945060608801356146628161559d565b93506080880135614672816155b5565b925060a0880135614682816155c5565b915060c08801356146928161559d565b8091505092959891949750929550565b6000602082840312156146b3578081fd5b5051919050565b6000602082840312156146cb578081fd5b8135611a22816155c5565b6000602082840312156146e7578081fd5b8151611a22816155c5565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452614734816020860160208601615571565b601f01601f19169290920160200192915050565b60609190911b6001600160601b031916815260140190565b6001600160601b0319606093841b811682529190921b16601482015260280190565b60008351614794818460208801615571565b60609390931b6001600160601b0319169190920190815260140192915050565b90565b60006001600160401b0360c01b8860c01b16825261ffff60f01b808860f01b1660088401526bffffffffffffffffffffffff198760601b16600a840152808660f01b16601e840152508351614813816020850160208801615571565b8083019050835161482b816020840160208801615571565b0160200198975050505050505050565b6001600160a01b0391909116815260200190565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526020830191909152604082015260600190565b6000858252606060208301526148ab6060830185876146f2565b905082604083015295945050505050565b600060208252612db06020830184866146f2565b600060208252611a22602083018461471c565b6000604082526148f6604083018561471c565b905061ffff831660208301529392505050565b60006060825261491c606083018661471c565b6001600160401b039490941660208301525060400152919050565b60208082526026908201527f4c617965725a65726f3a20696e76616c6964206f7574626f756e642070726f6f60408201526566207479706560d01b606082015260800190565b60208082526024908201527f4c617965725a65726f3a20647374436861696e496420646f6573206e6f7420656040820152631e1a5cdd60e21b606082015260800190565b60208082526018908201527f4c617965725a65726f3a206f6e6c792074726561737572790000000000000000604082015260600190565b6020808252601e908201527f4c617965725a65726f3a20496e76616c696420636f6e66696720747970650000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a207769746864726177206661696c6564000000000000604082015260600190565b60208082526025908201527f4c617965725a65726f3a206e6f7420656e6f756768206e617469766520666f72604082015264206665657360d81b606082015260800190565b60208082526025908201527f4c617965725a65726f3a205f746f2063616e6e6f74206265207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526031908201527f4c617965725a65726f3a205f6c617965725a65726f546f6b656e2063616e6e6f60408201527074206265207a65726f206164647265737360781b606082015260800190565b60208082526022908201527f4c617965725a65726f3a20696e76616c69642072656c61796572206164647265604082015261737360f01b606082015260800190565b6020808252601b908201527f4c617965725a65726f3a206661696c656420746f20726566756e640000000000604082015260600190565b6020808252602b908201527f4c617965725a65726f3a206d75737420626520706169642062792073656e646560408201526a391037b91037b934b3b4b760a91b606082015260800190565b6020808252601d908201527f4c617965725a65726f3a20696e76616c69642064737441646472657373000000604082015260600190565b60208082526032908201527f4c617965725a65726f3a206e6f6e6365436f6e747261637452616461722063616040820152716e206f6e6c7920626520736574206f6e636560701b606082015260800190565b60208082526021908201527f4c617965725a65726f3a20696e76616c6964206f7261636c65206164647265736040820152607360f81b606082015260800190565b60208082526025908201527f4c617965725a65726f3a20696e76616c6964205f7061636b65742e756c6e4164604082015264647265737360d81b606082015260800190565b6020808252601e908201527f4c617965725a65726f3a20696e76616c696420737263436861696e2049640000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a20696e76616c69642072656c61796572000000000000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a2077726f6e6720706174682064617461000000000000604082015260600190565b60208082526026908201527f4c617965725a65726f3a20646170705261646172206e6f6e636520616c726561604082015265191e481cd95d60d21b606082015260800190565b60208082526029908201527f4c617965725a65726f3a206c6962726172792063616e6e6f74206265207a65726040820152686f206164647265737360b81b606082015260800190565b60208082526043908201527f4c617965725a65726f3a206f7261636c6520646174612063616e206f6e6c792060408201527f75706461746520696620697420686173206d6f726520636f6e6669726d6174696060820152626f6e7360e81b608082015260a00190565b6020808252601e908201527f4c617965725a65726f3a20696e76616c696420647374436861696e2049640000604082015260600190565b60208082526030908201527f4c617965725a65726f3a20696e76616c696420696e626f756e642070726f6f6660408201526f103634b13930b93c903b32b939b4b7b760811b606082015260800190565b60208082526022908201527f4c617965725a65726f3a20696e76616c696420737263416464726573732073696040820152617a6560f01b606082015260800190565b6020808252602a908201527f4c617965725a65726f3a2074726561737572792063616e6e6f74206265207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526023908201527f4c617965725a65726f3a206e6f74206c6567616379207261646172206164647260408201526265737360e81b606082015260800190565b60208082526021908201527f4c617965725a65726f3a2072656d6f746520756c6e20616c72656164792073656040820152601d60fa1b606082015260800190565b60208082526022908201527f4c617965725a65726f3a2063616e206e6f7420616464206e6577206c69627261604082015261727960f01b606082015260800190565b60208082526019908201527f4c617965725a65726f3a206465636f6d6d697373696f6e656400000000000000604082015260600190565b60208082526018908201527f4c617965725a65726f3a206f6e6c7920656e64706f696e740000000000000000604082015260600190565b6020808252602e908201527f4c617965725a65726f3a20696e76616c6964206f7574626f756e6420626c6f6360408201526d359031b7b73334b936b0ba34b7b760911b606082015260800190565b60208082526028908201527f4c617965725a65726f3a20696e636f72726563742072656d6f746520616464726040820152676573732073697a6560c01b606082015260800190565b60208082526019908201527f4c617965725a65726f3a206f6e6c792064617070526164617200000000000000604082015260600190565b60208082526030908201527f4c617965725a65726f3a2072656d6f746520636861696e20616464726573732060408201526f1cda5e9948185b1c9958591e481cd95d60821b606082015260800190565b6020808252602d908201527f4c617965725a65726f3a20696e76616c696420696e626f756e6420626c6f636b60408201526c1031b7b73334b936b0ba34b7b760991b606082015260800190565b60208082526029908201527f4c617965725a65726f3a206e6f7420656e6f75676820626c6f636b20636f6e6660408201526869726d6174696f6e7360b81b606082015260800190565b600060c08201905061ffff80845116835260208401516001600160401b0380821660208601526040860151915060018060a01b0380831660408701528360608801511660608701528160808801511660808701528060a08801511660a08701525050505092915050565b61ffff91909116815260200190565b61ffff9290921682526001600160a01b0316602082015260400190565b61ffff841681526001600160a01b038316602082015260606040820181905260009061536f9083018461471c565b95945050505050565b600061ffff851682526040602083015261536f6040830184866146f2565b600061ffff8416825260406020830152612db0604083018461471c565b600061ffff8816825260c060208301526153d060c083018861471c565b6001600160a01b03871660408401526001600160401b03861660608401526080830185905282810360a0840152615407818561471c565b9998505050505050505050565b600061ffff8516825260606020830152615431606083018561471c565b90506001600160401b0383166040830152949350505050565b61ffff8681168252851660208201526001600160a01b03841660408201526060810183905260a060808201819052600090613d5c9083018461471c565b61ffff94851681529290931660208301526001600160401b031660408201526001600160a01b03909116606082015260800190565b61ffff96871681526001600160401b0395861660208201526001600160a01b03948516604082015292909516606083015290921660808301529190911660a082015260c00190565b918252602082015260400190565b6001600160401b0391909116815260200190565b6040518181016001600160401b038111828210171561554157fe5b604052919050565b60008085851115615558578182fd5b83861115615564578182fd5b5050820193919092039150565b60005b8381101561558c578181015183820152602001615574565b83811115613b8b5750506000910152565b6001600160a01b03811681146155b257600080fd5b50565b61ffff811681146155b257600080fd5b6001600160401b03811681146155b257600080fdfe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220a1d60004ed519b486657de8dfd367da434e640dceb118d064a98219dba3429be64736f6c6343000706003300000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6750000000000000000000000000000000000000000000000000000000000000001000000000000000000000000962b4d8b1f8940d6a67399dc3a8d7549250888b8
Deployed Bytecode
0x6080604052600436106102ff5760003560e01c80637f068c0f11610190578063b8e7e3e0116100dc578063eb0d4c3111610095578063f2fde38b1161006f578063f2fde38b146108cd578063f47a5feb146108ed578063f58589a214610902578063f8e1734c14610922576102ff565b8063eb0d4c311461086d578063ed28580a1461088d578063f0f44260146108ad576102ff565b8063b8e7e3e0146107ad578063b9a99bed146107cd578063d543c774146107ed578063db00719b1461080d578063ddfdef5a1461082d578063ea216c211461084d576102ff565b80638da5cb5b11610149578063959f594311610123578063959f59431461072b578063987fa2d51461074b578063a46622221461076b578063b77d22ad14610798576102ff565b80638da5cb5b146106ec578063904d3b8d1461070157806394e17ef914610716576102ff565b80637f068c0f146106425780638140666e146106575780638207f79d1461066c5780638317814a1461068c5780638525b711146106ac57806387078f9f146106cc576102ff565b806352d3b5001161024f5780636a14ac8211610208578063715018a6116101e2578063715018a6146105cd578063759c5b3b146105e25780637728882f146106025780637754537314610622576102ff565b80636a14ac82146105785780636d51012614610598578063704316e5146105ad576102ff565b806352d3b500146104a757806357983548146104c75780635af7956c146104f45780635b056da5146105215780635e280f111461054357806369412bfa14610558576102ff565b80632cfacb06116102bc57806340a7bb101161029657806340a7bb101461043157806349148c371461045f5780634d3a0f7c1461047457806352d2871f14610487576102ff565b80632cfacb06146103c85780632f813464146103ea57806331bd24301461041c576102ff565b806302bd97431461030457806307b18bde1461032f57806307b9ca7c146103515780630fcbae371461036657806318da0011146103865780632a819bbf1461039b575b600080fd5b34801561031057600080fd5b50610319610942565b604051610326919061483b565b60405180910390f35b34801561033b57600080fd5b5061034f61034a36600461401e565b610951565b005b34801561035d57600080fd5b50610319610adb565b34801561037257600080fd5b5061034f6103813660046144b5565b610aea565b34801561039257600080fd5b50610319610e93565b3480156103a757600080fd5b506103bb6103b636600461458e565b610ea2565b60405161032691906148d0565b3480156103d457600080fd5b506103dd610f46565b6040516103269190614872565b3480156103f657600080fd5b5061040a6104053660046142a2565b610f4b565b604051610326969594939291906154bc565b34801561042857600080fd5b506103dd610fa7565b34801561043d57600080fd5b5061045161044c3660046142eb565b610fac565b604051610326929190615504565b34801561046b57600080fd5b506103dd6112a5565b61034f6104823660046140d8565b6112aa565b34801561049357600080fd5b506103bb6104a2366004614395565b61173a565b3480156104b357600080fd5b5061034f6104c2366004614002565b611a29565b3480156104d357600080fd5b506104e76104e2366004614002565b611afb565b6040516103269190615512565b34801561050057600080fd5b5061051461050f3660046142a2565b611b16565b604051610326919061484f565b34801561052d57600080fd5b50610536611b2b565b6040516103269190615315565b34801561054f57600080fd5b50610319611b4f565b34801561056457600080fd5b506103dd610573366004614002565b611b73565b34801561058457600080fd5b5061034f61059336600461460d565b611b92565b3480156105a457600080fd5b50610319611eda565b3480156105b957600080fd5b5061034f6105c8366004614502565b611efe565b3480156105d957600080fd5b5061034f611fc3565b3480156105ee57600080fd5b506103dd6105fd366004614081565b61206f565b34801561060e57600080fd5b5061034f61061d366004614002565b61209b565b34801561062e57600080fd5b5061034f61063d3660046142be565b612148565b34801561064e57600080fd5b5061034f612365565b34801561066357600080fd5b506103dd6123dc565b34801561067857600080fd5b5061034f6106873660046142be565b6123e1565b34801561069857600080fd5b5061034f6106a73660046145ab565b612533565b3480156106b857600080fd5b5061034f6106c73660046140c6565b61260a565b3480156106d857600080fd5b5061034f6106e73660046144e5565b61270c565b3480156106f857600080fd5b506103196127f1565b34801561070d57600080fd5b506103dd612800565b34801561072257600080fd5b50610514612805565b34801561073757600080fd5b506103dd6107463660046142a2565b612815565b34801561075757600080fd5b5061034f6107663660046143d5565b612827565b34801561077757600080fd5b5061078b6107863660046142be565b612cfe565b60405161032691906152ab565b3480156107a457600080fd5b506103dd612d10565b3480156107b957600080fd5b506105366107c83660046142a2565b612d15565b3480156107d957600080fd5b506104e76107e836600461453c565b612d2b565b3480156107f957600080fd5b5061051461080836600461458e565b612db8565b34801561081957600080fd5b5061031961082836600461458e565b612dd8565b34801561083957600080fd5b5061040a610848366004614049565b612dfe565b34801561085957600080fd5b506103dd6108683660046142a2565b612e65565b34801561087957600080fd5b5061034f61088836600461458e565b612e77565b34801561089957600080fd5b5061034f6108a83660046144e5565b612f35565b3480156108b957600080fd5b5061034f6108c8366004614002565b61300e565b3480156108d957600080fd5b5061034f6108e8366004614002565b6130e0565b3480156108f957600080fd5b506103dd6131e3565b34801561090e57600080fd5b506103dd61091d366004614002565b6131e9565b34801561092e57600080fd5b5061034f61093d366004614445565b6131fb565b600f546001600160a01b031681565b600260005414156109a9576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556001600160a01b0382166109dd5760405162461bcd60e51b81526004016109d490614aab565b60405180910390fd5b336000908152600460205260409020546109f790826134c9565b336000908152600460205260408082209290925590516001600160a01b038416908390610a23906147b4565b60006040518083038185875af1925050503d8060008114610a60576040519150601f19603f3d011682016040523d82523d6000602084013e610a65565b606091505b5050905080610a865760405162461bcd60e51b81526004016109d490614a2f565b826001600160a01b0316336001600160a01b03167f3bfd26201736b5cb14a562ab3cfc2bef76901726e3a78483d6288af47131e1d984604051610ac99190614872565b60405180910390a35050600160005550565b6002546001600160a01b031681565b610af2613526565b6001600160a01b0316610b036127f1565b6001600160a01b031614610b4c576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001600160a01b0383166000908152601160205260409020546001600160401b0316610c945760007f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b031663fdc07c708686604051602001610bb59190614748565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610be1929190615396565b60206040518083038186803b158015610bf957600080fd5b505afa158015610c0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3191906146d6565b90506000816001600160401b031611610c5c5760405162461bcd60e51b81526004016109d490614fc4565b6001600160a01b0384166000908152601160205260409020805467ffffffffffffffff19166001600160401b03929092169190911790555b6000837f000000000000000000000000962b4d8b1f8940d6a67399dc3a8d7549250888b8604051602001610cc9929190614760565b60408051601f1981840301815290829052630fdc07c760e41b825291506000906001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675169063fdc07c7090610d2a9089908690600401615396565b60206040518083038186803b158015610d4257600080fd5b505afa158015610d56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7a91906146d6565b6001600160a01b0386166000908152601160205260408120549192506001600160401b03909116905b84811015610e89576001909201916001600160401b038083169084161115610dca57610e89565b6040805160208101825260008152905163c2fa481360e01b81526001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675169163c2fa481391610e4b918c9189917f000000000000000000000000962b4d8b1f8940d6a67399dc3a8d7549250888b8918a918e916004016153b3565b600060405180830381600087803b158015610e6557600080fd5b505af1158015610e79573d6000803e3d6000fd5b505060019092019150610da39050565b5050505050505050565b6003546001600160a01b031681565b60086020908152600092835260408084208252918352918190208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015610f3e5780601f10610f1357610100808354040283529160200191610f3e565b820191906000526020600020905b815481529060010190602001808311610f2157829003601f168201915b505050505081565b600381565b6007602052600090815260409020805460019091015461ffff808316926001600160401b036201000082048116936001600160a01b03600160501b8404811694600160f01b9094049093169291811691600160401b9091041686565b600681565b6000806000610fbb8a8a61352a565b9050606084156110045785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293506110b592505050565b61ffff808c166000908152600860209081526040808320606087015190941683529281529082902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156110ad5780601f10611082576101008083540402835291602001916110ad565b820191906000526020600020905b81548152906001019060200180831161109057829003601f168201915b505050505090505b600082604001516001600160a01b031663c03f15298d85606001518e8e8e9050876040518663ffffffff1660e01b81526004016110f695949392919061544a565b60206040518083038186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114691906146a2565b905060008b905060008460a001516001600160a01b0316635553fb8e8f87606001518860800151866040518563ffffffff1660e01b815260040161118d9493929190615487565b60206040518083038186803b1580156111a557600080fd5b505afa1580156111b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111dd91906146a2565b600354604051635cbbbd7560e01b81529192506000916001600160a01b0390911690635cbbbd7590611217908e908890879060040161485a565b60206040518083038186803b15801561122f57600080fd5b505afa158015611243573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126791906146a2565b90508a611277578097508761127c565b809650865b506112918261128b8a876136a2565b906136a2565b975050505050505097509795505050505050565b600281565b7f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b031633146112f25760405162461bcd60e51b81526004016109d4906150c1565b7f000000000000000000000000962b4d8b1f8940d6a67399dc3a8d7549250888b86001600160a01b03168b6001600160a01b0316146113435760405162461bcd60e51b81526004016109d49061518e565b600f54600160a01b900460ff161561136d5760405162461bcd60e51b81526004016109d49061508a565b61ffff89166000908152600e60205260409020548b908a906113a15760405162461bcd60e51b81526004016109d49061497d565b61ffff81166000908152600c60205260408120546060919080158015906113ca5750601481018c145b6113e65760405162461bcd60e51b81526004016109d490615146565b6000808e8e8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505083810160140151925090506001600160a01b03878116908316146114555760405162461bcd60e51b81526004016109d490614d82565b8e8e600090859261146893929190615549565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050600f54604051636fe7b67360e01b81529398506001600160a01b031692636fe7b67392506114d1915089908b908690600401615341565b602060405180830381600087803b1580156114eb57600080fd5b505af11580156114ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152391906146d6565b935050505060008a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093945061156f925087915088905061352a565b905060006115b786838986518d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506136fc92505050565b905060006115c687848a61389f565b905060006115d683838b8f613940565b905060006115e88261128b86866136a2565b90503481111561160a5760405162461bcd60e51b81526004016109d490614a66565b600061161634836134c9565b9050801561169c5760008f6001600160a01b031682604051611637906147b4565b60006040518083038185875af1925050503d8060008114611674576040519150601f19603f3d011682016040523d82523d6000602084013e611679565b606091505b505090508061169a5760405162461bcd60e51b81526004016109d490614b83565b505b6000887f00000000000000000000000000000000000000000000000000000000000000018d8d8d8c6040516020016116d9969594939291906147b7565b60405160208183030381529060405290507fe9bded5f24a4168e4f3bf44e00298c993b22376aad8c58c7dda9718a54cbea828160405161171991906148d0565b60405180910390a15050505050505050505050505050505050505050505050565b6001600160a01b038216600090815260066020908152604080832061ffff87168452909152902060609060018314156117ce57805461ffff166117b85761ffff8086166000908152600760209081526040918290205491516117a193929092169101615315565b604051602081830303815290604052915050611a22565b80546040516117a19161ffff1690602001615315565b60028314156118415780546201000090046001600160401b03166118205761ffff85166000908152600760209081526040918290205491516117a1926201000090046001600160401b03169101615512565b80546040516117a1916201000090046001600160401b031690602001615512565b60038314156118b7578054600160501b90046001600160a01b03166118955761ffff85166000908152600760209081526040918290205491516117a192600160501b90046001600160a01b0316910161483b565b80546040516117a191600160501b90046001600160a01b03169060200161483b565b600483141561191f578054600160f01b900461ffff166119025761ffff8086166000908152600760209081526040918290205491516117a193600160f01b9093049092169101615315565b80546040516117a191600160f01b900461ffff1690602001615315565b60058314156119895760018101546001600160401b031661196b5761ffff85166000908152600760209081526040918290206001015491516117a1926001600160401b03169101615512565b60018101546040516117a1916001600160401b031690602001615512565b6006831415611a08576001810154600160401b90046001600160a01b03166119e35761ffff85166000908152600760209081526040918290206001015491516117a192600160401b90046001600160a01b0316910161483b565b60018101546040516117a191600160401b90046001600160a01b03169060200161483b565b60405162461bcd60e51b81526004016109d4906149f8565b505b9392505050565b611a31613526565b6001600160a01b0316611a426127f1565b6001600160a01b031614611a8b576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001600160a01b038116611ab15760405162461bcd60e51b81526004016109d490614af0565b600280546001600160a01b0319166001600160a01b0383169081179091556040517f33d644987381deff4408951d55afa136f124e22a7810b163b2aaa3ebef770f6490600090a250565b6011602052600090815260409020546001600160401b031681565b60106020526000908152604090205460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000181565b7f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67581565b6001600160a01b0381166000908152600460205260409020545b919050565b611b9a613526565b6001600160a01b0316611bab6127f1565b6001600160a01b031614611bf4576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff8088166000908152600a6020526040902054811690871611801590611c20575060008661ffff16115b611c3c5760405162461bcd60e51b81526004016109d490614ee8565b6000856001600160401b031611611c655760405162461bcd60e51b81526004016109d490615215565b6001600160a01b038416611c8b5760405162461bcd60e51b81526004016109d490614b41565b61ffff8088166000908152600b602090815260408083209387168352929052205460ff16611ccb5760405162461bcd60e51b81526004016109d490614937565b6000826001600160401b031611611cf45760405162461bcd60e51b81526004016109d4906150f8565b6001600160a01b038116611d1a5760405162461bcd60e51b81526004016109d490614c8e565b6040518060c001604052808761ffff168152602001866001600160401b03168152602001856001600160a01b031681526020018461ffff168152602001836001600160401b03168152602001826001600160a01b0316815250600760008961ffff1661ffff16815260200190815260200160002060008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a8154816001600160401b0302191690836001600160401b03160217905550604082015181600001600a6101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600001601e6101000a81548161ffff021916908361ffff16021790555060808201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060a08201518160010160086101000a8154816001600160a01b0302191690836001600160a01b031602179055509050508661ffff167f5a76432853a0871c4e780def7f3ffc7912339b53f022ac31127fe5ff84a36fa1878787878787604051611ec9969594939291906154bc565b60405180910390a250505050505050565b7f000000000000000000000000962b4d8b1f8940d6a67399dc3a8d7549250888b881565b336000908152600d6020908152604080832061ffff8816845282528083208684528252808320848452909152902054828110611f4c5760405162461bcd60e51b81526004016109d490614e48565b336000818152600d6020908152604080832061ffff8a1680855290835281842089855283528184208785529092529182902086905590517f74bbc026808dcba59692d6a8bb20596849ca718e10e2432c6cdf48af865bc5d990611fb49088908790899061487b565b60405180910390a35050505050565b611fcb613526565b6001600160a01b0316611fdc6127f1565b6001600160a01b031614612025576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b600d60209081526000948552604080862082529385528385208152918452828420909152825290205481565b6120a3613526565b6001600160a01b03166120b46127f1565b6001600160a01b0316146120fd576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b600f546001600160a01b0316156121265760405162461bcd60e51b81526004016109d490614c3c565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b612150613526565b6001600160a01b03166121616127f1565b6001600160a01b0316146121aa576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff821660009081526010602052604090205460ff16156121de5760405162461bcd60e51b81526004016109d490614db9565b604051630f428ae960e31b81526000906001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6751690637a1457489061224f9086907f000000000000000000000000962b4d8b1f8940d6a67399dc3a8d7549250888b890600401615324565b60206040518083038186803b15801561226757600080fd5b505afa15801561227b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229f91906146d6565b61ffff84166000908152601060209081526040808320805460ff191660011790555192935090916122f49185917f000000000000000000000000962b4d8b1f8940d6a67399dc3a8d7549250888b89101614760565b60408051601f1981840301815290829052600f54631a30ffab60e11b83529092506001600160a01b031690633461ff569061233790879085908790600401615414565b600060405180830381600087803b15801561235157600080fd5b505af1158015610e89573d6000803e3d6000fd5b61236d613526565b6001600160a01b031661237e6127f1565b6001600160a01b0316146123c7576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b600f805460ff60a01b1916600160a01b179055565b600481565b6123e9613526565b6001600160a01b03166123fa6127f1565b6001600160a01b031614612443576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001600160a01b0381166124695760405162461bcd60e51b81526004016109d490614dff565b61ffff8083166000908152600a6020526040902054811690811061249f5760405162461bcd60e51b81526004016109d490615048565b61ffff8381166000818152600a60209081526040808320805461ffff191660019790970195861696871790556009825280832095835294905283902080546001600160a01b0319166001600160a01b03861617905591519091907f802d55279d51813cb7a9a98e8fd2d7bec5346cb830901c11b85d1650cb857e9a9061252690859061483b565b60405180910390a2505050565b61253b613526565b6001600160a01b031661254c6127f1565b6001600160a01b031614612595576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff80851660009081526008602090815260408083209387168352929052206125c0908383613e0b565b508261ffff168461ffff167f4a5695eee2a74d548d5f5c485a3de99ace99e3b664c8e30a90f49be6ebb5493284846040516125fc9291906148bc565b60405180910390a350505050565b60026000541415612662576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556003546001600160a01b031633146126915760405162461bcd60e51b81526004016109d4906149c1565b60055461269e90826134c9565b6005556002546126b8906001600160a01b03168383613a91565b816001600160a01b0316336001600160a01b03167f3a20c8c3cd1848485ae8261a52398bb9b26f195b717306b3cf7f058e62c095d5836040516126fb9190614872565b60405180910390a350506001600055565b612714613526565b6001600160a01b03166127256127f1565b6001600160a01b03161461276e576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff82166000908152600c60205260409020541561279f5760405162461bcd60e51b81526004016109d4906151c5565b61ffff82166000818152600c602052604090819020839055517f0611bb2107e385b79ec826fff8ecc1c1248a7aae3c875c96668f8cfbf1734220906127e5908490614872565b60405180910390a25050565b6001546001600160a01b031690565b600581565b600f54600160a01b900460ff1681565b600c6020526000908152604090205481565b7f000000000000000000000000962b4d8b1f8940d6a67399dc3a8d7549250888b86001600160a01b0316866001600160a01b0316146128785760405162461bcd60e51b81526004016109d49061518e565b600f54600160a01b900460ff16156128a25760405162461bcd60e51b81526004016109d49061508a565b60006128ae888861352a565b60408101519091506001600160a01b031633146128dd5760405162461bcd60e51b81526004016109d490614d4b565b6128e5613e97565b61ffff89166000908152600c6020526040902054806129165760405162461bcd60e51b81526004016109d490615146565b60a08301516001600160a01b03166000908152600d6020908152604080832061ffff8e16845282528083208a84528252808320898452909152902054801580159061296e575083602001516001600160401b03168110155b61298a5760405162461bcd60e51b81526004016109d490615262565b61ffff808c1660009081526009602090815260408083208851909416835292905281902054905163b71e0f7160e01b81526001600160a01b0390911690819063b71e0f71906129e3908b908b908b908990600401614891565b600060405180830381600087803b1580156129fd57600080fd5b505af1158015612a11573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a3991908101906141c7565b60a081015161ffff8e166000908152600e6020526040902054919550149150508015612a68575060a082015115155b612a845760405162461bcd60e51b81526004016109d490614ccf565b8961ffff16826000015161ffff1614612aaf5760405162461bcd60e51b81526004016109d490614d14565b8082608001515114612ad35760405162461bcd60e51b81526004016109d490614f38565b7f000000000000000000000000000000000000000000000000000000000000000161ffff16826020015161ffff1614612b1e5760405162461bcd60e51b81526004016109d490614eb1565b886001600160a01b031682606001516001600160a01b031614612b535760405162461bcd60e51b81526004016109d490614c05565b612b5c89613ae8565b612bcd5781606001516001600160a01b0316826000015161ffff167fa2786598bd84ae4a299103996359e6cb4333404583256079dfc279386baf5832846080015185604001518660c0015180519060200120604051612bbd93929190614909565b60405180910390a3505050612cf5565b600082608001518360600151604051602001612bea929190614782565b604051602081830303815290604052905082606001516001600160a01b0316836000015161ffff167f2bd2d8a84b748439fd50d79a49502b4eb5faa25b864da6a9ab5c150704be9a4d856080015186604001518760c0015180519060200120604051612c5893929190614909565b60405180910390a37f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b031663c2fa48138c838d87604001518e8960c001516040518763ffffffff1660e01b8152600401612cbe969594939291906153b3565b600060405180830381600087803b158015612cd857600080fd5b505af1158015612cec573d6000803e3d6000fd5b50505050505050505b50505050505050565b612d06613ed5565b611a22838361352a565b600181565b600a6020526000908152604090205461ffff1681565b600f5460405163c533338f60e01b81526000916001600160a01b03169063c533338f90612d6090879087908790600401615378565b60206040518083038186803b158015612d7857600080fd5b505afa158015612d8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612db091906146d6565b949350505050565b600b60209081526000928352604080842090915290825290205460ff1681565b60096020908152600092835260408084209091529082529020546001600160a01b031681565b60066020908152600092835260408084209091529082529020805460019091015461ffff808316926001600160401b036201000082048116936001600160a01b03600160501b8404811694600160f01b9094049093169291811691600160401b9091041686565b600e6020526000908152604090205481565b612e7f613526565b6001600160a01b0316612e906127f1565b6001600160a01b031614612ed9576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff8083166000818152600b602090815260408083209486168352939052829020805460ff1916600117905590517fec23bee6f88cfecebb09d6aaaed66f0ce110debc1f61117c8270a7116597df9a906127e5908490615315565b612f3d613526565b6001600160a01b0316612f4e6127f1565b6001600160a01b031614612f97576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b61ffff82166000908152600e602052604090205415612fc85760405162461bcd60e51b81526004016109d490615007565b61ffff82166000818152600e602052604090819020839055517f0dad975e1d2fbe771c95cdcc7be9a1e61181de7173abe0a32b8f8f83140873e5906127e5908490614872565b613016613526565b6001600160a01b03166130276127f1565b6001600160a01b031614613070576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001600160a01b0381166130965760405162461bcd60e51b81526004016109d490614f7a565b600380546001600160a01b0319166001600160a01b0383169081179091556040517fcb7ef3e545f5cdb893f5c568ba710fe08f336375a2d9fd66e161033f8fc09ef390600090a250565b6130e8613526565b6001600160a01b03166130f96127f1565b6001600160a01b031614613142576040805162461bcd60e51b81526020600482018190526024820152600080516020615601833981519152604482015290519081900360640190fd5b6001600160a01b0381166131875760405162461bcd60e51b81526004018080602001828103825260268152602001806155db6026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b60055481565b60046020526000908152604090205481565b7f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b031633146132435760405162461bcd60e51b81526004016109d4906150c1565b6001600160a01b038416600090815260066020908152604080832061ffff89168452909152902060018414156132d3576000613281838501856142a2565b61ffff8089166000908152600a602052604090205491925090811690821611156132bd5760405162461bcd60e51b81526004016109d490614ee8565b815461ffff191661ffff9190911617815561347d565b60028414156133145760006132ea838501856146ba565b82546001600160401b03909116620100000269ffffffffffffffff0000199091161782555061347d565b600384141561336b57600061332b83850185614002565b82546001600160a01b03909116600160501b027fffff0000000000000000000000000000000000000000ffffffffffffffffffff9091161782555061347d565b60048414156133f3576000613382838501856142a2565b61ffff8089166000908152600b602090815260408083209385168352929052205490915060ff16806133b6575061ffff8116155b6133d25760405162461bcd60e51b81526004016109d490614937565b815461ffff909116600160f01b026001600160f01b0390911617815561347d565b600584141561343357600061340a838501856146ba565b60018301805467ffffffffffffffff19166001600160401b03929092169190911790555061347d565b6006841415611a0857600061344a83850185614002565b6001830180546001600160a01b03909216600160401b0268010000000000000000600160e01b0319909216919091179055505b83856001600160a01b03167ffc01bf86212a14151d51d1be5c2ac64d67d5ec823dfc6f53298d7ce3f3d3d25285856040516134b99291906148bc565b60405180910390a3505050505050565b600082821115613520576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b3390565b613532613ed5565b6001600160a01b03808316600090815260066020908152604080832061ffff808916808652918452828520835160c081018552815480841682526001600160401b03620100008204811683890152600160501b82048a1683880152600160f01b909104841660608301526001909201549182166080820152600160401b90910490961660a0870152908452600790925290912082519091166135d757805461ffff1682525b60208201516001600160401b03166136005780546201000090046001600160401b031660208301525b60408201516001600160a01b031661362a578054600160501b90046001600160a01b031660408301525b606082015161ffff1661364a578054600160f01b900461ffff1660608301525b60808201516001600160401b03166136705760018101546001600160401b031660808301525b60a08201516001600160a01b0316611a205760010154600160401b90046001600160a01b031660a08201529392505050565b600082820183811015611a22576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008151600014156137b95761ffff808716600090815260086020908152604080832060608a015190941683529281529082902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156137b15780601f10613786576101008083540402835291602001916137b1565b820191906000526020600020905b81548152906001019060200180831161379457829003601f168201915b505050505091505b60408086015160608701519151635886ea6560e01b8152909182916001600160a01b03831691635886ea65916137f9918c918b908b908b9060040161544a565b602060405180830381600087803b15801561381357600080fd5b505af1158015613827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061384b91906146a2565b92506138578284613aee565b7fb0c632f55f1e1b3b2c3d82f41ee4716bb4c00f0f5d84cdafc141581bb8757a4f84886060015160405161388c9291906148e3565b60405180910390a1505095945050505050565b60a08201516060830151608084015160405163c5e193cd60e01b8152600093926001600160a01b0384169263c5e193cd926138e2928a9290918990600401615487565b602060405180830381600087803b1580156138fc57600080fd5b505af1158015613910573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061393491906146a2565b9150611a208183613aee565b6000806001600160a01b038316158061396257506002546001600160a01b0316155b600354604051635cbbbd7560e01b81529192506000916001600160a01b0390911690635cbbbd759061399d908515908b908b9060040161485a565b60206040518083038186803b1580156139b557600080fd5b505afa1580156139c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ed91906146a2565b90508015613a87578115613a1a576003546001600160a01b0316613a118183613aee565b81935050613a87565b846001600160a01b0316846001600160a01b03161480613a4257506001600160a01b03841632145b613a5e5760405162461bcd60e51b81526004016109d490614bba565b600254613a76906001600160a01b0316853084613b31565b600554613a8390826136a2565b6005555b5050949350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052613ae3908490613b91565b505050565b3b151590565b6001600160a01b038216600090815260046020526040902054613b1190826136a2565b6001600160a01b0390921660009081526004602052604090209190915550565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052613b8b908590613b91565b50505050565b6000613be6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613c429092919063ffffffff16565b805190915015613ae357808060200190516020811015613c0557600080fd5b5051613ae35760405162461bcd60e51b815260040180806020018281038252602a815260200180615621602a913960400191505060405180910390fd5b6060612db0848460008585613c5685613ae8565b613ca7576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b60208310613ce55780518252601f199092019160209182019101613cc6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613d47576040519150601f19603f3d011682016040523d82523d6000602084013e613d4c565b606091505b5091509150613d5c828286613d67565b979650505050505050565b60608315613d76575081611a22565b825115613d865782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613dd0578181015183820152602001613db8565b50505050905090810190601f168015613dfd5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282613e415760008555613e87565b82601f10613e5a5782800160ff19823516178555613e87565b82800160010185558215613e87579182015b82811115613e87578235825591602001919060010190613e6c565b50613e93929150613f0a565b5090565b6040805160e08101825260008082526020820181905291810182905260608082018390526080820181905260a082019290925260c081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b5b80821115613e935760008155600101613f0b565b8035611b8d8161559d565b8051611b8d8161559d565b60008083601f840112613f46578182fd5b5081356001600160401b03811115613f5c578182fd5b602083019150836020828501011115613f7457600080fd5b9250929050565b600082601f830112613f8b578081fd5b81516001600160401b03811115613f9e57fe5b613fb1601f8201601f1916602001615526565b818152846020838601011115613fc5578283fd5b612db0826020830160208701615571565b8035611b8d816155b5565b8051611b8d816155b5565b8035611b8d816155c5565b8051611b8d816155c5565b600060208284031215614013578081fd5b8135611a228161559d565b60008060408385031215614030578081fd5b823561403b8161559d565b946020939093013593505050565b6000806040838503121561405b578182fd5b82356140668161559d565b91506020830135614076816155b5565b809150509250929050565b60008060008060808587031215614096578182fd5b84356140a18161559d565b935060208501356140b1816155b5565b93969395505050506040820135916060013590565b60008060408385031215614030578182fd5b60008060008060008060008060008060006101008c8e0312156140f9578687fd5b6141028c613f1f565b9a5061411060208d01613fec565b995061411e60408d01613fd6565b98506001600160401b038060608e01351115614138578788fd5b6141488e60608f01358f01613f35565b909950975060808d013581101561415d578687fd5b61416d8e60808f01358f01613f35565b909750955061417e60a08e01613f1f565b945061418c60c08e01613f1f565b93508060e08e0135111561419e578283fd5b506141af8d60e08e01358e01613f35565b81935080925050509295989b509295989b9093969950565b6000602082840312156141d8578081fd5b81516001600160401b03808211156141ee578283fd5b9083019060e08286031215614201578283fd5b61420b60e0615526565b61421483613fe1565b815261422260208401613fe1565b602082015261423360408401613ff7565b604082015261424460608401613f2a565b606082015260808301518281111561425a578485fd5b61426687828601613f7b565b60808301525060a083015160a082015260c083015182811115614287578485fd5b61429387828601613f7b565b60c08301525095945050505050565b6000602082840312156142b3578081fd5b8135611a22816155b5565b600080604083850312156142d0578182fd5b82356142db816155b5565b915060208301356140768161559d565b600080600080600080600060a0888a031215614305578081fd5b8735614310816155b5565b965060208801356143208161559d565b955060408801356001600160401b038082111561433b578283fd5b6143478b838c01613f35565b909750955060608a013591508115158214614360578283fd5b90935060808901359080821115614375578283fd5b506143828a828b01613f35565b989b979a50959850939692959293505050565b6000806000606084860312156143a9578081fd5b83356143b4816155b5565b925060208401356143c48161559d565b929592945050506040919091013590565b600080600080600080600060c0888a0312156143ef578081fd5b87356143fa816155b5565b9650602088013561440a8161559d565b955060408801359450606088013593506080880135925060a08801356001600160401b03811115614439578182fd5b6143828a828b01613f35565b60008060008060006080868803121561445c578283fd5b8535614467816155b5565b945060208601356144778161559d565b93506040860135925060608601356001600160401b03811115614498578182fd5b6144a488828901613f35565b969995985093965092949392505050565b600080600080608085870312156144ca578182fd5b84356144d5816155b5565b935060208501356140b18161559d565b600080604083850312156144f7578182fd5b823561403b816155b5565b60008060008060808587031215614517578182fd5b8435614522816155b5565b966020860135965060408601359560600135945092505050565b600080600060408486031215614550578081fd5b833561455b816155b5565b925060208401356001600160401b03811115614575578182fd5b61458186828701613f35565b9497909650939450505050565b600080604083850312156145a0578182fd5b8235614066816155b5565b600080600080606085870312156145c0578182fd5b84356145cb816155b5565b935060208501356145db816155b5565b925060408501356001600160401b038111156145f5578283fd5b61460187828801613f35565b95989497509550505050565b600080600080600080600060e0888a031215614627578081fd5b8735614632816155b5565b96506020880135614642816155b5565b95506040880135614652816155c5565b945060608801356146628161559d565b93506080880135614672816155b5565b925060a0880135614682816155c5565b915060c08801356146928161559d565b8091505092959891949750929550565b6000602082840312156146b3578081fd5b5051919050565b6000602082840312156146cb578081fd5b8135611a22816155c5565b6000602082840312156146e7578081fd5b8151611a22816155c5565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452614734816020860160208601615571565b601f01601f19169290920160200192915050565b60609190911b6001600160601b031916815260140190565b6001600160601b0319606093841b811682529190921b16601482015260280190565b60008351614794818460208801615571565b60609390931b6001600160601b0319169190920190815260140192915050565b90565b60006001600160401b0360c01b8860c01b16825261ffff60f01b808860f01b1660088401526bffffffffffffffffffffffff198760601b16600a840152808660f01b16601e840152508351614813816020850160208801615571565b8083019050835161482b816020840160208801615571565b0160200198975050505050505050565b6001600160a01b0391909116815260200190565b901515815260200190565b92151583526020830191909152604082015260600190565b90815260200190565b9283526020830191909152604082015260600190565b6000858252606060208301526148ab6060830185876146f2565b905082604083015295945050505050565b600060208252612db06020830184866146f2565b600060208252611a22602083018461471c565b6000604082526148f6604083018561471c565b905061ffff831660208301529392505050565b60006060825261491c606083018661471c565b6001600160401b039490941660208301525060400152919050565b60208082526026908201527f4c617965725a65726f3a20696e76616c6964206f7574626f756e642070726f6f60408201526566207479706560d01b606082015260800190565b60208082526024908201527f4c617965725a65726f3a20647374436861696e496420646f6573206e6f7420656040820152631e1a5cdd60e21b606082015260800190565b60208082526018908201527f4c617965725a65726f3a206f6e6c792074726561737572790000000000000000604082015260600190565b6020808252601e908201527f4c617965725a65726f3a20496e76616c696420636f6e66696720747970650000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a207769746864726177206661696c6564000000000000604082015260600190565b60208082526025908201527f4c617965725a65726f3a206e6f7420656e6f756768206e617469766520666f72604082015264206665657360d81b606082015260800190565b60208082526025908201527f4c617965725a65726f3a205f746f2063616e6e6f74206265207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526031908201527f4c617965725a65726f3a205f6c617965725a65726f546f6b656e2063616e6e6f60408201527074206265207a65726f206164647265737360781b606082015260800190565b60208082526022908201527f4c617965725a65726f3a20696e76616c69642072656c61796572206164647265604082015261737360f01b606082015260800190565b6020808252601b908201527f4c617965725a65726f3a206661696c656420746f20726566756e640000000000604082015260600190565b6020808252602b908201527f4c617965725a65726f3a206d75737420626520706169642062792073656e646560408201526a391037b91037b934b3b4b760a91b606082015260800190565b6020808252601d908201527f4c617965725a65726f3a20696e76616c69642064737441646472657373000000604082015260600190565b60208082526032908201527f4c617965725a65726f3a206e6f6e6365436f6e747261637452616461722063616040820152716e206f6e6c7920626520736574206f6e636560701b606082015260800190565b60208082526021908201527f4c617965725a65726f3a20696e76616c6964206f7261636c65206164647265736040820152607360f81b606082015260800190565b60208082526025908201527f4c617965725a65726f3a20696e76616c6964205f7061636b65742e756c6e4164604082015264647265737360d81b606082015260800190565b6020808252601e908201527f4c617965725a65726f3a20696e76616c696420737263436861696e2049640000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a20696e76616c69642072656c61796572000000000000604082015260600190565b6020808252601a908201527f4c617965725a65726f3a2077726f6e6720706174682064617461000000000000604082015260600190565b60208082526026908201527f4c617965725a65726f3a20646170705261646172206e6f6e636520616c726561604082015265191e481cd95d60d21b606082015260800190565b60208082526029908201527f4c617965725a65726f3a206c6962726172792063616e6e6f74206265207a65726040820152686f206164647265737360b81b606082015260800190565b60208082526043908201527f4c617965725a65726f3a206f7261636c6520646174612063616e206f6e6c792060408201527f75706461746520696620697420686173206d6f726520636f6e6669726d6174696060820152626f6e7360e81b608082015260a00190565b6020808252601e908201527f4c617965725a65726f3a20696e76616c696420647374436861696e2049640000604082015260600190565b60208082526030908201527f4c617965725a65726f3a20696e76616c696420696e626f756e642070726f6f6660408201526f103634b13930b93c903b32b939b4b7b760811b606082015260800190565b60208082526022908201527f4c617965725a65726f3a20696e76616c696420737263416464726573732073696040820152617a6560f01b606082015260800190565b6020808252602a908201527f4c617965725a65726f3a2074726561737572792063616e6e6f74206265207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526023908201527f4c617965725a65726f3a206e6f74206c6567616379207261646172206164647260408201526265737360e81b606082015260800190565b60208082526021908201527f4c617965725a65726f3a2072656d6f746520756c6e20616c72656164792073656040820152601d60fa1b606082015260800190565b60208082526022908201527f4c617965725a65726f3a2063616e206e6f7420616464206e6577206c69627261604082015261727960f01b606082015260800190565b60208082526019908201527f4c617965725a65726f3a206465636f6d6d697373696f6e656400000000000000604082015260600190565b60208082526018908201527f4c617965725a65726f3a206f6e6c7920656e64706f696e740000000000000000604082015260600190565b6020808252602e908201527f4c617965725a65726f3a20696e76616c6964206f7574626f756e6420626c6f6360408201526d359031b7b73334b936b0ba34b7b760911b606082015260800190565b60208082526028908201527f4c617965725a65726f3a20696e636f72726563742072656d6f746520616464726040820152676573732073697a6560c01b606082015260800190565b60208082526019908201527f4c617965725a65726f3a206f6e6c792064617070526164617200000000000000604082015260600190565b60208082526030908201527f4c617965725a65726f3a2072656d6f746520636861696e20616464726573732060408201526f1cda5e9948185b1c9958591e481cd95d60821b606082015260800190565b6020808252602d908201527f4c617965725a65726f3a20696e76616c696420696e626f756e6420626c6f636b60408201526c1031b7b73334b936b0ba34b7b760991b606082015260800190565b60208082526029908201527f4c617965725a65726f3a206e6f7420656e6f75676820626c6f636b20636f6e6660408201526869726d6174696f6e7360b81b606082015260800190565b600060c08201905061ffff80845116835260208401516001600160401b0380821660208601526040860151915060018060a01b0380831660408701528360608801511660608701528160808801511660808701528060a08801511660a08701525050505092915050565b61ffff91909116815260200190565b61ffff9290921682526001600160a01b0316602082015260400190565b61ffff841681526001600160a01b038316602082015260606040820181905260009061536f9083018461471c565b95945050505050565b600061ffff851682526040602083015261536f6040830184866146f2565b600061ffff8416825260406020830152612db0604083018461471c565b600061ffff8816825260c060208301526153d060c083018861471c565b6001600160a01b03871660408401526001600160401b03861660608401526080830185905282810360a0840152615407818561471c565b9998505050505050505050565b600061ffff8516825260606020830152615431606083018561471c565b90506001600160401b0383166040830152949350505050565b61ffff8681168252851660208201526001600160a01b03841660408201526060810183905260a060808201819052600090613d5c9083018461471c565b61ffff94851681529290931660208301526001600160401b031660408201526001600160a01b03909116606082015260800190565b61ffff96871681526001600160401b0395861660208201526001600160a01b03948516604082015292909516606083015290921660808301529190911660a082015260c00190565b918252602082015260400190565b6001600160401b0391909116815260200190565b6040518181016001600160401b038111828210171561554157fe5b604052919050565b60008085851115615558578182fd5b83861115615564578182fd5b5050820193919092039150565b60005b8381101561558c578181015183820152602001615574565b83811115613b8b5750506000910152565b6001600160a01b03811681146155b257600080fd5b50565b61ffff811681146155b257600080fd5b6001600160401b03811681146155b257600080fdfe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220a1d60004ed519b486657de8dfd367da434e640dceb118d064a98219dba3429be64736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6750000000000000000000000000000000000000000000000000000000000000001000000000000000000000000962b4d8b1f8940d6a67399dc3a8d7549250888b8
-----Decoded View---------------
Arg [0] : _endpoint (address): 0x66A71Dcef29A0fFBDBE3c6a460a3B5BC225Cd675
Arg [1] : _localChainId (uint16): 1
Arg [2] : _dappRadar (address): 0x962B4D8b1f8940D6a67399DC3A8D7549250888B8
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [2] : 000000000000000000000000962b4d8b1f8940d6a67399dc3a8d7549250888b8
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $3,304.45 | 0.000000000622 | $0.000002 |
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.