Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 47 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer Ownersh... | 111991603 | 396 days ago | IN | 0 ETH | 0.00008529243 | ||||
Set Per Color Ex... | 111344703 | 411 days ago | IN | 0 ETH | 0.000040086921 | ||||
Set Per Color Ex... | 111344701 | 411 days ago | IN | 0 ETH | 0.000040086921 | ||||
Set Per Color Ex... | 111344700 | 411 days ago | IN | 0 ETH | 0.000040086921 | ||||
Set Per Color Ex... | 111344699 | 411 days ago | IN | 0 ETH | 0.000040086921 | ||||
Set Per Color Ex... | 111344698 | 411 days ago | IN | 0 ETH | 0.000040142769 | ||||
Set Per Color Ex... | 111344698 | 411 days ago | IN | 0 ETH | 0.000040142769 | ||||
Set Per Color Ex... | 111344697 | 411 days ago | IN | 0 ETH | 0.00003996688 | ||||
Set Per Color Ex... | 111344696 | 411 days ago | IN | 0 ETH | 0.00003996688 | ||||
Set Min Dst Gas | 111344695 | 411 days ago | IN | 0 ETH | 0.00004015255 | ||||
Set Min Dst Gas | 111344693 | 411 days ago | IN | 0 ETH | 0.000040328439 | ||||
Set Min Dst Gas | 111344692 | 411 days ago | IN | 0 ETH | 0.000039775756 | ||||
Set Min Dst Gas | 111344691 | 411 days ago | IN | 0 ETH | 0.000039775756 | ||||
Set Min Dst Gas | 111344691 | 411 days ago | IN | 0 ETH | 0.000039775756 | ||||
Set Min Dst Gas | 111344689 | 411 days ago | IN | 0 ETH | 0.000039775756 | ||||
Set Min Dst Gas | 111344689 | 411 days ago | IN | 0 ETH | 0.000039775756 | ||||
Set Min Dst Gas | 111344687 | 411 days ago | IN | 0 ETH | 0.000039775756 | ||||
Set Min Dst Gas | 111344686 | 411 days ago | IN | 0 ETH | 0.000039238642 | ||||
Set Min Dst Gas | 111344685 | 411 days ago | IN | 0 ETH | 0.000039238642 | ||||
Set Min Dst Gas | 111344684 | 411 days ago | IN | 0 ETH | 0.000039238642 | ||||
Set Min Dst Gas | 111344684 | 411 days ago | IN | 0 ETH | 0.000039238642 | ||||
Set Precrime | 111136916 | 416 days ago | IN | 0 ETH | 0.000015959946 | ||||
Set Per Color Ex... | 111136180 | 416 days ago | IN | 0 ETH | 0.000017527426 | ||||
Set Per Color Ex... | 111136179 | 416 days ago | IN | 0 ETH | 0.000017470381 | ||||
Set Per Color Ex... | 111136178 | 416 days ago | IN | 0 ETH | 0.000017527426 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
129104366 | 6 hrs ago | 0.000097364633221 ETH | ||||
129104366 | 6 hrs ago | 0.000097364633221 ETH | ||||
129086863 | 16 hrs ago | 0.000091872451808 ETH | ||||
129086863 | 16 hrs ago | 0.000091872451808 ETH | ||||
129060039 | 31 hrs ago | 0.000091235634463 ETH | ||||
129060039 | 31 hrs ago | 0.000091235634463 ETH | ||||
129030821 | 47 hrs ago | 0.000082596287714 ETH | ||||
129030821 | 47 hrs ago | 0.000082596287714 ETH | ||||
129026321 | 2 days ago | 0.000152781073816 ETH | ||||
129026321 | 2 days ago | 0.000152781073816 ETH | ||||
129015626 | 2 days ago | 0.000185514318261 ETH | ||||
129015626 | 2 days ago | 0.000185514318261 ETH | ||||
128987014 | 3 days ago | 0.000092175297808 ETH | ||||
128987014 | 3 days ago | 0.000092175297808 ETH | ||||
128981974 | 3 days ago | 0.000093115885808 ETH | ||||
128981974 | 3 days ago | 0.000093115885808 ETH | ||||
128974030 | 3 days ago | 0.000198708446159 ETH | ||||
128974030 | 3 days ago | 0.000198708446159 ETH | ||||
128947138 | 3 days ago | 0.000113120999104 ETH | ||||
128947138 | 3 days ago | 0.000113120999104 ETH | ||||
128908527 | 4 days ago | 0.000114167623405 ETH | ||||
128908527 | 4 days ago | 0.000114167623405 ETH | ||||
128899609 | 5 days ago | 0.000095807515405 ETH | ||||
128899609 | 5 days ago | 0.000095807515405 ETH | ||||
128845384 | 6 days ago | 0.000100747910605 ETH |
Loading...
Loading
Contract Name:
MessagingV1
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: LZBL-1.1 // Copyright 2023 LayerZero Labs Ltd. // You may obtain a copy of the License at // https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1 pragma solidity 0.8.19; import "@openzeppelin/contracts/utils/math/SafeCast.sol"; import "@layerzerolabs/lz-evm-oapp-v2/contracts/standards/oft/interfaces/IOFT.sol"; import "@layerzerolabs/lz-evm-oapp-v2/contracts/standards/precrime/PreCrimeV2Simulator.sol"; import "../usdv/interfaces/IUSDV.sol"; import "../usdv/interfaces/IUSDVMain.sol"; import "./Messaging.sol"; import "./NonblockingLzApp.sol"; import "./libs/MsgCodec.sol"; contract MessagingV1 is NonblockingLzApp, Messaging, PreCrimeV2Simulator { using BytesLib for bytes; using MsgCodec for bytes; using SafeCast for uint32; constructor( address _endpoint, address _usdv, uint32 _mainChainEid, bool _isMainChain ) Messaging(_usdv, _mainChainEid, _isMainChain) NonblockingLzApp(_endpoint) {} // ======================== onlyUSDV ======================== function send( SendParam calldata _param, bytes calldata _extraOptions, MessagingFee calldata /* _msgFee */, address payable _refundAddress, bytes calldata _composeMsg ) external payable onlyUSDV returns (MessagingReceipt memory msgReceipt) { require(_composeMsg.length == 0, "MessagingV1: composeMsg not supported"); uint16 dstEid = _param.dstEid.toUint16(); _checkGasLimit(dstEid, MsgCodec.MSG_TYPE_SEND, _extraOptions, 0); _lzSend( dstEid, MsgCodec.encodeSendMsg(_param.to, _param.color, _param.amount, _param.theta), _refundAddress, address(0x0), _extraOptions, msg.value ); return msgReceipt; } /// @dev gas provided to sync linearly increases with num deltas function syncDelta( uint32 _dstEid, Delta[] calldata _deltas, bytes calldata _extraOptions, MessagingFee calldata /* _msgFee */, address payable _refundAddress ) external payable onlyUSDV returns (MessagingReceipt memory msgReceipt) { uint16 dstEid = _dstEid.toUint16(); _checkGasLimit( dstEid, MsgCodec.MSG_TYPE_SYNC_DELTA, _extraOptions, perColorExtraGasLookup[_dstEid][MsgCodec.MSG_TYPE_SYNC_DELTA] * _deltas.length ); _lzSend(dstEid, MsgCodec.encodeSyncDeltaMsg(_deltas), _refundAddress, address(0x0), _extraOptions, msg.value); return msgReceipt; } /// @dev gas provided to remint linearly increases with num deltas function remint( Delta[] calldata _deltas, uint32 _feeColor, uint64 _feeAmount, uint64 _feeTheta, bytes calldata _extraOptions, MessagingFee calldata /* _msgFee */, address payable _refundAddress ) external payable onlyUSDV returns (MessagingReceipt memory msgReceipt) { uint16 dstEid = mainChainEid.toUint16(); _checkGasLimit( dstEid, MsgCodec.MSG_TYPE_REMINT, _extraOptions, perColorExtraGasLookup[mainChainEid][MsgCodec.MSG_TYPE_REMINT] * _deltas.length ); _lzSend( dstEid, MsgCodec.encodeRemintMsg(_deltas, _feeColor, _feeAmount, _feeTheta), _refundAddress, address(0x0), _extraOptions, msg.value ); return msgReceipt; } // ======================== View ======================== function quoteSendFee( uint32 _dstEid, bytes calldata _extraOptions, bool /*_useLZToken*/, bytes calldata _composeMsg ) external view returns (uint nativeFee, uint lzTokenFee) { require(_composeMsg.length == 0, "MessagingV1: composeMsg not supported"); uint16 dstEid = _dstEid.toUint16(); _checkGasLimit(dstEid, MsgCodec.MSG_TYPE_SEND, _extraOptions, 0); return lzEndpoint.estimateFees(dstEid, address(this), MsgCodec.encodeSendMsg(0x0, 0, 0, 0), false, _extraOptions); } function quoteSyncDeltaFee( uint32 _dstEid, Delta[] calldata _deltas, bytes calldata _extraOptions, bool /*_useLZToken*/ ) external view returns (uint nativeFee, uint lzTokenFee) { uint16 dstEid = _dstEid.toUint16(); _checkGasLimit( dstEid, MsgCodec.MSG_TYPE_SYNC_DELTA, _extraOptions, perColorExtraGasLookup[_dstEid][MsgCodec.MSG_TYPE_SYNC_DELTA] * _deltas.length ); return lzEndpoint.estimateFees(dstEid, address(this), MsgCodec.encodeSyncDeltaMsg(_deltas), false, _extraOptions); } function quoteRemintFee( Delta[] calldata _deltas, bytes calldata _extraOptions, bool /*_useLZToken*/ ) external view returns (uint nativeFee, uint lzTokenFee) { uint16 dstEid = mainChainEid.toUint16(); _checkGasLimit( dstEid, MsgCodec.MSG_TYPE_REMINT, _extraOptions, perColorExtraGasLookup[mainChainEid][MsgCodec.MSG_TYPE_REMINT] * _deltas.length ); return lzEndpoint.estimateFees( dstEid, address(this), MsgCodec.encodeRemintMsg(_deltas, 0, 0, 0), false, _extraOptions ); } function isPeer(uint32 _eid, bytes32 _peer) public view override returns (bool) { bytes memory path = trustedRemoteLookup[_eid.toUint16()]; uint pathLength = path.length; require(pathLength > 20 && pathLength <= 52, "MessagingV1: invalid path length"); bytes32 expectedPeer = bytes32(path.slice(0, pathLength - 20)); unchecked { uint offset = 52 - path.length; expectedPeer = expectedPeer >> (offset * 8); } return expectedPeer == _peer; } // ======================== Internal ======================== function _nonblockingLzReceive( uint16 /*_srcChainId*/, bytes calldata /*_srcAddress*/, uint64 /*_nonce*/, bytes calldata _message ) internal override { uint8 msgType = _message.msgType(); if (msgType == MsgCodec.MSG_TYPE_SEND) { SendMsg memory message = _message.decodeSendMsg(); IUSDV(usdv).sendAck(0x0, message.to, message.color, message.amount, message.theta); } else if (msgType == MsgCodec.MSG_TYPE_SYNC_DELTA) { SyncDeltaMsg memory message = _message.decodeSyncDeltaMsg(); IUSDV(usdv).syncDeltaAck(message.deltas); } else if (msgType == MsgCodec.MSG_TYPE_REMINT) { if (!isMainChain) revert NotMainChain(); RemintMsg memory message = _message.decodeRemintMsg(); IUSDVMain(usdv).remintAck(message.deltas, message.color, message.amount, message.theta); } else { revert NotImplemented(); } } // ======================== precrime ======================== function _lzReceive(Origin calldata /*_origin*/, bytes32 /*_guid*/, bytes calldata _message) internal override { // only pass in the message this.nonblockingLzReceive(0x0, bytes(""), 0, _message); } }
pragma solidity ^0.8.4; /** * @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. * @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 Initializes a new buffer from an existing bytes object. * Changes to the buffer may mutate the original value. * @param b The bytes object to initialize the buffer with. * @return A new buffer. */ function fromBytes(bytes memory b) internal pure returns(buffer memory) { buffer memory buf; buf.buf = b; buf.capacity = b.length; return buf; } 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; } /** * @dev Sets buffer length to 0. * @param buf The buffer to truncate. * @return The original buffer, for chaining.. */ function truncate(buffer memory buf) internal pure returns (buffer memory) { assembly { let bufptr := mload(buf) mstore(bufptr, 0) } 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 unchecked { 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 Appends 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 data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, len); } /** * @dev Appends 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 data The data to append. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, data.length); } /** * @dev Writes a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write the byte at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) { if (off >= buf.capacity) { resize(buf, buf.capacity * 2); } assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Address = buffer address + sizeof(buffer length) + off let dest := add(add(bufptr, off), 32) mstore8(dest, data) // Update buffer length if we extended it if eq(off, buflen) { mstore(bufptr, add(buflen, 1)) } } return buf; } /** * @dev Appends a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) { return writeUint8(buf, buf.buf.length, data); } /** * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (left-aligned). * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } unchecked { uint mask = (256 ** len) - 1; // Right-align data data = data >> (8 * (32 - len)); assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + sizeof(buffer length) + off + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } } return buf; } /** * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) { return write(buf, off, bytes32(data), 20); } /** * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chhaining. */ function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, bytes32(data), 20); } /** * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, 32); } /** * @dev Writes an integer to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (right-aligned). * @return The original buffer, for chaining. */ function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } uint mask = (256 ** len) - 1; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + off + sizeof(buffer length) + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } return buf; } /** * @dev Appends a byte to the end of the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer. */ function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) { return writeInt(buf, buf.buf.length, data, len); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; import "@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver.sol"; import "@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig.sol"; import "@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint.sol"; import "solidity-bytes-utils/contracts/BytesLib.sol"; /* * a generic LzReceiver implementation */ abstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig { using BytesLib for bytes; ILayerZeroEndpoint public immutable lzEndpoint; mapping(uint16 => bytes) public trustedRemoteLookup; mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup; address public precrime; event SetPrecrime(address precrime); event SetTrustedRemote(uint16 _remoteChainId, bytes _path); event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress); event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas); constructor(address _endpoint) { lzEndpoint = ILayerZeroEndpoint(_endpoint); } function lzReceive( uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload ) public virtual override { // lzReceive must be called by the endpoint for security require(_msgSender() == address(lzEndpoint), "LzApp: invalid endpoint caller"); bytes memory trustedRemote = trustedRemoteLookup[_srcChainId]; // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote. require( _srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote), "LzApp: invalid source sending contract" ); _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging function _blockingLzReceive( uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload ) internal virtual; function _lzSend( uint16 _dstChainId, bytes memory _payload, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, uint _nativeFee ) internal virtual { bytes memory trustedRemote = trustedRemoteLookup[_dstChainId]; require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source"); lzEndpoint.send{value: _nativeFee}( _dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams ); } function _checkGasLimit( uint16 _dstChainId, uint16 _type, bytes memory _adapterParams, uint _extraGas ) internal view virtual { uint providedGasLimit = _getGasLimit(_adapterParams); uint minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas; require(minGasLimit > 0, "LzApp: minGasLimit not set"); require(providedGasLimit >= minGasLimit, "LzApp: gas limit is too low"); } function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) { require(_adapterParams.length >= 34, "LzApp: invalid adapterParams"); assembly { gasLimit := mload(add(_adapterParams, 34)) } } //---------------------------UserApplication config---------------------------------------- function getConfig( uint16 _version, uint16 _chainId, address, uint _configType ) external view returns (bytes memory) { return lzEndpoint.getConfig(_version, _chainId, address(this), _configType); } // generic config for LayerZero user Application function setConfig( uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config ) external override onlyOwner { lzEndpoint.setConfig(_version, _chainId, _configType, _config); } function setSendVersion(uint16 _version) external override onlyOwner { lzEndpoint.setSendVersion(_version); } function setReceiveVersion(uint16 _version) external override onlyOwner { lzEndpoint.setReceiveVersion(_version); } function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner { lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress); } // _path = abi.encodePacked(remoteAddress, localAddress) // this function set the trusted path for the cross-chain communication function setTrustedRemote(uint16 _srcChainId, bytes calldata _path) external onlyOwner { trustedRemoteLookup[_srcChainId] = _path; emit SetTrustedRemote(_srcChainId, _path); } function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner { trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this)); emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress); } function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) { bytes memory path = trustedRemoteLookup[_remoteChainId]; require(path.length != 0, "LzApp: no trusted path record"); return path.slice(0, path.length - 20); // the last 20 bytes should be address(this) } function setPrecrime(address _precrime) external onlyOwner { precrime = _precrime; emit SetPrecrime(_precrime); } function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint _minGas) external onlyOwner { require(_minGas > 0, "LzApp: invalid minGas"); minDstGasLookup[_dstChainId][_packetType] = _minGas; emit SetMinDstGas(_dstChainId, _packetType, _minGas); } //--------------------------- VIEW FUNCTION ---------------------------------------- function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) { bytes memory trustedSource = trustedRemoteLookup[_srcChainId]; return keccak256(trustedSource) == keccak256(_srcAddress); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.6; library ExcessivelySafeCall { uint256 constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff; /// @notice Use when you _really_ really _really_ don't trust the called /// contract. This prevents the called contract from causing reversion of /// the caller in as many ways as we can. /// @dev The main difference between this and a solidity low-level call is /// that we limit the number of bytes that the callee can cause to be /// copied to caller memory. This prevents stupid things like malicious /// contracts returning 10,000,000 bytes causing a local OOG when copying /// to memory. /// @param _target The address to call /// @param _gas The amount of gas to forward to the remote contract /// @param _maxCopy The maximum number of bytes of returndata to copy /// to memory. /// @param _calldata The data to send to the remote contract /// @return success and returndata, as `.call()`. Returndata is capped to /// `_maxCopy` bytes. function excessivelySafeCall( address _target, uint256 _gas, uint16 _maxCopy, bytes memory _calldata ) internal returns (bool, bytes memory) { // set up for assembly call uint256 _toCopy; bool _success; bytes memory _returnData = new bytes(_maxCopy); // dispatch message to recipient // by assembly calling "handle" function // we call via assembly to avoid memcopying a very large returndata // returned by a malicious contract assembly { _success := call( _gas, // gas _target, // recipient 0, // ether value add(_calldata, 0x20), // inloc mload(_calldata), // inlen 0, // outloc 0 // outlen ) // limit our copy to 256 bytes _toCopy := returndatasize() if gt(_toCopy, _maxCopy) { _toCopy := _maxCopy } // Store the length of the copied bytes mstore(_returnData, _toCopy) // copy the bytes from returndata[0:_toCopy] returndatacopy(add(_returnData, 0x20), 0, _toCopy) } return (_success, _returnData); } /// @notice Use when you _really_ really _really_ don't trust the called /// contract. This prevents the called contract from causing reversion of /// the caller in as many ways as we can. /// @dev The main difference between this and a solidity low-level call is /// that we limit the number of bytes that the callee can cause to be /// copied to caller memory. This prevents stupid things like malicious /// contracts returning 10,000,000 bytes causing a local OOG when copying /// to memory. /// @param _target The address to call /// @param _gas The amount of gas to forward to the remote contract /// @param _maxCopy The maximum number of bytes of returndata to copy /// to memory. /// @param _calldata The data to send to the remote contract /// @return success and returndata, as `.call()`. Returndata is capped to /// `_maxCopy` bytes. function excessivelySafeStaticCall( address _target, uint256 _gas, uint16 _maxCopy, bytes memory _calldata ) internal view returns (bool, bytes memory) { // set up for assembly call uint256 _toCopy; bool _success; bytes memory _returnData = new bytes(_maxCopy); // dispatch message to recipient // by assembly calling "handle" function // we call via assembly to avoid memcopying a very large returndata // returned by a malicious contract assembly { _success := staticcall( _gas, // gas _target, // recipient add(_calldata, 0x20), // inloc mload(_calldata), // inlen 0, // outloc 0 // outlen ) // limit our copy to 256 bytes _toCopy := returndatasize() if gt(_toCopy, _maxCopy) { _toCopy := _maxCopy } // Store the length of the copied bytes mstore(_returnData, _toCopy) // copy the bytes from returndata[0:_toCopy] returndatacopy(add(_returnData, 0x20), 0, _toCopy) } return (_success, _returnData); } /** * @notice Swaps function selectors in encoded contract calls * @dev Allows reuse of encoded calldata for functions with identical * argument types but different names. It simply swaps out the first 4 bytes * for the new selector. This function modifies memory in place, and should * only be used with caution. * @param _newSelector The new 4-byte selector * @param _buf The encoded contract args */ function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure { require(_buf.length >= 4); uint256 _mask = LOW_28_MASK; assembly { // load the first word of let _word := mload(add(_buf, 0x20)) // mask out the top 4 bytes // /x _word := and(_word, _mask) _word := or(_newSelector, _word) mstore(add(_buf, 0x20), _word) } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {MessagingFee, MessagingReceipt} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; // @dev unable to inherit ERC20 because the OFTAdapter needs to use this interface as well interface IOFT { struct SendParam { bytes32 to; uint amountLD; uint minAmountLD; uint32 dstEid; } error LDMinusSD(); error AmountSlippage(uint _amountLDSend, uint256 _minAmountLD); event SetInspector(address _inspector); event SendOFT(bytes32 indexed _guid, address indexed _fromAddress, uint _amountLD, bytes _composeMsg); event ReceiveOFT(bytes32 indexed _guid, address indexed _toAddress, uint _amountLD); function token() external view returns (address); function quoteSendFee( SendParam calldata _send, bytes calldata _options, bool _useLZToken, bytes calldata _composeMsg ) external view returns (uint nativeFee, uint lzTokenFee); function send( SendParam calldata _send, bytes calldata _options, MessagingFee calldata _msgFee, address payable _refundAddress, bytes calldata _composeMsg ) external payable returns (MessagingReceipt memory); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {Origin} from "@layerzerolabs/lz-evm-protocol-v2/contracts/MessagingStructs.sol"; import "./interfaces/IPreCrimeV2Simulator.sol"; import "./interfaces/IPreCrimeV2.sol"; abstract contract PreCrimeV2Simulator is IPreCrimeV2Simulator { /// @dev a generic interface for precrime simulations /// @dev this function reverts at the end with the simulation results /// @dev value is provided as a lump sum, does not restrict how much each packet can consume function lzReceiveAndRevert(InboundPacket[] calldata _packets) external payable virtual override { this._simulateLzReceive{value: msg.value}(_packets); // msg.sender should be the precrime contract with the buildSimulationResult() function revert SimulationResult(IPreCrimeV2(msg.sender).buildSimulationResult()); } function _simulateLzReceive(InboundPacket[] calldata _packets) external payable virtual { assert(msg.sender == address(this)); _beforeSimulation(_packets); for (uint i = 0; i < _packets.length; i++) { // skip packet from untrusted peer InboundPacket calldata packet = _packets[i]; if (!isPeer(packet.origin.srcEid, packet.origin.sender)) continue; _lzReceive(packet.origin, packet.guid, packet.message); } } function _beforeSimulation(InboundPacket[] calldata _packets) internal virtual {} function _lzReceive(Origin calldata _origin, bytes32 _guid, bytes calldata _message) internal virtual; function isPeer(uint32 _eid, bytes32 _peer) public view virtual returns (bool); /// @dev The simulator contract is the base contract for the OApp by default. /// @dev If the simulator is a separate contract, override this function. function oapp() external view virtual returns (address) { return address(this); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.0; struct PreCrimePeer { uint32 eid; bytes32 precrime; bytes32 oapp; } interface IPreCrimeV2 { error OnlyOffChain(); // for simulate() error PacketOversize(uint max, uint actual); error PacketUnsorted(); error SimulationFailed(bytes reason); // for precrime() error SimulationResultNotFound(uint32 eid); error InvalidSimulationResult(uint32 eid, bytes reason); error CrimeFound(bytes crime); function getConfig(bytes[] calldata _packets) external returns (bytes memory); function simulate(bytes[] calldata _packets) external payable returns (bytes memory); function buildSimulationResult() external view returns (bytes memory); function precrime(bytes[] calldata _packets, bytes[] calldata _simulations) external; function version() external view returns (uint64 major, uint8 minor); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.0; import {InboundPacket} from "../libs/Packet.sol"; interface IPreCrimeV2Simulator { // this error is only used to return the simulation result error SimulationResult(bytes result); function lzReceiveAndRevert(InboundPacket[] calldata _packets) external payable; function isPeer(uint32 _eid, bytes32 _peer) external view returns (bool); function oapp() external view returns (address); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {Origin} from "@layerzerolabs/lz-evm-protocol-v2/contracts/MessagingStructs.sol"; import {PacketV1Codec} from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.sol"; struct InboundPacket { Origin origin; uint32 dstEid; address receiver; bytes32 guid; bytes message; } library PacketDecoder { using PacketV1Codec for bytes; function decode(bytes calldata _packet) internal pure returns (InboundPacket memory packet) { packet.origin = Origin(_packet.srcEid(), _packet.sender(), _packet.nonce()); packet.dstEid = _packet.dstEid(); packet.receiver = _packet.receiverB20(); packet.guid = _packet.guid(); packet.message = _packet.message(); } function decode(bytes[] calldata _packets) internal pure returns (InboundPacket[] memory packets) { packets = new InboundPacket[](_packets.length); for (uint i = 0; i < _packets.length; i++) { bytes calldata packet = _packets[i]; packets[i] = PacketDecoder.decode(packet); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.0; struct PacketForQuote { address sender; uint32 dstEid; bytes message; } struct Packet { uint64 nonce; uint32 srcEid; address sender; uint32 dstEid; bytes32 receiver; bytes32 guid; bytes message; } struct Origin { uint32 srcEid; bytes32 sender; uint64 nonce; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.0; import "./IMessageLibManager.sol"; import "./IMessagingComposer.sol"; import "./IMessagingChannel.sol"; import "./IMessagingContext.sol"; import {Origin} from "../MessagingStructs.sol"; struct MessagingParams { uint32 dstEid; bytes32 receiver; bytes message; bytes options; } struct MessagingReceipt { bytes32 guid; uint64 nonce; MessagingFee fee; } struct MessagingFee { uint nativeFee; uint lzTokenFee; } interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext { event PacketSent(bytes encodedPayload, bytes options, address sendLibrary); event PacketDelivered(Origin origin, address receiver, bytes32 payloadHash); event PacketReceived(Origin origin, address receiver); event LzReceiveFailed(Origin origin, address receiver, bytes reason); event LayerZeroTokenSet(address token); function quote( address _sender, uint32 _dstEid, bytes calldata _message, bool _payInLzToken, bytes calldata _options ) external view returns (MessagingFee memory); function send( MessagingParams calldata _params, uint _lzTokenFee, address payable _refundAddress ) external payable returns (MessagingReceipt memory); function sendWithAlt( MessagingParams calldata _params, uint _lzTokenFee, uint _altTokenFee ) external returns (MessagingReceipt memory); function deliver(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external; function deliverable(Origin calldata _origin, address _receiveLib, address _receiver) external view returns (bool); function lzReceive( Origin calldata _origin, address _receiver, bytes32 _guid, bytes calldata _message, bytes calldata _extraData ) external payable returns (bool, bytes memory); // oapp can burn messages partially by calling this function with its own business logic if messages are delivered in order function clear(Origin calldata _origin, bytes32 _guid, bytes calldata _message) external; function setLayerZeroToken(address _layerZeroToken) external; function layerZeroToken() external view returns (address); function altFeeToken() external view returns (address); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.0; struct SetConfigParam { uint32 configType; bytes config; } interface IMessageLibManager { struct Timeout { address lib; uint expiry; } event LibraryRegistered(address newLib); event DefaultSendLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibrarySet(uint32 eid, address oldLib, address newLib); event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint expiry); event SendLibrarySet(address sender, uint32 eid, address newLib); event ReceiveLibrarySet(address receiver, uint32 eid, address oldLib, address newLib); event ReceiveLibraryTimoutSet(address receiver, uint32 eid, address oldLib, uint timeout); function registerLibrary(address _lib) external; function isRegisteredLibrary(address _lib) external view returns (bool); function getRegisteredLibraries() external view returns (address[] memory); function setDefaultSendLibrary(uint32 _eid, address _newLib) external; function defaultSendLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint _timeout) external; function defaultReceiveLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint _expiry) external; function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint expiry); function defaultConfig(address _lib, uint32 _eid, uint32 _configType) external view returns (bytes memory); function isSupportedEid(uint32 _eid) external view returns (bool); /// ------------------- OApp interfaces ------------------- function setSendLibrary(uint32 _eid, address _newLib) external; function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib); function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool); function setReceiveLibrary(uint32 _eid, address _newLib, uint _gracePeriod) external; function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault); function setReceiveLibraryTimeout(uint32 _eid, address _lib, uint _gracePeriod) external; function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint expiry); function setConfig(address _lib, uint32 _eid, SetConfigParam[] calldata _params) external; function getConfig( address _oapp, address _lib, uint32 _eid, uint32 _configType ) external view returns (bytes memory config, bool isDefault); function snapshotConfig(address _lib, uint32[] calldata _eids) external; function resetConfig(address _lib, uint32[] calldata _eids) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.0; interface IMessagingChannel { event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce); function eid() external view returns (uint32); // this is an emergency function if a message can not be delivered for some reasons // required to provide _nextNonce to avoid race condition function skip(uint32 _srcEid, bytes32 _sender, uint64 _nonce) external; function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32); function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64); function inboundPayloadHash( address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce ) external view returns (bytes32); function hasPayloadHash( address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce ) external view returns (bool); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.0; interface IMessagingComposer { event ComposedMessageDelivered(address receiver, address composer, bytes32 guid, bytes message); event ComposedMessageReceived(address receiver, address composer, bytes32 guid); event LzComposeFailed(address receiver, address composer, bytes32 guid, bytes reason); function deliverComposedMessage(address _composer, bytes32 _guid, bytes calldata _message) external; function lzCompose( address _receiver, address _composer, bytes32 _guid, bytes calldata _message, bytes calldata _extraData ) external payable returns (bool, bytes memory); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.8.0; interface IMessagingContext { function isSendingMessage() external view returns (bool); function getSendContext() external view returns (uint32, address); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Errors.sol"; library AddressCast { function toBytes32(bytes calldata _addressBytes) internal pure returns (bytes32 result) { require(_addressBytes.length <= 32, Errors.INVALID_SIZE); result = bytes32(_addressBytes); unchecked { uint offset = 32 - _addressBytes.length; result = result >> (offset * 8); } } function toBytes32(address _address) internal pure returns (bytes32 result) { result = bytes32(uint(uint160(_address))); } function toBytes(bytes32 _addressBytes32, uint _size) internal pure returns (bytes memory result) { require(_size > 0 && _size <= 32, Errors.INVALID_SIZE); result = new bytes(_size); unchecked { uint256 offset = 256 - _size * 8; assembly { mstore(add(result, 32), shl(offset, _addressBytes32)) } } } function toAddress(bytes32 _addressBytes32) internal pure returns (address result) { result = address(uint160(uint(_addressBytes32))); } function toAddress(bytes calldata _addressBytes) internal pure returns (address result) { require(_addressBytes.length == 20, Errors.INVALID_SIZE); result = address(bytes20(_addressBytes)); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library Errors { // Invalid Argument (http: 400) string internal constant INVALID_ARGUMENT = "LZ10000"; string internal constant ONLY_REGISTERED = "LZ10001"; string internal constant ONLY_REGISTERED_OR_DEFAULT = "LZ10002"; string internal constant INVALID_AMOUNT = "LZ10003"; string internal constant INVALID_NONCE = "LZ10004"; string internal constant SAME_VALUE = "LZ10005"; string internal constant UNSORTED = "LZ10006"; string internal constant INVALID_VERSION = "LZ10007"; string internal constant INVALID_EID = "LZ10008"; string internal constant INVALID_SIZE = "LZ10009"; string internal constant ONLY_NON_DEFAULT = "LZ10010"; string internal constant INVALID_VERIFIERS = "LZ10011"; string internal constant INVALID_WORKER_ID = "LZ10012"; string internal constant DUPLICATED_OPTION = "LZ10013"; string internal constant INVALID_LEGACY_OPTION = "LZ10014"; string internal constant INVALID_VERIFIER_OPTION = "LZ10015"; string internal constant INVALID_WORKER_OPTIONS = "LZ10016"; string internal constant INVALID_EXECUTOR_OPTION = "LZ10017"; string internal constant INVALID_ADDRESS = "LZ10018"; // Out of Range (http: 400) string internal constant OUT_OF_RANGE = "LZ20000"; // Invalid State (http: 400) string internal constant INVALID_STATE = "LZ30000"; string internal constant SEND_REENTRANCY = "LZ30001"; string internal constant RECEIVE_REENTRANCY = "LZ30002"; string internal constant COMPOSE_REENTRANCY = "LZ30003"; // Permission Denied (http: 403) string internal constant PERMISSION_DENIED = "LZ50000"; // Not Found (http: 404) string internal constant NOT_FOUND = "LZ60000"; // Already Exists (http: 409) string internal constant ALREADY_EXISTS = "LZ80000"; // Not Implemented (http: 501) string internal constant NOT_IMPLEMENTED = "LZC0000"; string internal constant UNSUPPORTED_INTERFACE = "LZC0001"; string internal constant UNSUPPORTED_OPTION_TYPE = "LZC0002"; // Unavailable (http: 503) string internal constant UNAVAILABLE = "LZD0000"; string internal constant NATIVE_COIN_UNAVAILABLE = "LZD0001"; string internal constant TOKEN_UNAVAILABLE = "LZD0002"; string internal constant DEFAULT_LIBRARY_UNAVAILABLE = "LZD0003"; string internal constant VERIFIERS_UNAVAILABLE = "LZD0004"; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../../libs/AddressCast.sol"; import {Packet} from "../../MessagingStructs.sol"; library PacketV1Codec { using AddressCast for address; using AddressCast for bytes32; uint8 internal constant PACKET_VERSION = 1; // header (version + nonce + path) // version uint private constant PACKET_VERSION_OFFSET = 0; // nonce uint private constant NONCE_OFFSET = 1; // path uint private constant SRC_EID_OFFSET = 9; uint private constant SENDER_OFFSET = 13; uint private constant DST_EID_OFFSET = 45; uint private constant RECEIVER_OFFSET = 49; // payload (guid + message) uint private constant GUID_OFFSET = 81; // keccak256(nonce + path) uint private constant MESSAGE_OFFSET = 113; function encode(Packet memory _packet) internal pure returns (bytes memory encodedPacket) { encodedPacket = abi.encodePacked( PACKET_VERSION, _packet.nonce, _packet.srcEid, _packet.sender.toBytes32(), _packet.dstEid, _packet.receiver, _packet.guid, _packet.message ); } function encodePacketHeader(Packet memory _packet) internal pure returns (bytes memory) { return abi.encodePacked( PACKET_VERSION, _packet.nonce, _packet.srcEid, _packet.sender.toBytes32(), _packet.dstEid, _packet.receiver ); } function encodePayload(Packet memory _packet) internal pure returns (bytes memory) { return abi.encodePacked(_packet.guid, _packet.message); } function header(bytes calldata _packet) internal pure returns (bytes calldata) { return _packet[0:GUID_OFFSET]; } function version(bytes calldata _packet) internal pure returns (uint8) { return uint8(bytes1(_packet[PACKET_VERSION_OFFSET:NONCE_OFFSET])); } function nonce(bytes calldata _packet) internal pure returns (uint64) { return uint64(bytes8(_packet[NONCE_OFFSET:SRC_EID_OFFSET])); } function srcEid(bytes calldata _packet) internal pure returns (uint32) { return uint32(bytes4(_packet[SRC_EID_OFFSET:SENDER_OFFSET])); } function sender(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[SENDER_OFFSET:DST_EID_OFFSET]); } function senderAddressB20(bytes calldata _packet) internal pure returns (address) { return sender(_packet).toAddress(); } function dstEid(bytes calldata _packet) internal pure returns (uint32) { return uint32(bytes4(_packet[DST_EID_OFFSET:RECEIVER_OFFSET])); } function receiver(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[RECEIVER_OFFSET:GUID_OFFSET]); } function receiverB20(bytes calldata _packet) internal pure returns (address) { return receiver(_packet).toAddress(); } function guid(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[GUID_OFFSET:MESSAGE_OFFSET]); } function message(bytes calldata _packet) internal pure returns (bytes calldata) { return bytes(_packet[MESSAGE_OFFSET:]); } function payload(bytes calldata _packet) internal pure returns (bytes calldata) { return bytes(_packet[GUID_OFFSET:]); } function payloadHash(bytes calldata _packet) internal pure returns (bytes32) { return keccak256(payload(_packet)); } }
// SPDX-License-Identifier: 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.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 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: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the 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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.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() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the 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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.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 Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.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' 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)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @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"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/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"); (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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^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 meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such 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. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: LZBL-1.1 // Copyright 2023 LayerZero Labs Ltd. // You may obtain a copy of the License at // https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1 pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; import {IMessaging} from "./interfaces/IMessaging.sol"; import {IUSDV} from "../usdv/interfaces/IUSDV.sol"; import {IVaultManager} from "../vault/interfaces/IVaultManager.sol"; abstract contract Messaging is Ownable, IMessaging { uint32 public immutable mainChainEid; bool public immutable isMainChain; address public immutable usdv; mapping(uint32 dstEid => mapping(uint8 msgType => uint extraGas)) public perColorExtraGasLookup; constructor(address _usdv, uint32 _mainChainEid, bool _isMainChain) { usdv = _usdv; mainChainEid = _mainChainEid; isMainChain = _isMainChain; } modifier onlyUSDV() { if (msg.sender != usdv) revert NotUSDV(msg.sender); _; } // ======================== onlyOwner ======================== function setPerColorExtraGas(uint32 _dstEid, uint8 _msgType, uint _extraGas) external onlyOwner { perColorExtraGasLookup[_dstEid][_msgType] = _extraGas; emit SetPerColorExtraGas(_dstEid, _msgType, _extraGas); } }
// SPDX-License-Identifier: LZBL-1.1 // Copyright 2023 LayerZero Labs Ltd. // You may obtain a copy of the License at // https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1 pragma solidity ^0.8.0; import "@layerzerolabs/lz-evm-oapp-v1/contracts/lzApp/LzApp.sol"; import "@layerzerolabs/lz-evm-oapp-v1/contracts/util/ExcessivelySafeCall.sol"; /* * COPY of https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/NonblockingLzApp.sol * Only diff is using calldata for _nonblockingLzReceive params * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress) */ abstract contract NonblockingLzApp is LzApp { using ExcessivelySafeCall for address; constructor(address _endpoint) LzApp(_endpoint) {} mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages; event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason); event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash); // overriding the virtual function in LzReceiver function _blockingLzReceive( uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload ) internal virtual override { (bool success, bytes memory reason) = address(this).excessivelySafeCall( gasleft(), 150, abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload) ); // try-catch all errors/exceptions if (!success) { _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason); } } function _storeFailedMessage( uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload, bytes memory _reason ) internal virtual { failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason); } function nonblockingLzReceive( uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload ) public virtual { // only internal transaction require(_msgSender() == address(this), "NonblockingLzApp: caller must be LzApp"); _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } //@notice override this function function _nonblockingLzReceive( uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload ) internal virtual; function retryMessage( uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload ) public payable virtual { // assert there is message to retry bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce]; require(payloadHash != bytes32(0), "NonblockingLzApp: no stored message"); require(keccak256(_payload) == payloadHash, "NonblockingLzApp: invalid payload"); // clear the stored message failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0); // execute the message. revert if it fails again _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash); } }
// SPDX-License-Identifier: LZBL-1.1 // Copyright 2023 LayerZero Labs Ltd. // You may obtain a copy of the License at // https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1 pragma solidity ^0.8.0; import "@layerzerolabs/lz-evm-oapp-v2/contracts/standards/oft/interfaces/IOFT.sol"; import {MessagingFee, MessagingParams, MessagingReceipt} from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import {Delta} from "../../usdv/interfaces/IUSDV.sol"; interface IMessaging { error NotUSDV(address sender); error NotImplemented(); error NotMainChain(); event SetPerColorExtraGas(uint32 dstEid, uint8 msgType, uint extraGas); struct SendParam { uint32 dstEid; bytes32 to; uint32 color; uint64 amount; uint64 theta; } function send( SendParam calldata _pram, bytes calldata _extraOptions, MessagingFee calldata _msgFee, address payable _refundAddress, bytes calldata _composeMsg ) external payable returns (MessagingReceipt memory msgReceipt); function syncDelta( uint32 _dstEid, Delta[] calldata _deltas, bytes calldata _extraOptions, MessagingFee calldata _msgFee, address payable _refundAddress ) external payable returns (MessagingReceipt memory msgReceipt); function quoteSendFee( uint32 _dstEid, bytes calldata _extraOptions, bool _useLZToken, bytes calldata _composeMsg ) external view returns (uint nativeFee, uint lzTokenFee); function quoteSyncDeltaFee( uint32 _dstEid, Delta[] calldata _deltas, bytes calldata _extraOptions, bool _useLZToken ) external view returns (uint nativeFee, uint lzTokenFee); function remint( Delta[] calldata _deltas, uint32 _feeColor, uint64 _feeAmount, uint64 _feeTheta, bytes calldata _extraOptions, MessagingFee calldata _msgFee, address payable _refundAddress ) external payable returns (MessagingReceipt memory msgReceipt); function quoteRemintFee( Delta[] calldata _deltas, bytes calldata _extraOptions, bool _useLZToken ) external view returns (uint nativeFee, uint lzTokenFee); }
// SPDX-License-Identifier: LZBL-1.1 // Copyright 2023 LayerZero Labs Ltd. // You may obtain a copy of the License at // https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1 pragma solidity ^0.8.0; import {Delta} from "../../usdv/interfaces/IUSDV.sol"; import "@ensdomain/buffer/contracts/Buffer.sol"; struct SendMsg { address to; uint32 color; uint64 amount; uint64 theta; } struct SendAndCallMsg { address to; uint32 color; uint64 amount; uint64 theta; bytes composeMsg; } struct SyncDeltaMsg { Delta[] deltas; } struct RemintMsg { Delta[] deltas; uint32 color; uint64 amount; uint64 theta; } library MsgCodec { using Buffer for Buffer.buffer; // message types uint8 internal constant MSG_TYPE_SEND = 1; uint8 internal constant MSG_TYPE_SEND_AND_CALL = 2; uint8 internal constant MSG_TYPE_SYNC_DELTA = 3; uint8 internal constant MSG_TYPE_REMINT = 4; // offsets uint8 internal constant MSG_TYPE_OFFSET = 0; // send / send and call uint8 internal constant TO_OFFSET = 1; uint8 internal constant COLOR_OFFSET = 33; uint8 internal constant AMOUNT_OFFSET = 37; uint8 internal constant THETA_OFFSET = 45; // send and call uint8 internal constant COMPOSED_MSG_OFFSET = 53; // sync delta uint8 internal constant SYNC_DELTAS_OFFSET = 1; // remint uint8 internal constant REMINT_COLOR_OFFSET = 1; uint8 internal constant REMINT_AMOUNT_OFFSET = 5; uint8 internal constant REMINT_THETA_OFFSET = 13; uint8 internal constant REMINT_DELTAS_OFFSET = 21; error InvalidSize(); function encodeSendMsg( bytes32 _to, uint32 _color, uint64 _amount, uint64 _theta ) internal pure returns (bytes memory) { return abi.encodePacked(MSG_TYPE_SEND, _to, _color, _amount, _theta); } function decodeSendMsg(bytes calldata _message) internal pure returns (SendMsg memory) { if (_message.length != 53) revert InvalidSize(); return SendMsg({ to: toAddressB20(bytes32(_message[TO_OFFSET:COLOR_OFFSET])), color: uint32(bytes4(_message[COLOR_OFFSET:AMOUNT_OFFSET])), amount: uint64(bytes8(_message[AMOUNT_OFFSET:THETA_OFFSET])), theta: uint64(bytes8(_message[THETA_OFFSET:53])) }); } function encodeSendAndCallMsg( bytes32 _to, uint32 _color, uint64 _amount, uint64 _theta, address _caller, // OFTComposeMsgCodec expects compose msg to include caller/composeFrom bytes memory _composeMsg // extra data ) internal pure returns (bytes memory) { return abi.encodePacked( MSG_TYPE_SEND_AND_CALL, _to, _color, _amount, _theta, addressToBytes32(_caller), _composeMsg ); } function decodeSendAndCallMsg(bytes calldata _message) internal pure returns (SendAndCallMsg memory) { if (_message.length < 53) revert InvalidSize(); return SendAndCallMsg({ to: toAddressB20(bytes32(_message[TO_OFFSET:COLOR_OFFSET])), color: uint32(bytes4(_message[COLOR_OFFSET:AMOUNT_OFFSET])), amount: uint64(bytes8(_message[AMOUNT_OFFSET:THETA_OFFSET])), theta: uint64(bytes8(_message[THETA_OFFSET:COMPOSED_MSG_OFFSET])), composeMsg: _message[COMPOSED_MSG_OFFSET:] }); } function encodeSyncDeltaMsg(Delta[] calldata _deltas) internal pure returns (bytes memory) { Buffer.buffer memory buf; buf.init(_deltas.length * 12 + 1); buf.appendUint8(MSG_TYPE_SYNC_DELTA); for (uint i = 0; i < _deltas.length; i++) { Delta calldata delta = _deltas[i]; buf.appendInt(delta.color, 4); buf.appendInt(uint64(delta.amount), 8); } return buf.buf; } function decodeSyncDeltaMsg(bytes calldata _message) internal pure returns (SyncDeltaMsg memory) { if ((_message.length - SYNC_DELTAS_OFFSET) % 12 != 0) revert InvalidSize(); uint size = (_message.length - SYNC_DELTAS_OFFSET) / 12; Delta[] memory deltas = new Delta[](size); for (uint i = 0; i < size; i++) { uint offset = SYNC_DELTAS_OFFSET + i * 12; deltas[i] = Delta({ color: uint32(bytes4(_message[offset:offset + 4])), amount: int64(uint64(bytes8(_message[offset + 4:offset + 12]))) }); } return SyncDeltaMsg({deltas: deltas}); } function encodeRemintMsg( Delta[] calldata _deltas, uint32 _color, uint64 _amount, uint64 _theta ) internal pure returns (bytes memory) { Buffer.buffer memory buf; buf.init(_deltas.length * 12 + 21); // 1 + 4 + 8 + 8 buf.appendUint8(MSG_TYPE_REMINT); buf.appendInt(_color, 4); buf.appendInt(_amount, 8); buf.appendInt(_theta, 8); for (uint i = 0; i < _deltas.length; i++) { Delta calldata delta = _deltas[i]; buf.appendInt(delta.color, 4); buf.appendInt(uint64(delta.amount), 8); } return buf.buf; } function decodeRemintMsg(bytes calldata _message) internal pure returns (RemintMsg memory) { if ((_message.length - REMINT_DELTAS_OFFSET) % 12 != 0) revert InvalidSize(); uint size = (_message.length - REMINT_DELTAS_OFFSET) / 12; Delta[] memory deltas = new Delta[](size); for (uint i = 0; i < size; i++) { uint offset = REMINT_DELTAS_OFFSET + i * 12; deltas[i] = Delta({ color: uint32(bytes4(_message[offset:offset + 4])), amount: int64(uint64(bytes8(_message[offset + 4:offset + 12]))) }); } return RemintMsg({ color: uint32(bytes4(_message[REMINT_COLOR_OFFSET:REMINT_AMOUNT_OFFSET])), amount: uint64(bytes8(_message[REMINT_AMOUNT_OFFSET:REMINT_THETA_OFFSET])), theta: uint64(bytes8(_message[REMINT_THETA_OFFSET:REMINT_DELTAS_OFFSET])), deltas: deltas }); } function msgType(bytes calldata _message) internal pure returns (uint8) { return uint8(bytes1(_message[MSG_TYPE_OFFSET:1])); } function toAddressB20(bytes32 _addr) internal pure returns (address) { return bytes32ToAddress(_addr); } function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } }
// SPDX-License-Identifier: LZBL-1.1 // Copyright 2023 LayerZero Labs Ltd. // You may obtain a copy of the License at // https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1 pragma solidity ^0.8.0; import "@layerzerolabs/lz-evm-oapp-v2/contracts/standards/oft/interfaces/IOFT.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; struct Delta { uint32 color; int64 amount; } struct State { uint32 color; uint64 balance; // config bool blacklisted; uint32 defaultColor; } enum Role { OWNER, OPERATOR, VAULT, MESSAGING, FOUNDATION } interface IUSDV is IOFT, IERC20Upgradeable { error Unauthorized(); error InvalidUser(); error InvalidArgument(); error NotImplemented(); error InsufficientBalance(); error Paused(); error Blacklisted(); error FeeTooHigh(); // role assigment event SetRole(Role role, address addr); event SetColorer(address indexed caller, address indexed user, address colorer); event SetDefaultColor(address indexed caller, address indexed user, uint32 defaultColor); // governance state event SetBlacklist(address indexed user, bool isBlacklisted); event SetPause(bool paused); // cross-chain events event Synced(bytes32 guid, Delta[] deltas); function mint(address _receiver, uint64 _amount, uint32 _color) external; function burn(address _from, uint64 _amount, uint32[] calldata _delta) external returns (Delta[] memory deltas); /// -------- coloring interfaces -------- function setColorer(address _user, address _colorer) external; function setDefaultColor(address _user, uint32 _defaultColor) external; /// -------- governance interfaces -------- function setPause(bool _pause) external; function setRole(Role _role, address _addr) external; /// -------- cross-chain interfaces (non-OFT) -------- function sendAck(bytes32 _guid, address _receiver, uint32 _color, uint64 _amount, uint64 _theta) external; function syncDelta( uint32 _dstEid, uint64 _theta, uint32[] calldata _deficits, uint64 _feeCap, bytes calldata _extraOptions, MessagingFee calldata _msgFee, address payable _refundAddress ) external payable returns (MessagingReceipt memory msgReceipt); function syncDeltaAck(Delta[] calldata _deltas) external; function quoteSyncDeltaFee( uint32 _dstEid, uint32 _numDeficits, bytes calldata _extraOptions, bool _useLzToken ) external view returns (uint nativeFee, uint lzTokenFee); function userStates( address _user ) external view returns (uint32 color, uint64 balance, bool blacklisted, uint32 defaultColor); }
// SPDX-License-Identifier: LZBL-1.1 // Copyright 2023 LayerZero Labs Ltd. // You may obtain a copy of the License at // https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1 pragma solidity ^0.8.0; import "./IUSDV.sol"; interface IUSDVMain is IUSDV { event Reminted(Delta[] deltas, uint64 remintFee); function remint(uint32 _surplusColor, uint64 _surplusAmount, uint32[] calldata _deficits, uint64 _feeCap) external; function remintAck(Delta[] calldata _deltas, uint32 _feeColor, uint64 _feeAmount, uint64 _feeTheta) external; }
// SPDX-License-Identifier: LZBL-1.1 // Copyright 2023 LayerZero Labs Ltd. // You may obtain a copy of the License at // https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1 pragma solidity ^0.8.0; import {Delta} from "../../usdv/interfaces/IUSDV.sol"; import "../libs/Asset.sol"; enum Role { OWNER, OPERATOR, FOUNDATION, LIQUIDITY_PROVIDER, DONOR } interface IVaultManager { error InvalidAmount(); error NotDeltaZero(); error WrongSign(); error InvalidArgument(); error InvalidColor(uint32 color); error ColorPaused(); error Unauthorized(); event DistributedReward(address[] token, uint[] amounts); event Minted(address indexed receiver, uint32 indexed color, uint64 amount, bytes32 memo); event Redeemed(address indexed redeemer, uint64 amount); event PendingRemint(Delta[] deltas); event WithdrewReward(address caller, address receiver, uint32 color, uint64 rewards); event WithdrewFees(address caller, address receiver, uint64 fees); event RegisteredAsset(address asset); event EnabledAsset(bool enabled); event SetRole(Role role, address addr); event SetFeeBpsCap(Role role, uint16 cap); event SetFeeBps(Role role, uint16 bps); event SetRateLimiter(address limiter); event PausedColor(uint32 color, bool paused); event SetMinter(address minter, uint32 color); function assetInfoOf( address _token ) external view returns (bool enabled, uint usdvToTokenRate, uint collateralized); function mint(address _token, address _receiver, uint64 _amount, uint32 _color, bytes32 _memo) external; function remint(Delta[] calldata _deltas, uint64 _remintFee) external; function redeem( address _token, address _receiver, uint64 _amount, uint64 _minAmount, uint32[] calldata _deficits ) external returns (uint amountAfterFee); function redeemOut(address _token, uint64 _amount) external view returns (uint); }
// SPDX-License-Identifier: LZBL-1.1 // Copyright 2023 LayerZero Labs Ltd. // You may obtain a copy of the License at // https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1 pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {Governance} from "./Governance.sol"; library Asset { using SafeERC20 for IERC20; using Governance for Governance.Info; struct Info { IERC20 token; bool registered; bool enabled; // to allow minting uint usdvToTokenRate; // all the following values are in token amount uint collateralized; } error TokenDecimalInvalid(uint provided, uint min); error Disabled(); error AlreadyRegistered(); error SlippageTooHigh(); error NotRegistered(); modifier onlyRegistered(Info storage _self) { if (!_self.registered) revert NotRegistered(); _; } function initialize(Info storage _self, address _token, uint8 _shareDecimals) internal { if (_self.registered) revert AlreadyRegistered(); // set token _self.token = IERC20(_token); _self.enabled = true; _self.registered = true; // set conversion rate uint8 tokenDecimals = IERC20Metadata(_token).decimals(); if (_shareDecimals > tokenDecimals) { revert TokenDecimalInvalid(tokenDecimals, _shareDecimals); } _self.usdvToTokenRate = 10 ** (tokenDecimals - _shareDecimals); } // @dev if _newFund is true, _from must approve the token transfer // @dev if internal mint such as turning yield into collateral, _newFund should be false function credit(Info storage _self, address _from, uint64 _usdvAmount, bool _newFund) internal { // assert the asset is enabled if (!_self.enabled) revert Disabled(); uint tokenAmount = _usdv2Token(_self, _usdvAmount); _self.collateralized += tokenAmount; if (_newFund) { _self.token.safeTransferFrom(_from, address(this), tokenAmount); } } function redeem( Info storage _self, Governance.Info storage _govInfo, address _receiver, uint64 _usdvAmount, uint64 _minUsdvAmount ) internal onlyRegistered(_self) returns (uint amountAfterFee) { uint tokenAmount = _usdv2Token(_self, _usdvAmount); _self.collateralized -= tokenAmount; // pay redemption fee amountAfterFee = _govInfo.payRedemptionFee(_self.token, tokenAmount); if (amountAfterFee < _usdv2Token(_self, _minUsdvAmount)) revert SlippageTooHigh(); // transfer collateral to receiver _self.token.safeTransfer(_receiver, amountAfterFee); } function setEnabled(Info storage _self, bool _enabled) internal onlyRegistered(_self) { _self.enabled = _enabled; } // ========================= View ========================= /// @return reward in usdv function distributable(Info storage _self) internal view returns (uint) { uint rebasedFunds = _self.token.balanceOf(address(this)) - _self.collateralized; return rebasedFunds / _self.usdvToTokenRate; } function redeemOutput( Info storage _self, Governance.Info storage _govInfo, uint64 _shares ) internal view returns (uint) { uint tokenAmount = _usdv2Token(_self, _shares); return tokenAmount - _govInfo.getRedemptionFee(tokenAmount); } // ========================= Internal ========================= function _usdv2Token(Info storage _self, uint64 _shares) private view returns (uint) { return _shares * _self.usdvToTokenRate; } }
// SPDX-License-Identifier: LZBL-1.1 // Copyright 2023 LayerZero Labs Ltd. // You may obtain a copy of the License at // https://github.com/LayerZero-Labs/license/blob/main/LICENSE-LZBL-1.1 pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {Role} from "../interfaces/IVaultManager.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; library Governance { using SafeERC20 for IERC20; uint16 internal constant ONE_HUNDRED_PERCENT = 10000; // 100% uint16 internal constant RESERVE_FEE_BPS_CAP = 300; // 3% // A % fee is applicable on yield distribution for the vault service. uint16 internal constant REDEMPTION_FEE_BPS_CAP_MIN = 10; //0.1% struct Fee { uint16 bps; uint16 cap; } struct Info { mapping(Role => Fee) fees; mapping(Role => address) roles; uint operatorLastPing; // timestamp } event PaidRedemptionFee(address indexed to, uint amount); // ========================= Operator ========================= function ping(Info storage _self) internal { _self.operatorLastPing = block.timestamp; } // ========================= Fees ========================= function getRedemptionFee(Info storage _self, uint _amount) internal view returns (uint fee) { return (_amount * _self.fees[Role.FOUNDATION].bps) / ONE_HUNDRED_PERCENT; } function payRedemptionFee(Info storage _self, IERC20 _token, uint _amount) internal returns (uint) { uint fee = getRedemptionFee(_self, _amount); // pay redemption fee to operator address _to = _self.roles[Role.OPERATOR]; _token.safeTransfer(_to, fee); emit PaidRedemptionFee(_to, fee); return _amount - fee; } }
// SPDX-License-Identifier: Unlicense /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.8.0 <0.9.0; library BytesLib { function concat( bytes memory _preBytes, bytes memory _postBytes ) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage( bytes storage _preBytes, bytes memory _postBytes ) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } }
{ "evmVersion": "paris", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 5000 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_endpoint","type":"address"},{"internalType":"address","name":"_usdv","type":"address"},{"internalType":"uint32","name":"_mainChainEid","type":"uint32"},{"internalType":"bool","name":"_isMainChain","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidSize","type":"error"},{"inputs":[],"name":"NotImplemented","type":"error"},{"inputs":[],"name":"NotMainChain","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"NotUSDV","type":"error"},{"inputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"name":"SimulationResult","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"MessageFailed","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":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"_payloadHash","type":"bytes32"}],"name":"RetryMessageSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_type","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_minDstGas","type":"uint256"}],"name":"SetMinDstGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"dstEid","type":"uint32"},{"indexed":false,"internalType":"uint8","name":"msgType","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"extraGas","type":"uint256"}],"name":"SetPerColorExtraGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"precrime","type":"address"}],"name":"SetPrecrime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_path","type":"bytes"}],"name":"SetTrustedRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"SetTrustedRemoteAddress","type":"event"},{"inputs":[{"components":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"},{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct InboundPacket[]","name":"_packets","type":"tuple[]"}],"name":"_simulateLzReceive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"failedMessages","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"forceResumeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"}],"name":"getTrustedRemoteAddress","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMainChain","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"isPeer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"isTrustedRemote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"},{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct InboundPacket[]","name":"_packets","type":"tuple[]"}],"name":"lzReceiveAndRevert","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mainChainEid","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"minDstGasLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"nonblockingLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oapp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"uint8","name":"msgType","type":"uint8"}],"name":"perColorExtraGasLookup","outputs":[{"internalType":"uint256","name":"extraGas","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"precrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"color","type":"uint32"},{"internalType":"int64","name":"amount","type":"int64"}],"internalType":"struct Delta[]","name":"_deltas","type":"tuple[]"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"},{"internalType":"bool","name":"","type":"bool"}],"name":"quoteRemintFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_dstEid","type":"uint32"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"bytes","name":"_composeMsg","type":"bytes"}],"name":"quoteSendFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_dstEid","type":"uint32"},{"components":[{"internalType":"uint32","name":"color","type":"uint32"},{"internalType":"int64","name":"amount","type":"int64"}],"internalType":"struct Delta[]","name":"_deltas","type":"tuple[]"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"},{"internalType":"bool","name":"","type":"bool"}],"name":"quoteSyncDeltaFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"color","type":"uint32"},{"internalType":"int64","name":"amount","type":"int64"}],"internalType":"struct Delta[]","name":"_deltas","type":"tuple[]"},{"internalType":"uint32","name":"_feeColor","type":"uint32"},{"internalType":"uint64","name":"_feeAmount","type":"uint64"},{"internalType":"uint64","name":"_feeTheta","type":"uint64"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"","type":"tuple"},{"internalType":"address payable","name":"_refundAddress","type":"address"}],"name":"remint","outputs":[{"components":[{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt","name":"msgReceipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint32","name":"color","type":"uint32"},{"internalType":"uint64","name":"amount","type":"uint64"},{"internalType":"uint64","name":"theta","type":"uint64"}],"internalType":"struct IMessaging.SendParam","name":"_param","type":"tuple"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"","type":"tuple"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"bytes","name":"_composeMsg","type":"bytes"}],"name":"send","outputs":[{"components":[{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt","name":"msgReceipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGas","type":"uint256"}],"name":"setMinDstGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_dstEid","type":"uint32"},{"internalType":"uint8","name":"_msgType","type":"uint8"},{"internalType":"uint256","name":"_extraGas","type":"uint256"}],"name":"setPerColorExtraGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_precrime","type":"address"}],"name":"setPrecrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setReceiveVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setSendVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_path","type":"bytes"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"setTrustedRemoteAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_dstEid","type":"uint32"},{"components":[{"internalType":"uint32","name":"color","type":"uint32"},{"internalType":"int64","name":"amount","type":"int64"}],"internalType":"struct Delta[]","name":"_deltas","type":"tuple[]"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"","type":"tuple"},{"internalType":"address payable","name":"_refundAddress","type":"address"}],"name":"syncDelta","outputs":[{"components":[{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt","name":"msgReceipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdv","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b5060405162004e6c38038062004e6c8339810160408190526200003591620000e3565b8282828680620000453362000076565b6001600160a01b039081166080529390931660e05263ffffffff90911660a052151560c05250620001519350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620000de57600080fd5b919050565b60008060008060808587031215620000fa57600080fd5b6200010585620000c6565b93506200011560208601620000c6565b9250604085015163ffffffff811681146200012f57600080fd5b606086015190925080151581146200014657600080fd5b939692955090935050565b60805160a05160c05160e051614c4e6200021e6000396000818161064101528181610b6c015281816114c5015281816119c1015281816129e801528181612ab60152612bba0152600081816107090152612b150152600081816105e501528181611090015281816110fe01528181611a210152611aa50152600081816106d50152818161080101528181610a8001528181610b2201528181610f2c0152818161114c015281816112360152818161134901528181611d5e015281816121ab01526125cd0152614c4e6000f3fe6080604052600436106102695760003560e01c80637533d78811610153578063a6c3d165116100cb578063d1deba1f1161007f578063eb8d72b711610064578063eb8d72b71461079e578063f2fde38b146107be578063f5ecbdbc146107de57600080fd5b8063d1deba1f1461076b578063df2a5b3b1461077e57600080fd5b8063b834f6fb116100b0578063b834f6fb146106f7578063baf3292d1461072b578063cbed8b9c1461074b57600080fd5b8063a6c3d165146106a3578063b353aaa7146106c357600080fd5b80639212a76e116101225780639420069c116101075780639420069c1461062f578063950c8a74146106635780639f38369a1461068357600080fd5b80639212a76e146105d357806393284d951461061c57600080fd5b80637533d788146105305780637f3cbb891461055d5780638cfd8f5c1461057d5780638da5cb5b146105b557600080fd5b806342d65a8d116101e65780635a0dfe4d116101b557806366ad5c8a1161019a57806366ad5c8a146104e8578063715018a61461050857806374c71e0d1461051d57600080fd5b80635a0dfe4d146104795780635b8c41e61461049957600080fd5b806342d65a8d1461041357806344d9c507146104335780635011e5b314610453578063564991451461046657600080fd5b806318d6b43a1161023d578063314dfef511610222578063314dfef51461038e5780633d8b38f6146103c3578063403a8942146103f357600080fd5b806318d6b43a146102fc57806327d19a2c1461034857600080fd5b80621d35671461026e57806307e0db17146102905780630931cf88146102b057806310ddb137146102dc575b600080fd5b34801561027a57600080fd5b5061028e610289366004613731565b6107fe565b005b34801561029c57600080fd5b5061028e6102ab3660046137c5565b610a46565b3480156102bc57600080fd5b50305b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102e857600080fd5b5061028e6102f73660046137c5565b610ae8565b61030f61030a366004613807565b610b59565b604080518251815260208084015167ffffffffffffffff16818301529282015180519282019290925291015160608201526080016102d3565b34801561035457600080fd5b506103806103633660046138e1565b600560209081526000928352604080842090915290825290205481565b6040519081526020016102d3565b34801561039a57600080fd5b506103ae6103a9366004613924565b610dd5565b604080519283526020830191909152016102d3565b3480156103cf57600080fd5b506103e36103de366004613983565b610fba565b60405190151581526020016102d3565b3480156103ff57600080fd5b506103ae61040e366004613a1b565b611086565b34801561041f57600080fd5b5061028e61042e366004613983565b6111fe565b34801561043f57600080fd5b506103ae61044e366004613a9c565b61129d565b61028e610461366004613b2c565b6113a7565b61030f610474366004613ba1565b6114b2565b34801561048557600080fd5b506103e3610494366004613c48565b611614565b3480156104a557600080fd5b506103806104b4366004613cfa565b6004602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b3480156104f457600080fd5b5061028e610503366004613731565b611767565b34801561051457600080fd5b5061028e6117f2565b61028e61052b366004613b2c565b611806565b34801561053c57600080fd5b5061055061054b3660046137c5565b61189f565b6040516102d39190613deb565b34801561056957600080fd5b5061028e610578366004613dfe565b611939565b34801561058957600080fd5b50610380610598366004613e3a565b600260209081526000928352604080842090915290825290205481565b3480156105c157600080fd5b506000546001600160a01b03166102bf565b3480156105df57600080fd5b506106077f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016102d3565b61030f61062a366004613e64565b6119ae565b34801561063b57600080fd5b506102bf7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066f57600080fd5b506003546102bf906001600160a01b031681565b34801561068f57600080fd5b5061055061069e3660046137c5565b611b20565b3480156106af57600080fd5b5061028e6106be366004613983565b611c36565b3480156106cf57600080fd5b506102bf7f000000000000000000000000000000000000000000000000000000000000000081565b34801561070357600080fd5b506103e37f000000000000000000000000000000000000000000000000000000000000000081565b34801561073757600080fd5b5061028e610746366004613f2f565b611cb2565b34801561075757600080fd5b5061028e610766366004613f4c565b611d26565b61028e610779366004613731565b611dd4565b34801561078a57600080fd5b5061028e610799366004613fbb565b611fbd565b3480156107aa57600080fd5b5061028e6107b9366004613983565b612077565b3480156107ca57600080fd5b5061028e6107d9366004613f2f565b6120d1565b3480156107ea57600080fd5b506105506107f9366004613fe7565b612161565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161461087b5760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff86166000908152600160205260408120805461089990614034565b80601f01602080910402602001604051908101604052809291908181526020018280546108c590614034565b80156109125780601f106108e757610100808354040283529160200191610912565b820191906000526020600020905b8154815290600101906020018083116108f557829003601f168201915b5050505050905080518686905014801561092d575060008151115b801561095557508051602082012060405161094b9088908890614081565b6040518091039020145b6109c75760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152608401610872565b610a3d8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061222b92505050565b50505050505050565b610a4e6122d1565b6040517f07e0db1700000000000000000000000000000000000000000000000000000000815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610acd57600080fd5b505af1158015610ae1573d6000803e3d6000fd5b5050505050565b610af06122d1565b6040517f10ddb13700000000000000000000000000000000000000000000000000000000815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb13790602401610ab3565b610b61613671565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610bc5576040517f871f077c000000000000000000000000000000000000000000000000000000008152336004820152602401610872565b8115610c395760405162461bcd60e51b815260206004820152602560248201527f4d6573736167696e6756313a20636f6d706f73654d7367206e6f74207375707060448201527f6f727465640000000000000000000000000000000000000000000000000000006064820152608401610872565b6000610c56610c4b60208b018b614091565b63ffffffff1661232b565b9050610c9d81600160ff168a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506123a9915050565b610dc981610d8860208c0135610cb960608e0160408f01614091565b8d6060016020810190610ccc91906140ac565b8e6080016020810190610cdf91906140ac565b604080517f01000000000000000000000000000000000000000000000000000000000000006020820152602181019590955260e09390931b7fffffffff0000000000000000000000000000000000000000000000000000000016604185015260c091821b7fffffffffffffffff0000000000000000000000000000000000000000000000009081166045860152911b16604d830152805160358184030181526055909201905290565b8760008c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250349250612488915050565b50979650505050505050565b6000808215610e4c5760405162461bcd60e51b815260206004820152602560248201527f4d6573736167696e6756313a20636f6d706f73654d7367206e6f74207375707060448201527f6f727465640000000000000000000000000000000000000000000000000000006064820152608401610872565b6000610e5d8963ffffffff1661232b565b9050610ea481600160ff168a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506123a9915050565b604080517f010000000000000000000000000000000000000000000000000000000000000060208201526000602182018190526041820181905260458201819052604d82018190528251603581840301815260558301938490527f40a7bb10000000000000000000000000000000000000000000000000000000009093526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926340a7bb1092610f6a92869230929091908f908f906059016140f2565b6040805180830381865afa158015610f86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610faa9190614146565b9250925050965096945050505050565b61ffff831660009081526001602052604081208054829190610fdb90614034565b80601f016020809104026020016040519081016040528092919081815260200182805461100790614034565b80156110545780601f1061102957610100808354040283529160200191611054565b820191906000526020600020905b81548152906001019060200180831161103757829003601f168201915b50505050509050838360405161106b929190614081565b60405180910390208180519060200120149150509392505050565b60008060006110ba7f000000000000000000000000000000000000000000000000000000000000000063ffffffff1661232b565b905061114a81600460ff1688888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525063ffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526005602090815260408083206004845290915290205461114593508e92509050614199565b6123a9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340a7bb10823061118a8c8c6000806000612649565b60008b8b6040518763ffffffff1660e01b81526004016111af969594939291906140f2565b6040805180830381865afa1580156111cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ef9190614146565b92509250509550959350505050565b6112066122d1565b6040517f42d65a8d0000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d9061126f908690869086906004016141b0565b600060405180830381600087803b15801561128957600080fd5b505af1158015610a3d573d6000803e3d6000fd5b60008060006112b18963ffffffff1661232b565b905061134781600360ff1688888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508b8b9050600560008f63ffffffff1663ffffffff1681526020019081526020016000206000600360ff1660ff168152602001908152602001600020546111459190614199565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340a7bb1082306113828c8c612773565b60008b8b6040518763ffffffff1660e01b8152600401610f6a969594939291906140f2565b6040517f74c71e0d00000000000000000000000000000000000000000000000000000000815230906374c71e0d9034906113e79086908690600401614232565b6000604051808303818588803b15801561140057600080fd5b505af1158015611414573d6000803e3d6000fd5b5050505050336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261147f919081019061436a565b6040517f8351eea70000000000000000000000000000000000000000000000000000000081526004016108729190613deb565b6114ba613671565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461151e576040517f871f077c000000000000000000000000000000000000000000000000000000008152336004820152602401610872565b600061152f8963ffffffff1661232b565b90506115c581600360ff1688888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508b8b9050600560008f63ffffffff1663ffffffff1681526020019081526020016000206000600360ff1660ff168152602001908152602001600020546111459190614199565b610dc9816115d38a8a612773565b8560008a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250349250612488915050565b6000806001600061162a8663ffffffff1661232b565b61ffff1661ffff168152602001908152602001600020805461164b90614034565b80601f016020809104026020016040519081016040528092919081815260200182805461167790614034565b80156116c45780601f10611699576101008083540402835291602001916116c4565b820191906000526020600020905b8154815290600101906020018083116116a757829003601f168201915b50508351939450506014831191505080156116e0575060348111155b61172c5760405162461bcd60e51b815260206004820181905260248201527f4d6573736167696e6756313a20696e76616c69642070617468206c656e6774686044820152606401610872565b60006117458161173d6014856143d8565b859190612823565b61174e906143eb565b92516034036008029290921c8414925050505b92915050565b3330146117dc5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d75737420626560448201527f204c7a41707000000000000000000000000000000000000000000000000000006064820152608401610872565b6117ea86868686868661294b565b505050505050565b6117fa6122d1565b6118046000612c24565b565b3330146118155761181561440f565b60005b8181101561189a57368383838181106118335761183361443e565b9050602002810190611845919061446d565b90506118616118576020830183614091565b6020830135611614565b61186b5750611888565b6118868160a081013561188160c08301836144ab565b612c8c565b505b8061189281614510565b915050611818565b505050565b600160205260009081526040902080546118b890614034565b80601f01602080910402602001604051908101604052809291908181526020018280546118e490614034565b80156119315780601f1061190657610100808354040283529160200191611931565b820191906000526020600020905b81548152906001019060200180831161191457829003601f168201915b505050505081565b6119416122d1565b63ffffffff8316600081815260056020908152604080832060ff87168085529083529281902085905580519384529083019190915281018290527f0564a47bb54b5af04d89fd36c310b8406fd9662464597e3af04594417ea05cf6906060015b60405180910390a1505050565b6119b6613671565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a1a576040517f871f077c000000000000000000000000000000000000000000000000000000008152336004820152602401610872565b6000611a4b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff1661232b565b9050611b0181600460ff1688888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8e9050600560007f000000000000000000000000000000000000000000000000000000000000000063ffffffff1663ffffffff1681526020019081526020016000206000600460ff1660ff168152602001908152602001600020546111459190614199565b611b12816115d38d8d8d8d8d612649565b509998505050505050505050565b61ffff8116600090815260016020526040812080546060929190611b4390614034565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6f90614034565b8015611bbc5780601f10611b9157610100808354040283529160200191611bbc565b820191906000526020600020905b815481529060010190602001808311611b9f57829003601f168201915b505050505090508051600003611c145760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610872565b611c2f600060148351611c2791906143d8565b839190612823565b9392505050565b611c3e6122d1565b818130604051602001611c539392919061452a565b60408051601f1981840301815291815261ffff8516600090815260016020522090611c7e90826145a9565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce8383836040516119a1939291906141b0565b611cba6122d1565b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b9060200160405180910390a150565b611d2e6122d1565b6040517fcbed8b9c0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c90611d9b9088908890889088908890600401614669565b600060405180830381600087803b158015611db557600080fd5b505af1158015611dc9573d6000803e3d6000fd5b505050505050505050565b61ffff86166000908152600460205260408082209051611df79088908890614081565b908152604080516020928190038301902067ffffffffffffffff871660009081529252902054905080611e925760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201527f61676500000000000000000000000000000000000000000000000000000000006064820152608401610872565b808383604051611ea3929190614081565b604051809103902014611f1e5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f6160448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610872565b61ffff87166000908152600460205260408082209051611f419089908990614081565b908152604080516020928190038301902067ffffffffffffffff881660009081529252902055611f7587878787878761294b565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e58787878785604051611fac9594939291906146a2565b60405180910390a150505050505050565b611fc56122d1565b600081116120155760405162461bcd60e51b815260206004820152601560248201527f4c7a4170703a20696e76616c6964206d696e47617300000000000000000000006044820152606401610872565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0906060016119a1565b61207f6122d1565b61ffff8316600090815260016020526040902061209d8284836146de565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab8383836040516119a1939291906141b0565b6120d96122d1565b6001600160a01b0381166121555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610872565b61215e81612c24565b50565b6040517ff5ecbdbc00000000000000000000000000000000000000000000000000000000815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc90608401600060405180830381865afa1580156121fa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612222919081019061436a565b95945050505050565b6000806122bb5a60966366ad5c8a60e01b89898989604051602401612253949392919061479e565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915230929190612d12565b91509150816117ea576117ea8686868685612d9d565b6000546001600160a01b031633146118045760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610872565b600061ffff8211156123a55760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203160448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610872565b5090565b60006123b483612e3b565b61ffff8087166000908152600260209081526040808320938916835292905290812054919250906123e69084906147dd565b9050600081116124385760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f74207365740000000000006044820152606401610872565b808210156117ea5760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f7700000000006044820152606401610872565b61ffff8616600090815260016020526040812080546124a690614034565b80601f01602080910402602001604051908101604052809291908181526020018280546124d290614034565b801561251f5780601f106124f45761010080835404028352916020019161251f565b820191906000526020600020905b81548152906001019060200180831161250257829003601f168201915b50505050509050805160000361259d5760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201527f61207472757374656420736f75726365000000000000000000000000000000006064820152608401610872565b6040517fc58031000000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c580310090849061260e908b9086908c908c908c908c906004016147f0565b6000604051808303818588803b15801561262757600080fd5b505af115801561263b573d6000803e3d6000fd5b505050505050505050505050565b6060612668604051806040016040528060608152602001600081525090565b61268861267687600c614199565b6126819060156147dd565b8290612e97565b50612694816004612efc565b506126ab8163ffffffff80881690600490612f2116565b506126c28167ffffffffffffffff86166008612f21565b506126d98167ffffffffffffffff85166008612f21565b5060005b8681101561276757368888838181106126f8576126f861443e565b60400291909101915061272b90506127136020830183614091565b63ffffffff16600485612f219092919063ffffffff16565b5061275261273f604083016020840161484a565b849067ffffffffffffffff166008612f21565b5050808061275f90614510565b9150506126dd565b50519695505050505050565b6060612792604051806040016040528060608152602001600081525090565b6127ab6127a084600c614199565b6126819060016147dd565b506127b7816003612efc565b5060005b8381101561281a57368585838181106127d6576127d661443e565b6040029190910191506127f190506127136020830183614091565b5061280561273f604083016020840161484a565b5050808061281290614510565b9150506127bb565b50519392505050565b60608161283181601f6147dd565b101561287f5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610872565b61288982846147dd565b845110156128d95760405162461bcd60e51b815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610872565b6060821580156128f85760405191506000825260208201604052612942565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612931578051835260209283019201612919565b5050858452601f01601f1916604052505b50949350505050565b60006129578383612f4f565b905060001960ff821601612a4b5760006129718484612f71565b80516020820151604080840151606085015191517f75c2f575000000000000000000000000000000000000000000000000000000008152600060048201526001600160a01b03948516602482015263ffffffff909316604484015267ffffffffffffffff90811660648401521660848201529192507f000000000000000000000000000000000000000000000000000000000000000016906375c2f5759060a4015b600060405180830381600087803b158015612a2d57600080fd5b505af1158015612a41573d6000803e3d6000fd5b5050505050610a3d565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd60ff821601612ae9576000612a818484613069565b80516040517f5ae0d1af0000000000000000000000000000000000000000000000000000000081529192506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691635ae0d1af91612a13916004016148b1565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60ff821601612bf2577f0000000000000000000000000000000000000000000000000000000000000000612b6a576040517f60dee01500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b768484613221565b80516020820151604080840151606085015191517f698b933e0000000000000000000000000000000000000000000000000000000081529495506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169463698b933e94612a139490939092916004016148c4565b6040517fd623472500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60408051602081018252600080825291517f66ad5c8a00000000000000000000000000000000000000000000000000000000815230926366ad5c8a92612cda92829088908890600401614904565b600060405180830381600087803b158015612cf457600080fd5b505af1158015612d08573d6000803e3d6000fd5b5050505050505050565b6000606060008060008661ffff1667ffffffffffffffff811115612d3857612d38613c72565b6040519080825280601f01601f191660200182016040528015612d62576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115612d84578692505b828152826000602083013e909890975095505050505050565b8180519060200120600460008761ffff1661ffff16815260200190815260200160002085604051612dce9190614950565b90815260408051918290036020908101832067ffffffffffffffff88166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c90612e2c9087908790879087908790614962565b60405180910390a15050505050565b6000602282511015612e8f5760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d73000000006044820152606401610872565b506022015190565b604080518082019091526060815260006020820152612eb76020836149e4565b15612edf57612ec76020836149e4565b612ed29060206143d8565b612edc90836147dd565b91505b506020828101829052604080518085526000815290920101905290565b604080518082019091526060815260006020820152611c2f838460000151518461344d565b604080518082019091526060815260006020820152612f478485600001515185856134ad565b949350505050565b6000612f5e60018284866149f8565b612f6791614a22565b60f81c9392505050565b60408051608081018252600080825260208201819052918101829052606081019190915260358214612fcf576040517f0ffd11ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810190915280612ffa612fec6021600187896149f8565b612ff591614a6a565b613539565b6001600160a01b031681526020016130166025602186886149f8565b61301f91614a88565b60e01c8152602001613035602d602586886149f8565b61303e91614ace565b60c01c81526020016130546035602d86886149f8565b61305d91614ace565b60c01c90529392505050565b604080516020810190915260608152600c6130856001846143d8565b61308f91906149e4565b156130c6576040517f0ffd11ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600c6130d56001856143d8565b6130df9190614b14565b905060008167ffffffffffffffff8111156130fc576130fc613c72565b60405190808252806020026020018201604052801561314157816020015b604080518082019091526000808252602082015281526020019060019003908161311a5790505b50905060005b8281101561320a57600061315c82600c614199565b6131679060016147dd565b905060405180604001604052808888849085600461318591906147dd565b92613192939291906149f8565b61319b91614a88565b60e01c815260200188886131b08560046147dd565b906131bc86600c6147dd565b926131c9939291906149f8565b6131d291614ace565b60c01d905283518490849081106131eb576131eb61443e565b602002602001018190525050808061320290614510565b915050613147565b506040805160208101909152908152949350505050565b604080516080810182526060808252600060208301819052928201839052810191909152600c6132526015846143d8565b61325c91906149e4565b15613293576040517f0ffd11ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600c6132a26015856143d8565b6132ac9190614b14565b905060008167ffffffffffffffff8111156132c9576132c9613c72565b60405190808252806020026020018201604052801561330e57816020015b60408051808201909152600080825260208201528152602001906001900390816132e75790505b50905060005b828110156133d757600061332982600c614199565b6133349060156147dd565b905060405180604001604052808888849085600461335291906147dd565b9261335f939291906149f8565b61336891614a88565b60e01c8152602001888861337d8560046147dd565b9061338986600c6147dd565b92613396939291906149f8565b61339f91614ace565b60c01d905283518490849081106133b8576133b861443e565b60200260200101819052505080806133cf90614510565b915050613314565b506040805160808101909152818152602081016133f860056001888a6149f8565b61340191614a88565b60e01c8152602001613417600d6005888a6149f8565b61342091614ace565b60c01c81526020016134366015600d888a6149f8565b61343f91614ace565b60c01c905295945050505050565b604080518082019091526060815260006020820152836020015183106134875761348784856020015160026134829190614199565b613541565b83518051602085830101848153508085036134a3576001810182525b5093949350505050565b60408051808201909152606081526000602082015260208501516134d185846147dd565b11156134f0576134f0856134e586856147dd565b613482906002614199565b6000600161350084610100614c0c565b61350a91906143d8565b905085518386820101858319825116178152508051848701111561352e5783860181525b509495945050505050565b600081611761565b815161354d8383612e97565b50613558838261355e565b50505050565b604080518082019091526060815260006020820152611c2f8384600001515184855160408051808201909152606081526000602082015282518211156135a357600080fd5b60208501516135b283866147dd565b11156135d5576135d5856134e5876020015187866135d091906147dd565b61365a565b6000808651805187602083010193508088870111156135f45787860182525b505050602084015b6020841061363457805182526136136020836147dd565b91506136206020826147dd565b905061362d6020856143d8565b93506135fc565b51815160001960208690036101000a019081169019919091161790525083949350505050565b60008183111561366b575081611761565b50919050565b604051806060016040528060008019168152602001600067ffffffffffffffff1681526020016136b4604051806040016040528060008152602001600081525090565b905290565b803561ffff811681146136cb57600080fd5b919050565b60008083601f8401126136e257600080fd5b50813567ffffffffffffffff8111156136fa57600080fd5b60208301915083602082850101111561371257600080fd5b9250929050565b803567ffffffffffffffff811681146136cb57600080fd5b6000806000806000806080878903121561374a57600080fd5b613753876136b9565b9550602087013567ffffffffffffffff8082111561377057600080fd5b61377c8a838b016136d0565b909750955085915061379060408a01613719565b945060608901359150808211156137a657600080fd5b506137b389828a016136d0565b979a9699509497509295939492505050565b6000602082840312156137d757600080fd5b611c2f826136b9565b60006040828403121561366b57600080fd5b6001600160a01b038116811461215e57600080fd5b600080600080600080600087890361014081121561382457600080fd5b60a081121561383257600080fd5b5087965060a088013567ffffffffffffffff8082111561385157600080fd5b61385d8b838c016136d0565b90985096508691506138728b60c08c016137e0565b95506101008a01359150613885826137f2565b909350610120890135908082111561389c57600080fd5b506138a98a828b016136d0565b989b979a50959850939692959293505050565b803563ffffffff811681146136cb57600080fd5b803560ff811681146136cb57600080fd5b600080604083850312156138f457600080fd5b6138fd836138bc565b915061390b602084016138d0565b90509250929050565b803580151581146136cb57600080fd5b6000806000806000806080878903121561393d57600080fd5b613946876138bc565b9550602087013567ffffffffffffffff8082111561396357600080fd5b61396f8a838b016136d0565b909750955085915061379060408a01613914565b60008060006040848603121561399857600080fd5b6139a1846136b9565b9250602084013567ffffffffffffffff8111156139bd57600080fd5b6139c9868287016136d0565b9497909650939450505050565b60008083601f8401126139e857600080fd5b50813567ffffffffffffffff811115613a0057600080fd5b6020830191508360208260061b850101111561371257600080fd5b600080600080600060608688031215613a3357600080fd5b853567ffffffffffffffff80821115613a4b57600080fd5b613a5789838a016139d6565b90975095506020880135915080821115613a7057600080fd5b50613a7d888289016136d0565b9094509250613a90905060408701613914565b90509295509295909350565b60008060008060008060808789031215613ab557600080fd5b613abe876138bc565b9550602087013567ffffffffffffffff80821115613adb57600080fd5b613ae78a838b016139d6565b90975095506040890135915080821115613b0057600080fd5b50613b0d89828a016136d0565b9094509250613b20905060608801613914565b90509295509295509295565b60008060208385031215613b3f57600080fd5b823567ffffffffffffffff80821115613b5757600080fd5b818501915085601f830112613b6b57600080fd5b813581811115613b7a57600080fd5b8660208260051b8501011115613b8f57600080fd5b60209290920196919550909350505050565b600080600080600080600060c0888a031215613bbc57600080fd5b613bc5886138bc565b9650602088013567ffffffffffffffff80821115613be257600080fd5b613bee8b838c016139d6565b909850965060408a0135915080821115613c0757600080fd5b50613c148a828b016136d0565b9095509350613c2890508960608a016137e0565b915060a0880135613c38816137f2565b8091505092959891949750929550565b60008060408385031215613c5b57600080fd5b613c64836138bc565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613cca57613cca613c72565b604052919050565b600067ffffffffffffffff821115613cec57613cec613c72565b50601f01601f191660200190565b600080600060608486031215613d0f57600080fd5b613d18846136b9565b9250602084013567ffffffffffffffff811115613d3457600080fd5b8401601f81018613613d4557600080fd5b8035613d58613d5382613cd2565b613ca1565b818152876020838501011115613d6d57600080fd5b81602084016020830137600060208383010152809450505050613d9260408501613719565b90509250925092565b60005b83811015613db6578181015183820152602001613d9e565b50506000910152565b60008151808452613dd7816020860160208601613d9b565b601f01601f19169290920160200192915050565b602081526000611c2f6020830184613dbf565b600080600060608486031215613e1357600080fd5b613e1c846138bc565b9250613e2a602085016138d0565b9150604084013590509250925092565b60008060408385031215613e4d57600080fd5b613e56836136b9565b915061390b602084016136b9565b60008060008060008060008060006101008a8c031215613e8357600080fd5b893567ffffffffffffffff80821115613e9b57600080fd5b613ea78d838e016139d6565b909b509950899150613ebb60208d016138bc565b9850613ec960408d01613719565b9750613ed760608d01613719565b965060808c0135915080821115613eed57600080fd5b50613efa8c828d016136d0565b9095509350613f0e90508b60a08c016137e0565b915060e08a0135613f1e816137f2565b809150509295985092959850929598565b600060208284031215613f4157600080fd5b8135611c2f816137f2565b600080600080600060808688031215613f6457600080fd5b613f6d866136b9565b9450613f7b602087016136b9565b935060408601359250606086013567ffffffffffffffff811115613f9e57600080fd5b613faa888289016136d0565b969995985093965092949392505050565b600080600060608486031215613fd057600080fd5b613fd9846136b9565b9250613e2a602085016136b9565b60008060008060808587031215613ffd57600080fd5b614006856136b9565b9350614014602086016136b9565b92506040850135614024816137f2565b9396929550929360600135925050565b600181811c9082168061404857607f821691505b60208210810361366b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8183823760009101908152919050565b6000602082840312156140a357600080fd5b611c2f826138bc565b6000602082840312156140be57600080fd5b611c2f82613719565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b61ffff871681526001600160a01b038616602082015260a06040820152600061411e60a0830187613dbf565b851515606084015282810360808401526141398185876140c7565b9998505050505050505050565b6000806040838503121561415957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176117615761176161416a565b61ffff841681526040602082015260006122226040830184866140c7565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261420357600080fd5b830160208101925035905067ffffffffffffffff81111561422357600080fd5b80360382131561371257600080fd5b60208082528181018390526000906040808401600586901b850182018785805b8981101561435b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089850301855282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff218c36030181126142b2578283fd5b8b0160e063ffffffff806142c5846138bc565b168752898301358a88015267ffffffffffffffff6142e48a8501613719565b16898801526060816142f78286016138bc565b16908801525060808281013561430c816137f2565b6001600160a01b03169087015260a0828101359087015260c0614331818401846141ce565b9350828289015261434583890185836140c7565b988b019897505050938801935050600101614252565b50919998505050505050505050565b60006020828403121561437c57600080fd5b815167ffffffffffffffff81111561439357600080fd5b8201601f810184136143a457600080fd5b80516143b2613d5382613cd2565b8181528560208385010111156143c757600080fd5b612222826020830160208601613d9b565b818103818111156117615761176161416a565b8051602080830151919081101561366b5760001960209190910360031b1b16919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff218336030181126144a157600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126144e057600080fd5b83018035915067ffffffffffffffff8211156144fb57600080fd5b60200191503681900382131561371257600080fd5b600060001982036145235761452361416a565b5060010190565b8284823760609190911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169101908152601401919050565b601f82111561189a57600081815260208120601f850160051c8101602086101561458a5750805b601f850160051c820191505b818110156117ea57828155600101614596565b815167ffffffffffffffff8111156145c3576145c3613c72565b6145d7816145d18454614034565b84614563565b602080601f83116001811461460c57600084156145f45750858301515b600019600386901b1c1916600185901b1785556117ea565b600085815260208120601f198616915b8281101561463b5788860151825594840194600190910190840161461c565b50858210156146595787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600061ffff8088168352808716602084015250846040830152608060608301526146976080830184866140c7565b979650505050505050565b61ffff861681526080602082015260006146c06080830186886140c7565b67ffffffffffffffff94909416604083015250606001529392505050565b67ffffffffffffffff8311156146f6576146f6613c72565b61470a836147048354614034565b83614563565b6000601f84116001811461473e57600085156147265750838201355b600019600387901b1c1916600186901b178355610ae1565b600083815260209020601f19861690835b8281101561476f578685013582556020948501946001909201910161474f565b508682101561478c5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b61ffff851681526080602082015260006147bb6080830186613dbf565b67ffffffffffffffff8516604084015282810360608401526146978185613dbf565b808201808211156117615761176161416a565b61ffff8716815260c06020820152600061480d60c0830188613dbf565b828103604084015261481f8188613dbf565b6001600160a01b0387811660608601528616608085015283810360a085015290506141398185613dbf565b60006020828403121561485c57600080fd5b81358060070b8114611c2f57600080fd5b600081518084526020808501945080840160005b8381101561352e578151805163ffffffff16885283015160070b8388015260409096019590820190600101614881565b602081526000611c2f602083018461486d565b6080815260006148d7608083018761486d565b63ffffffff9590951660208301525067ffffffffffffffff92831660408201529116606090910152919050565b61ffff861681526080602082015260006149216080830187613dbf565b67ffffffffffffffff8616604084015282810360608401526149448185876140c7565b98975050505050505050565b600082516144a1818460208701613d9b565b61ffff8616815260a06020820152600061497f60a0830187613dbf565b67ffffffffffffffff8616604084015282810360608401526149a18186613dbf565b905082810360808401526149448185613dbf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826149f3576149f36149b5565b500690565b60008085851115614a0857600080fd5b83861115614a1557600080fd5b5050820193919092039150565b7fff000000000000000000000000000000000000000000000000000000000000008135818116916001851015614a625780818660010360031b1b83161692505b505092915050565b8035602083101561176157600019602084900360031b1b1692915050565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614a625760049490940360031b84901b1690921692915050565b7fffffffffffffffff0000000000000000000000000000000000000000000000008135818116916008851015614a625760089490940360031b84901b1690921692915050565b600082614b2357614b236149b5565b500490565b600181815b80851115614b63578160001904821115614b4957614b4961416a565b80851615614b5657918102915b93841c9390800290614b2d565b509250929050565b600082614b7a57506001611761565b81614b8757506000611761565b8160018114614b9d5760028114614ba757614bc3565b6001915050611761565b60ff841115614bb857614bb861416a565b50506001821b611761565b5060208310610133831016604e8410600b8410161715614be6575081810a611761565b614bf08383614b28565b8060001904821115614c0457614c0461416a565b029392505050565b6000611c2f8383614b6b56fea264697066735822122067c06fc72b4c2b3575ccdb82bfe4a9b27765fc1231748bb5055ec71e99e9492964736f6c634300081300330000000000000000000000003c2269811836af69497e5f486a85d7316753cf62000000000000000000000000323665443cef804a3b5206103304bd4872ea425300000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102695760003560e01c80637533d78811610153578063a6c3d165116100cb578063d1deba1f1161007f578063eb8d72b711610064578063eb8d72b71461079e578063f2fde38b146107be578063f5ecbdbc146107de57600080fd5b8063d1deba1f1461076b578063df2a5b3b1461077e57600080fd5b8063b834f6fb116100b0578063b834f6fb146106f7578063baf3292d1461072b578063cbed8b9c1461074b57600080fd5b8063a6c3d165146106a3578063b353aaa7146106c357600080fd5b80639212a76e116101225780639420069c116101075780639420069c1461062f578063950c8a74146106635780639f38369a1461068357600080fd5b80639212a76e146105d357806393284d951461061c57600080fd5b80637533d788146105305780637f3cbb891461055d5780638cfd8f5c1461057d5780638da5cb5b146105b557600080fd5b806342d65a8d116101e65780635a0dfe4d116101b557806366ad5c8a1161019a57806366ad5c8a146104e8578063715018a61461050857806374c71e0d1461051d57600080fd5b80635a0dfe4d146104795780635b8c41e61461049957600080fd5b806342d65a8d1461041357806344d9c507146104335780635011e5b314610453578063564991451461046657600080fd5b806318d6b43a1161023d578063314dfef511610222578063314dfef51461038e5780633d8b38f6146103c3578063403a8942146103f357600080fd5b806318d6b43a146102fc57806327d19a2c1461034857600080fd5b80621d35671461026e57806307e0db17146102905780630931cf88146102b057806310ddb137146102dc575b600080fd5b34801561027a57600080fd5b5061028e610289366004613731565b6107fe565b005b34801561029c57600080fd5b5061028e6102ab3660046137c5565b610a46565b3480156102bc57600080fd5b50305b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102e857600080fd5b5061028e6102f73660046137c5565b610ae8565b61030f61030a366004613807565b610b59565b604080518251815260208084015167ffffffffffffffff16818301529282015180519282019290925291015160608201526080016102d3565b34801561035457600080fd5b506103806103633660046138e1565b600560209081526000928352604080842090915290825290205481565b6040519081526020016102d3565b34801561039a57600080fd5b506103ae6103a9366004613924565b610dd5565b604080519283526020830191909152016102d3565b3480156103cf57600080fd5b506103e36103de366004613983565b610fba565b60405190151581526020016102d3565b3480156103ff57600080fd5b506103ae61040e366004613a1b565b611086565b34801561041f57600080fd5b5061028e61042e366004613983565b6111fe565b34801561043f57600080fd5b506103ae61044e366004613a9c565b61129d565b61028e610461366004613b2c565b6113a7565b61030f610474366004613ba1565b6114b2565b34801561048557600080fd5b506103e3610494366004613c48565b611614565b3480156104a557600080fd5b506103806104b4366004613cfa565b6004602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b3480156104f457600080fd5b5061028e610503366004613731565b611767565b34801561051457600080fd5b5061028e6117f2565b61028e61052b366004613b2c565b611806565b34801561053c57600080fd5b5061055061054b3660046137c5565b61189f565b6040516102d39190613deb565b34801561056957600080fd5b5061028e610578366004613dfe565b611939565b34801561058957600080fd5b50610380610598366004613e3a565b600260209081526000928352604080842090915290825290205481565b3480156105c157600080fd5b506000546001600160a01b03166102bf565b3480156105df57600080fd5b506106077f000000000000000000000000000000000000000000000000000000000000006581565b60405163ffffffff90911681526020016102d3565b61030f61062a366004613e64565b6119ae565b34801561063b57600080fd5b506102bf7f000000000000000000000000323665443cef804a3b5206103304bd4872ea425381565b34801561066f57600080fd5b506003546102bf906001600160a01b031681565b34801561068f57600080fd5b5061055061069e3660046137c5565b611b20565b3480156106af57600080fd5b5061028e6106be366004613983565b611c36565b3480156106cf57600080fd5b506102bf7f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6281565b34801561070357600080fd5b506103e37f000000000000000000000000000000000000000000000000000000000000000081565b34801561073757600080fd5b5061028e610746366004613f2f565b611cb2565b34801561075757600080fd5b5061028e610766366004613f4c565b611d26565b61028e610779366004613731565b611dd4565b34801561078a57600080fd5b5061028e610799366004613fbb565b611fbd565b3480156107aa57600080fd5b5061028e6107b9366004613983565b612077565b3480156107ca57600080fd5b5061028e6107d9366004613f2f565b6120d1565b3480156107ea57600080fd5b506105506107f9366004613fe7565b612161565b337f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b03161461087b5760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff86166000908152600160205260408120805461089990614034565b80601f01602080910402602001604051908101604052809291908181526020018280546108c590614034565b80156109125780601f106108e757610100808354040283529160200191610912565b820191906000526020600020905b8154815290600101906020018083116108f557829003601f168201915b5050505050905080518686905014801561092d575060008151115b801561095557508051602082012060405161094b9088908890614081565b6040518091039020145b6109c75760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152608401610872565b610a3d8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061222b92505050565b50505050505050565b610a4e6122d1565b6040517f07e0db1700000000000000000000000000000000000000000000000000000000815261ffff821660048201527f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610acd57600080fd5b505af1158015610ae1573d6000803e3d6000fd5b5050505050565b610af06122d1565b6040517f10ddb13700000000000000000000000000000000000000000000000000000000815261ffff821660048201527f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b0316906310ddb13790602401610ab3565b610b61613671565b336001600160a01b037f000000000000000000000000323665443cef804a3b5206103304bd4872ea42531614610bc5576040517f871f077c000000000000000000000000000000000000000000000000000000008152336004820152602401610872565b8115610c395760405162461bcd60e51b815260206004820152602560248201527f4d6573736167696e6756313a20636f6d706f73654d7367206e6f74207375707060448201527f6f727465640000000000000000000000000000000000000000000000000000006064820152608401610872565b6000610c56610c4b60208b018b614091565b63ffffffff1661232b565b9050610c9d81600160ff168a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506123a9915050565b610dc981610d8860208c0135610cb960608e0160408f01614091565b8d6060016020810190610ccc91906140ac565b8e6080016020810190610cdf91906140ac565b604080517f01000000000000000000000000000000000000000000000000000000000000006020820152602181019590955260e09390931b7fffffffff0000000000000000000000000000000000000000000000000000000016604185015260c091821b7fffffffffffffffff0000000000000000000000000000000000000000000000009081166045860152911b16604d830152805160358184030181526055909201905290565b8760008c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250349250612488915050565b50979650505050505050565b6000808215610e4c5760405162461bcd60e51b815260206004820152602560248201527f4d6573736167696e6756313a20636f6d706f73654d7367206e6f74207375707060448201527f6f727465640000000000000000000000000000000000000000000000000000006064820152608401610872565b6000610e5d8963ffffffff1661232b565b9050610ea481600160ff168a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506123a9915050565b604080517f010000000000000000000000000000000000000000000000000000000000000060208201526000602182018190526041820181905260458201819052604d82018190528251603581840301815260558301938490527f40a7bb10000000000000000000000000000000000000000000000000000000009093526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6216926340a7bb1092610f6a92869230929091908f908f906059016140f2565b6040805180830381865afa158015610f86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610faa9190614146565b9250925050965096945050505050565b61ffff831660009081526001602052604081208054829190610fdb90614034565b80601f016020809104026020016040519081016040528092919081815260200182805461100790614034565b80156110545780601f1061102957610100808354040283529160200191611054565b820191906000526020600020905b81548152906001019060200180831161103757829003601f168201915b50505050509050838360405161106b929190614081565b60405180910390208180519060200120149150509392505050565b60008060006110ba7f000000000000000000000000000000000000000000000000000000000000006563ffffffff1661232b565b905061114a81600460ff1688888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525063ffffffff7f00000000000000000000000000000000000000000000000000000000000000651681526005602090815260408083206004845290915290205461114593508e92509050614199565b6123a9565b7f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b03166340a7bb10823061118a8c8c6000806000612649565b60008b8b6040518763ffffffff1660e01b81526004016111af969594939291906140f2565b6040805180830381865afa1580156111cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ef9190614146565b92509250509550959350505050565b6112066122d1565b6040517f42d65a8d0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6216906342d65a8d9061126f908690869086906004016141b0565b600060405180830381600087803b15801561128957600080fd5b505af1158015610a3d573d6000803e3d6000fd5b60008060006112b18963ffffffff1661232b565b905061134781600360ff1688888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508b8b9050600560008f63ffffffff1663ffffffff1681526020019081526020016000206000600360ff1660ff168152602001908152602001600020546111459190614199565b7f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b03166340a7bb1082306113828c8c612773565b60008b8b6040518763ffffffff1660e01b8152600401610f6a969594939291906140f2565b6040517f74c71e0d00000000000000000000000000000000000000000000000000000000815230906374c71e0d9034906113e79086908690600401614232565b6000604051808303818588803b15801561140057600080fd5b505af1158015611414573d6000803e3d6000fd5b5050505050336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261147f919081019061436a565b6040517f8351eea70000000000000000000000000000000000000000000000000000000081526004016108729190613deb565b6114ba613671565b336001600160a01b037f000000000000000000000000323665443cef804a3b5206103304bd4872ea4253161461151e576040517f871f077c000000000000000000000000000000000000000000000000000000008152336004820152602401610872565b600061152f8963ffffffff1661232b565b90506115c581600360ff1688888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508b8b9050600560008f63ffffffff1663ffffffff1681526020019081526020016000206000600360ff1660ff168152602001908152602001600020546111459190614199565b610dc9816115d38a8a612773565b8560008a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250349250612488915050565b6000806001600061162a8663ffffffff1661232b565b61ffff1661ffff168152602001908152602001600020805461164b90614034565b80601f016020809104026020016040519081016040528092919081815260200182805461167790614034565b80156116c45780601f10611699576101008083540402835291602001916116c4565b820191906000526020600020905b8154815290600101906020018083116116a757829003601f168201915b50508351939450506014831191505080156116e0575060348111155b61172c5760405162461bcd60e51b815260206004820181905260248201527f4d6573736167696e6756313a20696e76616c69642070617468206c656e6774686044820152606401610872565b60006117458161173d6014856143d8565b859190612823565b61174e906143eb565b92516034036008029290921c8414925050505b92915050565b3330146117dc5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d75737420626560448201527f204c7a41707000000000000000000000000000000000000000000000000000006064820152608401610872565b6117ea86868686868661294b565b505050505050565b6117fa6122d1565b6118046000612c24565b565b3330146118155761181561440f565b60005b8181101561189a57368383838181106118335761183361443e565b9050602002810190611845919061446d565b90506118616118576020830183614091565b6020830135611614565b61186b5750611888565b6118868160a081013561188160c08301836144ab565b612c8c565b505b8061189281614510565b915050611818565b505050565b600160205260009081526040902080546118b890614034565b80601f01602080910402602001604051908101604052809291908181526020018280546118e490614034565b80156119315780601f1061190657610100808354040283529160200191611931565b820191906000526020600020905b81548152906001019060200180831161191457829003601f168201915b505050505081565b6119416122d1565b63ffffffff8316600081815260056020908152604080832060ff87168085529083529281902085905580519384529083019190915281018290527f0564a47bb54b5af04d89fd36c310b8406fd9662464597e3af04594417ea05cf6906060015b60405180910390a1505050565b6119b6613671565b336001600160a01b037f000000000000000000000000323665443cef804a3b5206103304bd4872ea42531614611a1a576040517f871f077c000000000000000000000000000000000000000000000000000000008152336004820152602401610872565b6000611a4b7f000000000000000000000000000000000000000000000000000000000000006563ffffffff1661232b565b9050611b0181600460ff1688888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508e8e9050600560007f000000000000000000000000000000000000000000000000000000000000006563ffffffff1663ffffffff1681526020019081526020016000206000600460ff1660ff168152602001908152602001600020546111459190614199565b611b12816115d38d8d8d8d8d612649565b509998505050505050505050565b61ffff8116600090815260016020526040812080546060929190611b4390614034565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6f90614034565b8015611bbc5780601f10611b9157610100808354040283529160200191611bbc565b820191906000526020600020905b815481529060010190602001808311611b9f57829003601f168201915b505050505090508051600003611c145760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610872565b611c2f600060148351611c2791906143d8565b839190612823565b9392505050565b611c3e6122d1565b818130604051602001611c539392919061452a565b60408051601f1981840301815291815261ffff8516600090815260016020522090611c7e90826145a9565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce8383836040516119a1939291906141b0565b611cba6122d1565b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b9060200160405180910390a150565b611d2e6122d1565b6040517fcbed8b9c0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62169063cbed8b9c90611d9b9088908890889088908890600401614669565b600060405180830381600087803b158015611db557600080fd5b505af1158015611dc9573d6000803e3d6000fd5b505050505050505050565b61ffff86166000908152600460205260408082209051611df79088908890614081565b908152604080516020928190038301902067ffffffffffffffff871660009081529252902054905080611e925760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201527f61676500000000000000000000000000000000000000000000000000000000006064820152608401610872565b808383604051611ea3929190614081565b604051809103902014611f1e5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f6160448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610872565b61ffff87166000908152600460205260408082209051611f419089908990614081565b908152604080516020928190038301902067ffffffffffffffff881660009081529252902055611f7587878787878761294b565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e58787878785604051611fac9594939291906146a2565b60405180910390a150505050505050565b611fc56122d1565b600081116120155760405162461bcd60e51b815260206004820152601560248201527f4c7a4170703a20696e76616c6964206d696e47617300000000000000000000006044820152606401610872565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac0906060016119a1565b61207f6122d1565b61ffff8316600090815260016020526040902061209d8284836146de565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab8383836040516119a1939291906141b0565b6120d96122d1565b6001600160a01b0381166121555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610872565b61215e81612c24565b50565b6040517ff5ecbdbc00000000000000000000000000000000000000000000000000000000815261ffff808616600483015284166024820152306044820152606481018290526060907f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b03169063f5ecbdbc90608401600060405180830381865afa1580156121fa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612222919081019061436a565b95945050505050565b6000806122bb5a60966366ad5c8a60e01b89898989604051602401612253949392919061479e565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915230929190612d12565b91509150816117ea576117ea8686868685612d9d565b6000546001600160a01b031633146118045760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610872565b600061ffff8211156123a55760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203160448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610872565b5090565b60006123b483612e3b565b61ffff8087166000908152600260209081526040808320938916835292905290812054919250906123e69084906147dd565b9050600081116124385760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f74207365740000000000006044820152606401610872565b808210156117ea5760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f7700000000006044820152606401610872565b61ffff8616600090815260016020526040812080546124a690614034565b80601f01602080910402602001604051908101604052809291908181526020018280546124d290614034565b801561251f5780601f106124f45761010080835404028352916020019161251f565b820191906000526020600020905b81548152906001019060200180831161250257829003601f168201915b50505050509050805160000361259d5760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201527f61207472757374656420736f75726365000000000000000000000000000000006064820152608401610872565b6040517fc58031000000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62169063c580310090849061260e908b9086908c908c908c908c906004016147f0565b6000604051808303818588803b15801561262757600080fd5b505af115801561263b573d6000803e3d6000fd5b505050505050505050505050565b6060612668604051806040016040528060608152602001600081525090565b61268861267687600c614199565b6126819060156147dd565b8290612e97565b50612694816004612efc565b506126ab8163ffffffff80881690600490612f2116565b506126c28167ffffffffffffffff86166008612f21565b506126d98167ffffffffffffffff85166008612f21565b5060005b8681101561276757368888838181106126f8576126f861443e565b60400291909101915061272b90506127136020830183614091565b63ffffffff16600485612f219092919063ffffffff16565b5061275261273f604083016020840161484a565b849067ffffffffffffffff166008612f21565b5050808061275f90614510565b9150506126dd565b50519695505050505050565b6060612792604051806040016040528060608152602001600081525090565b6127ab6127a084600c614199565b6126819060016147dd565b506127b7816003612efc565b5060005b8381101561281a57368585838181106127d6576127d661443e565b6040029190910191506127f190506127136020830183614091565b5061280561273f604083016020840161484a565b5050808061281290614510565b9150506127bb565b50519392505050565b60608161283181601f6147dd565b101561287f5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610872565b61288982846147dd565b845110156128d95760405162461bcd60e51b815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610872565b6060821580156128f85760405191506000825260208201604052612942565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612931578051835260209283019201612919565b5050858452601f01601f1916604052505b50949350505050565b60006129578383612f4f565b905060001960ff821601612a4b5760006129718484612f71565b80516020820151604080840151606085015191517f75c2f575000000000000000000000000000000000000000000000000000000008152600060048201526001600160a01b03948516602482015263ffffffff909316604484015267ffffffffffffffff90811660648401521660848201529192507f000000000000000000000000323665443cef804a3b5206103304bd4872ea425316906375c2f5759060a4015b600060405180830381600087803b158015612a2d57600080fd5b505af1158015612a41573d6000803e3d6000fd5b5050505050610a3d565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd60ff821601612ae9576000612a818484613069565b80516040517f5ae0d1af0000000000000000000000000000000000000000000000000000000081529192506001600160a01b037f000000000000000000000000323665443cef804a3b5206103304bd4872ea42531691635ae0d1af91612a13916004016148b1565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60ff821601612bf2577f0000000000000000000000000000000000000000000000000000000000000000612b6a576040517f60dee01500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b768484613221565b80516020820151604080840151606085015191517f698b933e0000000000000000000000000000000000000000000000000000000081529495506001600160a01b037f000000000000000000000000323665443cef804a3b5206103304bd4872ea4253169463698b933e94612a139490939092916004016148c4565b6040517fd623472500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60408051602081018252600080825291517f66ad5c8a00000000000000000000000000000000000000000000000000000000815230926366ad5c8a92612cda92829088908890600401614904565b600060405180830381600087803b158015612cf457600080fd5b505af1158015612d08573d6000803e3d6000fd5b5050505050505050565b6000606060008060008661ffff1667ffffffffffffffff811115612d3857612d38613c72565b6040519080825280601f01601f191660200182016040528015612d62576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115612d84578692505b828152826000602083013e909890975095505050505050565b8180519060200120600460008761ffff1661ffff16815260200190815260200160002085604051612dce9190614950565b90815260408051918290036020908101832067ffffffffffffffff88166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c90612e2c9087908790879087908790614962565b60405180910390a15050505050565b6000602282511015612e8f5760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d73000000006044820152606401610872565b506022015190565b604080518082019091526060815260006020820152612eb76020836149e4565b15612edf57612ec76020836149e4565b612ed29060206143d8565b612edc90836147dd565b91505b506020828101829052604080518085526000815290920101905290565b604080518082019091526060815260006020820152611c2f838460000151518461344d565b604080518082019091526060815260006020820152612f478485600001515185856134ad565b949350505050565b6000612f5e60018284866149f8565b612f6791614a22565b60f81c9392505050565b60408051608081018252600080825260208201819052918101829052606081019190915260358214612fcf576040517f0ffd11ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516080810190915280612ffa612fec6021600187896149f8565b612ff591614a6a565b613539565b6001600160a01b031681526020016130166025602186886149f8565b61301f91614a88565b60e01c8152602001613035602d602586886149f8565b61303e91614ace565b60c01c81526020016130546035602d86886149f8565b61305d91614ace565b60c01c90529392505050565b604080516020810190915260608152600c6130856001846143d8565b61308f91906149e4565b156130c6576040517f0ffd11ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600c6130d56001856143d8565b6130df9190614b14565b905060008167ffffffffffffffff8111156130fc576130fc613c72565b60405190808252806020026020018201604052801561314157816020015b604080518082019091526000808252602082015281526020019060019003908161311a5790505b50905060005b8281101561320a57600061315c82600c614199565b6131679060016147dd565b905060405180604001604052808888849085600461318591906147dd565b92613192939291906149f8565b61319b91614a88565b60e01c815260200188886131b08560046147dd565b906131bc86600c6147dd565b926131c9939291906149f8565b6131d291614ace565b60c01d905283518490849081106131eb576131eb61443e565b602002602001018190525050808061320290614510565b915050613147565b506040805160208101909152908152949350505050565b604080516080810182526060808252600060208301819052928201839052810191909152600c6132526015846143d8565b61325c91906149e4565b15613293576040517f0ffd11ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600c6132a26015856143d8565b6132ac9190614b14565b905060008167ffffffffffffffff8111156132c9576132c9613c72565b60405190808252806020026020018201604052801561330e57816020015b60408051808201909152600080825260208201528152602001906001900390816132e75790505b50905060005b828110156133d757600061332982600c614199565b6133349060156147dd565b905060405180604001604052808888849085600461335291906147dd565b9261335f939291906149f8565b61336891614a88565b60e01c8152602001888861337d8560046147dd565b9061338986600c6147dd565b92613396939291906149f8565b61339f91614ace565b60c01d905283518490849081106133b8576133b861443e565b60200260200101819052505080806133cf90614510565b915050613314565b506040805160808101909152818152602081016133f860056001888a6149f8565b61340191614a88565b60e01c8152602001613417600d6005888a6149f8565b61342091614ace565b60c01c81526020016134366015600d888a6149f8565b61343f91614ace565b60c01c905295945050505050565b604080518082019091526060815260006020820152836020015183106134875761348784856020015160026134829190614199565b613541565b83518051602085830101848153508085036134a3576001810182525b5093949350505050565b60408051808201909152606081526000602082015260208501516134d185846147dd565b11156134f0576134f0856134e586856147dd565b613482906002614199565b6000600161350084610100614c0c565b61350a91906143d8565b905085518386820101858319825116178152508051848701111561352e5783860181525b509495945050505050565b600081611761565b815161354d8383612e97565b50613558838261355e565b50505050565b604080518082019091526060815260006020820152611c2f8384600001515184855160408051808201909152606081526000602082015282518211156135a357600080fd5b60208501516135b283866147dd565b11156135d5576135d5856134e5876020015187866135d091906147dd565b61365a565b6000808651805187602083010193508088870111156135f45787860182525b505050602084015b6020841061363457805182526136136020836147dd565b91506136206020826147dd565b905061362d6020856143d8565b93506135fc565b51815160001960208690036101000a019081169019919091161790525083949350505050565b60008183111561366b575081611761565b50919050565b604051806060016040528060008019168152602001600067ffffffffffffffff1681526020016136b4604051806040016040528060008152602001600081525090565b905290565b803561ffff811681146136cb57600080fd5b919050565b60008083601f8401126136e257600080fd5b50813567ffffffffffffffff8111156136fa57600080fd5b60208301915083602082850101111561371257600080fd5b9250929050565b803567ffffffffffffffff811681146136cb57600080fd5b6000806000806000806080878903121561374a57600080fd5b613753876136b9565b9550602087013567ffffffffffffffff8082111561377057600080fd5b61377c8a838b016136d0565b909750955085915061379060408a01613719565b945060608901359150808211156137a657600080fd5b506137b389828a016136d0565b979a9699509497509295939492505050565b6000602082840312156137d757600080fd5b611c2f826136b9565b60006040828403121561366b57600080fd5b6001600160a01b038116811461215e57600080fd5b600080600080600080600087890361014081121561382457600080fd5b60a081121561383257600080fd5b5087965060a088013567ffffffffffffffff8082111561385157600080fd5b61385d8b838c016136d0565b90985096508691506138728b60c08c016137e0565b95506101008a01359150613885826137f2565b909350610120890135908082111561389c57600080fd5b506138a98a828b016136d0565b989b979a50959850939692959293505050565b803563ffffffff811681146136cb57600080fd5b803560ff811681146136cb57600080fd5b600080604083850312156138f457600080fd5b6138fd836138bc565b915061390b602084016138d0565b90509250929050565b803580151581146136cb57600080fd5b6000806000806000806080878903121561393d57600080fd5b613946876138bc565b9550602087013567ffffffffffffffff8082111561396357600080fd5b61396f8a838b016136d0565b909750955085915061379060408a01613914565b60008060006040848603121561399857600080fd5b6139a1846136b9565b9250602084013567ffffffffffffffff8111156139bd57600080fd5b6139c9868287016136d0565b9497909650939450505050565b60008083601f8401126139e857600080fd5b50813567ffffffffffffffff811115613a0057600080fd5b6020830191508360208260061b850101111561371257600080fd5b600080600080600060608688031215613a3357600080fd5b853567ffffffffffffffff80821115613a4b57600080fd5b613a5789838a016139d6565b90975095506020880135915080821115613a7057600080fd5b50613a7d888289016136d0565b9094509250613a90905060408701613914565b90509295509295909350565b60008060008060008060808789031215613ab557600080fd5b613abe876138bc565b9550602087013567ffffffffffffffff80821115613adb57600080fd5b613ae78a838b016139d6565b90975095506040890135915080821115613b0057600080fd5b50613b0d89828a016136d0565b9094509250613b20905060608801613914565b90509295509295509295565b60008060208385031215613b3f57600080fd5b823567ffffffffffffffff80821115613b5757600080fd5b818501915085601f830112613b6b57600080fd5b813581811115613b7a57600080fd5b8660208260051b8501011115613b8f57600080fd5b60209290920196919550909350505050565b600080600080600080600060c0888a031215613bbc57600080fd5b613bc5886138bc565b9650602088013567ffffffffffffffff80821115613be257600080fd5b613bee8b838c016139d6565b909850965060408a0135915080821115613c0757600080fd5b50613c148a828b016136d0565b9095509350613c2890508960608a016137e0565b915060a0880135613c38816137f2565b8091505092959891949750929550565b60008060408385031215613c5b57600080fd5b613c64836138bc565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613cca57613cca613c72565b604052919050565b600067ffffffffffffffff821115613cec57613cec613c72565b50601f01601f191660200190565b600080600060608486031215613d0f57600080fd5b613d18846136b9565b9250602084013567ffffffffffffffff811115613d3457600080fd5b8401601f81018613613d4557600080fd5b8035613d58613d5382613cd2565b613ca1565b818152876020838501011115613d6d57600080fd5b81602084016020830137600060208383010152809450505050613d9260408501613719565b90509250925092565b60005b83811015613db6578181015183820152602001613d9e565b50506000910152565b60008151808452613dd7816020860160208601613d9b565b601f01601f19169290920160200192915050565b602081526000611c2f6020830184613dbf565b600080600060608486031215613e1357600080fd5b613e1c846138bc565b9250613e2a602085016138d0565b9150604084013590509250925092565b60008060408385031215613e4d57600080fd5b613e56836136b9565b915061390b602084016136b9565b60008060008060008060008060006101008a8c031215613e8357600080fd5b893567ffffffffffffffff80821115613e9b57600080fd5b613ea78d838e016139d6565b909b509950899150613ebb60208d016138bc565b9850613ec960408d01613719565b9750613ed760608d01613719565b965060808c0135915080821115613eed57600080fd5b50613efa8c828d016136d0565b9095509350613f0e90508b60a08c016137e0565b915060e08a0135613f1e816137f2565b809150509295985092959850929598565b600060208284031215613f4157600080fd5b8135611c2f816137f2565b600080600080600060808688031215613f6457600080fd5b613f6d866136b9565b9450613f7b602087016136b9565b935060408601359250606086013567ffffffffffffffff811115613f9e57600080fd5b613faa888289016136d0565b969995985093965092949392505050565b600080600060608486031215613fd057600080fd5b613fd9846136b9565b9250613e2a602085016136b9565b60008060008060808587031215613ffd57600080fd5b614006856136b9565b9350614014602086016136b9565b92506040850135614024816137f2565b9396929550929360600135925050565b600181811c9082168061404857607f821691505b60208210810361366b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8183823760009101908152919050565b6000602082840312156140a357600080fd5b611c2f826138bc565b6000602082840312156140be57600080fd5b611c2f82613719565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b61ffff871681526001600160a01b038616602082015260a06040820152600061411e60a0830187613dbf565b851515606084015282810360808401526141398185876140c7565b9998505050505050505050565b6000806040838503121561415957600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176117615761176161416a565b61ffff841681526040602082015260006122226040830184866140c7565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261420357600080fd5b830160208101925035905067ffffffffffffffff81111561422357600080fd5b80360382131561371257600080fd5b60208082528181018390526000906040808401600586901b850182018785805b8981101561435b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089850301855282357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff218c36030181126142b2578283fd5b8b0160e063ffffffff806142c5846138bc565b168752898301358a88015267ffffffffffffffff6142e48a8501613719565b16898801526060816142f78286016138bc565b16908801525060808281013561430c816137f2565b6001600160a01b03169087015260a0828101359087015260c0614331818401846141ce565b9350828289015261434583890185836140c7565b988b019897505050938801935050600101614252565b50919998505050505050505050565b60006020828403121561437c57600080fd5b815167ffffffffffffffff81111561439357600080fd5b8201601f810184136143a457600080fd5b80516143b2613d5382613cd2565b8181528560208385010111156143c757600080fd5b612222826020830160208601613d9b565b818103818111156117615761176161416a565b8051602080830151919081101561366b5760001960209190910360031b1b16919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff218336030181126144a157600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126144e057600080fd5b83018035915067ffffffffffffffff8211156144fb57600080fd5b60200191503681900382131561371257600080fd5b600060001982036145235761452361416a565b5060010190565b8284823760609190911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169101908152601401919050565b601f82111561189a57600081815260208120601f850160051c8101602086101561458a5750805b601f850160051c820191505b818110156117ea57828155600101614596565b815167ffffffffffffffff8111156145c3576145c3613c72565b6145d7816145d18454614034565b84614563565b602080601f83116001811461460c57600084156145f45750858301515b600019600386901b1c1916600185901b1785556117ea565b600085815260208120601f198616915b8281101561463b5788860151825594840194600190910190840161461c565b50858210156146595787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600061ffff8088168352808716602084015250846040830152608060608301526146976080830184866140c7565b979650505050505050565b61ffff861681526080602082015260006146c06080830186886140c7565b67ffffffffffffffff94909416604083015250606001529392505050565b67ffffffffffffffff8311156146f6576146f6613c72565b61470a836147048354614034565b83614563565b6000601f84116001811461473e57600085156147265750838201355b600019600387901b1c1916600186901b178355610ae1565b600083815260209020601f19861690835b8281101561476f578685013582556020948501946001909201910161474f565b508682101561478c5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b61ffff851681526080602082015260006147bb6080830186613dbf565b67ffffffffffffffff8516604084015282810360608401526146978185613dbf565b808201808211156117615761176161416a565b61ffff8716815260c06020820152600061480d60c0830188613dbf565b828103604084015261481f8188613dbf565b6001600160a01b0387811660608601528616608085015283810360a085015290506141398185613dbf565b60006020828403121561485c57600080fd5b81358060070b8114611c2f57600080fd5b600081518084526020808501945080840160005b8381101561352e578151805163ffffffff16885283015160070b8388015260409096019590820190600101614881565b602081526000611c2f602083018461486d565b6080815260006148d7608083018761486d565b63ffffffff9590951660208301525067ffffffffffffffff92831660408201529116606090910152919050565b61ffff861681526080602082015260006149216080830187613dbf565b67ffffffffffffffff8616604084015282810360608401526149448185876140c7565b98975050505050505050565b600082516144a1818460208701613d9b565b61ffff8616815260a06020820152600061497f60a0830187613dbf565b67ffffffffffffffff8616604084015282810360608401526149a18186613dbf565b905082810360808401526149448185613dbf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826149f3576149f36149b5565b500690565b60008085851115614a0857600080fd5b83861115614a1557600080fd5b5050820193919092039150565b7fff000000000000000000000000000000000000000000000000000000000000008135818116916001851015614a625780818660010360031b1b83161692505b505092915050565b8035602083101561176157600019602084900360031b1b1692915050565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015614a625760049490940360031b84901b1690921692915050565b7fffffffffffffffff0000000000000000000000000000000000000000000000008135818116916008851015614a625760089490940360031b84901b1690921692915050565b600082614b2357614b236149b5565b500490565b600181815b80851115614b63578160001904821115614b4957614b4961416a565b80851615614b5657918102915b93841c9390800290614b2d565b509250929050565b600082614b7a57506001611761565b81614b8757506000611761565b8160018114614b9d5760028114614ba757614bc3565b6001915050611761565b60ff841115614bb857614bb861416a565b50506001821b611761565b5060208310610133831016604e8410600b8410161715614be6575081810a611761565b614bf08383614b28565b8060001904821115614c0457614c0461416a565b029392505050565b6000611c2f8383614b6b56fea264697066735822122067c06fc72b4c2b3575ccdb82bfe4a9b27765fc1231748bb5055ec71e99e9492964736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62000000000000000000000000323665443cef804a3b5206103304bd4872ea425300000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _endpoint (address): 0x3c2269811836af69497E5F486A85D7316753cf62
Arg [1] : _usdv (address): 0x323665443CEf804A3b5206103304BD4872EA4253
Arg [2] : _mainChainEid (uint32): 101
Arg [3] : _isMainChain (bool): False
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62
Arg [1] : 000000000000000000000000323665443cef804a3b5206103304bd4872ea4253
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000065
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.