编译器
0.8.22+commit.4fc1097e
文件 1 的 35:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
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");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
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");
}
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);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
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);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
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);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
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 {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 35:AddressCast.sol
pragma solidity ^0.8.20;
library AddressCast {
error AddressCast_InvalidSizeForAddress();
error AddressCast_InvalidAddress();
function toBytes32(bytes calldata _addressBytes) internal pure returns (bytes32 result) {
if (_addressBytes.length > 32) revert AddressCast_InvalidAddress();
result = bytes32(_addressBytes);
unchecked {
uint256 offset = 32 - _addressBytes.length;
result = result >> (offset * 8);
}
}
function toBytes32(address _address) internal pure returns (bytes32 result) {
result = bytes32(uint256(uint160(_address)));
}
function toBytes(bytes32 _addressBytes32, uint256 _size) internal pure returns (bytes memory result) {
if (_size == 0 || _size > 32) revert AddressCast_InvalidSizeForAddress();
result = new bytes(_size);
unchecked {
uint256 offset = 256 - _size * 8;
assembly {
mstore(add(result, 32), shl(offset, _addressBytes32))
}
}
}
function toAddress(bytes32 _addressBytes32) internal pure returns (address result) {
result = address(uint160(uint256(_addressBytes32)));
}
function toAddress(bytes calldata _addressBytes) internal pure returns (address result) {
if (_addressBytes.length != 20) revert AddressCast_InvalidAddress();
result = address(bytes20(_addressBytes));
}
}
文件 3 的 35:BitMaps.sol
pragma solidity ^0.8.20;
type BitMap256 is uint256;
using BitMaps for BitMap256 global;
library BitMaps {
function get(BitMap256 bitmap, uint8 index) internal pure returns (bool) {
uint256 mask = 1 << index;
return BitMap256.unwrap(bitmap) & mask != 0;
}
function set(BitMap256 bitmap, uint8 index) internal pure returns (BitMap256) {
uint256 mask = 1 << index;
return BitMap256.wrap(BitMap256.unwrap(bitmap) | mask);
}
}
文件 4 的 35:BytesLib.sol
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 {
tempBytes := mload(0x40)
let length := mload(_preBytes)
mstore(tempBytes, length)
let mc := add(tempBytes, 0x20)
let end := add(mc, length)
for {
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
mc := end
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))
}
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31)
))
}
return tempBytes;
}
function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
assembly {
let fslot := sload(_preBytes.slot)
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
let newlength := add(slength, mlength)
switch add(lt(slength, 32), lt(newlength, 32))
case 2 {
sstore(
_preBytes.slot,
add(
fslot,
add(
mul(
div(
mload(add(_postBytes, 0x20)),
exp(0x100, sub(32, mlength))
),
exp(0x100, sub(32, newlength))
),
mul(mlength, 2)
)
)
)
}
case 1 {
mstore(0x0, _preBytes.slot)
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
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 {
mstore(0x0, _preBytes.slot)
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
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 {
tempBytes := mload(0x40)
let lengthmod := and(_length, 31)
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
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)
mstore(0x40, and(add(mc, 31), not(31)))
}
default {
tempBytes := mload(0x40)
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)
switch eq(length, mload(_postBytes))
case 1 {
let cb := 1
let mc := add(_preBytes, 0x20)
let end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} eq(add(lt(mc, end), cb), 2) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
if iszero(eq(mload(mc), mload(cc))) {
success := 0
cb := 0
}
}
}
default {
success := 0
}
}
return success;
}
function equalStorage(
bytes storage _preBytes,
bytes memory _postBytes
)
internal
view
returns (bool)
{
bool success = true;
assembly {
let fslot := sload(_preBytes.slot)
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
switch eq(slength, mlength)
case 1 {
if iszero(iszero(slength)) {
switch lt(slength, 32)
case 1 {
fslot := mul(div(fslot, 0x100), 0x100)
if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
success := 0
}
}
default {
let cb := 1
mstore(0x0, _preBytes.slot)
let sc := keccak256(0x0, 0x20)
let mc := add(_postBytes, 0x20)
let end := add(mc, mlength)
for {} eq(add(lt(mc, end), cb), 2) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
if iszero(eq(sload(sc), mload(mc))) {
success := 0
cb := 0
}
}
}
}
}
default {
success := 0
}
}
return success;
}
}
文件 5 的 35:CalldataBytesLib.sol
pragma solidity ^0.8.20;
library CalldataBytesLib {
function toU8(bytes calldata _bytes, uint256 _start) internal pure returns (uint8) {
return uint8(_bytes[_start]);
}
function toU16(bytes calldata _bytes, uint256 _start) internal pure returns (uint16) {
unchecked {
uint256 end = _start + 2;
return uint16(bytes2(_bytes[_start:end]));
}
}
function toU32(bytes calldata _bytes, uint256 _start) internal pure returns (uint32) {
unchecked {
uint256 end = _start + 4;
return uint32(bytes4(_bytes[_start:end]));
}
}
function toU64(bytes calldata _bytes, uint256 _start) internal pure returns (uint64) {
unchecked {
uint256 end = _start + 8;
return uint64(bytes8(_bytes[_start:end]));
}
}
function toU128(bytes calldata _bytes, uint256 _start) internal pure returns (uint128) {
unchecked {
uint256 end = _start + 16;
return uint128(bytes16(_bytes[_start:end]));
}
}
function toU256(bytes calldata _bytes, uint256 _start) internal pure returns (uint256) {
unchecked {
uint256 end = _start + 32;
return uint256(bytes32(_bytes[_start:end]));
}
}
function toAddr(bytes calldata _bytes, uint256 _start) internal pure returns (address) {
unchecked {
uint256 end = _start + 20;
return address(bytes20(_bytes[_start:end]));
}
}
function toB32(bytes calldata _bytes, uint256 _start) internal pure returns (bytes32) {
unchecked {
uint256 end = _start + 32;
return bytes32(_bytes[_start:end]);
}
}
}
文件 6 的 35:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 7 的 35:DVNOptions.sol
pragma solidity ^0.8.20;
import { BytesLib } from "solidity-bytes-utils/contracts/BytesLib.sol";
import { BitMap256 } from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/BitMaps.sol";
import { CalldataBytesLib } from "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/CalldataBytesLib.sol";
library DVNOptions {
using CalldataBytesLib for bytes;
using BytesLib for bytes;
uint8 internal constant WORKER_ID = 2;
uint8 internal constant OPTION_TYPE_PRECRIME = 1;
error DVN_InvalidDVNIdx();
error DVN_InvalidDVNOptions(uint256 cursor);
function groupDVNOptionsByIdx(
bytes memory _options
) internal pure returns (bytes[] memory dvnOptions, uint8[] memory dvnIndices) {
if (_options.length == 0) return (dvnOptions, dvnIndices);
uint8 numDVNs = getNumDVNs(_options);
if (numDVNs == 1) {
dvnOptions = new bytes[](1);
dvnOptions[0] = _options;
dvnIndices = new uint8[](1);
dvnIndices[0] = _options.toUint8(3);
return (dvnOptions, dvnIndices);
}
dvnIndices = new uint8[](numDVNs);
dvnOptions = new bytes[](numDVNs);
unchecked {
uint256 cursor = 0;
uint256 start = 0;
uint8 lastDVNIdx = 255;
while (cursor < _options.length) {
++cursor;
uint16 optionLength = _options.toUint16(cursor);
cursor += 2;
uint8 dvnIdx = _options.toUint8(cursor);
if (lastDVNIdx == 255) {
lastDVNIdx = dvnIdx;
} else if (dvnIdx != lastDVNIdx) {
uint256 len = cursor - start - 3;
bytes memory opt = _options.slice(start, len);
_insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, opt);
start += len;
lastDVNIdx = dvnIdx;
}
cursor += optionLength;
}
uint256 size = cursor - start;
bytes memory op = _options.slice(start, size);
_insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, op);
for (uint8 i = 0; i < numDVNs; ++i) {
--dvnIndices[i];
}
}
}
function _insertDVNOptions(
bytes[] memory _dvnOptions,
uint8[] memory _dvnIndices,
uint8 _dvnIdx,
bytes memory _newOptions
) internal pure {
if (_dvnIdx == 255) revert DVN_InvalidDVNIdx();
uint8 dvnIdxAdj = _dvnIdx + 1;
for (uint256 j = 0; j < _dvnIndices.length; ++j) {
uint8 index = _dvnIndices[j];
if (dvnIdxAdj == index) {
_dvnOptions[j] = abi.encodePacked(_dvnOptions[j], _newOptions);
break;
} else if (index == 0) {
_dvnIndices[j] = dvnIdxAdj;
_dvnOptions[j] = _newOptions;
break;
}
}
}
function getNumDVNs(bytes memory _options) internal pure returns (uint8 numDVNs) {
uint256 cursor = 0;
BitMap256 bitmap;
unchecked {
while (cursor < _options.length) {
++cursor;
uint16 optionLength = _options.toUint16(cursor);
cursor += 2;
if (optionLength < 2) revert DVN_InvalidDVNOptions(cursor);
uint8 dvnIdx = _options.toUint8(cursor);
if (dvnIdx == 255) revert DVN_InvalidDVNIdx();
if (!bitmap.get(dvnIdx)) {
++numDVNs;
bitmap = bitmap.set(dvnIdx);
}
cursor += optionLength;
}
}
if (cursor != _options.length) revert DVN_InvalidDVNOptions(cursor);
}
function nextDVNOption(
bytes calldata _options,
uint256 _cursor
) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {
unchecked {
cursor = _cursor + 1;
uint16 size = _options.toU16(cursor);
cursor += 2;
optionType = _options.toU8(cursor + 1);
uint256 startCursor = cursor + 2;
uint256 endCursor = cursor + size;
option = _options[startCursor:endCursor];
cursor += size;
}
}
}
文件 8 的 35:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 9 的 35:ExecutorOptions.sol
pragma solidity ^0.8.20;
import { CalldataBytesLib } from "../../libs/CalldataBytesLib.sol";
library ExecutorOptions {
using CalldataBytesLib for bytes;
uint8 internal constant WORKER_ID = 1;
uint8 internal constant OPTION_TYPE_LZRECEIVE = 1;
uint8 internal constant OPTION_TYPE_NATIVE_DROP = 2;
uint8 internal constant OPTION_TYPE_LZCOMPOSE = 3;
uint8 internal constant OPTION_TYPE_ORDERED_EXECUTION = 4;
error Executor_InvalidLzReceiveOption();
error Executor_InvalidNativeDropOption();
error Executor_InvalidLzComposeOption();
function nextExecutorOption(
bytes calldata _options,
uint256 _cursor
) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {
unchecked {
cursor = _cursor + 1;
uint16 size = _options.toU16(cursor);
cursor += 2;
optionType = _options.toU8(cursor);
uint256 startCursor = cursor + 1;
uint256 endCursor = cursor + size;
option = _options[startCursor:endCursor];
cursor += size;
}
}
function decodeLzReceiveOption(bytes calldata _option) internal pure returns (uint128 gas, uint128 value) {
if (_option.length != 16 && _option.length != 32) revert Executor_InvalidLzReceiveOption();
gas = _option.toU128(0);
value = _option.length == 32 ? _option.toU128(16) : 0;
}
function decodeNativeDropOption(bytes calldata _option) internal pure returns (uint128 amount, bytes32 receiver) {
if (_option.length != 48) revert Executor_InvalidNativeDropOption();
amount = _option.toU128(0);
receiver = _option.toB32(16);
}
function decodeLzComposeOption(
bytes calldata _option
) internal pure returns (uint16 index, uint128 gas, uint128 value) {
if (_option.length != 18 && _option.length != 34) revert Executor_InvalidLzComposeOption();
index = _option.toU16(0);
gas = _option.toU128(2);
value = _option.length == 34 ? _option.toU128(18) : 0;
}
function encodeLzReceiveOption(uint128 _gas, uint128 _value) internal pure returns (bytes memory) {
return _value == 0 ? abi.encodePacked(_gas) : abi.encodePacked(_gas, _value);
}
function encodeNativeDropOption(uint128 _amount, bytes32 _receiver) internal pure returns (bytes memory) {
return abi.encodePacked(_amount, _receiver);
}
function encodeLzComposeOption(uint16 _index, uint128 _gas, uint128 _value) internal pure returns (bytes memory) {
return _value == 0 ? abi.encodePacked(_index, _gas) : abi.encodePacked(_index, _gas, _value);
}
}
文件 10 的 35:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 11 的 35:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 12 的 35:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 13 的 35:ILayerZeroDVN.sol
pragma solidity >=0.8.0;
interface ILayerZeroDVN {
struct AssignJobParam {
uint32 dstEid;
bytes packetHeader;
bytes32 payloadHash;
uint64 confirmations;
address sender;
}
function assignJob(AssignJobParam calldata _param, bytes calldata _options) external payable returns (uint256 fee);
function getFee(
uint32 _dstEid,
uint64 _confirmations,
address _sender,
bytes calldata _options
) external view returns (uint256 fee);
}
文件 14 的 35:ILayerZeroEndpointV2.sol
pragma solidity >=0.8.0;
import { IMessageLibManager } from "./IMessageLibManager.sol";
import { IMessagingComposer } from "./IMessagingComposer.sol";
import { IMessagingChannel } from "./IMessagingChannel.sol";
import { IMessagingContext } from "./IMessagingContext.sol";
struct MessagingParams {
uint32 dstEid;
bytes32 receiver;
bytes message;
bytes options;
bool payInLzToken;
}
struct MessagingReceipt {
bytes32 guid;
uint64 nonce;
MessagingFee fee;
}
struct MessagingFee {
uint256 nativeFee;
uint256 lzTokenFee;
}
struct Origin {
uint32 srcEid;
bytes32 sender;
uint64 nonce;
}
interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext {
event PacketSent(bytes encodedPayload, bytes options, address sendLibrary);
event PacketVerified(Origin origin, address receiver, bytes32 payloadHash);
event PacketDelivered(Origin origin, address receiver);
event LzReceiveAlert(
address indexed receiver,
address indexed executor,
Origin origin,
bytes32 guid,
uint256 gas,
uint256 value,
bytes message,
bytes extraData,
bytes reason
);
event LzTokenSet(address token);
event DelegateSet(address sender, address delegate);
function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory);
function send(
MessagingParams calldata _params,
address _refundAddress
) external payable returns (MessagingReceipt memory);
function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external;
function verifiable(Origin calldata _origin, address _receiver) external view returns (bool);
function initializable(Origin calldata _origin, address _receiver) external view returns (bool);
function lzReceive(
Origin calldata _origin,
address _receiver,
bytes32 _guid,
bytes calldata _message,
bytes calldata _extraData
) external payable;
function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external;
function setLzToken(address _lzToken) external;
function lzToken() external view returns (address);
function nativeToken() external view returns (address);
function setDelegate(address _delegate) external;
}
文件 15 的 35:ILayerZeroExecutor.sol
pragma solidity >=0.8.0;
interface ILayerZeroExecutor {
function assignJob(
uint32 _dstEid,
address _sender,
uint256 _calldataSize,
bytes calldata _options
) external returns (uint256 price);
function getFee(
uint32 _dstEid,
address _sender,
uint256 _calldataSize,
bytes calldata _options
) external view returns (uint256 price);
}
文件 16 的 35:ILayerZeroTreasury.sol
pragma solidity >=0.8.0;
interface ILayerZeroTreasury {
function getFee(
address _sender,
uint32 _dstEid,
uint256 _totalNativeFee,
bool _payInLzToken
) external view returns (uint256 fee);
function payFee(
address _sender,
uint32 _dstEid,
uint256 _totalNativeFee,
bool _payInLzToken
) external payable returns (uint256 fee);
}
文件 17 的 35:IMessageLib.sol
pragma solidity >=0.8.0;
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { SetConfigParam } from "./IMessageLibManager.sol";
enum MessageLibType {
Send,
Receive,
SendAndReceive
}
interface IMessageLib is IERC165 {
function setConfig(address _oapp, SetConfigParam[] calldata _config) external;
function getConfig(uint32 _eid, address _oapp, uint32 _configType) external view returns (bytes memory config);
function isSupportedEid(uint32 _eid) external view returns (bool);
function version() external view returns (uint64 major, uint8 minor, uint8 endpointVersion);
function messageLibType() external view returns (MessageLibType);
}
文件 18 的 35:IMessageLibManager.sol
pragma solidity >=0.8.0;
struct SetConfigParam {
uint32 eid;
uint32 configType;
bytes config;
}
interface IMessageLibManager {
struct Timeout {
address lib;
uint256 expiry;
}
event LibraryRegistered(address newLib);
event DefaultSendLibrarySet(uint32 eid, address newLib);
event DefaultReceiveLibrarySet(uint32 eid, address newLib);
event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry);
event SendLibrarySet(address sender, uint32 eid, address newLib);
event ReceiveLibrarySet(address receiver, uint32 eid, address newLib);
event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout);
function registerLibrary(address _lib) external;
function isRegisteredLibrary(address _lib) external view returns (bool);
function getRegisteredLibraries() external view returns (address[] memory);
function setDefaultSendLibrary(uint32 _eid, address _newLib) external;
function defaultSendLibrary(uint32 _eid) external view returns (address);
function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _timeout) external;
function defaultReceiveLibrary(uint32 _eid) external view returns (address);
function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external;
function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry);
function isSupportedEid(uint32 _eid) external view returns (bool);
function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool);
function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external;
function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib);
function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool);
function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external;
function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault);
function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _gracePeriod) external;
function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry);
function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external;
function getConfig(
address _oapp,
address _lib,
uint32 _eid,
uint32 _configType
) external view returns (bytes memory config);
}
文件 19 的 35:IMessagingChannel.sol
pragma solidity >=0.8.0;
interface IMessagingChannel {
event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce);
event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);
event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);
function eid() external view returns (uint32);
function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external;
function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;
function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;
function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32);
function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);
function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64);
function inboundPayloadHash(
address _receiver,
uint32 _srcEid,
bytes32 _sender,
uint64 _nonce
) external view returns (bytes32);
function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);
}
文件 20 的 35:IMessagingComposer.sol
pragma solidity >=0.8.0;
interface IMessagingComposer {
event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message);
event ComposeDelivered(address from, address to, bytes32 guid, uint16 index);
event LzComposeAlert(
address indexed from,
address indexed to,
address indexed executor,
bytes32 guid,
uint16 index,
uint256 gas,
uint256 value,
bytes message,
bytes extraData,
bytes reason
);
function composeQueue(
address _from,
address _to,
bytes32 _guid,
uint16 _index
) external view returns (bytes32 messageHash);
function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external;
function lzCompose(
address _from,
address _to,
bytes32 _guid,
uint16 _index,
bytes calldata _message,
bytes calldata _extraData
) external payable;
}
文件 21 的 35:IMessagingContext.sol
pragma solidity >=0.8.0;
interface IMessagingContext {
function isSendingMessage() external view returns (bool);
function getSendContext() external view returns (uint32 dstEid, address sender);
}
文件 22 的 35:ISendLib.sol
pragma solidity >=0.8.0;
import { MessagingFee } from "./ILayerZeroEndpointV2.sol";
import { IMessageLib } from "./IMessageLib.sol";
struct Packet {
uint64 nonce;
uint32 srcEid;
address sender;
uint32 dstEid;
bytes32 receiver;
bytes32 guid;
bytes message;
}
interface ISendLib is IMessageLib {
function send(
Packet calldata _packet,
bytes calldata _options,
bool _payInLzToken
) external returns (MessagingFee memory, bytes memory encodedPacket);
function quote(
Packet calldata _packet,
bytes calldata _options,
bool _payInLzToken
) external view returns (MessagingFee memory);
function setTreasury(address _treasury) external;
function withdrawFee(address _to, uint256 _amount) external;
function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external;
}
文件 23 的 35:MessageLibBase.sol
pragma solidity ^0.8.20;
abstract contract MessageLibBase {
address internal immutable endpoint;
uint32 internal immutable localEid;
error LZ_MessageLib_OnlyEndpoint();
modifier onlyEndpoint() {
if (endpoint != msg.sender) revert LZ_MessageLib_OnlyEndpoint();
_;
}
constructor(address _endpoint, uint32 _localEid) {
endpoint = _endpoint;
localEid = _localEid;
}
}
文件 24 的 35:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 25 的 35:PacketV1Codec.sol
pragma solidity ^0.8.20;
import { Packet } from "../../interfaces/ISendLib.sol";
import { AddressCast } from "../../libs/AddressCast.sol";
library PacketV1Codec {
using AddressCast for address;
using AddressCast for bytes32;
uint8 internal constant PACKET_VERSION = 1;
uint256 private constant PACKET_VERSION_OFFSET = 0;
uint256 private constant NONCE_OFFSET = 1;
uint256 private constant SRC_EID_OFFSET = 9;
uint256 private constant SENDER_OFFSET = 13;
uint256 private constant DST_EID_OFFSET = 45;
uint256 private constant RECEIVER_OFFSET = 49;
uint256 private constant GUID_OFFSET = 81;
uint256 private constant MESSAGE_OFFSET = 113;
function encode(Packet memory _packet) internal pure returns (bytes memory encodedPacket) {
encodedPacket = abi.encodePacked(
PACKET_VERSION,
_packet.nonce,
_packet.srcEid,
_packet.sender.toBytes32(),
_packet.dstEid,
_packet.receiver,
_packet.guid,
_packet.message
);
}
function encodePacketHeader(Packet memory _packet) internal pure returns (bytes memory) {
return
abi.encodePacked(
PACKET_VERSION,
_packet.nonce,
_packet.srcEid,
_packet.sender.toBytes32(),
_packet.dstEid,
_packet.receiver
);
}
function encodePayload(Packet memory _packet) internal pure returns (bytes memory) {
return abi.encodePacked(_packet.guid, _packet.message);
}
function header(bytes calldata _packet) internal pure returns (bytes calldata) {
return _packet[0:GUID_OFFSET];
}
function version(bytes calldata _packet) internal pure returns (uint8) {
return uint8(bytes1(_packet[PACKET_VERSION_OFFSET:NONCE_OFFSET]));
}
function nonce(bytes calldata _packet) internal pure returns (uint64) {
return uint64(bytes8(_packet[NONCE_OFFSET:SRC_EID_OFFSET]));
}
function srcEid(bytes calldata _packet) internal pure returns (uint32) {
return uint32(bytes4(_packet[SRC_EID_OFFSET:SENDER_OFFSET]));
}
function sender(bytes calldata _packet) internal pure returns (bytes32) {
return bytes32(_packet[SENDER_OFFSET:DST_EID_OFFSET]);
}
function senderAddressB20(bytes calldata _packet) internal pure returns (address) {
return sender(_packet).toAddress();
}
function dstEid(bytes calldata _packet) internal pure returns (uint32) {
return uint32(bytes4(_packet[DST_EID_OFFSET:RECEIVER_OFFSET]));
}
function receiver(bytes calldata _packet) internal pure returns (bytes32) {
return bytes32(_packet[RECEIVER_OFFSET:GUID_OFFSET]);
}
function receiverB20(bytes calldata _packet) internal pure returns (address) {
return receiver(_packet).toAddress();
}
function guid(bytes calldata _packet) internal pure returns (bytes32) {
return bytes32(_packet[GUID_OFFSET:MESSAGE_OFFSET]);
}
function message(bytes calldata _packet) internal pure returns (bytes calldata) {
return bytes(_packet[MESSAGE_OFFSET:]);
}
function payload(bytes calldata _packet) internal pure returns (bytes calldata) {
return bytes(_packet[GUID_OFFSET:]);
}
function payloadHash(bytes calldata _packet) internal pure returns (bytes32) {
return keccak256(payload(_packet));
}
}
文件 26 的 35:SafeCall.sol
pragma solidity ^0.8.20;
library SafeCall {
function safeCall(
address _target,
uint256 _gas,
uint256 _value,
uint16 _maxCopy,
bytes memory _calldata
) internal returns (bool, bytes memory) {
uint size;
assembly {
size := extcodesize(_target)
}
if (size == 0) {
return (false, new bytes(0));
}
uint256 _toCopy;
bool _success;
bytes memory _returnData = new bytes(_maxCopy);
assembly {
_success := call(
_gas,
_target,
_value,
add(_calldata, 0x20),
mload(_calldata),
0,
0
)
_toCopy := returndatasize()
if gt(_toCopy, _maxCopy) {
_toCopy := _maxCopy
}
mstore(_returnData, _toCopy)
returndatacopy(add(_returnData, 0x20), 0, _toCopy)
}
return (_success, _returnData);
}
function safeStaticCall(
address _target,
uint256 _gas,
uint16 _maxCopy,
bytes memory _calldata
) internal view returns (bool, bytes memory) {
uint size;
assembly {
size := extcodesize(_target)
}
if (size == 0) {
return (false, new bytes(0));
}
uint256 _toCopy;
bool _success;
bytes memory _returnData = new bytes(_maxCopy);
assembly {
_success := staticcall(
_gas,
_target,
add(_calldata, 0x20),
mload(_calldata),
0,
0
)
_toCopy := returndatasize()
if gt(_toCopy, _maxCopy) {
_toCopy := _maxCopy
}
mstore(_returnData, _toCopy)
returndatacopy(add(_returnData, 0x20), 0, _toCopy)
}
return (_success, _returnData);
}
}
文件 27 的 35:SafeCast.sol
pragma solidity ^0.8.0;
library SafeCast {
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
function toInt256(uint256 value) internal pure returns (int256) {
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
文件 28 的 35:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
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));
}
}
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);
}
}
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");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
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");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 29 的 35:SendLibBase.sol
pragma solidity ^0.8.20;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Transfer } from "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/Transfer.sol";
import { ILayerZeroExecutor } from "./interfaces/ILayerZeroExecutor.sol";
import { ILayerZeroTreasury } from "./interfaces/ILayerZeroTreasury.sol";
import { SafeCall } from "./libs/SafeCall.sol";
import { MessageLibBase } from "./MessageLibBase.sol";
struct WorkerOptions {
uint8 workerId;
bytes options;
}
struct SetDefaultExecutorConfigParam {
uint32 eid;
ExecutorConfig config;
}
struct ExecutorConfig {
uint32 maxMessageSize;
address executor;
}
abstract contract SendLibBase is MessageLibBase, Ownable {
using SafeCall for address;
address private constant DEFAULT_CONFIG = address(0);
uint16 internal constant TREASURY_MAX_COPY = 32;
uint256 internal immutable treasuryGasLimit;
uint256 internal treasuryNativeFeeCap;
address public treasury;
mapping(address oapp => mapping(uint32 eid => ExecutorConfig)) public executorConfigs;
mapping(address worker => uint256) public fees;
event ExecutorFeePaid(address executor, uint256 fee);
event TreasurySet(address treasury);
event DefaultExecutorConfigsSet(SetDefaultExecutorConfigParam[] params);
event ExecutorConfigSet(address oapp, uint32 eid, ExecutorConfig config);
event TreasuryNativeFeeCapSet(uint256 newTreasuryNativeFeeCap);
error LZ_MessageLib_InvalidMessageSize(uint256 actual, uint256 max);
error LZ_MessageLib_InvalidAmount(uint256 requested, uint256 available);
error LZ_MessageLib_TransferFailed();
error LZ_MessageLib_InvalidExecutor();
error LZ_MessageLib_ZeroMessageSize();
constructor(
address _endpoint,
uint32 _localEid,
uint256 _treasuryGasLimit,
uint256 _treasuryNativeFeeCap
) MessageLibBase(_endpoint, _localEid) {
treasuryGasLimit = _treasuryGasLimit;
treasuryNativeFeeCap = _treasuryNativeFeeCap;
}
function setDefaultExecutorConfigs(SetDefaultExecutorConfigParam[] calldata _params) external onlyOwner {
for (uint256 i = 0; i < _params.length; ++i) {
SetDefaultExecutorConfigParam calldata param = _params[i];
if (param.config.executor == address(0x0)) revert LZ_MessageLib_InvalidExecutor();
if (param.config.maxMessageSize == 0) revert LZ_MessageLib_ZeroMessageSize();
executorConfigs[DEFAULT_CONFIG][param.eid] = param.config;
}
emit DefaultExecutorConfigsSet(_params);
}
function setTreasuryNativeFeeCap(uint256 _newTreasuryNativeFeeCap) external onlyOwner {
if (_newTreasuryNativeFeeCap > treasuryNativeFeeCap)
revert LZ_MessageLib_InvalidAmount(_newTreasuryNativeFeeCap, treasuryNativeFeeCap);
treasuryNativeFeeCap = _newTreasuryNativeFeeCap;
emit TreasuryNativeFeeCapSet(_newTreasuryNativeFeeCap);
}
function getExecutorConfig(address _oapp, uint32 _remoteEid) public view returns (ExecutorConfig memory rtnConfig) {
ExecutorConfig storage defaultConfig = executorConfigs[DEFAULT_CONFIG][_remoteEid];
ExecutorConfig storage customConfig = executorConfigs[_oapp][_remoteEid];
uint32 maxMessageSize = customConfig.maxMessageSize;
rtnConfig.maxMessageSize = maxMessageSize != 0 ? maxMessageSize : defaultConfig.maxMessageSize;
address executor = customConfig.executor;
rtnConfig.executor = executor != address(0x0) ? executor : defaultConfig.executor;
}
function _assertMessageSize(uint256 _actual, uint256 _max) internal pure {
if (_actual > _max) revert LZ_MessageLib_InvalidMessageSize(_actual, _max);
}
function _payExecutor(
address _executor,
uint32 _dstEid,
address _sender,
uint256 _msgSize,
bytes memory _executorOptions
) internal returns (uint256 executorFee) {
executorFee = ILayerZeroExecutor(_executor).assignJob(_dstEid, _sender, _msgSize, _executorOptions);
if (executorFee > 0) {
fees[_executor] += executorFee;
}
emit ExecutorFeePaid(_executor, executorFee);
}
function _payTreasury(
address _sender,
uint32 _dstEid,
uint256 _totalNativeFee,
bool _payInLzToken
) internal returns (uint256 treasuryNativeFee, uint256 lzTokenFee) {
if (treasury != address(0x0)) {
bytes memory callData = abi.encodeCall(
ILayerZeroTreasury.payFee,
(_sender, _dstEid, _totalNativeFee, _payInLzToken)
);
(bool success, bytes memory result) = treasury.safeCall(treasuryGasLimit, 0, TREASURY_MAX_COPY, callData);
(treasuryNativeFee, lzTokenFee) = _parseTreasuryResult(_totalNativeFee, _payInLzToken, success, result);
if (treasuryNativeFee > 0) {
fees[treasury] += treasuryNativeFee;
}
}
}
function _quote(
address _sender,
uint32 _dstEid,
uint256 _msgSize,
bool _payInLzToken,
bytes calldata _options
) internal view returns (uint256, uint256) {
(bytes memory executorOptions, WorkerOptions[] memory validationOptions) = _splitOptions(_options);
uint256 nativeFee = _quoteVerifier(_sender, _dstEid, validationOptions);
ExecutorConfig memory config = getExecutorConfig(_sender, _dstEid);
_assertMessageSize(_msgSize, config.maxMessageSize);
nativeFee += ILayerZeroExecutor(config.executor).getFee(_dstEid, _sender, _msgSize, executorOptions);
(uint256 treasuryNativeFee, uint256 lzTokenFee) = _quoteTreasury(_sender, _dstEid, nativeFee, _payInLzToken);
nativeFee += treasuryNativeFee;
return (nativeFee, lzTokenFee);
}
function _quoteTreasury(
address _sender,
uint32 _dstEid,
uint256 _totalNativeFee,
bool _payInLzToken
) internal view returns (uint256 nativeFee, uint256 lzTokenFee) {
if (treasury != address(0x0)) {
bytes memory callData = abi.encodeCall(
ILayerZeroTreasury.getFee,
(_sender, _dstEid, _totalNativeFee, _payInLzToken)
);
(bool success, bytes memory result) = treasury.safeStaticCall(
treasuryGasLimit,
TREASURY_MAX_COPY,
callData
);
return _parseTreasuryResult(_totalNativeFee, _payInLzToken, success, result);
}
}
function _parseTreasuryResult(
uint256 _totalNativeFee,
bool _payInLzToken,
bool _success,
bytes memory _result
) internal view returns (uint256 nativeFee, uint256 lzTokenFee) {
if (!_success || _result.length < TREASURY_MAX_COPY) return (0, 0);
uint256 treasureFeeQuote = abi.decode(_result, (uint256));
if (_payInLzToken) {
lzTokenFee = treasureFeeQuote;
} else {
uint256 maxNativeFee = _totalNativeFee > treasuryNativeFeeCap ? _totalNativeFee : treasuryNativeFeeCap;
nativeFee = treasureFeeQuote > maxNativeFee ? maxNativeFee : treasureFeeQuote;
}
}
function _debitFee(uint256 _amount) internal {
uint256 fee = fees[msg.sender];
if (_amount > fee) revert LZ_MessageLib_InvalidAmount(_amount, fee);
unchecked {
fees[msg.sender] = fee - _amount;
}
}
function _setTreasury(address _treasury) internal {
treasury = _treasury;
emit TreasurySet(_treasury);
}
function _setExecutorConfig(uint32 _remoteEid, address _oapp, ExecutorConfig memory _config) internal {
executorConfigs[_oapp][_remoteEid] = _config;
emit ExecutorConfigSet(_oapp, _remoteEid, _config);
}
function _quoteVerifier(
address _oapp,
uint32 _eid,
WorkerOptions[] memory _options
) internal view virtual returns (uint256 nativeFee);
function _splitOptions(
bytes calldata _options
) internal view virtual returns (bytes memory executorOptions, WorkerOptions[] memory validationOptions);
}
文件 30 的 35:SendLibBaseE2.sol
pragma solidity ^0.8.20;
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import { ILayerZeroEndpointV2, MessagingFee } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";
import { IMessageLib, MessageLibType } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLib.sol";
import { ISendLib, Packet } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol";
import { Transfer } from "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/Transfer.sol";
import { SendLibBase, WorkerOptions, ExecutorConfig } from "./SendLibBase.sol";
abstract contract SendLibBaseE2 is SendLibBase, ERC165, ISendLib {
event NativeFeeWithdrawn(address worker, address receiver, uint256 amount);
event LzTokenFeeWithdrawn(address lzToken, address receiver, uint256 amount);
error LZ_MessageLib_NotTreasury();
error LZ_MessageLib_CannotWithdrawAltToken();
constructor(
address _endpoint,
uint256 _treasuryGasLimit,
uint256 _treasuryNativeFeeCap
) SendLibBase(_endpoint, ILayerZeroEndpointV2(_endpoint).eid(), _treasuryGasLimit, _treasuryNativeFeeCap) {}
function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
_interfaceId == type(IMessageLib).interfaceId ||
_interfaceId == type(ISendLib).interfaceId ||
super.supportsInterface(_interfaceId);
}
function send(
Packet calldata _packet,
bytes calldata _options,
bool _payInLzToken
) public virtual onlyEndpoint returns (MessagingFee memory, bytes memory) {
(bytes memory encodedPacket, uint256 totalNativeFee) = _payWorkers(_packet, _options);
(uint256 treasuryNativeFee, uint256 lzTokenFee) = _payTreasury(
_packet.sender,
_packet.dstEid,
totalNativeFee,
_payInLzToken
);
totalNativeFee += treasuryNativeFee;
return (MessagingFee(totalNativeFee, lzTokenFee), encodedPacket);
}
function setTreasury(address _treasury) external onlyOwner {
_setTreasury(_treasury);
}
function withdrawFee(address _to, uint256 _amount) external {
_debitFee(_amount);
address nativeToken = ILayerZeroEndpointV2(endpoint).nativeToken();
Transfer.nativeOrToken(nativeToken, _to, _amount);
emit NativeFeeWithdrawn(msg.sender, _to, _amount);
}
function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external {
if (msg.sender != treasury) revert LZ_MessageLib_NotTreasury();
if (ILayerZeroEndpointV2(endpoint).nativeToken() == _lzToken) revert LZ_MessageLib_CannotWithdrawAltToken();
Transfer.token(_lzToken, _to, _amount);
emit LzTokenFeeWithdrawn(_lzToken, _to, _amount);
}
function quote(
Packet calldata _packet,
bytes calldata _options,
bool _payInLzToken
) external view returns (MessagingFee memory) {
(uint256 nativeFee, uint256 lzTokenFee) = _quote(
_packet.sender,
_packet.dstEid,
_packet.message.length,
_payInLzToken,
_options
);
return MessagingFee(nativeFee, lzTokenFee);
}
function messageLibType() external pure virtual override returns (MessageLibType) {
return MessageLibType.Send;
}
function _payWorkers(
Packet calldata _packet,
bytes calldata _options
) internal returns (bytes memory encodedPacket, uint256 totalNativeFee) {
(bytes memory executorOptions, WorkerOptions[] memory validationOptions) = _splitOptions(_options);
ExecutorConfig memory config = getExecutorConfig(_packet.sender, _packet.dstEid);
uint256 msgSize = _packet.message.length;
_assertMessageSize(msgSize, config.maxMessageSize);
totalNativeFee += _payExecutor(config.executor, _packet.dstEid, _packet.sender, msgSize, executorOptions);
(uint256 verifierFee, bytes memory packetBytes) = _payVerifier(_packet, validationOptions);
totalNativeFee += verifierFee;
encodedPacket = packetBytes;
}
function _payVerifier(
Packet calldata _packet,
WorkerOptions[] memory _options
) internal virtual returns (uint256 otherWorkerFees, bytes memory encodedPacket);
receive() external payable virtual {}
}
文件 31 的 35:SendUln302.sol
pragma solidity ^0.8.20;
import { Packet } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol";
import { SetConfigParam } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLibManager.sol";
import { ExecutorConfig } from "../../SendLibBase.sol";
import { SendLibBaseE2, WorkerOptions } from "../../SendLibBaseE2.sol";
import { UlnConfig } from "../UlnBase.sol";
import { SendUlnBase } from "../SendUlnBase.sol";
contract SendUln302 is SendUlnBase, SendLibBaseE2 {
uint32 internal constant CONFIG_TYPE_EXECUTOR = 1;
uint32 internal constant CONFIG_TYPE_ULN = 2;
error LZ_ULN_InvalidConfigType(uint32 configType);
constructor(
address _endpoint,
uint256 _treasuryGasLimit,
uint256 _treasuryGasForFeeCap
) SendLibBaseE2(_endpoint, _treasuryGasLimit, _treasuryGasForFeeCap) {}
function setConfig(address _oapp, SetConfigParam[] calldata _params) external override onlyEndpoint {
for (uint256 i = 0; i < _params.length; i++) {
SetConfigParam calldata param = _params[i];
_assertSupportedEid(param.eid);
if (param.configType == CONFIG_TYPE_EXECUTOR) {
_setExecutorConfig(param.eid, _oapp, abi.decode(param.config, (ExecutorConfig)));
} else if (param.configType == CONFIG_TYPE_ULN) {
_setUlnConfig(param.eid, _oapp, abi.decode(param.config, (UlnConfig)));
} else {
revert LZ_ULN_InvalidConfigType(param.configType);
}
}
}
function getConfig(uint32 _eid, address _oapp, uint32 _configType) external view override returns (bytes memory) {
if (_configType == CONFIG_TYPE_EXECUTOR) {
return abi.encode(getExecutorConfig(_oapp, _eid));
} else if (_configType == CONFIG_TYPE_ULN) {
return abi.encode(getUlnConfig(_oapp, _eid));
} else {
revert LZ_ULN_InvalidConfigType(_configType);
}
}
function version() external pure override returns (uint64 major, uint8 minor, uint8 endpointVersion) {
return (3, 0, 2);
}
function isSupportedEid(uint32 _eid) external view override returns (bool) {
return _isSupportedEid(_eid);
}
function _quoteVerifier(
address _sender,
uint32 _dstEid,
WorkerOptions[] memory _options
) internal view override returns (uint256) {
return _quoteDVNs(_sender, _dstEid, _options);
}
function _payVerifier(
Packet calldata _packet,
WorkerOptions[] memory _options
) internal override returns (uint256 otherWorkerFees, bytes memory encodedPacket) {
(otherWorkerFees, encodedPacket) = _payDVNs(fees, _packet, _options);
}
function _splitOptions(
bytes calldata _options
) internal pure override returns (bytes memory, WorkerOptions[] memory) {
return _splitUlnOptions(_options);
}
}
文件 32 的 35:SendUlnBase.sol
pragma solidity ^0.8.20;
import { Packet } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol";
import { PacketV1Codec } from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.sol";
import { ILayerZeroDVN } from "./interfaces/ILayerZeroDVN.sol";
import { DVNOptions } from "./libs/DVNOptions.sol";
import { UlnOptions } from "./libs/UlnOptions.sol";
import { WorkerOptions } from "../SendLibBase.sol";
import { UlnConfig, UlnBase } from "./UlnBase.sol";
abstract contract SendUlnBase is UlnBase {
event DVNFeePaid(address[] requiredDVNs, address[] optionalDVNs, uint256[] fees);
function _splitUlnOptions(bytes calldata _options) internal pure returns (bytes memory, WorkerOptions[] memory) {
(bytes memory executorOpts, bytes memory dvnOpts) = UlnOptions.decode(_options);
if (dvnOpts.length == 0) {
return (executorOpts, new WorkerOptions[](0));
}
WorkerOptions[] memory workerOpts = new WorkerOptions[](1);
workerOpts[0] = WorkerOptions(DVNOptions.WORKER_ID, dvnOpts);
return (executorOpts, workerOpts);
}
function _payDVNs(
mapping(address => uint256) storage _fees,
Packet memory _packet,
WorkerOptions[] memory _options
) internal returns (uint256 totalFee, bytes memory encodedPacket) {
bytes memory packetHeader = PacketV1Codec.encodePacketHeader(_packet);
bytes memory payload = PacketV1Codec.encodePayload(_packet);
bytes32 payloadHash = keccak256(payload);
uint32 dstEid = _packet.dstEid;
address sender = _packet.sender;
UlnConfig memory config = getUlnConfig(sender, dstEid);
bytes memory dvnOptions = _options.length == 0 ? bytes("") : _options[0].options;
uint256[] memory dvnFees;
(totalFee, dvnFees) = _assignJobs(
_fees,
config,
ILayerZeroDVN.AssignJobParam(dstEid, packetHeader, payloadHash, config.confirmations, sender),
dvnOptions
);
encodedPacket = abi.encodePacked(packetHeader, payload);
emit DVNFeePaid(config.requiredDVNs, config.optionalDVNs, dvnFees);
}
function _assignJobs(
mapping(address => uint256) storage _fees,
UlnConfig memory _ulnConfig,
ILayerZeroDVN.AssignJobParam memory _param,
bytes memory dvnOptions
) internal returns (uint256 totalFee, uint256[] memory dvnFees) {
(bytes[] memory optionsArray, uint8[] memory dvnIds) = DVNOptions.groupDVNOptionsByIdx(dvnOptions);
uint8 dvnsLength = _ulnConfig.requiredDVNCount + _ulnConfig.optionalDVNCount;
dvnFees = new uint256[](dvnsLength);
for (uint8 i = 0; i < dvnsLength; ++i) {
address dvn = i < _ulnConfig.requiredDVNCount
? _ulnConfig.requiredDVNs[i]
: _ulnConfig.optionalDVNs[i - _ulnConfig.requiredDVNCount];
bytes memory options = "";
for (uint256 j = 0; j < dvnIds.length; ++j) {
if (dvnIds[j] == i) {
options = optionsArray[j];
break;
}
}
dvnFees[i] = ILayerZeroDVN(dvn).assignJob(_param, options);
if (dvnFees[i] > 0) {
_fees[dvn] += dvnFees[i];
totalFee += dvnFees[i];
}
}
}
function _quoteDVNs(
address _sender,
uint32 _dstEid,
WorkerOptions[] memory _options
) internal view returns (uint256 totalFee) {
UlnConfig memory config = getUlnConfig(_sender, _dstEid);
bytes memory dvnOptions = _options.length == 0 ? bytes("") : _options[0].options;
(bytes[] memory optionsArray, uint8[] memory dvnIndices) = DVNOptions.groupDVNOptionsByIdx(dvnOptions);
totalFee = _getFees(config, _dstEid, _sender, optionsArray, dvnIndices);
}
function _getFees(
UlnConfig memory _config,
uint32 _dstEid,
address _sender,
bytes[] memory _optionsArray,
uint8[] memory _dvnIds
) internal view returns (uint256 totalFee) {
uint8 dvnsLength = _config.requiredDVNCount + _config.optionalDVNCount;
for (uint8 i = 0; i < dvnsLength; ++i) {
address dvn = i < _config.requiredDVNCount
? _config.requiredDVNs[i]
: _config.optionalDVNs[i - _config.requiredDVNCount];
bytes memory options = "";
for (uint256 j = 0; j < _dvnIds.length; ++j) {
if (_dvnIds[j] == i) {
options = _optionsArray[j];
break;
}
}
totalFee += ILayerZeroDVN(dvn).getFee(_dstEid, _config.confirmations, _sender, options);
}
}
}
文件 33 的 35:Transfer.sol
pragma solidity ^0.8.20;
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
library Transfer {
using SafeERC20 for IERC20;
address internal constant ADDRESS_ZERO = address(0);
error Transfer_NativeFailed(address _to, uint256 _value);
error Transfer_ToAddressIsZero();
function native(address _to, uint256 _value) internal {
if (_to == ADDRESS_ZERO) revert Transfer_ToAddressIsZero();
(bool success, ) = _to.call{ value: _value }("");
if (!success) revert Transfer_NativeFailed(_to, _value);
}
function token(address _token, address _to, uint256 _value) internal {
if (_to == ADDRESS_ZERO) revert Transfer_ToAddressIsZero();
IERC20(_token).safeTransfer(_to, _value);
}
function nativeOrToken(address _token, address _to, uint256 _value) internal {
if (_token == ADDRESS_ZERO) {
native(_to, _value);
} else {
token(_token, _to, _value);
}
}
}
文件 34 的 35:UlnBase.sol
pragma solidity ^0.8.20;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
struct UlnConfig {
uint64 confirmations;
uint8 requiredDVNCount;
uint8 optionalDVNCount;
uint8 optionalDVNThreshold;
address[] requiredDVNs;
address[] optionalDVNs;
}
struct SetDefaultUlnConfigParam {
uint32 eid;
UlnConfig config;
}
abstract contract UlnBase is Ownable {
address private constant DEFAULT_CONFIG = address(0);
uint8 internal constant DEFAULT = 0;
uint8 internal constant NIL_DVN_COUNT = type(uint8).max;
uint64 internal constant NIL_CONFIRMATIONS = type(uint64).max;
uint8 private constant MAX_COUNT = (type(uint8).max - 1) / 2;
mapping(address oapp => mapping(uint32 eid => UlnConfig)) internal ulnConfigs;
error LZ_ULN_Unsorted();
error LZ_ULN_InvalidRequiredDVNCount();
error LZ_ULN_InvalidOptionalDVNCount();
error LZ_ULN_AtLeastOneDVN();
error LZ_ULN_InvalidOptionalDVNThreshold();
error LZ_ULN_InvalidConfirmations();
error LZ_ULN_UnsupportedEid(uint32 eid);
event DefaultUlnConfigsSet(SetDefaultUlnConfigParam[] params);
event UlnConfigSet(address oapp, uint32 eid, UlnConfig config);
function setDefaultUlnConfigs(SetDefaultUlnConfigParam[] calldata _params) external onlyOwner {
for (uint256 i = 0; i < _params.length; ++i) {
SetDefaultUlnConfigParam calldata param = _params[i];
if (param.config.requiredDVNCount == NIL_DVN_COUNT) revert LZ_ULN_InvalidRequiredDVNCount();
if (param.config.optionalDVNCount == NIL_DVN_COUNT) revert LZ_ULN_InvalidOptionalDVNCount();
if (param.config.confirmations == NIL_CONFIRMATIONS) revert LZ_ULN_InvalidConfirmations();
_assertAtLeastOneDVN(param.config);
_setConfig(DEFAULT_CONFIG, param.eid, param.config);
}
emit DefaultUlnConfigsSet(_params);
}
function getUlnConfig(address _oapp, uint32 _remoteEid) public view returns (UlnConfig memory rtnConfig) {
UlnConfig storage defaultConfig = ulnConfigs[DEFAULT_CONFIG][_remoteEid];
UlnConfig storage customConfig = ulnConfigs[_oapp][_remoteEid];
uint64 confirmations = customConfig.confirmations;
if (confirmations == DEFAULT) {
rtnConfig.confirmations = defaultConfig.confirmations;
} else if (confirmations != NIL_CONFIRMATIONS) {
rtnConfig.confirmations = confirmations;
}
if (customConfig.requiredDVNCount == DEFAULT) {
if (defaultConfig.requiredDVNCount > 0) {
rtnConfig.requiredDVNs = defaultConfig.requiredDVNs;
rtnConfig.requiredDVNCount = defaultConfig.requiredDVNCount;
}
} else {
if (customConfig.requiredDVNCount != NIL_DVN_COUNT) {
rtnConfig.requiredDVNs = customConfig.requiredDVNs;
rtnConfig.requiredDVNCount = customConfig.requiredDVNCount;
}
}
if (customConfig.optionalDVNCount == DEFAULT) {
if (defaultConfig.optionalDVNCount > 0) {
rtnConfig.optionalDVNs = defaultConfig.optionalDVNs;
rtnConfig.optionalDVNCount = defaultConfig.optionalDVNCount;
rtnConfig.optionalDVNThreshold = defaultConfig.optionalDVNThreshold;
}
} else {
if (customConfig.optionalDVNCount != NIL_DVN_COUNT) {
rtnConfig.optionalDVNs = customConfig.optionalDVNs;
rtnConfig.optionalDVNCount = customConfig.optionalDVNCount;
rtnConfig.optionalDVNThreshold = customConfig.optionalDVNThreshold;
}
}
_assertAtLeastOneDVN(rtnConfig);
}
function getAppUlnConfig(address _oapp, uint32 _remoteEid) external view returns (UlnConfig memory) {
return ulnConfigs[_oapp][_remoteEid];
}
function _setUlnConfig(uint32 _remoteEid, address _oapp, UlnConfig memory _param) internal {
_setConfig(_oapp, _remoteEid, _param);
getUlnConfig(_oapp, _remoteEid);
emit UlnConfigSet(_oapp, _remoteEid, _param);
}
function _isSupportedEid(uint32 _remoteEid) internal view returns (bool) {
UlnConfig storage defaultConfig = ulnConfigs[DEFAULT_CONFIG][_remoteEid];
return defaultConfig.requiredDVNCount > 0 || defaultConfig.optionalDVNThreshold > 0;
}
function _assertSupportedEid(uint32 _remoteEid) internal view {
if (!_isSupportedEid(_remoteEid)) revert LZ_ULN_UnsupportedEid(_remoteEid);
}
function _assertAtLeastOneDVN(UlnConfig memory _config) private pure {
if (_config.requiredDVNCount == 0 && _config.optionalDVNThreshold == 0) revert LZ_ULN_AtLeastOneDVN();
}
function _setConfig(address _oapp, uint32 _eid, UlnConfig memory _param) private {
if (_param.requiredDVNCount == NIL_DVN_COUNT || _param.requiredDVNCount == DEFAULT) {
if (_param.requiredDVNs.length != 0) revert LZ_ULN_InvalidRequiredDVNCount();
} else {
if (_param.requiredDVNs.length != _param.requiredDVNCount || _param.requiredDVNCount > MAX_COUNT)
revert LZ_ULN_InvalidRequiredDVNCount();
_assertNoDuplicates(_param.requiredDVNs);
}
if (_param.optionalDVNCount == NIL_DVN_COUNT || _param.optionalDVNCount == DEFAULT) {
if (_param.optionalDVNs.length != 0) revert LZ_ULN_InvalidOptionalDVNCount();
if (_param.optionalDVNThreshold != 0) revert LZ_ULN_InvalidOptionalDVNThreshold();
} else {
if (_param.optionalDVNs.length != _param.optionalDVNCount || _param.optionalDVNCount > MAX_COUNT)
revert LZ_ULN_InvalidOptionalDVNCount();
if (_param.optionalDVNThreshold == 0 || _param.optionalDVNThreshold > _param.optionalDVNCount)
revert LZ_ULN_InvalidOptionalDVNThreshold();
_assertNoDuplicates(_param.optionalDVNs);
}
ulnConfigs[_oapp][_eid] = _param;
}
function _assertNoDuplicates(address[] memory _dvns) private pure {
address lastDVN = address(0);
for (uint256 i = 0; i < _dvns.length; i++) {
address dvn = _dvns[i];
if (dvn <= lastDVN) revert LZ_ULN_Unsorted();
lastDVN = dvn;
}
}
}
文件 35 的 35:UlnOptions.sol
pragma solidity ^0.8.20;
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import { ExecutorOptions } from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/ExecutorOptions.sol";
import { DVNOptions } from "./DVNOptions.sol";
library UlnOptions {
using SafeCast for uint256;
uint16 internal constant TYPE_1 = 1;
uint16 internal constant TYPE_2 = 2;
uint16 internal constant TYPE_3 = 3;
error LZ_ULN_InvalidWorkerOptions(uint256 cursor);
error LZ_ULN_InvalidWorkerId(uint8 workerId);
error LZ_ULN_InvalidLegacyType1Option();
error LZ_ULN_InvalidLegacyType2Option();
error LZ_ULN_UnsupportedOptionType(uint16 optionType);
function decode(
bytes calldata _options
) internal pure returns (bytes memory executorOptions, bytes memory dvnOptions) {
if (_options.length < 2) revert LZ_ULN_InvalidWorkerOptions(0);
uint16 optionsType = uint16(bytes2(_options[0:2]));
uint256 cursor = 2;
if (optionsType == TYPE_3) {
unchecked {
uint256 start = cursor;
uint8 lastWorkerId;
while (cursor < _options.length) {
uint8 workerId = uint8(bytes1(_options[cursor:cursor + 1]));
if (workerId == 0) revert LZ_ULN_InvalidWorkerId(0);
if (lastWorkerId == 0) {
lastWorkerId = workerId;
} else if (workerId != lastWorkerId) {
bytes calldata op = _options[start:cursor];
(executorOptions, dvnOptions) = _insertWorkerOptions(
executorOptions,
dvnOptions,
lastWorkerId,
op
);
start = cursor;
lastWorkerId = workerId;
}
++cursor;
uint16 size = uint16(bytes2(_options[cursor:cursor + 2]));
if (size == 0) revert LZ_ULN_InvalidWorkerOptions(cursor);
cursor += size + 2;
}
if (cursor != _options.length) revert LZ_ULN_InvalidWorkerOptions(cursor);
if (_options.length > 2) {
bytes calldata op = _options[start:cursor];
(executorOptions, dvnOptions) = _insertWorkerOptions(executorOptions, dvnOptions, lastWorkerId, op);
}
}
} else {
executorOptions = decodeLegacyOptions(optionsType, _options);
}
}
function _insertWorkerOptions(
bytes memory _executorOptions,
bytes memory _dvnOptions,
uint8 _workerId,
bytes calldata _newOptions
) private pure returns (bytes memory, bytes memory) {
if (_workerId == ExecutorOptions.WORKER_ID) {
_executorOptions = _executorOptions.length == 0
? _newOptions
: abi.encodePacked(_executorOptions, _newOptions);
} else if (_workerId == DVNOptions.WORKER_ID) {
_dvnOptions = _dvnOptions.length == 0 ? _newOptions : abi.encodePacked(_dvnOptions, _newOptions);
} else {
revert LZ_ULN_InvalidWorkerId(_workerId);
}
return (_executorOptions, _dvnOptions);
}
function decodeLegacyOptions(
uint16 _optionType,
bytes calldata _options
) internal pure returns (bytes memory executorOptions) {
if (_optionType == TYPE_1) {
if (_options.length != 34) revert LZ_ULN_InvalidLegacyType1Option();
uint128 executionGas = uint256(bytes32(_options[2:2 + 32])).toUint128();
executorOptions = abi.encodePacked(
ExecutorOptions.WORKER_ID,
uint16(17),
ExecutorOptions.OPTION_TYPE_LZRECEIVE,
executionGas
);
} else if (_optionType == TYPE_2) {
if (_options.length <= 66 || _options.length > 98) revert LZ_ULN_InvalidLegacyType2Option();
uint128 executionGas = uint256(bytes32(_options[2:2 + 32])).toUint128();
uint128 amount = uint256(bytes32(_options[34:34 + 32])).toUint128();
bytes32 receiver;
unchecked {
uint256 receiverLen = _options.length - 66;
receiver = bytes32(_options[66:]);
receiver = receiver >> (8 * (32 - receiverLen));
}
executorOptions = abi.encodePacked(
ExecutorOptions.WORKER_ID,
uint16(17),
ExecutorOptions.OPTION_TYPE_LZRECEIVE,
executionGas,
ExecutorOptions.WORKER_ID,
uint16(49),
ExecutorOptions.OPTION_TYPE_NATIVE_DROP,
amount,
receiver
);
} else {
revert LZ_ULN_UnsupportedOptionType(_optionType);
}
}
}
{
"compilationTarget": {
"contracts/uln/uln302/SendUln302.sol": "SendUln302"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 20000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_endpoint","type":"address"},{"internalType":"uint256","name":"_treasuryGasLimit","type":"uint256"},{"internalType":"uint256","name":"_treasuryGasForFeeCap","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DVN_InvalidDVNIdx","type":"error"},{"inputs":[{"internalType":"uint256","name":"cursor","type":"uint256"}],"name":"DVN_InvalidDVNOptions","type":"error"},{"inputs":[],"name":"LZ_MessageLib_CannotWithdrawAltToken","type":"error"},{"inputs":[{"internalType":"uint256","name":"requested","type":"uint256"},{"internalType":"uint256","name":"available","type":"uint256"}],"name":"LZ_MessageLib_InvalidAmount","type":"error"},{"inputs":[],"name":"LZ_MessageLib_InvalidExecutor","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"LZ_MessageLib_InvalidMessageSize","type":"error"},{"inputs":[],"name":"LZ_MessageLib_NotTreasury","type":"error"},{"inputs":[],"name":"LZ_MessageLib_OnlyEndpoint","type":"error"},{"inputs":[],"name":"LZ_MessageLib_TransferFailed","type":"error"},{"inputs":[],"name":"LZ_MessageLib_ZeroMessageSize","type":"error"},{"inputs":[],"name":"LZ_ULN_AtLeastOneDVN","type":"error"},{"inputs":[{"internalType":"uint32","name":"configType","type":"uint32"}],"name":"LZ_ULN_InvalidConfigType","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidConfirmations","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidLegacyType1Option","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidLegacyType2Option","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidOptionalDVNCount","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidOptionalDVNThreshold","type":"error"},{"inputs":[],"name":"LZ_ULN_InvalidRequiredDVNCount","type":"error"},{"inputs":[{"internalType":"uint8","name":"workerId","type":"uint8"}],"name":"LZ_ULN_InvalidWorkerId","type":"error"},{"inputs":[{"internalType":"uint256","name":"cursor","type":"uint256"}],"name":"LZ_ULN_InvalidWorkerOptions","type":"error"},{"inputs":[],"name":"LZ_ULN_Unsorted","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"LZ_ULN_UnsupportedEid","type":"error"},{"inputs":[{"internalType":"uint16","name":"optionType","type":"uint16"}],"name":"LZ_ULN_UnsupportedOptionType","type":"error"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer_NativeFailed","type":"error"},{"inputs":[],"name":"Transfer_ToAddressIsZero","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"optionalDVNs","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"fees","type":"uint256[]"}],"name":"DVNFeePaid","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint32","name":"maxMessageSize","type":"uint32"},{"internalType":"address","name":"executor","type":"address"}],"internalType":"struct ExecutorConfig","name":"config","type":"tuple"}],"indexed":false,"internalType":"struct SetDefaultExecutorConfigParam[]","name":"params","type":"tuple[]"}],"name":"DefaultExecutorConfigsSet","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint8","name":"requiredDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNThreshold","type":"uint8"},{"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"internalType":"address[]","name":"optionalDVNs","type":"address[]"}],"internalType":"struct UlnConfig","name":"config","type":"tuple"}],"indexed":false,"internalType":"struct SetDefaultUlnConfigParam[]","name":"params","type":"tuple[]"}],"name":"DefaultUlnConfigsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oapp","type":"address"},{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint32","name":"maxMessageSize","type":"uint32"},{"internalType":"address","name":"executor","type":"address"}],"indexed":false,"internalType":"struct ExecutorConfig","name":"config","type":"tuple"}],"name":"ExecutorConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"executor","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"ExecutorFeePaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lzToken","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LzTokenFeeWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"worker","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NativeFeeWithdrawn","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":"uint256","name":"newTreasuryNativeFeeCap","type":"uint256"}],"name":"TreasuryNativeFeeCapSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"treasury","type":"address"}],"name":"TreasurySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oapp","type":"address"},{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint8","name":"requiredDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNThreshold","type":"uint8"},{"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"internalType":"address[]","name":"optionalDVNs","type":"address[]"}],"indexed":false,"internalType":"struct UlnConfig","name":"config","type":"tuple"}],"name":"UlnConfigSet","type":"event"},{"inputs":[{"internalType":"address","name":"oapp","type":"address"},{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"executorConfigs","outputs":[{"internalType":"uint32","name":"maxMessageSize","type":"uint32"},{"internalType":"address","name":"executor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"worker","type":"address"}],"name":"fees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oapp","type":"address"},{"internalType":"uint32","name":"_remoteEid","type":"uint32"}],"name":"getAppUlnConfig","outputs":[{"components":[{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint8","name":"requiredDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNThreshold","type":"uint8"},{"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"internalType":"address[]","name":"optionalDVNs","type":"address[]"}],"internalType":"struct UlnConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"address","name":"_oapp","type":"address"},{"internalType":"uint32","name":"_configType","type":"uint32"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oapp","type":"address"},{"internalType":"uint32","name":"_remoteEid","type":"uint32"}],"name":"getExecutorConfig","outputs":[{"components":[{"internalType":"uint32","name":"maxMessageSize","type":"uint32"},{"internalType":"address","name":"executor","type":"address"}],"internalType":"struct ExecutorConfig","name":"rtnConfig","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oapp","type":"address"},{"internalType":"uint32","name":"_remoteEid","type":"uint32"}],"name":"getUlnConfig","outputs":[{"components":[{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint8","name":"requiredDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNThreshold","type":"uint8"},{"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"internalType":"address[]","name":"optionalDVNs","type":"address[]"}],"internalType":"struct UlnConfig","name":"rtnConfig","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"}],"name":"isSupportedEid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messageLibType","outputs":[{"internalType":"enum MessageLibType","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"nonce","type":"uint64"},{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"receiver","type":"bytes32"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct Packet","name":"_packet","type":"tuple"},{"internalType":"bytes","name":"_options","type":"bytes"},{"internalType":"bool","name":"_payInLzToken","type":"bool"}],"name":"quote","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"nonce","type":"uint64"},{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"receiver","type":"bytes32"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct Packet","name":"_packet","type":"tuple"},{"internalType":"bytes","name":"_options","type":"bytes"},{"internalType":"bool","name":"_payInLzToken","type":"bool"}],"name":"send","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oapp","type":"address"},{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint32","name":"configType","type":"uint32"},{"internalType":"bytes","name":"config","type":"bytes"}],"internalType":"struct SetConfigParam[]","name":"_params","type":"tuple[]"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint32","name":"maxMessageSize","type":"uint32"},{"internalType":"address","name":"executor","type":"address"}],"internalType":"struct ExecutorConfig","name":"config","type":"tuple"}],"internalType":"struct SetDefaultExecutorConfigParam[]","name":"_params","type":"tuple[]"}],"name":"setDefaultExecutorConfigs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"components":[{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint8","name":"requiredDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNCount","type":"uint8"},{"internalType":"uint8","name":"optionalDVNThreshold","type":"uint8"},{"internalType":"address[]","name":"requiredDVNs","type":"address[]"},{"internalType":"address[]","name":"optionalDVNs","type":"address[]"}],"internalType":"struct UlnConfig","name":"config","type":"tuple"}],"internalType":"struct SetDefaultUlnConfigParam[]","name":"_params","type":"tuple[]"}],"name":"setDefaultUlnConfigs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTreasuryNativeFeeCap","type":"uint256"}],"name":"setTreasuryNativeFeeCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint64","name":"major","type":"uint64"},{"internalType":"uint8","name":"minor","type":"uint8"},{"internalType":"uint8","name":"endpointVersion","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lzToken","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawLzTokenFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]