编译器
0.8.21+commit.d9974bed
文件 1 的 6:GasZipLZ.sol
pragma solidity ^0.8.0;
import "./OptimizedLzApp.sol";
contract GasZipLZ is OptimizedLzApp {
constructor(address _lzEndpoint) OptimizedLzApp(_lzEndpoint) {
_initializeOwner(msg.sender);
}
function estimateFees(uint16[] calldata _dstChainIds, bytes[] calldata _adapterParams) external view returns (uint256[] memory nativeFees) {
nativeFees = new uint256[](_dstChainIds.length);
for (uint i; i < _dstChainIds.length; i++) {
nativeFees[i] = estimateFees(_dstChainIds[i], _adapterParams[i]);
}
}
function estimateFees(uint16 _dstChainId, bytes memory _adapterParams) public view returns (uint256 nativeFee) {
(nativeFee,) = lzEndpoint.estimateFees(_dstChainId, address(this), "", false, _adapterParams);
}
function deposit(
uint256[] calldata _depositParams,
address to
) external payable {
uint256 fee;
for (uint i; i < _depositParams.length; i++) {
fee += _deposit(_depositParams[i], to);
}
require(msg.value >= fee, "Fee Not Met");
}
function _deposit(uint256 _depositParam, address _to) internal returns (uint256 fee) {
(uint16 _dstChainId, bytes memory _adapterParams) = _decodeDeposit(_depositParam, _to);
fee = estimateFees(_dstChainId, _adapterParams);
_lzSend(_dstChainId, "", payable(this), _adapterParams, fee);
}
function _decodeDeposit(uint256 _depositParam, address _to) internal view returns (uint16 _dstChainId, bytes memory _adapterParams) {
_dstChainId = uint16(_depositParam >> 240);
_adapterParams = createAdapterParams(_dstChainId, uint256(uint240(_depositParam)), _to);
}
function createAdapterParams(uint16 dstChainId, uint256 nativeAmount, address to) public view returns (bytes memory) {
return abi.encodePacked(uint16(2), getGasLimit(dstChainId), nativeAmount, to);
}
function withdraw(address token, uint256 amount) external onlyOwner {
bool s;
if (token == address(0)) {
(s,) = msg.sender.call{value: address(this).balance}("");
} else {
(s,) = token.call(abi.encodeWithSignature("transfer(address,uint256)", msg.sender, amount));
}
require(s, "Withdraw Failed");
}
receive() external payable {}
}
文件 2 的 6:ILayerZeroEndpoint.sol
pragma solidity >=0.5.0;
import "./ILayerZeroUserApplicationConfig.sol";
interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {
function send(
uint16 _dstChainId,
bytes calldata _destination,
bytes calldata _payload,
address payable _refundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParams
) external payable;
function receivePayload(
uint16 _srcChainId,
bytes calldata _srcAddress,
address _dstAddress,
uint64 _nonce,
uint _gasLimit,
bytes calldata _payload
) external;
function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);
function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);
function estimateFees(
uint16 _dstChainId,
address _userApplication,
bytes calldata _payload,
bool _payInZRO,
bytes calldata _adapterParam
) external view returns (uint nativeFee, uint zroFee);
function getChainId() external view returns (uint16);
function retryPayload(
uint16 _srcChainId,
bytes calldata _srcAddress,
bytes calldata _payload
) external;
function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);
function getSendLibraryAddress(address _userApplication) external view returns (address);
function getReceiveLibraryAddress(address _userApplication) external view returns (address);
function isSendingPayload() external view returns (bool);
function isReceivingPayload() external view returns (bool);
function getConfig(
uint16 _version,
uint16 _chainId,
address _userApplication,
uint _configType
) external view returns (bytes memory);
function getSendVersion(address _userApplication) external view returns (uint16);
function getReceiveVersion(address _userApplication) external view returns (uint16);
}
文件 3 的 6:ILayerZeroReceiver.sol
pragma solidity >=0.5.0;
interface ILayerZeroReceiver {
function lzReceive(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes calldata _payload
) external;
}
文件 4 的 6:ILayerZeroUserApplicationConfig.sol
pragma solidity >=0.5.0;
interface ILayerZeroUserApplicationConfig {
function setConfig(
uint16 _version,
uint16 _chainId,
uint _configType,
bytes calldata _config
) external;
function setSendVersion(uint16 _version) external;
function setReceiveVersion(uint16 _version) external;
function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
}
文件 5 的 6:OptimizedLzApp.sol
pragma solidity ^0.8.0;
import "./Ownable.sol";
import "./layerzero/ILayerZeroReceiver.sol";
import "./layerzero/ILayerZeroEndpoint.sol";
abstract contract OptimizedLzApp is Ownable, ILayerZeroReceiver {
ILayerZeroEndpoint public immutable lzEndpoint;
mapping(uint16 => bytes) public trustedRemoteLookup;
mapping(uint16 => uint256) public gasLimitLookup;
uint256 public defaultGasLimit = 20_000;
constructor(address _endpoint) {
lzEndpoint = ILayerZeroEndpoint(_endpoint);
}
function lzReceive(
uint16,
bytes calldata,
uint64,
bytes calldata
) public virtual override {
return;
}
function _lzSend(
uint16 _dstChainId,
bytes memory _payload,
address payable _refundAddress,
bytes memory _adapterParams,
uint _nativeFee
) internal virtual {
bytes memory trustedRemote = getTrusted(_dstChainId);
lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, address(0), _adapterParams);
}
function getTrusted(uint16 _dstChainId) internal view returns (bytes memory) {
bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];
if (trustedRemote.length == 0) {
return abi.encodePacked(address(this), address(this));
} else {
return trustedRemote;
}
}
function getGasLimit(uint16 _dstChainId) internal view returns (uint256) {
uint256 gasLimit = gasLimitLookup[_dstChainId];
if (gasLimit == 0) {
return defaultGasLimit;
} else {
return gasLimit;
}
}
function setTrusted(
uint16[] calldata _remoteChainIds,
address[] calldata _remoteAddresses
) external onlyOwner {
require(_remoteChainIds.length == _remoteAddresses.length, "Length Mismatch");
for (uint i; i < _remoteChainIds.length; i++) {
trustedRemoteLookup[_remoteChainIds[i]] = abi.encodePacked(_remoteAddresses[i], address(this));
}
}
function setGasLimit(
uint16[] calldata _remoteChainIds,
uint256[] calldata _gasLimits
) external onlyOwner {
require(_remoteChainIds.length == _gasLimits.length, "Length Mismatch");
for (uint i; i < _remoteChainIds.length; i++) {
gasLimitLookup[_remoteChainIds[i]] = _gasLimits[i];
}
}
function setDefaultGasLimit(uint256 _defaultGasLimit) external onlyOwner {
defaultGasLimit = _defaultGasLimit;
}
function setConfig(
uint16 _version,
uint16 _chainId,
uint _configType,
bytes calldata _config
) external onlyOwner {
lzEndpoint.setConfig(_version, _chainId, _configType, _config);
}
}
文件 6 的 6:Ownable.sol
pragma solidity ^0.8.4;
abstract contract Ownable {
error Unauthorized();
error NewOwnerIsZeroAddress();
error NoHandoverRequest();
error AlreadyInitialized();
event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
event OwnershipHandoverRequested(address indexed pendingOwner);
event OwnershipHandoverCanceled(address indexed pendingOwner);
uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;
uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;
uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;
bytes32 internal constant _OWNER_SLOT =
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;
uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;
function _guardInitializeOwner() internal pure virtual returns (bool guard) {}
function _initializeOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
assembly {
let ownerSlot := _OWNER_SLOT
if sload(ownerSlot) {
mstore(0x00, 0x0dc149f0)
revert(0x1c, 0x04)
}
newOwner := shr(96, shl(96, newOwner))
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
} else {
assembly {
newOwner := shr(96, shl(96, newOwner))
sstore(_OWNER_SLOT, newOwner)
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
}
}
function _setOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
assembly {
let ownerSlot := _OWNER_SLOT
newOwner := shr(96, shl(96, newOwner))
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
}
} else {
assembly {
let ownerSlot := _OWNER_SLOT
newOwner := shr(96, shl(96, newOwner))
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
sstore(ownerSlot, newOwner)
}
}
}
function _checkOwner() internal view virtual {
assembly {
if iszero(eq(caller(), sload(_OWNER_SLOT))) {
mstore(0x00, 0x82b42900)
revert(0x1c, 0x04)
}
}
}
function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
return 48 * 3600;
}
function transferOwnership(address newOwner) public payable virtual onlyOwner {
assembly {
if iszero(shl(96, newOwner)) {
mstore(0x00, 0x7448fbae)
revert(0x1c, 0x04)
}
}
_setOwner(newOwner);
}
function renounceOwnership() public payable virtual onlyOwner {
_setOwner(address(0));
}
function requestOwnershipHandover() public payable virtual {
unchecked {
uint256 expires = block.timestamp + _ownershipHandoverValidFor();
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), expires)
log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
}
}
}
function cancelOwnershipHandover() public payable virtual {
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), 0)
log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
}
}
function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
let handoverSlot := keccak256(0x0c, 0x20)
if gt(timestamp(), sload(handoverSlot)) {
mstore(0x00, 0x6f5e8818)
revert(0x1c, 0x04)
}
sstore(handoverSlot, 0)
}
_setOwner(pendingOwner);
}
function owner() public view virtual returns (address result) {
assembly {
result := sload(_OWNER_SLOT)
}
}
function ownershipHandoverExpiresAt(address pendingOwner)
public
view
virtual
returns (uint256 result)
{
assembly {
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
result := sload(keccak256(0x0c, 0x20))
}
}
modifier onlyOwner() virtual {
_checkOwner();
_;
}
}
{
"compilationTarget": {
"src/GasZipLZ.sol": "GasZipLZ"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 20000
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
}
[{"inputs":[{"internalType":"address","name":"_lzEndpoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"createAdapterParams","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultGasLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_depositParams","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_dstChainIds","type":"uint16[]"},{"internalType":"bytes[]","name":"_adapterParams","type":"bytes[]"}],"name":"estimateFees","outputs":[{"internalType":"uint256[]","name":"nativeFees","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateFees","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"gasLimitLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","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":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_defaultGasLimit","type":"uint256"}],"name":"setDefaultGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_remoteChainIds","type":"uint16[]"},{"internalType":"uint256[]","name":"_gasLimits","type":"uint256[]"}],"name":"setGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_remoteChainIds","type":"uint16[]"},{"internalType":"address[]","name":"_remoteAddresses","type":"address[]"}],"name":"setTrusted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]