编译器
0.8.19+commit.7dd6d404
文件 1 的 13:AddressHelper.sol
pragma solidity 0.8.19;
error NonContractAddressError(address account);
function isContract(address _account) view returns (bool) {
return _account.code.length > 0;
}
function requireContract(address _account) view {
if (!isContract(_account)) {
revert NonContractAddressError(_account);
}
}
function requireContractOrZeroAddress(address _account) view {
if (_account != address(0)) {
requireContract(_account);
}
}
文件 2 的 13:Constants.sol
pragma solidity 0.8.19;
uint256 constant DECIMALS_DEFAULT = 18;
uint256 constant INFINITY = type(uint256).max;
uint256 constant LIST_SIZE_LIMIT_DEFAULT = 100;
uint256 constant LIST_SIZE_LIMIT_ROUTERS = 200;
uint256 constant MILLIPERCENT_FACTOR = 100_000;
address constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
文件 3 的 13: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;
}
}
文件 4 的 13:ILayerZeroEndpoint.sol
pragma solidity 0.8.19;
interface ILayerZeroEndpoint {
function send(
uint16 _dstChainId,
bytes calldata _destination,
bytes calldata _payload,
address payable _refundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParam
) external payable;
function estimateFees(
uint16 _dstChainId,
address _userApplication,
bytes calldata _payload,
bool _payInZRO,
bytes calldata _adapterParam
) external view returns (uint256 nativeFee, uint256 zroFee);
}
文件 5 的 13:ILayerZeroRelayer.sol
pragma solidity 0.8.19;
interface ILayerZeroRelayer {
function dstConfigLookup(
uint16 _chainId,
uint16 _outboundProofType
) external view returns (uint128 dstNativeAmtCap, uint64 baseGas, uint64 gasPerByte);
}
文件 6 的 13:ILayerZeroResumeReceive.sol
pragma solidity 0.8.19;
interface ILayerZeroResumeReceive {
function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
}
文件 7 的 13:ITokenBalance.sol
pragma solidity 0.8.19;
interface ITokenBalance {
function balanceOf(address _account) external view returns (uint256);
}
文件 8 的 13:InterportLZGasTransfer.sol
pragma solidity 0.8.19;
import { ILayerZeroEndpoint } from '../crosschain/layerzero/interfaces/ILayerZeroEndpoint.sol';
import { ILayerZeroRelayer } from '../crosschain/layerzero/interfaces/ILayerZeroRelayer.sol';
import { ILayerZeroResumeReceive } from '../crosschain/layerzero/interfaces/ILayerZeroResumeReceive.sol';
import { OwnerManageable } from '../access/OwnerManageable.sol';
import { SystemVersionId } from '../SystemVersionId.sol';
import '../helpers/AddressHelper.sol' as AddressHelper;
contract InterportLZGasTransfer is SystemVersionId, OwnerManageable {
struct GasTransferParameters {
uint16 lzChainId;
address recipient;
uint256 amount;
bytes settings;
}
address public lzEndpoint;
address public lzRelayer;
uint16 private constant LZ_ADAPTER_PARAMETERS_VERSION = 2;
bytes private constant LZ_PAYLOAD_NONE = '';
uint256 private minDstGas;
uint256 private minReserve;
event SetEndpoint(address indexed endpoint);
event SetRelayer(address indexed relayer);
error ValidationError();
constructor(address _lzEndpoint, address _lzRelayer, bytes memory _validation, address _owner) {
_setEndpoint(_lzEndpoint);
_setRelayer(_lzRelayer);
_setValidation(_validation);
_initOwner(_owner);
}
receive() external payable {}
function gasTransfer(
GasTransferParameters calldata _parameters
) external payable whenNotPaused {
(uint256 lzValue, address dstApp, bytes memory lzAdapterParameters) = _getEndpointData(
_parameters,
true
);
ILayerZeroEndpoint(lzEndpoint).send{ value: lzValue }(
_parameters.lzChainId,
abi.encodePacked(dstApp, address(this)),
LZ_PAYLOAD_NONE,
payable(this),
address(0),
lzAdapterParameters
);
}
function lzReceive(uint16, bytes calldata, uint64, bytes calldata) external {}
function resumeReceive(uint16 _lzSourceChainId, address _sourceApp) external {
ILayerZeroResumeReceive(lzEndpoint).forceResumeReceive(
_lzSourceChainId,
abi.encodePacked(_sourceApp, address(this))
);
}
function setEndpoint(address _lzEndpoint) external onlyOwner {
_setEndpoint(_lzEndpoint);
}
function setRelayer(address _lzRelayer) external onlyOwner {
_setRelayer(_lzRelayer);
}
function setValidation(bytes memory _validation) external onlyOwner {
_setValidation(_validation);
}
function estimateSourceValue(
GasTransferParameters calldata _parameters
) external view returns (uint256 lzValue) {
(lzValue, , ) = _getEndpointData(_parameters, false);
}
function destinationAmountCap(
uint16[] calldata _lzChainIds
) external view returns (uint128[] memory) {
uint128[] memory result = new uint128[](_lzChainIds.length);
uint16 lzChainId;
uint16 outboundProofType;
uint128 cap;
address sendLibrary = SendLibraryProvider(lzEndpoint).getSendLibraryAddress(address(this));
for (uint256 index; index < _lzChainIds.length; index++) {
lzChainId = _lzChainIds[index];
outboundProofType = AppConfigProvider(sendLibrary)
.getAppConfig(lzChainId, address(this))
.outboundProofType;
(cap, , ) = ILayerZeroRelayer(lzRelayer).dstConfigLookup(lzChainId, outboundProofType);
result[index] = cap;
}
return result;
}
function _setEndpoint(address _lzEndpoint) private {
AddressHelper.requireContract(_lzEndpoint);
lzEndpoint = _lzEndpoint;
emit SetEndpoint(_lzEndpoint);
}
function _setRelayer(address _lzRelayer) private {
AddressHelper.requireContract(_lzRelayer);
lzRelayer = _lzRelayer;
emit SetRelayer(_lzRelayer);
}
function _setValidation(bytes memory _validation) private {
(minDstGas, minReserve) = abi.decode(_validation, (uint256, uint256));
}
function _getEndpointData(
GasTransferParameters calldata _parameters,
bool _validate
) private view returns (uint256 lzValue, address dstApp, bytes memory lzAdapterParameters) {
uint256 dstGas;
(dstApp, dstGas, lzAdapterParameters) = _decodeParameters(_parameters);
(lzValue, ) = ILayerZeroEndpoint(lzEndpoint).estimateFees(
_parameters.lzChainId,
address(this),
LZ_PAYLOAD_NONE,
false,
lzAdapterParameters
);
if (_validate && (dstGas < minDstGas || lzValue + minReserve > msg.value)) {
revert ValidationError();
}
}
function _decodeParameters(
GasTransferParameters calldata _parameters
) private view returns (address dstApp, uint256 dstGas, bytes memory lzAdapterParameters) {
(dstApp, dstGas) = abi.decode(_parameters.settings, (address, uint256));
lzAdapterParameters = abi.encodePacked(
LZ_ADAPTER_PARAMETERS_VERSION,
dstGas,
_parameters.amount,
_parameters.recipient == address(0) ? msg.sender : _parameters.recipient
);
}
}
interface SendLibraryProvider {
function getSendLibraryAddress(
address _userApplication
) external view returns (address sendLibraryAddress);
}
interface AppConfigProvider {
struct ApplicationConfiguration {
uint16 inboundProofLibraryVersion;
uint64 inboundBlockConfirmations;
address relayer;
uint16 outboundProofType;
uint64 outboundBlockConfirmations;
address oracle;
}
function getAppConfig(
uint16 _remoteChainId,
address _userApplicationAddress
) external view returns (ApplicationConfiguration memory);
}
文件 9 的 13: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);
}
}
文件 10 的 13:OwnerManageable.sol
pragma solidity 0.8.19;
import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol';
import { Pausable } from '@openzeppelin/contracts/security/Pausable.sol';
import { ITokenBalance } from '../interfaces/ITokenBalance.sol';
import '../helpers/TransferHelper.sol' as TransferHelper;
import '../Constants.sol' as Constants;
contract OwnerManageable is Ownable, Pausable {
function pause() external onlyOwner whenNotPaused {
_pause();
}
function unpause() external onlyOwner whenPaused {
_unpause();
}
function cleanup(address _tokenAddress) external onlyOwner {
if (_tokenAddress == Constants.NATIVE_TOKEN_ADDRESS) {
TransferHelper.safeTransferNative(msg.sender, address(this).balance);
} else {
TransferHelper.safeTransfer(
_tokenAddress,
msg.sender,
ITokenBalance(_tokenAddress).balanceOf(address(this))
);
}
}
function cleanupWithAmount(address _tokenAddress, uint256 _tokenAmount) external onlyOwner {
if (_tokenAddress == Constants.NATIVE_TOKEN_ADDRESS) {
TransferHelper.safeTransferNative(msg.sender, _tokenAmount);
} else {
TransferHelper.safeTransfer(_tokenAddress, msg.sender, _tokenAmount);
}
}
function _initOwner(address _owner) internal {
if (_owner != _msgSender() && _owner != address(0)) {
_transferOwnership(_owner);
}
}
}
文件 11 的 13:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 12 的 13:SystemVersionId.sol
pragma solidity 0.8.19;
abstract contract SystemVersionId {
uint256 public constant SYSTEM_VERSION_ID = uint256(keccak256('Initial'));
}
文件 13 的 13:TransferHelper.sol
pragma solidity 0.8.19;
error SafeApproveError();
error SafeTransferError();
error SafeTransferFromError();
error SafeTransferNativeError();
function safeApprove(address _token, address _to, uint256 _value) {
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(0x095ea7b3, _to, _value)
);
bool condition = success && (data.length == 0 || abi.decode(data, (bool)));
if (!condition) {
revert SafeApproveError();
}
}
function safeTransfer(address _token, address _to, uint256 _value) {
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(0xa9059cbb, _to, _value)
);
bool condition = success && (data.length == 0 || abi.decode(data, (bool)));
if (!condition) {
revert SafeTransferError();
}
}
function safeTransferFrom(address _token, address _from, address _to, uint256 _value) {
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(0x23b872dd, _from, _to, _value)
);
bool condition = success && (data.length == 0 || abi.decode(data, (bool)));
if (!condition) {
revert SafeTransferFromError();
}
}
function safeTransferNative(address _to, uint256 _value) {
(bool success, ) = _to.call{ value: _value }(new bytes(0));
if (!success) {
revert SafeTransferNativeError();
}
}
{
"compilationTarget": {
"contracts/gas-transfer/InterportLZGasTransfer.sol": "InterportLZGasTransfer"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_lzEndpoint","type":"address"},{"internalType":"address","name":"_lzRelayer","type":"address"},{"internalType":"bytes","name":"_validation","type":"bytes"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NonContractAddressError","type":"error"},{"inputs":[],"name":"SafeTransferError","type":"error"},{"inputs":[],"name":"SafeTransferNativeError","type":"error"},{"inputs":[],"name":"ValidationError","type":"error"},{"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":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"endpoint","type":"address"}],"name":"SetEndpoint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"relayer","type":"address"}],"name":"SetRelayer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"SYSTEM_VERSION_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"cleanup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"cleanupWithAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_lzChainIds","type":"uint16[]"}],"name":"destinationAmountCap","outputs":[{"internalType":"uint128[]","name":"","type":"uint128[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"lzChainId","type":"uint16"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"settings","type":"bytes"}],"internalType":"struct InterportLZGasTransfer.GasTransferParameters","name":"_parameters","type":"tuple"}],"name":"estimateSourceValue","outputs":[{"internalType":"uint256","name":"lzValue","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"lzChainId","type":"uint16"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"settings","type":"bytes"}],"internalType":"struct InterportLZGasTransfer.GasTransferParameters","name":"_parameters","type":"tuple"}],"name":"gasTransfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lzRelayer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_lzSourceChainId","type":"uint16"},{"internalType":"address","name":"_sourceApp","type":"address"}],"name":"resumeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lzEndpoint","type":"address"}],"name":"setEndpoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lzRelayer","type":"address"}],"name":"setRelayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_validation","type":"bytes"}],"name":"setValidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]