编译器
0.8.13+commit.abaa5c0e
文件 1 的 28: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 的 28:BaseOFTV2.sol
pragma solidity ^0.8.0;
import "./OFTCoreV2.sol";
import "./interfaces/IOFTV2.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
abstract contract BaseOFTV2 is OFTCoreV2, ERC165, IOFTV2 {
constructor(uint8 _sharedDecimals, address _lzEndpoint) OFTCoreV2(_sharedDecimals, _lzEndpoint) {}
function sendFrom(
address _from,
uint16 _dstChainId,
bytes32 _toAddress,
uint _amount,
LzCallParams calldata _callParams
) public payable virtual override {
_send(_from, _dstChainId, _toAddress, _amount, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams);
}
function sendAndCall(
address _from,
uint16 _dstChainId,
bytes32 _toAddress,
uint _amount,
bytes calldata _payload,
uint64 _dstGasForCall,
LzCallParams calldata _callParams
) public payable virtual override {
_sendAndCall(
_from,
_dstChainId,
_toAddress,
_amount,
_payload,
_dstGasForCall,
_callParams.refundAddress,
_callParams.zroPaymentAddress,
_callParams.adapterParams
);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IOFTV2).interfaceId || super.supportsInterface(interfaceId);
}
function estimateSendFee(
uint16 _dstChainId,
bytes32 _toAddress,
uint _amount,
bool _useZro,
bytes calldata _adapterParams
) public view virtual override returns (uint nativeFee, uint zroFee) {
return _estimateSendFee(_dstChainId, _toAddress, _amount, _useZro, _adapterParams);
}
function estimateSendAndCallFee(
uint16 _dstChainId,
bytes32 _toAddress,
uint _amount,
bytes calldata _payload,
uint64 _dstGasForCall,
bool _useZro,
bytes calldata _adapterParams
) public view virtual override returns (uint nativeFee, uint zroFee) {
return _estimateSendAndCallFee(_dstChainId, _toAddress, _amount, _payload, _dstGasForCall, _useZro, _adapterParams);
}
function circulatingSupply() public view virtual override returns (uint);
function token() public view virtual override returns (address);
}
文件 3 的 28:BaseXVSProxyOFT.sol
pragma solidity 0.8.13;
import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { ResilientOracleInterface } from "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol";
import { Pausable } from "@openzeppelin/contracts/security/Pausable.sol";
import { BaseOFTV2 } from "@layerzerolabs/solidity-examples/contracts/token/oft/v2/BaseOFTV2.sol";
import { ensureNonzeroAddress } from "@venusprotocol/solidity-utilities/contracts/validators.sol";
import { ExponentialNoError } from "@venusprotocol/solidity-utilities/contracts/ExponentialNoError.sol";
abstract contract BaseXVSProxyOFT is Pausable, ExponentialNoError, BaseOFTV2 {
using SafeERC20 for IERC20;
IERC20 internal immutable innerToken;
uint256 internal immutable ld2sdRate;
bool public sendAndCallEnabled;
ResilientOracleInterface public oracle;
mapping(uint16 => uint256) public chainIdToMaxSingleTransactionLimit;
mapping(uint16 => uint256) public chainIdToMaxDailyLimit;
mapping(uint16 => uint256) public chainIdToLast24HourTransferred;
mapping(uint16 => uint256) public chainIdToLast24HourWindowStart;
mapping(uint16 => uint256) public chainIdToMaxSingleReceiveTransactionLimit;
mapping(uint16 => uint256) public chainIdToMaxDailyReceiveLimit;
mapping(uint16 => uint256) public chainIdToLast24HourReceived;
mapping(uint16 => uint256) public chainIdToLast24HourReceiveWindowStart;
mapping(address => bool) public whitelist;
event SetWhitelist(address indexed addr, bool isWhitelist);
event SetMaxSingleTransactionLimit(uint16 chainId, uint256 oldMaxLimit, uint256 newMaxLimit);
event SetMaxDailyLimit(uint16 chainId, uint256 oldMaxLimit, uint256 newMaxLimit);
event SetMaxSingleReceiveTransactionLimit(uint16 chainId, uint256 oldMaxLimit, uint256 newMaxLimit);
event SetMaxDailyReceiveLimit(uint16 chainId, uint256 oldMaxLimit, uint256 newMaxLimit);
event OracleChanged(address indexed oldOracle, address indexed newOracle);
event TrustedRemoteRemoved(uint16 chainId);
event InnerTokenAdded(address indexed innerToken);
event SweepToken(address indexed token, address indexed to, uint256 sweepAmount);
event UpdateSendAndCallEnabled(bool indexed enabled);
error InsufficientBalance(uint256 sweepAmount, uint256 balance);
constructor(
address tokenAddress_,
uint8 sharedDecimals_,
address lzEndpoint_,
address oracle_
) BaseOFTV2(sharedDecimals_, lzEndpoint_) {
ensureNonzeroAddress(tokenAddress_);
ensureNonzeroAddress(lzEndpoint_);
ensureNonzeroAddress(oracle_);
innerToken = IERC20(tokenAddress_);
(bool success, bytes memory data) = tokenAddress_.staticcall(abi.encodeWithSignature("decimals()"));
require(success, "ProxyOFT: failed to get token decimals");
uint8 decimals = abi.decode(data, (uint8));
require(sharedDecimals_ <= decimals, "ProxyOFT: sharedDecimals must be <= decimals");
ld2sdRate = 10 ** (decimals - sharedDecimals_);
emit InnerTokenAdded(tokenAddress_);
emit OracleChanged(address(0), oracle_);
oracle = ResilientOracleInterface(oracle_);
}
function setOracle(address oracleAddress_) external onlyOwner {
ensureNonzeroAddress(oracleAddress_);
emit OracleChanged(address(oracle), oracleAddress_);
oracle = ResilientOracleInterface(oracleAddress_);
}
function setMaxSingleTransactionLimit(uint16 chainId_, uint256 limit_) external onlyOwner {
require(limit_ <= chainIdToMaxDailyLimit[chainId_], "Single transaction limit > Daily limit");
emit SetMaxSingleTransactionLimit(chainId_, chainIdToMaxSingleTransactionLimit[chainId_], limit_);
chainIdToMaxSingleTransactionLimit[chainId_] = limit_;
}
function setMaxDailyLimit(uint16 chainId_, uint256 limit_) external onlyOwner {
require(limit_ >= chainIdToMaxSingleTransactionLimit[chainId_], "Daily limit < single transaction limit");
emit SetMaxDailyLimit(chainId_, chainIdToMaxDailyLimit[chainId_], limit_);
chainIdToMaxDailyLimit[chainId_] = limit_;
}
function setMaxSingleReceiveTransactionLimit(uint16 chainId_, uint256 limit_) external onlyOwner {
require(limit_ <= chainIdToMaxDailyReceiveLimit[chainId_], "single receive transaction limit > Daily limit");
emit SetMaxSingleReceiveTransactionLimit(chainId_, chainIdToMaxSingleReceiveTransactionLimit[chainId_], limit_);
chainIdToMaxSingleReceiveTransactionLimit[chainId_] = limit_;
}
function setMaxDailyReceiveLimit(uint16 chainId_, uint256 limit_) external onlyOwner {
require(
limit_ >= chainIdToMaxSingleReceiveTransactionLimit[chainId_],
"Daily limit < single receive transaction limit"
);
emit SetMaxDailyReceiveLimit(chainId_, chainIdToMaxDailyReceiveLimit[chainId_], limit_);
chainIdToMaxDailyReceiveLimit[chainId_] = limit_;
}
function setWhitelist(address user_, bool val_) external onlyOwner {
emit SetWhitelist(user_, val_);
whitelist[user_] = val_;
}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
function sweepToken(IERC20 token_, address to_, uint256 amount_) external onlyOwner {
uint256 balance = token_.balanceOf(address(this));
if (amount_ > balance) {
revert InsufficientBalance(amount_, balance);
}
emit SweepToken(address(token_), to_, amount_);
token_.safeTransfer(to_, amount_);
}
function removeTrustedRemote(uint16 remoteChainId_) external onlyOwner {
delete trustedRemoteLookup[remoteChainId_];
emit TrustedRemoteRemoved(remoteChainId_);
}
function updateSendAndCallEnabled(bool enabled_) external onlyOwner {
sendAndCallEnabled = enabled_;
emit UpdateSendAndCallEnabled(enabled_);
}
function isEligibleToSend(
address from_,
uint16 dstChainId_,
uint256 amount_
)
external
view
returns (
bool eligibleToSend,
uint256 maxSingleTransactionLimit,
uint256 maxDailyLimit,
uint256 amountInUsd,
uint256 transferredInWindow,
uint256 last24HourWindowStart,
bool isWhiteListedUser
)
{
isWhiteListedUser = whitelist[from_];
Exp memory oraclePrice = Exp({ mantissa: oracle.getPrice(token()) });
amountInUsd = mul_ScalarTruncate(oraclePrice, amount_);
uint256 currentBlockTimestamp = block.timestamp;
last24HourWindowStart = chainIdToLast24HourWindowStart[dstChainId_];
transferredInWindow = chainIdToLast24HourTransferred[dstChainId_];
maxSingleTransactionLimit = chainIdToMaxSingleTransactionLimit[dstChainId_];
maxDailyLimit = chainIdToMaxDailyLimit[dstChainId_];
if (currentBlockTimestamp - last24HourWindowStart > 1 days) {
transferredInWindow = amountInUsd;
last24HourWindowStart = currentBlockTimestamp;
} else {
transferredInWindow += amountInUsd;
}
eligibleToSend = (isWhiteListedUser ||
((amountInUsd <= maxSingleTransactionLimit) && (transferredInWindow <= maxDailyLimit)));
}
function sendAndCall(
address from_,
uint16 dstChainId_,
bytes32 toAddress_,
uint256 amount_,
bytes calldata payload_,
uint64 dstGasForCall_,
LzCallParams calldata callparams_
) public payable override {
require(sendAndCallEnabled, "sendAndCall is disabled");
super.sendAndCall(from_, dstChainId_, toAddress_, amount_, payload_, dstGasForCall_, callparams_);
}
function retryMessage(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes calldata _payload
) public payable override {
bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];
require(
_srcAddress.length == trustedRemote.length &&
trustedRemote.length > 0 &&
keccak256(_srcAddress) == keccak256(trustedRemote),
"LzApp: invalid source sending contract"
);
super.retryMessage(_srcChainId, _srcAddress, _nonce, _payload);
}
function renounceOwnership() public override {}
function token() public view override returns (address) {
return address(innerToken);
}
function _isEligibleToSend(address from_, uint16 dstChainId_, uint256 amount_) internal {
bool isWhiteListedUser = whitelist[from_];
if (isWhiteListedUser) {
return;
}
uint256 amountInUsd;
Exp memory oraclePrice = Exp({ mantissa: oracle.getPrice(token()) });
amountInUsd = mul_ScalarTruncate(oraclePrice, amount_);
uint256 currentBlockTimestamp = block.timestamp;
uint256 lastDayWindowStart = chainIdToLast24HourWindowStart[dstChainId_];
uint256 transferredInWindow = chainIdToLast24HourTransferred[dstChainId_];
uint256 maxSingleTransactionLimit = chainIdToMaxSingleTransactionLimit[dstChainId_];
uint256 maxDailyLimit = chainIdToMaxDailyLimit[dstChainId_];
require(amountInUsd <= maxSingleTransactionLimit, "Single Transaction Limit Exceed");
if (currentBlockTimestamp - lastDayWindowStart > 1 days) {
transferredInWindow = amountInUsd;
chainIdToLast24HourWindowStart[dstChainId_] = currentBlockTimestamp;
} else {
transferredInWindow += amountInUsd;
}
require(transferredInWindow <= maxDailyLimit, "Daily Transaction Limit Exceed");
chainIdToLast24HourTransferred[dstChainId_] = transferredInWindow;
}
function _isEligibleToReceive(address toAddress_, uint16 srcChainId_, uint256 receivedAmount_) internal {
bool isWhiteListedUser = whitelist[toAddress_];
if (isWhiteListedUser) {
return;
}
uint256 receivedAmountInUsd;
Exp memory oraclePrice = Exp({ mantissa: oracle.getPrice(address(token())) });
receivedAmountInUsd = mul_ScalarTruncate(oraclePrice, receivedAmount_);
uint256 currentBlockTimestamp = block.timestamp;
uint256 lastDayReceiveWindowStart = chainIdToLast24HourReceiveWindowStart[srcChainId_];
uint256 receivedInWindow = chainIdToLast24HourReceived[srcChainId_];
uint256 maxSingleReceiveTransactionLimit = chainIdToMaxSingleReceiveTransactionLimit[srcChainId_];
uint256 maxDailyReceiveLimit = chainIdToMaxDailyReceiveLimit[srcChainId_];
require(receivedAmountInUsd <= maxSingleReceiveTransactionLimit, "Single Transaction Limit Exceed");
if (currentBlockTimestamp - lastDayReceiveWindowStart > 1 days) {
receivedInWindow = receivedAmountInUsd;
chainIdToLast24HourReceiveWindowStart[srcChainId_] = currentBlockTimestamp;
} else {
receivedInWindow += receivedAmountInUsd;
}
require(receivedInWindow <= maxDailyReceiveLimit, "Daily Transaction Limit Exceed");
chainIdToLast24HourReceived[srcChainId_] = receivedInWindow;
}
function _transferFrom(
address from_,
address to_,
uint256 amount_
) internal override whenNotPaused returns (uint256) {
uint256 before = innerToken.balanceOf(to_);
if (from_ == address(this)) {
innerToken.safeTransfer(to_, amount_);
} else {
innerToken.safeTransferFrom(from_, to_, amount_);
}
return innerToken.balanceOf(to_) - before;
}
function _ld2sdRate() internal view override returns (uint256) {
return ld2sdRate;
}
}
文件 4 的 28: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,
uint _start,
uint _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, uint _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, uint _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, uint _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, uint _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, uint _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, uint _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, uint _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, uint _start) internal pure returns (uint) {
require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
uint tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x20), _start))
}
return tempUint;
}
function toBytes32(bytes memory _bytes, uint _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 的 28: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;
}
}
文件 6 的 28: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;
}
}
文件 7 的 28:ExcessivelySafeCall.sol
pragma solidity >=0.7.6;
library ExcessivelySafeCall {
uint constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
function excessivelySafeCall(
address _target,
uint _gas,
uint16 _maxCopy,
bytes memory _calldata
) internal returns (bool, bytes memory) {
uint _toCopy;
bool _success;
bytes memory _returnData = new bytes(_maxCopy);
assembly {
_success := call(
_gas,
_target,
0,
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 excessivelySafeStaticCall(
address _target,
uint _gas,
uint16 _maxCopy,
bytes memory _calldata
) internal view returns (bool, bytes memory) {
uint _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);
}
function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure {
require(_buf.length >= 4);
uint _mask = LOW_28_MASK;
assembly {
let _word := mload(add(_buf, 0x20))
_word := and(_word, _mask)
_word := or(_newSelector, _word)
mstore(add(_buf, 0x20), _word)
}
}
}
文件 8 的 28:ExponentialNoError.sol
pragma solidity 0.8.13;
import { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from "./constants.sol";
contract ExponentialNoError {
struct Exp {
uint256 mantissa;
}
struct Double {
uint256 mantissa;
}
uint256 internal constant EXP_SCALE = EXP_SCALE_;
uint256 internal constant DOUBLE_SCALE = 1e36;
uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;
uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;
function truncate(Exp memory exp) internal pure returns (uint256) {
return exp.mantissa / EXP_SCALE;
}
function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {
Exp memory product = mul_(a, scalar);
return truncate(product);
}
function mul_ScalarTruncateAddUInt(Exp memory a, uint256 scalar, uint256 addend) internal pure returns (uint256) {
Exp memory product = mul_(a, scalar);
return add_(truncate(product), addend);
}
function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {
return left.mantissa < right.mantissa;
}
function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {
require(n <= type(uint224).max, errorMessage);
return uint224(n);
}
function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {
require(n <= type(uint32).max, errorMessage);
return uint32(n);
}
function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {
return Exp({ mantissa: add_(a.mantissa, b.mantissa) });
}
function add_(Double memory a, Double memory b) internal pure returns (Double memory) {
return Double({ mantissa: add_(a.mantissa, b.mantissa) });
}
function add_(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {
return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });
}
function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {
return Double({ mantissa: sub_(a.mantissa, b.mantissa) });
}
function sub_(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {
return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / EXP_SCALE });
}
function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {
return Exp({ mantissa: mul_(a.mantissa, b) });
}
function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {
return mul_(a, b.mantissa) / EXP_SCALE;
}
function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {
return Double({ mantissa: mul_(a.mantissa, b.mantissa) / DOUBLE_SCALE });
}
function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {
return Double({ mantissa: mul_(a.mantissa, b) });
}
function mul_(uint256 a, Double memory b) internal pure returns (uint256) {
return mul_(a, b.mantissa) / DOUBLE_SCALE;
}
function mul_(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {
return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });
}
function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {
return Exp({ mantissa: div_(a.mantissa, b) });
}
function div_(uint256 a, Exp memory b) internal pure returns (uint256) {
return div_(mul_(a, EXP_SCALE), b.mantissa);
}
function div_(Double memory a, Double memory b) internal pure returns (Double memory) {
return Double({ mantissa: div_(mul_(a.mantissa, DOUBLE_SCALE), b.mantissa) });
}
function div_(Double memory a, uint256 b) internal pure returns (Double memory) {
return Double({ mantissa: div_(a.mantissa, b) });
}
function div_(uint256 a, Double memory b) internal pure returns (uint256) {
return div_(mul_(a, DOUBLE_SCALE), b.mantissa);
}
function div_(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {
return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });
}
}
文件 9 的 28:ICommonOFT.sol
pragma solidity >=0.5.0;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface ICommonOFT is IERC165 {
struct LzCallParams {
address payable refundAddress;
address zroPaymentAddress;
bytes adapterParams;
}
function estimateSendFee(uint16 _dstChainId, bytes32 _toAddress, uint _amount, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
function estimateSendAndCallFee(uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes calldata _payload, uint64 _dstGasForCall, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
function circulatingSupply() external view returns (uint);
function token() external view returns (address);
}
文件 10 的 28:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 11 的 28: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 的 28: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 的 28: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);
}
文件 14 的 28:ILayerZeroReceiver.sol
pragma solidity >=0.5.0;
interface ILayerZeroReceiver {
function lzReceive(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes calldata _payload
) external;
}
文件 15 的 28: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;
}
文件 16 的 28:IOFTReceiverV2.sol
pragma solidity >=0.5.0;
interface IOFTReceiverV2 {
function onOFTReceived(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes32 _from, uint _amount, bytes calldata _payload) external;
}
文件 17 的 28:IOFTV2.sol
pragma solidity >=0.5.0;
import "./ICommonOFT.sol";
interface IOFTV2 is ICommonOFT {
function sendFrom(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, LzCallParams calldata _callParams) external payable;
function sendAndCall(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes calldata _payload, uint64 _dstGasForCall, LzCallParams calldata _callParams) external payable;
}
文件 18 的 28:IXVS.sol
pragma solidity 0.8.13;
interface IXVS {
function mint(address to, uint256 amount) external;
function burn(address from, uint256 amount) external;
}
文件 19 的 28:LzApp.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/ILayerZeroReceiver.sol";
import "./interfaces/ILayerZeroUserApplicationConfig.sol";
import "./interfaces/ILayerZeroEndpoint.sol";
import "../libraries/BytesLib.sol";
abstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {
using BytesLib for bytes;
uint public constant DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;
ILayerZeroEndpoint public immutable lzEndpoint;
mapping(uint16 => bytes) public trustedRemoteLookup;
mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;
mapping(uint16 => uint) public payloadSizeLimitLookup;
address public precrime;
event SetPrecrime(address precrime);
event SetTrustedRemote(uint16 _remoteChainId, bytes _path);
event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);
event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);
constructor(address _endpoint) {
lzEndpoint = ILayerZeroEndpoint(_endpoint);
}
function lzReceive(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes calldata _payload
) public virtual override {
require(_msgSender() == address(lzEndpoint), "LzApp: invalid endpoint caller");
bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];
require(
_srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote),
"LzApp: invalid source sending contract"
);
_blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
}
function _blockingLzReceive(
uint16 _srcChainId,
bytes memory _srcAddress,
uint64 _nonce,
bytes memory _payload
) internal virtual;
function _lzSend(
uint16 _dstChainId,
bytes memory _payload,
address payable _refundAddress,
address _zroPaymentAddress,
bytes memory _adapterParams,
uint _nativeFee
) internal virtual {
bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];
require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
_checkPayloadSize(_dstChainId, _payload.length);
lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams);
}
function _checkGasLimit(
uint16 _dstChainId,
uint16 _type,
bytes memory _adapterParams,
uint _extraGas
) internal view virtual {
uint providedGasLimit = _getGasLimit(_adapterParams);
uint minGasLimit = minDstGasLookup[_dstChainId][_type];
require(minGasLimit > 0, "LzApp: minGasLimit not set");
require(providedGasLimit >= minGasLimit + _extraGas, "LzApp: gas limit is too low");
}
function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {
require(_adapterParams.length >= 34, "LzApp: invalid adapterParams");
assembly {
gasLimit := mload(add(_adapterParams, 34))
}
}
function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual {
uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];
if (payloadSizeLimit == 0) {
payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;
}
require(_payloadSize <= payloadSizeLimit, "LzApp: payload size is too large");
}
function getConfig(
uint16 _version,
uint16 _chainId,
address,
uint _configType
) external view returns (bytes memory) {
return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);
}
function setConfig(
uint16 _version,
uint16 _chainId,
uint _configType,
bytes calldata _config
) external override onlyOwner {
lzEndpoint.setConfig(_version, _chainId, _configType, _config);
}
function setSendVersion(uint16 _version) external override onlyOwner {
lzEndpoint.setSendVersion(_version);
}
function setReceiveVersion(uint16 _version) external override onlyOwner {
lzEndpoint.setReceiveVersion(_version);
}
function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {
lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);
}
function setTrustedRemote(uint16 _remoteChainId, bytes calldata _path) external onlyOwner {
trustedRemoteLookup[_remoteChainId] = _path;
emit SetTrustedRemote(_remoteChainId, _path);
}
function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {
trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));
emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);
}
function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {
bytes memory path = trustedRemoteLookup[_remoteChainId];
require(path.length != 0, "LzApp: no trusted path record");
return path.slice(0, path.length - 20);
}
function setPrecrime(address _precrime) external onlyOwner {
precrime = _precrime;
emit SetPrecrime(_precrime);
}
function setMinDstGas(
uint16 _dstChainId,
uint16 _packetType,
uint _minGas
) external onlyOwner {
minDstGasLookup[_dstChainId][_packetType] = _minGas;
emit SetMinDstGas(_dstChainId, _packetType, _minGas);
}
function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner {
payloadSizeLimitLookup[_dstChainId] = _size;
}
function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {
bytes memory trustedSource = trustedRemoteLookup[_srcChainId];
return keccak256(trustedSource) == keccak256(_srcAddress);
}
}
文件 20 的 28:NonblockingLzApp.sol
pragma solidity ^0.8.0;
import "./LzApp.sol";
import "../libraries/ExcessivelySafeCall.sol";
abstract contract NonblockingLzApp is LzApp {
using ExcessivelySafeCall for address;
constructor(address _endpoint) LzApp(_endpoint) {}
mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;
event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);
event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);
function _blockingLzReceive(
uint16 _srcChainId,
bytes memory _srcAddress,
uint64 _nonce,
bytes memory _payload
) internal virtual override {
(bool success, bytes memory reason) = address(this).excessivelySafeCall(
gasleft(),
150,
abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload)
);
if (!success) {
_storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);
}
}
function _storeFailedMessage(
uint16 _srcChainId,
bytes memory _srcAddress,
uint64 _nonce,
bytes memory _payload,
bytes memory _reason
) internal virtual {
failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);
emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);
}
function nonblockingLzReceive(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes calldata _payload
) public virtual {
require(_msgSender() == address(this), "NonblockingLzApp: caller must be LzApp");
_nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
}
function _nonblockingLzReceive(
uint16 _srcChainId,
bytes memory _srcAddress,
uint64 _nonce,
bytes memory _payload
) internal virtual;
function retryMessage(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes calldata _payload
) public payable virtual {
bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];
require(payloadHash != bytes32(0), "NonblockingLzApp: no stored message");
require(keccak256(_payload) == payloadHash, "NonblockingLzApp: invalid payload");
failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);
_nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);
}
}
文件 21 的 28:OFTCoreV2.sol
pragma solidity ^0.8.0;
import "../../../lzApp/NonblockingLzApp.sol";
import "../../../libraries/ExcessivelySafeCall.sol";
import "./interfaces/ICommonOFT.sol";
import "./interfaces/IOFTReceiverV2.sol";
abstract contract OFTCoreV2 is NonblockingLzApp {
using BytesLib for bytes;
using ExcessivelySafeCall for address;
uint public constant NO_EXTRA_GAS = 0;
uint8 public constant PT_SEND = 0;
uint8 public constant PT_SEND_AND_CALL = 1;
uint8 public immutable sharedDecimals;
mapping(uint16 => mapping(bytes => mapping(uint64 => bool))) public creditedPackets;
event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes32 indexed _toAddress, uint _amount);
event ReceiveFromChain(uint16 indexed _srcChainId, address indexed _to, uint _amount);
event CallOFTReceivedSuccess(uint16 indexed _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _hash);
event NonContractAddress(address _address);
constructor(uint8 _sharedDecimals, address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
sharedDecimals = _sharedDecimals;
}
function callOnOFTReceived(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes32 _from,
address _to,
uint _amount,
bytes calldata _payload,
uint _gasForCall
) public virtual {
require(_msgSender() == address(this), "OFTCore: caller must be OFTCore");
_amount = _transferFrom(address(this), _to, _amount);
emit ReceiveFromChain(_srcChainId, _to, _amount);
IOFTReceiverV2(_to).onOFTReceived{gas: _gasForCall}(_srcChainId, _srcAddress, _nonce, _from, _amount, _payload);
}
function _estimateSendFee(
uint16 _dstChainId,
bytes32 _toAddress,
uint _amount,
bool _useZro,
bytes memory _adapterParams
) internal view virtual returns (uint nativeFee, uint zroFee) {
bytes memory payload = _encodeSendPayload(_toAddress, _ld2sd(_amount));
return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);
}
function _estimateSendAndCallFee(
uint16 _dstChainId,
bytes32 _toAddress,
uint _amount,
bytes memory _payload,
uint64 _dstGasForCall,
bool _useZro,
bytes memory _adapterParams
) internal view virtual returns (uint nativeFee, uint zroFee) {
bytes memory payload = _encodeSendAndCallPayload(msg.sender, _toAddress, _ld2sd(_amount), _payload, _dstGasForCall);
return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);
}
function _nonblockingLzReceive(
uint16 _srcChainId,
bytes memory _srcAddress,
uint64 _nonce,
bytes memory _payload
) internal virtual override {
uint8 packetType = _payload.toUint8(0);
if (packetType == PT_SEND) {
_sendAck(_srcChainId, _srcAddress, _nonce, _payload);
} else if (packetType == PT_SEND_AND_CALL) {
_sendAndCallAck(_srcChainId, _srcAddress, _nonce, _payload);
} else {
revert("OFTCore: unknown packet type");
}
}
function _send(
address _from,
uint16 _dstChainId,
bytes32 _toAddress,
uint _amount,
address payable _refundAddress,
address _zroPaymentAddress,
bytes memory _adapterParams
) internal virtual returns (uint amount) {
_checkGasLimit(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS);
(amount, ) = _removeDust(_amount);
amount = _debitFrom(_from, _dstChainId, _toAddress, amount);
require(amount > 0, "OFTCore: amount too small");
bytes memory lzPayload = _encodeSendPayload(_toAddress, _ld2sd(amount));
_lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);
emit SendToChain(_dstChainId, _from, _toAddress, amount);
}
function _sendAck(
uint16 _srcChainId,
bytes memory,
uint64,
bytes memory _payload
) internal virtual {
(address to, uint64 amountSD) = _decodeSendPayload(_payload);
if (to == address(0)) {
to = address(0xdead);
}
uint amount = _sd2ld(amountSD);
amount = _creditTo(_srcChainId, to, amount);
emit ReceiveFromChain(_srcChainId, to, amount);
}
function _sendAndCall(
address _from,
uint16 _dstChainId,
bytes32 _toAddress,
uint _amount,
bytes memory _payload,
uint64 _dstGasForCall,
address payable _refundAddress,
address _zroPaymentAddress,
bytes memory _adapterParams
) internal virtual returns (uint amount) {
_checkGasLimit(_dstChainId, PT_SEND_AND_CALL, _adapterParams, _dstGasForCall);
(amount, ) = _removeDust(_amount);
amount = _debitFrom(_from, _dstChainId, _toAddress, amount);
require(amount > 0, "OFTCore: amount too small");
bytes memory lzPayload = _encodeSendAndCallPayload(msg.sender, _toAddress, _ld2sd(amount), _payload, _dstGasForCall);
_lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);
emit SendToChain(_dstChainId, _from, _toAddress, amount);
}
function _sendAndCallAck(
uint16 _srcChainId,
bytes memory _srcAddress,
uint64 _nonce,
bytes memory _payload
) internal virtual {
(bytes32 from, address to, uint64 amountSD, bytes memory payloadForCall, uint64 gasForCall) = _decodeSendAndCallPayload(_payload);
bool credited = creditedPackets[_srcChainId][_srcAddress][_nonce];
uint amount = _sd2ld(amountSD);
if (!credited) {
amount = _creditTo(_srcChainId, address(this), amount);
creditedPackets[_srcChainId][_srcAddress][_nonce] = true;
}
if (!_isContract(to)) {
emit NonContractAddress(to);
return;
}
uint16 srcChainId = _srcChainId;
bytes memory srcAddress = _srcAddress;
uint64 nonce = _nonce;
bytes memory payload = _payload;
bytes32 from_ = from;
address to_ = to;
uint amount_ = amount;
bytes memory payloadForCall_ = payloadForCall;
uint gas = credited ? gasleft() : gasForCall;
(bool success, bytes memory reason) = address(this).excessivelySafeCall(
gasleft(),
150,
abi.encodeWithSelector(this.callOnOFTReceived.selector, srcChainId, srcAddress, nonce, from_, to_, amount_, payloadForCall_, gas)
);
if (success) {
bytes32 hash = keccak256(payload);
emit CallOFTReceivedSuccess(srcChainId, srcAddress, nonce, hash);
} else {
_storeFailedMessage(srcChainId, srcAddress, nonce, payload, reason);
}
}
function _isContract(address _account) internal view returns (bool) {
return _account.code.length > 0;
}
function _ld2sd(uint _amount) internal view virtual returns (uint64) {
uint amountSD = _amount / _ld2sdRate();
require(amountSD <= type(uint64).max, "OFTCore: amountSD overflow");
return uint64(amountSD);
}
function _sd2ld(uint64 _amountSD) internal view virtual returns (uint) {
return _amountSD * _ld2sdRate();
}
function _removeDust(uint _amount) internal view virtual returns (uint amountAfter, uint dust) {
dust = _amount % _ld2sdRate();
amountAfter = _amount - dust;
}
function _encodeSendPayload(bytes32 _toAddress, uint64 _amountSD) internal view virtual returns (bytes memory) {
return abi.encodePacked(PT_SEND, _toAddress, _amountSD);
}
function _decodeSendPayload(bytes memory _payload) internal view virtual returns (address to, uint64 amountSD) {
require(_payload.toUint8(0) == PT_SEND && _payload.length == 41, "OFTCore: invalid payload");
to = _payload.toAddress(13);
amountSD = _payload.toUint64(33);
}
function _encodeSendAndCallPayload(
address _from,
bytes32 _toAddress,
uint64 _amountSD,
bytes memory _payload,
uint64 _dstGasForCall
) internal view virtual returns (bytes memory) {
return abi.encodePacked(PT_SEND_AND_CALL, _toAddress, _amountSD, _addressToBytes32(_from), _dstGasForCall, _payload);
}
function _decodeSendAndCallPayload(bytes memory _payload)
internal
view
virtual
returns (
bytes32 from,
address to,
uint64 amountSD,
bytes memory payload,
uint64 dstGasForCall
)
{
require(_payload.toUint8(0) == PT_SEND_AND_CALL, "OFTCore: invalid payload");
to = _payload.toAddress(13);
amountSD = _payload.toUint64(33);
from = _payload.toBytes32(41);
dstGasForCall = _payload.toUint64(73);
payload = _payload.slice(81, _payload.length - 81);
}
function _addressToBytes32(address _address) internal pure virtual returns (bytes32) {
return bytes32(uint(uint160(_address)));
}
function _debitFrom(
address _from,
uint16 _dstChainId,
bytes32 _toAddress,
uint _amount
) internal virtual returns (uint);
function _creditTo(
uint16 _srcChainId,
address _toAddress,
uint _amount
) internal virtual returns (uint);
function _transferFrom(
address _from,
address _to,
uint _amount
) internal virtual returns (uint);
function _ld2sdRate() internal view virtual returns (uint);
}
文件 22 的 28:OracleInterface.sol
pragma solidity 0.8.13;
interface OracleInterface {
function getPrice(address asset) external view returns (uint256);
}
interface ResilientOracleInterface is OracleInterface {
function updatePrice(address vToken) external;
function updateAssetPrice(address asset) external;
function getUnderlyingPrice(address vToken) external view returns (uint256);
}
interface TwapInterface is OracleInterface {
function updateTwap(address asset) external returns (uint256);
}
interface BoundValidatorInterface {
function validatePriceWithAnchorPrice(
address asset,
uint256 reporterPrice,
uint256 anchorPrice
) external view returns (bool);
}
文件 23 的 28: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);
}
}
文件 24 的 28: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());
}
}
文件 25 的 28: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));
}
}
文件 26 的 28:XVSProxyOFTDest.sol
pragma solidity 0.8.13;
import { IXVS } from "./interfaces/IXVS.sol";
import { BaseXVSProxyOFT } from "./BaseXVSProxyOFT.sol";
contract XVSProxyOFTDest is BaseXVSProxyOFT {
event DropFailedMessage(uint16 srcChainId, bytes indexed srcAddress, uint64 nonce);
constructor(
address tokenAddress_,
uint8 sharedDecimals_,
address lzEndpoint_,
address oracle_
) BaseXVSProxyOFT(tokenAddress_, sharedDecimals_, lzEndpoint_, oracle_) {}
function dropFailedMessage(uint16 srcChainId_, bytes memory srcAddress_, uint64 nonce_) external onlyOwner {
failedMessages[srcChainId_][srcAddress_][nonce_] = bytes32(0);
emit DropFailedMessage(srcChainId_, srcAddress_, nonce_);
}
function circulatingSupply() public view override returns (uint256) {
return innerToken.totalSupply();
}
function _debitFrom(
address from_,
uint16 dstChainId_,
bytes32,
uint256 amount_
) internal override whenNotPaused returns (uint256) {
require(from_ == _msgSender(), "ProxyOFT: owner is not send caller");
_isEligibleToSend(from_, dstChainId_, amount_);
IXVS(address(innerToken)).burn(from_, amount_);
return amount_;
}
function _creditTo(
uint16 srcChainId_,
address toAddress_,
uint256 amount_
) internal override whenNotPaused returns (uint256) {
_isEligibleToReceive(toAddress_, srcChainId_, amount_);
IXVS(address(innerToken)).mint(toAddress_, amount_);
return amount_;
}
}
文件 27 的 28:constants.sol
pragma solidity 0.8.13;
uint256 constant EXP_SCALE = 1e18;
uint256 constant MANTISSA_ONE = EXP_SCALE;
文件 28 的 28:validators.sol
pragma solidity 0.8.13;
error ZeroAddressNotAllowed();
function ensureNonzeroAddress(address address_) pure {
if (address_ == address(0)) {
revert ZeroAddressNotAllowed();
}
}
{
"compilationTarget": {
"contracts/Bridge/XVSProxyOFTDest.sol": "XVSProxyOFTDest"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"tokenAddress_","type":"address"},{"internalType":"uint8","name":"sharedDecimals_","type":"uint8"},{"internalType":"address","name":"lzEndpoint_","type":"address"},{"internalType":"address","name":"oracle_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"sweepAmount","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"CallOFTReceivedSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":true,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"nonce","type":"uint64"}],"name":"DropFailedMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"innerToken","type":"address"}],"name":"InnerTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"MessageFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"NonContractAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOracle","type":"address"},{"indexed":true,"internalType":"address","name":"newOracle","type":"address"}],"name":"OracleChanged","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":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"ReceiveFromChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"_payloadHash","type":"bytes32"}],"name":"RetryMessageSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"bytes32","name":"_toAddress","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"SendToChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"oldMaxLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxLimit","type":"uint256"}],"name":"SetMaxDailyLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"oldMaxLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxLimit","type":"uint256"}],"name":"SetMaxDailyReceiveLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"oldMaxLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxLimit","type":"uint256"}],"name":"SetMaxSingleReceiveTransactionLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"oldMaxLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxLimit","type":"uint256"}],"name":"SetMaxSingleTransactionLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_type","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_minDstGas","type":"uint256"}],"name":"SetMinDstGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"precrime","type":"address"}],"name":"SetPrecrime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_path","type":"bytes"}],"name":"SetTrustedRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"SetTrustedRemoteAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"isWhitelist","type":"bool"}],"name":"SetWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"sweepAmount","type":"uint256"}],"name":"SweepToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"}],"name":"TrustedRemoteRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"enabled","type":"bool"}],"name":"UpdateSendAndCallEnabled","type":"event"},{"inputs":[],"name":"DEFAULT_PAYLOAD_SIZE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NO_EXTRA_GAS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PT_SEND","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PT_SEND_AND_CALL","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes32","name":"_from","type":"bytes32"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"uint256","name":"_gasForCall","type":"uint256"}],"name":"callOnOFTReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainIdToLast24HourReceiveWindowStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainIdToLast24HourReceived","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainIdToLast24HourTransferred","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainIdToLast24HourWindowStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainIdToMaxDailyLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainIdToMaxDailyReceiveLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainIdToMaxSingleReceiveTransactionLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainIdToMaxSingleTransactionLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"circulatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"creditedPackets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"srcChainId_","type":"uint16"},{"internalType":"bytes","name":"srcAddress_","type":"bytes"},{"internalType":"uint64","name":"nonce_","type":"uint64"}],"name":"dropFailedMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes32","name":"_toAddress","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"uint64","name":"_dstGasForCall","type":"uint64"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendAndCallFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes32","name":"_toAddress","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"failedMessages","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"forceResumeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"}],"name":"getTrustedRemoteAddress","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint16","name":"dstChainId_","type":"uint16"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"isEligibleToSend","outputs":[{"internalType":"bool","name":"eligibleToSend","type":"bool"},{"internalType":"uint256","name":"maxSingleTransactionLimit","type":"uint256"},{"internalType":"uint256","name":"maxDailyLimit","type":"uint256"},{"internalType":"uint256","name":"amountInUsd","type":"uint256"},{"internalType":"uint256","name":"transferredInWindow","type":"uint256"},{"internalType":"uint256","name":"last24HourWindowStart","type":"uint256"},{"internalType":"bool","name":"isWhiteListedUser","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"isTrustedRemote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"minDstGasLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"nonblockingLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract ResilientOracleInterface","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":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"payloadSizeLimitLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"precrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"remoteChainId_","type":"uint16"}],"name":"removeTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint16","name":"dstChainId_","type":"uint16"},{"internalType":"bytes32","name":"toAddress_","type":"bytes32"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"bytes","name":"payload_","type":"bytes"},{"internalType":"uint64","name":"dstGasForCall_","type":"uint64"},{"components":[{"internalType":"address payable","name":"refundAddress","type":"address"},{"internalType":"address","name":"zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"adapterParams","type":"bytes"}],"internalType":"struct ICommonOFT.LzCallParams","name":"callparams_","type":"tuple"}],"name":"sendAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sendAndCallEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes32","name":"_toAddress","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"components":[{"internalType":"address payable","name":"refundAddress","type":"address"},{"internalType":"address","name":"zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"adapterParams","type":"bytes"}],"internalType":"struct ICommonOFT.LzCallParams","name":"_callParams","type":"tuple"}],"name":"sendFrom","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":"uint16","name":"chainId_","type":"uint16"},{"internalType":"uint256","name":"limit_","type":"uint256"}],"name":"setMaxDailyLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId_","type":"uint16"},{"internalType":"uint256","name":"limit_","type":"uint256"}],"name":"setMaxDailyReceiveLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId_","type":"uint16"},{"internalType":"uint256","name":"limit_","type":"uint256"}],"name":"setMaxSingleReceiveTransactionLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId_","type":"uint16"},{"internalType":"uint256","name":"limit_","type":"uint256"}],"name":"setMaxSingleTransactionLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGas","type":"uint256"}],"name":"setMinDstGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oracleAddress_","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"setPayloadSizeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_precrime","type":"address"}],"name":"setPrecrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setReceiveVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setSendVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_path","type":"bytes"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"setTrustedRemoteAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user_","type":"address"},{"internalType":"bool","name":"val_","type":"bool"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sharedDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"sweepToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled_","type":"bool"}],"name":"updateSendAndCallEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]