Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SuperbridgeProxy
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity)
/**
*Submitted for verification at uniscan.xyz on 2025-05-12
*/
// SPDX-License-Identifier: MIT
pragma solidity <0.9.0 >=0.4.21 >=0.5.0 >=0.8.0 ^0.8.0 ^0.8.1 ^0.8.2 ^0.8.20;
// lib/openzeppelin-contracts/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
// lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
// lib/openzeppelin-contracts/contracts/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
// src/interfaces/arbitrum/IERC20Inbox.sol
interface IERC20Inbox {
function createRetryableTicket(
address to,
uint256 l2CallValue,
uint256 maxSubmissionCost,
address excessFeeRefundAddress,
address callValueRefundAddress,
uint256 gasLimit,
uint256 maxFeePerGas,
uint256 tokenTotalFeeAmount,
bytes calldata data
) external returns (uint256);
}
// src/interfaces/arbitrum/IInbox.sol
interface IInbox {
function createRetryableTicket(
address to,
uint256 l2CallValue,
uint256 maxSubmissionCost,
address excessFeeRefundAddress,
address callValueRefundAddress,
uint256 gasLimit,
uint256 maxFeePerGas,
bytes calldata data
) external payable returns (uint256);
}
// src/interfaces/arbitrum/IL1GatewayRouter.sol
interface IL1GatewayRouter {
function outboundTransferCustomRefund(
address _token,
address _refundTo,
address _to,
uint256 _amount,
uint256 _maxGas,
uint256 _gasPriceBid,
bytes calldata _data
) external payable returns (bytes memory);
}
// lib/layerzero-v2/packages/layerzero-v2/evm/protocol/contracts/interfaces/IMessageLibManager.sol
struct SetConfigParam {
uint32 eid;
uint32 configType;
bytes config;
}
interface IMessageLibManager {
struct Timeout {
address lib;
uint256 expiry;
}
event LibraryRegistered(address newLib);
event DefaultSendLibrarySet(uint32 eid, address newLib);
event DefaultReceiveLibrarySet(uint32 eid, address newLib);
event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry);
event SendLibrarySet(address sender, uint32 eid, address newLib);
event ReceiveLibrarySet(address receiver, uint32 eid, address newLib);
event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout);
function registerLibrary(address _lib) external;
function isRegisteredLibrary(address _lib) external view returns (bool);
function getRegisteredLibraries() external view returns (address[] memory);
function setDefaultSendLibrary(uint32 _eid, address _newLib) external;
function defaultSendLibrary(uint32 _eid) external view returns (address);
function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _timeout) external;
function defaultReceiveLibrary(uint32 _eid) external view returns (address);
function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external;
function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry);
function isSupportedEid(uint32 _eid) external view returns (bool);
function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool);
/// ------------------- OApp interfaces -------------------
function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external;
function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib);
function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool);
function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external;
function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault);
function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _gracePeriod) external;
function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry);
function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external;
function getConfig(
address _oapp,
address _lib,
uint32 _eid,
uint32 _configType
) external view returns (bytes memory config);
}
// lib/layerzero-v2/packages/layerzero-v2/evm/protocol/contracts/interfaces/IMessagingChannel.sol
interface IMessagingChannel {
event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce);
event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);
event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);
function eid() external view returns (uint32);
// this is an emergency function if a message cannot be verified for some reasons
// required to provide _nextNonce to avoid race condition
function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external;
function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;
function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;
function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32);
function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);
function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64);
function inboundPayloadHash(
address _receiver,
uint32 _srcEid,
bytes32 _sender,
uint64 _nonce
) external view returns (bytes32);
function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);
}
// lib/layerzero-v2/packages/layerzero-v2/evm/protocol/contracts/interfaces/IMessagingComposer.sol
interface IMessagingComposer {
event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message);
event ComposeDelivered(address from, address to, bytes32 guid, uint16 index);
event LzComposeAlert(
address indexed from,
address indexed to,
address indexed executor,
bytes32 guid,
uint16 index,
uint256 gas,
uint256 value,
bytes message,
bytes extraData,
bytes reason
);
function composeQueue(
address _from,
address _to,
bytes32 _guid,
uint16 _index
) external view returns (bytes32 messageHash);
function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external;
function lzCompose(
address _from,
address _to,
bytes32 _guid,
uint16 _index,
bytes calldata _message,
bytes calldata _extraData
) external payable;
}
// lib/layerzero-v2/packages/layerzero-v2/evm/protocol/contracts/interfaces/IMessagingContext.sol
interface IMessagingContext {
function isSendingMessage() external view returns (bool);
function getSendContext() external view returns (uint32 dstEid, address sender);
}
// src/interfaces/IOptimismPortal.sol
interface IOptimismPortal {
function depositTransaction(
address _to,
uint256 _value,
uint64 _gasLimit,
bool _isCreation,
bytes memory _data
) external payable;
function depositERC20Transaction(
address _to,
uint256 _mint,
uint256 _value,
uint64 _gasLimit,
bool _isCreation,
bytes memory _data
) external;
}
// src/interfaces/ISpokePool.sol
interface ISpokePool {
function deposit(
bytes32 depositor,
bytes32 recipient,
bytes32 inputToken,
bytes32 outputToken,
uint256 inputAmount,
uint256 outputAmount,
uint256 destinationChainId,
bytes32 exclusiveRelayer,
uint32 quoteTimestamp,
uint32 fillDeadline,
uint32 exclusivityParameter,
bytes calldata message
) external payable;
}
// src/interfaces/IStandardBridge.sol
interface IStandardBridge {
// deposits
// Legacy but DAI and some other bridges only support this
function depositERC20To(
address _l1Token,
address _l2Token,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external;
// withdrawals
// legacy but DAI and some other bridges only support this
function withdrawTo(
address _l2Token,
address _to,
uint256 _amount,
uint32 _l1Gas,
bytes calldata _data
) external payable;
// both
function bridgeETHTo(address _to, uint32 _minGasLimit, bytes calldata _extraData)
external
payable;
// disabled because we prefer
function bridgeERC20To(
address _localToken,
address _remoteToken,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external payable;
}
// src/interfaces/cctp/ITokenMessenger.sol
interface ITokenMessenger {
function depositForBurn(
uint256 amount,
uint32 destinationDomain,
bytes32 mintRecipient,
address burnToken
) external returns (uint64 _nonce);
}
// src/interfaces/IWarpRoute.sol
interface IWarpRoute {
function transferRemote(uint32 _destination, bytes32 _recipient, uint256 _amountOrId)
external
payable
returns (bytes32 messageId);
}
// lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// lib/endpoint-v1-solidity-examples/contracts/token/oft/v2/interfaces/ICommonOFT.sol
/**
* @dev Interface of the IOFT core standard
*/
interface ICommonOFT is IERC165 {
struct LzCallParams {
address payable refundAddress;
address zroPaymentAddress;
bytes adapterParams;
}
/**
* @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
* _dstChainId - L0 defined chain id to send tokens too
* _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
* _amount - amount of the tokens to transfer
* _useZro - indicates to use zro to pay L0 fees
* _adapterParam - flexible bytes array to indicate messaging adapter services in L0
*/
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);
/**
* @dev returns the circulating amount of tokens on current chain
*/
function circulatingSupply() external view returns (uint);
/**
* @dev returns the address of the ERC20 token
*/
function token() external view returns (address);
}
// lib/endpoint-v1-solidity-examples/contracts/token/oft/v1/interfaces/IOFTCore.sol
/**
* @dev Interface of the IOFT core standard
*/
interface IOFTCore is IERC165 {
/**
* @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
* _dstChainId - L0 defined chain id to send tokens too
* _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
* _amount - amount of the tokens to transfer
* _useZro - indicates to use zro to pay L0 fees
* _adapterParam - flexible bytes array to indicate messaging adapter services in L0
*/
function estimateSendFee(uint16 _dstChainId, bytes calldata _toAddress, uint _amount, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
/**
* @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from`
* `_from` the owner of token
* `_dstChainId` the destination chain identifier
* `_toAddress` can be any size depending on the `dstChainId`.
* `_amount` the quantity of tokens in wei
* `_refundAddress` the address LayerZero refunds if too much message fee is sent
* `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
* `_adapterParams` is a flexible bytes array to indicate messaging adapter services
*/
function sendFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint _amount, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;
/**
* @dev returns the circulating amount of tokens on current chain
*/
function circulatingSupply() external view returns (uint);
/**
* @dev returns the address of the ERC20 token
*/
function token() external view returns (address);
/**
* @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)
* `_nonce` is the outbound nonce
*/
event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes _toAddress, uint _amount);
/**
* @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.
* `_nonce` is the inbound nonce.
*/
event ReceiveFromChain(uint16 indexed _srcChainId, address indexed _to, uint _amount);
event SetUseCustomAdapterParams(bool _useCustomAdapterParams);
}
// lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol
// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized < type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Internal function that returns the initialized version. Returns `_initialized`
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Internal function that returns the initialized version. Returns `_initializing`
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}
// lib/openzeppelin-contracts/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
// lib/endpoint-v1-solidity-examples/contracts/token/oft/v2/interfaces/IOFTV2.sol
/**
* @dev Interface of the IOFT core standard
*/
interface IOFTV2 is ICommonOFT {
/**
* @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from`
* `_from` the owner of token
* `_dstChainId` the destination chain identifier
* `_toAddress` can be any size depending on the `dstChainId`.
* `_amount` the quantity of tokens in wei
* `_refundAddress` the address LayerZero refunds if too much message fee is sent
* `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
* `_adapterParams` is a flexible bytes array to indicate messaging adapter services
*/
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;
}
// lib/endpoint-v1-solidity-examples/contracts/token/oft/v2/fee/IOFTWithFee.sol
/**
* @dev Interface of the IOFT core standard
*/
interface IOFTWithFee is ICommonOFT {
/**
* @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from`
* `_from` the owner of token
* `_dstChainId` the destination chain identifier
* `_toAddress` can be any size depending on the `dstChainId`.
* `_amount` the quantity of tokens in wei
* `_minAmount` the minimum amount of tokens to receive on dstChain
* `_refundAddress` the address LayerZero refunds if too much message fee is sent
* `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
* `_adapterParams` is a flexible bytes array to indicate messaging adapter services
*/
function sendFrom(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, LzCallParams calldata _callParams) external payable;
function sendAndCall(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, bytes calldata _payload, uint64 _dstGasForCall, LzCallParams calldata _callParams) external payable;
}
// lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuardUpgradeable is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
// lib/endpoint-v1-solidity-examples/contracts/token/oft/v1/interfaces/IOFT.sol
/**
* @dev Interface of the OFT standard
*/
interface IOFT_0 is IOFTCore, IERC20 {
}
// lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
// lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
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));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
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");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// lib/layerzero-v2/packages/layerzero-v2/evm/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol
struct MessagingParams {
uint32 dstEid;
bytes32 receiver;
bytes message;
bytes options;
bool payInLzToken;
}
struct MessagingReceipt {
bytes32 guid;
uint64 nonce;
MessagingFee fee;
}
struct MessagingFee {
uint256 nativeFee;
uint256 lzTokenFee;
}
struct Origin {
uint32 srcEid;
bytes32 sender;
uint64 nonce;
}
interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext {
event PacketSent(bytes encodedPayload, bytes options, address sendLibrary);
event PacketVerified(Origin origin, address receiver, bytes32 payloadHash);
event PacketDelivered(Origin origin, address receiver);
event LzReceiveAlert(
address indexed receiver,
address indexed executor,
Origin origin,
bytes32 guid,
uint256 gas,
uint256 value,
bytes message,
bytes extraData,
bytes reason
);
event LzTokenSet(address token);
event DelegateSet(address sender, address delegate);
function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory);
function send(
MessagingParams calldata _params,
address _refundAddress
) external payable returns (MessagingReceipt memory);
function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external;
function verifiable(Origin calldata _origin, address _receiver) external view returns (bool);
function initializable(Origin calldata _origin, address _receiver) external view returns (bool);
function lzReceive(
Origin calldata _origin,
address _receiver,
bytes32 _guid,
bytes calldata _message,
bytes calldata _extraData
) external payable;
// oapp can burn messages partially by calling this function with its own business logic if messages are verified in order
function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external;
function setLzToken(address _lzToken) external;
function lzToken() external view returns (address);
function nativeToken() external view returns (address);
function setDelegate(address _delegate) external;
}
// lib/layerzero-v2/packages/layerzero-v2/evm/oapp/contracts/oapp/interfaces/IOAppCore.sol
/**
* @title IOAppCore
*/
interface IOAppCore {
// Custom error messages
error OnlyPeer(uint32 eid, bytes32 sender);
error NoPeer(uint32 eid);
error InvalidEndpointCall();
error InvalidDelegate();
// Event emitted when a peer (OApp) is set for a corresponding endpoint
event PeerSet(uint32 eid, bytes32 peer);
/**
* @notice Retrieves the OApp version information.
* @return senderVersion The version of the OAppSender.sol contract.
* @return receiverVersion The version of the OAppReceiver.sol contract.
*/
function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion);
/**
* @notice Retrieves the LayerZero endpoint associated with the OApp.
* @return iEndpoint The LayerZero endpoint as an interface.
*/
function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint);
/**
* @notice Retrieves the peer (OApp) associated with a corresponding endpoint.
* @param _eid The endpoint ID.
* @return peer The peer address (OApp instance) associated with the corresponding endpoint.
*/
function peers(uint32 _eid) external view returns (bytes32 peer);
/**
* @notice Sets the peer address (OApp instance) for a corresponding endpoint.
* @param _eid The endpoint ID.
* @param _peer The address of the peer to be associated with the corresponding endpoint.
*/
function setPeer(uint32 _eid, bytes32 _peer) external;
/**
* @notice Sets the delegate address for the OApp Core.
* @param _delegate The address of the delegate to be set.
*/
function setDelegate(address _delegate) external;
}
// lib/layerzero-v2/packages/layerzero-v2/evm/oapp/contracts/oapp/OAppCore.sol
/**
* @title OAppCore
* @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations.
*/
abstract contract OAppCore is IOAppCore, Ownable {
// The LayerZero endpoint associated with the given OApp
ILayerZeroEndpointV2 public immutable endpoint;
// Mapping to store peers associated with corresponding endpoints
mapping(uint32 eid => bytes32 peer) public peers;
/**
* @dev Constructor to initialize the OAppCore with the provided endpoint and delegate.
* @param _endpoint The address of the LOCAL Layer Zero endpoint.
* @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
*
* @dev The delegate typically should be set as the owner of the contract.
*/
constructor(address _endpoint, address _delegate) {
endpoint = ILayerZeroEndpointV2(_endpoint);
if (_delegate == address(0)) revert InvalidDelegate();
endpoint.setDelegate(_delegate);
}
/**
* @notice Sets the peer address (OApp instance) for a corresponding endpoint.
* @param _eid The endpoint ID.
* @param _peer The address of the peer to be associated with the corresponding endpoint.
*
* @dev Only the owner/admin of the OApp can call this function.
* @dev Indicates that the peer is trusted to send LayerZero messages to this OApp.
* @dev Set this to bytes32(0) to remove the peer address.
* @dev Peer is a bytes32 to accommodate non-evm chains.
*/
function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner {
_setPeer(_eid, _peer);
}
/**
* @notice Sets the peer address (OApp instance) for a corresponding endpoint.
* @param _eid The endpoint ID.
* @param _peer The address of the peer to be associated with the corresponding endpoint.
*
* @dev Indicates that the peer is trusted to send LayerZero messages to this OApp.
* @dev Set this to bytes32(0) to remove the peer address.
* @dev Peer is a bytes32 to accommodate non-evm chains.
*/
function _setPeer(uint32 _eid, bytes32 _peer) internal virtual {
peers[_eid] = _peer;
emit PeerSet(_eid, _peer);
}
/**
* @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set.
* ie. the peer is set to bytes32(0).
* @param _eid The endpoint ID.
* @return peer The address of the peer associated with the specified endpoint.
*/
function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) {
bytes32 peer = peers[_eid];
if (peer == bytes32(0)) revert NoPeer(_eid);
return peer;
}
/**
* @notice Sets the delegate address for the OApp.
* @param _delegate The address of the delegate to be set.
*
* @dev Only the owner/admin of the OApp can call this function.
* @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract.
*/
function setDelegate(address _delegate) public onlyOwner {
endpoint.setDelegate(_delegate);
}
}
// lib/layerzero-v2/packages/layerzero-v2/evm/oapp/contracts/oapp/OAppSender.sol
/**
* @title OAppSender
* @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint.
*/
abstract contract OAppSender is OAppCore {
using SafeERC20 for IERC20;
// Custom error messages
error NotEnoughNative(uint256 msgValue);
error LzTokenUnavailable();
// @dev The version of the OAppSender implementation.
// @dev Version is bumped when changes are made to this contract.
uint64 internal constant SENDER_VERSION = 1;
/**
* @notice Retrieves the OApp version information.
* @return senderVersion The version of the OAppSender.sol contract.
* @return receiverVersion The version of the OAppReceiver.sol contract.
*
* @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented.
* ie. this is a SEND only OApp.
* @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions
*/
function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {
return (SENDER_VERSION, 0);
}
/**
* @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation.
* @param _dstEid The destination endpoint ID.
* @param _message The message payload.
* @param _options Additional options for the message.
* @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens.
* @return fee The calculated MessagingFee for the message.
* - nativeFee: The native fee for the message.
* - lzTokenFee: The LZ token fee for the message.
*/
function _quote(
uint32 _dstEid,
bytes memory _message,
bytes memory _options,
bool _payInLzToken
) internal view virtual returns (MessagingFee memory fee) {
return
endpoint.quote(
MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken),
address(this)
);
}
/**
* @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message.
* @param _dstEid The destination endpoint ID.
* @param _message The message payload.
* @param _options Additional options for the message.
* @param _fee The calculated LayerZero fee for the message.
* - nativeFee: The native fee.
* - lzTokenFee: The lzToken fee.
* @param _refundAddress The address to receive any excess fee values sent to the endpoint.
* @return receipt The receipt for the sent message.
* - guid: The unique identifier for the sent message.
* - nonce: The nonce of the sent message.
* - fee: The LayerZero fee incurred for the message.
*/
function _lzSend(
uint32 _dstEid,
bytes memory _message,
bytes memory _options,
MessagingFee memory _fee,
address _refundAddress
) internal virtual returns (MessagingReceipt memory receipt) {
// @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint.
uint256 messageValue = _payNative(_fee.nativeFee);
if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee);
return
// solhint-disable-next-line check-send-result
endpoint.send{ value: messageValue }(
MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0),
_refundAddress
);
}
/**
* @dev Internal function to pay the native fee associated with the message.
* @param _nativeFee The native fee to be paid.
* @return nativeFee The amount of native currency paid.
*
* @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction,
* this will need to be overridden because msg.value would contain multiple lzFees.
* @dev Should be overridden in the event the LayerZero endpoint requires a different native currency.
* @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees.
* @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time.
*/
function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) {
if (msg.value != _nativeFee) revert NotEnoughNative(msg.value);
return _nativeFee;
}
/**
* @dev Internal function to pay the LZ token fee associated with the message.
* @param _lzTokenFee The LZ token fee to be paid.
*
* @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint.
* @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend().
*/
function _payLzToken(uint256 _lzTokenFee) internal virtual {
// @dev Cannot cache the token because it is not immutable in the endpoint.
address lzToken = endpoint.lzToken();
if (lzToken == address(0)) revert LzTokenUnavailable();
// Pay LZ token fee by sending tokens to the endpoint.
IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee);
}
}
// lib/layerzero-v2/packages/layerzero-v2/evm/oapp/contracts/oft/interfaces/IOFT.sol
/**
* @dev Struct representing token parameters for the OFT send() operation.
*/
struct SendParam {
uint32 dstEid; // Destination endpoint ID.
bytes32 to; // Recipient address.
uint256 amountLD; // Amount to send in local decimals.
uint256 minAmountLD; // Minimum amount to send in local decimals.
bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message.
bytes composeMsg; // The composed message for the send() operation.
bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations.
}
/**
* @dev Struct representing OFT limit information.
* @dev These amounts can change dynamically and are up the the specific oft implementation.
*/
struct OFTLimit {
uint256 minAmountLD; // Minimum amount in local decimals that can be sent to the recipient.
uint256 maxAmountLD; // Maximum amount in local decimals that can be sent to the recipient.
}
/**
* @dev Struct representing OFT receipt information.
*/
struct OFTReceipt {
uint256 amountSentLD; // Amount of tokens ACTUALLY debited from the sender in local decimals.
// @dev In non-default implementations, the amountReceivedLD COULD differ from this value.
uint256 amountReceivedLD; // Amount of tokens to be received on the remote side.
}
/**
* @dev Struct representing OFT fee details.
* @dev Future proof mechanism to provide a standardized way to communicate fees to things like a UI.
*/
struct OFTFeeDetail {
int256 feeAmountLD; // Amount of the fee in local decimals.
string description; // Description of the fee.
}
/**
* @title IOFT
* @dev Interface for the OftChain (OFT) token.
* @dev Does not inherit ERC20 to accommodate usage by OFTAdapter as well.
* @dev This specific interface ID is '0x02e49c2c'.
*/
interface IOFT_1 {
// Custom error messages
error InvalidLocalDecimals();
error SlippageExceeded(uint256 amountLD, uint256 minAmountLD);
// Events
event OFTSent(
bytes32 indexed guid, // GUID of the OFT message.
uint32 dstEid, // Destination Endpoint ID.
address indexed fromAddress, // Address of the sender on the src chain.
uint256 amountSentLD, // Amount of tokens sent in local decimals.
uint256 amountReceivedLD // Amount of tokens received in local decimals.
);
event OFTReceived(
bytes32 indexed guid, // GUID of the OFT message.
uint32 srcEid, // Source Endpoint ID.
address indexed toAddress, // Address of the recipient on the dst chain.
uint256 amountReceivedLD // Amount of tokens received in local decimals.
);
/**
* @notice Retrieves interfaceID and the version of the OFT.
* @return interfaceId The interface ID.
* @return version The version.
*
* @dev interfaceId: This specific interface ID is '0x02e49c2c'.
* @dev version: Indicates a cross-chain compatible msg encoding with other OFTs.
* @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented.
* ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1)
*/
function oftVersion() external view returns (bytes4 interfaceId, uint64 version);
/**
* @notice Retrieves the address of the token associated with the OFT.
* @return token The address of the ERC20 token implementation.
*/
function token() external view returns (address);
/**
* @notice Indicates whether the OFT contract requires approval of the 'token()' to send.
* @return requiresApproval Needs approval of the underlying token implementation.
*
* @dev Allows things like wallet implementers to determine integration requirements,
* without understanding the underlying token implementation.
*/
function approvalRequired() external view returns (bool);
/**
* @notice Retrieves the shared decimals of the OFT.
* @return sharedDecimals The shared decimals of the OFT.
*/
function sharedDecimals() external view returns (uint8);
/**
* @notice Provides a quote for OFT-related operations.
* @param _sendParam The parameters for the send operation.
* @return limit The OFT limit information.
* @return oftFeeDetails The details of OFT fees.
* @return receipt The OFT receipt information.
*/
function quoteOFT(
SendParam calldata _sendParam
) external view returns (OFTLimit memory, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory);
/**
* @notice Provides a quote for the send() operation.
* @param _sendParam The parameters for the send() operation.
* @param _payInLzToken Flag indicating whether the caller is paying in the LZ token.
* @return fee The calculated LayerZero messaging fee from the send() operation.
*
* @dev MessagingFee: LayerZero msg fee
* - nativeFee: The native fee.
* - lzTokenFee: The lzToken fee.
*/
function quoteSend(SendParam calldata _sendParam, bool _payInLzToken) external view returns (MessagingFee memory);
/**
* @notice Executes the send() operation.
* @param _sendParam The parameters for the send operation.
* @param _fee The fee information supplied by the caller.
* - nativeFee: The native fee.
* - lzTokenFee: The lzToken fee.
* @param _refundAddress The address to receive any excess funds from fees etc. on the src.
* @return receipt The LayerZero messaging receipt from the send() operation.
* @return oftReceipt The OFT receipt information.
*
* @dev MessagingReceipt: LayerZero msg receipt
* - guid: The unique identifier for the sent message.
* - nonce: The nonce of the sent message.
* - fee: The LayerZero fee incurred for the message.
*/
function send(
SendParam calldata _sendParam,
MessagingFee calldata _fee,
address _refundAddress
) external payable returns (MessagingReceipt memory, OFTReceipt memory);
}
// src/SuperbridgeProxy.sol
contract SuperbridgeProxy is OwnableUpgradeable, ReentrancyGuardUpgradeable {
using SafeERC20 for IERC20;
event SuperbridgeSend(address from);
event SuperbridgeSend2(address from, uint256 total);
function initialize() public initializer {
__Ownable_init();
__ReentrancyGuard_init();
}
function withdrawEther() external onlyOwner {
(bool sent,) = owner().call{value: address(this).balance}("");
require(sent, "Failed to send Ether");
}
function withdrawToken(address _token) external onlyOwner {
IERC20(_token).safeTransfer(owner(), IERC20(_token).balanceOf(address(this)));
}
/**
* OP Stack
*/
function opEth(
uint256 _amount,
address payable _l1StandardBridge,
address _to,
uint32 _defaultGasLimit,
bytes calldata _graffiti
) public payable {
_beforeEth(_amount);
IStandardBridge(_l1StandardBridge).bridgeETHTo{value: _amount}(
_to, _defaultGasLimit, _graffiti
);
}
function opNativeCustomGasToken(
uint256 _total,
uint256 _amount,
address _portal,
address _gasToken,
address _to,
uint32 _defaultGasLimit,
bytes calldata _graffiti
) public payable {
_beforeErc20(_total, _amount, _portal, _gasToken);
IOptimismPortal(_portal).depositERC20Transaction(
_to, _amount, _amount, _defaultGasLimit, false, _graffiti
);
_afterErc20(_portal, _gasToken);
}
function opErc20(
uint256 _total,
uint256 _amount,
address _l1StandardBridge,
address _localToken,
address _remoteToken,
address _to,
uint32 _minGasLimit,
bytes calldata _extraData
) public payable {
_beforeErc20(_total, _amount, _l1StandardBridge, _localToken);
IStandardBridge(_l1StandardBridge).bridgeERC20To(
_localToken, _remoteToken, _to, _amount, _minGasLimit, _extraData
);
_afterErc20(_l1StandardBridge, _localToken);
}
/**
* LayerZero
*/
function sendOftV1(
address _oft,
uint256 _total,
uint16 _dstChainId,
bytes calldata _toAddress,
uint256 _amount,
address payable _refundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParams
) external payable nonReentrant {
address token = _oftBeforeSend(_oft, _total, _amount);
IOFT_0(_oft).sendFrom{value: msg.value}(
address(this),
_dstChainId,
_toAddress,
_amount,
_refundAddress,
_zroPaymentAddress,
_adapterParams
);
_oftAfterSend(_oft, token);
}
function sendOftV12(
address _oft,
uint256 _total,
uint16 _dstChainId,
bytes32 _toAddress,
uint256 _amount,
ICommonOFT.LzCallParams calldata _callParams
) external payable nonReentrant {
address token = _oftBeforeSend(_oft, _total, _amount);
IOFTV2(_oft).sendFrom{value: msg.value}(
address(this), _dstChainId, _toAddress, _amount, _callParams
);
_oftAfterSend(_oft, token);
}
function sendOftVFee(
address _oft,
uint256 _total,
uint16 _dstChainId,
bytes32 _toAddress,
uint256 _amount,
uint256 _minAmount,
ICommonOFT.LzCallParams calldata _callParams
) external payable nonReentrant {
address token = _oftBeforeSend(_oft, _total, _amount);
IOFTWithFee(_oft).sendFrom{value: msg.value}(
address(this), _dstChainId, _toAddress, _amount, _minAmount, _callParams
);
_oftAfterSend(_oft, token);
}
function sendOftV2(
address _oft,
uint256 _total,
SendParam calldata _sendParam,
MessagingFee calldata _fee,
address _refundAddress
) external payable nonReentrant {
address token = _oftBeforeSend(_oft, _total, _sendParam.amountLD);
IOFT_1(_oft).send{value: msg.value}(_sendParam, _fee, _refundAddress);
_oftAfterSend(_oft, token);
}
function _oftBeforeSend(address _oft, uint256 _total, uint256 _amount)
internal
returns (address token)
{
require(_total > _amount, "_total smaller than _amount");
token = IOFT_1(_oft).token();
IERC20(token).safeTransferFrom(msg.sender, address(this), _total);
if (token != _oft) {
IERC20(token).safeApprove(_oft, _amount);
}
emit SuperbridgeSend(msg.sender);
emit SuperbridgeSend2(msg.sender, _total);
}
function _oftAfterSend(address _oft, address _token) internal {
if (_token != _oft && IERC20(_token).allowance(address(this), _oft) > 0) {
IERC20(_token).safeApprove(_oft, 0);
}
}
struct AcrossBridgeParams {
bytes32 depositor;
bytes32 recipient;
bytes32 inputToken;
bytes32 outputToken;
uint256 inputAmount;
uint256 outputAmount;
uint256 destinationChainId;
bytes32 exclusiveRelayer;
uint32 quoteTimestamp;
uint32 fillDeadline;
uint32 exclusivityParameter;
bytes message;
}
/**
* Across
*/
function acrossEth(address _spokePool, AcrossBridgeParams calldata params)
external
payable
{
_beforeEth(params.inputAmount);
ISpokePool(_spokePool).deposit{value: params.inputAmount}(
params.depositor,
params.recipient,
params.inputToken,
params.outputToken,
params.inputAmount,
params.outputAmount,
params.destinationChainId,
params.exclusiveRelayer,
params.quoteTimestamp,
params.fillDeadline,
params.exclusivityParameter,
params.message
);
}
function acrossErc20(
uint256 _total,
address _spokePool,
AcrossBridgeParams calldata params
) external payable {
_beforeErc20(
_total, params.inputAmount, _spokePool, _bytes32ToAddress(params.inputToken)
);
ISpokePool(_spokePool).deposit(
params.depositor,
params.recipient,
params.inputToken,
params.outputToken,
params.inputAmount,
params.outputAmount,
params.destinationChainId,
params.exclusiveRelayer,
params.quoteTimestamp,
params.fillDeadline,
params.exclusivityParameter,
params.message
);
_afterErc20(_spokePool, _bytes32ToAddress(params.inputToken));
}
function hyperlaneErc20(
uint256 _total,
uint256 _amount,
address _warpRoute,
address _token,
uint32 _destination,
bytes32 _recipient
) external payable {
_beforeErc20(_total, _amount, _warpRoute, _token);
IWarpRoute(_warpRoute).transferRemote{value: msg.value}(
_destination, _recipient, _amount
);
_afterErc20(_warpRoute, _token);
}
struct ArbitrumInboxRetryableTicketParams {
address to;
uint256 maxSubmissionCost;
address excessFeeRefundAddress;
address callValueRefundAddress;
uint256 gasLimit;
uint256 maxFeePerGas;
bytes data;
}
function arbNative(
address inbox,
uint256 total,
uint256 amount,
uint256 gasCost,
ArbitrumInboxRetryableTicketParams calldata params
) external payable {
_beforeEthWithGasPayment(total, amount, gasCost);
IInbox(inbox).createRetryableTicket{value: amount + gasCost}(
params.to,
amount,
params.maxSubmissionCost,
params.excessFeeRefundAddress,
params.callValueRefundAddress,
params.gasLimit,
params.maxFeePerGas,
params.data
);
}
struct ArbitrumOutboundTransferCustomRefundParams {
address token;
address refundTo;
address to;
uint256 amount;
uint256 maxGas;
uint256 gasPriceBid;
bytes data;
}
function arbErc20(
uint256 _total,
address _gateway,
address _gatewayRouter,
ArbitrumOutboundTransferCustomRefundParams calldata params
) external payable {
_beforeErc20(_total, params.amount, _gateway, params.token);
IL1GatewayRouter(_gatewayRouter).outboundTransferCustomRefund{value: msg.value}(
params.token,
params.refundTo,
params.to,
params.amount,
params.maxGas,
params.gasPriceBid,
params.data
);
_afterErc20(_gateway, params.token);
}
function cctp(
uint256 _total,
address _tokenMessenger,
uint256 amount,
uint32 destinationDomain,
bytes32 mintRecipient,
address burnToken
) external {
_beforeErc20(_total, amount, _tokenMessenger, burnToken);
ITokenMessenger(_tokenMessenger).depositForBurn(
amount, destinationDomain, mintRecipient, burnToken
);
_afterErc20(_tokenMessenger, burnToken);
}
function _beforeEth(uint256 _amount) internal {
require(msg.value > _amount, "msg.value smaller than _amount");
emit SuperbridgeSend(msg.sender);
emit SuperbridgeSend2(msg.sender, msg.value);
}
function _beforeEthWithGasPayment(uint256 _total, uint256 _amount, uint256 _gasPayment)
internal
{
require(msg.value == _total + _gasPayment, "msg.value != _total + _gasPayment");
require(msg.value > _amount + _gasPayment, "msg.value < _amount + _gasPayment");
emit SuperbridgeSend2(msg.sender, _total);
}
function _beforeErc20(uint256 _total, uint256 _amount, address _bridge, address _token)
internal
{
require(_total > _amount, "_total smaller than _amount");
IERC20(_token).safeTransferFrom(msg.sender, address(this), _total);
IERC20(_token).safeApprove(_bridge, _amount);
emit SuperbridgeSend(msg.sender);
emit SuperbridgeSend2(msg.sender, _total);
}
function _afterErc20(address _bridge, address _token) internal {
IERC20(_token).safeApprove(_bridge, 0);
}
function _bytes32ToAddress(bytes32 _bytes) internal pure returns (address) {
require(uint256(_bytes) <= uint256(type(uint160).max), "overflow");
return address(uint160(uint256(_bytes)));
}
function _addressToBytes32(address _addr) internal pure returns (bytes32) {
return bytes32(uint256(uint160(_addr)));
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","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":"from","type":"address"}],"name":"SuperbridgeSend","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"}],"name":"SuperbridgeSend2","type":"event"},{"inputs":[{"internalType":"uint256","name":"_total","type":"uint256"},{"internalType":"address","name":"_spokePool","type":"address"},{"components":[{"internalType":"bytes32","name":"depositor","type":"bytes32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"inputToken","type":"bytes32"},{"internalType":"bytes32","name":"outputToken","type":"bytes32"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"bytes32","name":"exclusiveRelayer","type":"bytes32"},{"internalType":"uint32","name":"quoteTimestamp","type":"uint32"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"exclusivityParameter","type":"uint32"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct SuperbridgeProxy.AcrossBridgeParams","name":"params","type":"tuple"}],"name":"acrossErc20","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_spokePool","type":"address"},{"components":[{"internalType":"bytes32","name":"depositor","type":"bytes32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"inputToken","type":"bytes32"},{"internalType":"bytes32","name":"outputToken","type":"bytes32"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"bytes32","name":"exclusiveRelayer","type":"bytes32"},{"internalType":"uint32","name":"quoteTimestamp","type":"uint32"},{"internalType":"uint32","name":"fillDeadline","type":"uint32"},{"internalType":"uint32","name":"exclusivityParameter","type":"uint32"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct SuperbridgeProxy.AcrossBridgeParams","name":"params","type":"tuple"}],"name":"acrossEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_total","type":"uint256"},{"internalType":"address","name":"_gateway","type":"address"},{"internalType":"address","name":"_gatewayRouter","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"maxGas","type":"uint256"},{"internalType":"uint256","name":"gasPriceBid","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct SuperbridgeProxy.ArbitrumOutboundTransferCustomRefundParams","name":"params","type":"tuple"}],"name":"arbErc20","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"inbox","type":"address"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"gasCost","type":"uint256"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"maxSubmissionCost","type":"uint256"},{"internalType":"address","name":"excessFeeRefundAddress","type":"address"},{"internalType":"address","name":"callValueRefundAddress","type":"address"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct SuperbridgeProxy.ArbitrumInboxRetryableTicketParams","name":"params","type":"tuple"}],"name":"arbNative","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_total","type":"uint256"},{"internalType":"address","name":"_tokenMessenger","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint32","name":"destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"mintRecipient","type":"bytes32"},{"internalType":"address","name":"burnToken","type":"address"}],"name":"cctp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_total","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_warpRoute","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint32","name":"_destination","type":"uint32"},{"internalType":"bytes32","name":"_recipient","type":"bytes32"}],"name":"hyperlaneErc20","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_total","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_l1StandardBridge","type":"address"},{"internalType":"address","name":"_localToken","type":"address"},{"internalType":"address","name":"_remoteToken","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint32","name":"_minGasLimit","type":"uint32"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"opErc20","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address payable","name":"_l1StandardBridge","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint32","name":"_defaultGasLimit","type":"uint32"},{"internalType":"bytes","name":"_graffiti","type":"bytes"}],"name":"opEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_total","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_portal","type":"address"},{"internalType":"address","name":"_gasToken","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint32","name":"_defaultGasLimit","type":"uint32"},{"internalType":"bytes","name":"_graffiti","type":"bytes"}],"name":"opNativeCustomGasToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oft","type":"address"},{"internalType":"uint256","name":"_total","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"sendOftV1","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_oft","type":"address"},{"internalType":"uint256","name":"_total","type":"uint256"},{"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":"sendOftV12","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_oft","type":"address"},{"internalType":"uint256","name":"_total","type":"uint256"},{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"_fee","type":"tuple"},{"internalType":"address","name":"_refundAddress","type":"address"}],"name":"sendOftV2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_oft","type":"address"},{"internalType":"uint256","name":"_total","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes32","name":"_toAddress","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_minAmount","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":"sendOftVFee","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561000f575f80fd5b506131e68061001d5f395ff3fe60806040526004361061013d575f3560e01c80638129fc1c116100bb578063a9c93fbe11610071578063c977383411610057578063c9773834146102b3578063d4e1a69c146102c6578063f2fde38b146102d9575f80fd5b8063a9c93fbe14610281578063aa590ea914610294575f80fd5b806387fef1dc116100a157806387fef1dc14610217578063894760691461022a5780638da5cb5b14610249575f80fd5b80638129fc1c146101f05780638513b0ca14610204575f80fd5b806363eda6d111610110578063715018a6116100f6578063715018a6146101b55780637362377b146101c95780638091beae146101dd575f80fd5b806363eda6d11461018f578063666e15a1146101a2575f80fd5b806321fdeb8b1461014157806326cf2691146101565780632c912d6c146101695780635e5b120f1461017c575b5f80fd5b61015461014f3660046121c5565b6102f8565b005b610154610164366004612277565b610409565b6101546101773660046122f5565b6104a2565b61015461018a3660046123c4565b61054e565b61015461019d366004612445565b6105f4565b6101546101b03660046124cc565b610697565b3480156101c0575f80fd5b50610154610777565b3480156101d4575f80fd5b5061015461078a565b6101546101eb366004612534565b61087e565b3480156101fb575f80fd5b50610154610929565b6101546102123660046125cd565b610abd565b61015461022536600461262c565b610b78565b348015610235575f80fd5b506101546102443660046126f7565b610c27565b348015610254575f80fd5b506033546040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61015461028f366004612719565b610cfb565b34801561029f575f80fd5b506101546102ae366004612766565b610de4565b6101546102c13660046127c7565b610ea4565b6101546102d436600461282f565b610fbd565b3480156102e4575f80fd5b506101546102f33660046126f7565b611074565b6103148382608001358461030f8560400135611128565b6111ab565b73ffffffffffffffffffffffffffffffffffffffff821663ad5425c68235602084013560408501356060860135608087013560a088013560c089013560e08a01356103676101208c016101008d016128d2565b6103796101408d016101208e016128d2565b61038b6101608e016101408f016128d2565b6103996101608f018f6128eb565b6040518e63ffffffff1660e01b81526004016103c19d9c9b9a99989796959493929190612993565b5f604051808303815f87803b1580156103d8575f80fd5b505af11580156103ea573d5f803e3d5ffd5b50505050610404826103ff8360400135611128565b6112c9565b505050565b610412866112ee565b6040517fe11013dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86169063e11013dd90889061046c908890889088908890600401612a0e565b5f604051808303818588803b158015610483575f80fd5b505af1158015610495573d5f803e3d5ffd5b5050505050505050505050565b6104ae898989896111ab565b6040517f540abf7300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88169063540abf739061050c908990899089908e908a908a908a90600401612a53565b5f604051808303815f87803b158015610523575f80fd5b505af1158015610535573d5f803e3d5ffd5b5050505061054387876112c9565b505050505050505050565b6105566113bf565b5f610562888886611432565b90508773ffffffffffffffffffffffffffffffffffffffff16632cdf0b95343089898989896040518863ffffffff1660e01b81526004016105a896959493929190612b79565b5f604051808303818588803b1580156105bf575f80fd5b505af11580156105d1573d5f803e3d5ffd5b50505050506105e088826115f4565b506105eb6001606555565b50505050505050565b6105fc6113bf565b5f610608878785611432565b90508673ffffffffffffffffffffffffffffffffffffffff1663695ef6bf3430888888886040518763ffffffff1660e01b815260040161064c959493929190612bcf565b5f604051808303818588803b158015610663575f80fd5b505af1158015610675573d5f803e3d5ffd5b505050505061068487826115f4565b5061068f6001606555565b505050505050565b6106a28484846116f1565b73ffffffffffffffffffffffffffffffffffffffff851663679b6ded6106c88486612c13565b6106d560208501856126f7565b8660208601356106eb60608801604089016126f7565b6106fb6080890160608a016126f7565b608089013560a08a013561071260c08c018c6128eb565b6040518b63ffffffff1660e01b815260040161073699989796959493929190612c51565b60206040518083038185885af1158015610752573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061068f9190612cbb565b61077f61185f565b6107885f6118e0565b565b61079261185f565b5f6107b260335473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16476040515f6040518083038185875af1925050503d805f8114610806576040519150601f19603f3d011682016040523d82523d5f602084013e61080b565b606091505b505090508061087b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4661696c656420746f2073656e6420457468657200000000000000000000000060448201526064015b60405180910390fd5b50565b61088a888888886111ab565b6040517f149f2f2200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87169063149f2f22906108e89087908b90819089905f908a908a90600401612cd2565b5f604051808303815f87803b1580156108ff575f80fd5b505af1158015610911573d5f803e3d5ffd5b5050505061091f86866112c9565b5050505050505050565b5f54610100900460ff161580801561094757505f54600160ff909116105b806109605750303b15801561096057505f5460ff166001145b6109ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610872565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610a48575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a50611956565b610a586119f4565b801561087b575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a150565b610ac9868686866111ab565b6040517f81b4e8b400000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602481018290526044810186905273ffffffffffffffffffffffffffffffffffffffff8516906381b4e8b490349060640160206040518083038185885af1158015610b48573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610b6d9190612cbb565b5061068f84846112c9565b610b806113bf565b5f610b8c8b8b88611432565b90508a73ffffffffffffffffffffffffffffffffffffffff16635190563634308c8c8c8c8c8c8c8c6040518b63ffffffff1660e01b8152600401610bd899989796959493929190612d21565b5f604051808303818588803b158015610bef575f80fd5b505af1158015610c01573d5f803e3d5ffd5b5050505050610c108b826115f4565b50610c1b6001606555565b50505050505050505050565b610c2f61185f565b61087b610c5160335473ffffffffffffffffffffffffffffffffffffffff1690565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610cb9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cdd9190612cbb565b73ffffffffffffffffffffffffffffffffffffffff84169190611a92565b610d0881608001356112ee565b73ffffffffffffffffffffffffffffffffffffffff821663ad5425c6608083013583356020850135604086013560608701358460a089013560c08a013560e08b0135610d5c6101208d016101008e016128d2565b610d6e6101408e016101208f016128d2565b8d610140016020810190610d8291906128d2565b8e806101600190610d9391906128eb565b6040518f63ffffffff1660e01b8152600401610dbb9d9c9b9a99989796959493929190612993565b5f604051808303818588803b158015610dd2575f80fd5b505af11580156105eb573d5f803e3d5ffd5b610df0868587846111ab565b6040517f6fd3504e0000000000000000000000000000000000000000000000000000000081526004810185905263ffffffff841660248201526044810183905273ffffffffffffffffffffffffffffffffffffffff8281166064830152861690636fd3504e906084016020604051808303815f875af1158015610e75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e999190612dac565b5061068f85826112c9565b610ebb8460608301358561030f60208601866126f7565b73ffffffffffffffffffffffffffffffffffffffff8216634fb1a07b34610ee560208501856126f7565b610ef560408601602087016126f7565b610f0560608701604088016126f7565b6060870135608088013560a0890135610f2160c08b018b6128eb565b6040518a63ffffffff1660e01b8152600401610f44989796959493929190612dc5565b5f6040518083038185885af1158015610f5f573d5f803e3d5ffd5b50505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610fa59190810190612e75565b50610fb7836103ff60208401846126f7565b50505050565b610fc56113bf565b5f610fd586868660400135611432565b90508573ffffffffffffffffffffffffffffffffffffffff1663c7c7f5b3348686866040518563ffffffff1660e01b815260040161101593929190612f30565b60c06040518083038185885af1158015611031573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906110569190613086565b505061106286826115f4565b5061106d6001606555565b5050505050565b61107c61185f565b73ffffffffffffffffffffffffffffffffffffffff811661111f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610872565b61087b816118e0565b5f73ffffffffffffffffffffffffffffffffffffffff8211156111a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f6f766572666c6f770000000000000000000000000000000000000000000000006044820152606401610872565b5090565b828411611214576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5f746f74616c20736d616c6c6572207468616e205f616d6f756e7400000000006044820152606401610872565b61123673ffffffffffffffffffffffffffffffffffffffff8216333087611b66565b61125773ffffffffffffffffffffffffffffffffffffffff82168385611bc4565b6040513381527f01f2f98802a634db79fdb802b2b1e48f84cfb38cb729e62342a79e847b2d8e459060200160405180910390a160408051338152602081018690527f3fc237908c33fe15c69ac1a1cf1827c3a8bc1902f2905674f842dce90f4e2a28910160405180910390a150505050565b6112ea73ffffffffffffffffffffffffffffffffffffffff8216835f611bc4565b5050565b803411611357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f6d73672e76616c756520736d616c6c6572207468616e205f616d6f756e7400006044820152606401610872565b6040513381527f01f2f98802a634db79fdb802b2b1e48f84cfb38cb729e62342a79e847b2d8e459060200160405180910390a1604080513381523460208201527f3fc237908c33fe15c69ac1a1cf1827c3a8bc1902f2905674f842dce90f4e2a289101610ab2565b60026065540361142b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610872565b6002606555565b5f81831161149c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5f746f74616c20736d616c6c6572207468616e205f616d6f756e7400000000006044820152606401610872565b8373ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114e5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611509919061310b565b905061152d73ffffffffffffffffffffffffffffffffffffffff8216333086611b66565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146115815761158173ffffffffffffffffffffffffffffffffffffffff82168584611bc4565b6040513381527f01f2f98802a634db79fdb802b2b1e48f84cfb38cb729e62342a79e847b2d8e459060200160405180910390a160408051338152602081018590527f3fc237908c33fe15c69ac1a1cf1827c3a8bc1902f2905674f842dce90f4e2a28910160405180910390a19392505050565b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156116c457506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff83811660248301525f919083169063dd62ed3e90604401602060405180830381865afa15801561169e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116c29190612cbb565b115b156112ea576112ea73ffffffffffffffffffffffffffffffffffffffff8216835f611bc4565b6001606555565b6116fb8184612c13565b3414611789576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f6d73672e76616c756520213d205f746f74616c202b205f6761735061796d656e60448201527f74000000000000000000000000000000000000000000000000000000000000006064820152608401610872565b6117938183612c13565b3411611821576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f6d73672e76616c7565203c205f616d6f756e74202b205f6761735061796d656e60448201527f74000000000000000000000000000000000000000000000000000000000000006064820152608401610872565b60408051338152602081018590527f3fc237908c33fe15c69ac1a1cf1827c3a8bc1902f2905674f842dce90f4e2a28910160405180910390a1505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610872565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f54610100900460ff166119ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610872565b610788611d44565b5f54610100900460ff16611a8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610872565b610788611de3565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526104049084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611e79565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610fb79085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611ae4565b801580611c6257506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611c3c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c609190612cbb565b155b611cee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610872565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526104049084907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611ae4565b5f54610100900460ff16611dda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610872565b610788336118e0565b5f54610100900460ff166116ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610872565b5f611eda826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611f849092919063ffffffff16565b8051909150156104045780806020019051810190611ef89190613126565b610404576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610872565b6060611f9284845f85611f9a565b949350505050565b60608247101561202c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610872565b5f808673ffffffffffffffffffffffffffffffffffffffff1685876040516120549190613145565b5f6040518083038185875af1925050503d805f811461208e576040519150601f19603f3d011682016040523d82523d5f602084013e612093565b606091505b50915091506120a4878383876120af565b979650505050505050565b606083156121445782515f0361213d5773ffffffffffffffffffffffffffffffffffffffff85163b61213d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610872565b5081611f92565b611f9283838151156121595781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108729190613160565b73ffffffffffffffffffffffffffffffffffffffff8116811461087b575f80fd5b5f61018082840312156121bf575f80fd5b50919050565b5f805f606084860312156121d7575f80fd5b8335925060208401356121e98161218d565b9150604084013567ffffffffffffffff811115612204575f80fd5b612210868287016121ae565b9150509250925092565b803563ffffffff8116811461222d575f80fd5b919050565b5f8083601f840112612242575f80fd5b50813567ffffffffffffffff811115612259575f80fd5b602083019150836020828501011115612270575f80fd5b9250929050565b5f805f805f8060a0878903121561228c575f80fd5b86359550602087013561229e8161218d565b945060408701356122ae8161218d565b93506122bc6060880161221a565b9250608087013567ffffffffffffffff8111156122d7575f80fd5b6122e389828a01612232565b979a9699509497509295939492505050565b5f805f805f805f805f6101008a8c03121561230e575f80fd5b8935985060208a0135975060408a01356123278161218d565b965060608a01356123378161218d565b955060808a01356123478161218d565b945060a08a01356123578161218d565b935061236560c08b0161221a565b925060e08a013567ffffffffffffffff811115612380575f80fd5b61238c8c828d01612232565b915080935050809150509295985092959850929598565b803561ffff8116811461222d575f80fd5b5f606082840312156121bf575f80fd5b5f805f805f805f60e0888a0312156123da575f80fd5b87356123e58161218d565b9650602088013595506123fa604089016123a3565b9450606088013593506080880135925060a0880135915060c088013567ffffffffffffffff81111561242a575f80fd5b6124368a828b016123b4565b91505092959891949750929550565b5f805f805f8060c0878903121561245a575f80fd5b86356124658161218d565b95506020870135945061247a604088016123a3565b9350606087013592506080870135915060a087013567ffffffffffffffff8111156124a3575f80fd5b6124af89828a016123b4565b9150509295509295509295565b5f60e082840312156121bf575f80fd5b5f805f805f60a086880312156124e0575f80fd5b85356124eb8161218d565b9450602086013593506040860135925060608601359150608086013567ffffffffffffffff81111561251b575f80fd5b612527888289016124bc565b9150509295509295909350565b5f805f805f805f8060e0898b03121561254b575f80fd5b883597506020890135965060408901356125648161218d565b955060608901356125748161218d565b945060808901356125848161218d565b935061259260a08a0161221a565b925060c089013567ffffffffffffffff8111156125ad575f80fd5b6125b98b828c01612232565b999c989b5096995094979396929594505050565b5f805f805f8060c087890312156125e2575f80fd5b863595506020870135945060408701356125fb8161218d565b9350606087013561260b8161218d565b92506126196080880161221a565b915060a087013590509295509295509295565b5f805f805f805f805f806101008b8d031215612646575f80fd5b8a356126518161218d565b995060208b0135985061266660408c016123a3565b975060608b013567ffffffffffffffff80821115612682575f80fd5b61268e8e838f01612232565b909950975060808d0135965060a08d013591506126aa8261218d565b90945060c08c0135906126bc8261218d565b90935060e08c013590808211156126d1575f80fd5b506126de8d828e01612232565b915080935050809150509295989b9194979a5092959850565b5f60208284031215612707575f80fd5b81356127128161218d565b9392505050565b5f806040838503121561272a575f80fd5b82356127358161218d565b9150602083013567ffffffffffffffff811115612750575f80fd5b61275c858286016121ae565b9150509250929050565b5f805f805f8060c0878903121561277b575f80fd5b86359550602087013561278d8161218d565b9450604087013593506127a26060880161221a565b92506080870135915060a08701356127b98161218d565b809150509295509295509295565b5f805f80608085870312156127da575f80fd5b8435935060208501356127ec8161218d565b925060408501356127fc8161218d565b9150606085013567ffffffffffffffff811115612817575f80fd5b612823878288016124bc565b91505092959194509250565b5f805f805f85870360c0811215612844575f80fd5b863561284f8161218d565b955060208701359450604087013567ffffffffffffffff811115612871575f80fd5b61287d89828a016124bc565b94505060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0820112156128af575f80fd5b5060608601915060a08601356128c48161218d565b809150509295509295909350565b5f602082840312156128e2575f80fd5b6127128261221a565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261291e575f80fd5b83018035915067ffffffffffffffff821115612938575f80fd5b602001915036819003821315612270575f80fd5b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b5f6101808f83528e60208401528d60408401528c60608401528b60808401528a60a08401528960c08401528860e084015263ffffffff80891661010085015280881661012085015280871661014085015250806101608401526129f9818401858761294c565b9150509e9d5050505050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815263ffffffff84166020820152606060408201525f612a4960608301848661294c565b9695505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152612aa660c08301848661294c565b9998505050505050505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612ae6575f80fd5b830160208101925035905067ffffffffffffffff811115612b05575f80fd5b803603821315612270575f80fd5b5f8135612b1f8161218d565b73ffffffffffffffffffffffffffffffffffffffff9081168452602083013590612b488261218d565b166020840152612b5b6040830183612ab3565b60606040860152612b7060608601828461294c565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8716815261ffff8616602082015284604082015283606082015282608082015260c060a08201525f612bc360c0830184612b13565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8616815261ffff8516602082015283604082015282606082015260a060808201525f6120a460a0830184612b13565b80820180821115612c4b577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b92915050565b5f61010073ffffffffffffffffffffffffffffffffffffffff808d1684528b60208501528a6040850152808a1660608501528089166080850152508660a08401528560c08401528060e0840152612cab818401858761294c565b9c9b505050505050505050505050565b5f60208284031215612ccb575f80fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff8816815286602082015285604082015263ffffffff85166060820152831515608082015260c060a08201525f612aa660c08301848661294c565b5f73ffffffffffffffffffffffffffffffffffffffff808c16835261ffff8b16602084015260e06040840152612d5b60e084018a8c61294c565b886060850152818816608085015281871660a085015283810360c0850152612d8481868861294c565b9d9c50505050505050505050505050565b805167ffffffffffffffff8116811461222d575f80fd5b5f60208284031215612dbc575f80fd5b61271282612d95565b5f73ffffffffffffffffffffffffffffffffffffffff808b168352808a1660208401528089166040840152508660608301528560808301528460a083015260e060c0830152612e1860e08301848661294c565b9a9950505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5b83811015612e6d578181015183820152602001612e55565b50505f910152565b5f60208284031215612e85575f80fd5b815167ffffffffffffffff80821115612e9c575f80fd5b818401915084601f830112612eaf575f80fd5b815181811115612ec157612ec1612e26565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612f0757612f07612e26565b81604052828152876020848701011115612f1f575f80fd5b6120a4836020830160208801612e53565b6080815263ffffffff612f428561221a565b166080820152602084013560a0820152604084013560c0820152606084013560e08201525f612f746080860186612ab3565b60e0610100850152612f8b6101608501828461294c565b915050612f9b60a0870187612ab3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808086850301610120870152612fd284838561294c565b9350612fe160c08a018a612ab3565b93509150808685030161014087015250612ffc83838361294c565b9350505050613018602083018580358252602090810135910152565b73ffffffffffffffffffffffffffffffffffffffff83166060830152611f92565b5f60408284031215613049575f80fd5b6040516040810181811067ffffffffffffffff8211171561306c5761306c612e26565b604052825181526020928301519281019290925250919050565b5f8082840360c0811215613098575f80fd5b60808112156130a5575f80fd5b506040516060810181811067ffffffffffffffff821117156130c9576130c9612e26565b604052835181526130dc60208501612d95565b60208201526130ee8560408601613039565b604082015291506131028460808501613039565b90509250929050565b5f6020828403121561311b575f80fd5b81516127128161218d565b5f60208284031215613136575f80fd5b81518015158114612712575f80fd5b5f8251613156818460208701612e53565b9190910192915050565b602081525f825180602084015261317e816040850160208701612e53565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220084301a479fa0e7deb4e80757a9517af5fc0c1860f20f9bb77227c17bcd88eda64736f6c63430008140033
Deployed Bytecode
0x60806040526004361061013d575f3560e01c80638129fc1c116100bb578063a9c93fbe11610071578063c977383411610057578063c9773834146102b3578063d4e1a69c146102c6578063f2fde38b146102d9575f80fd5b8063a9c93fbe14610281578063aa590ea914610294575f80fd5b806387fef1dc116100a157806387fef1dc14610217578063894760691461022a5780638da5cb5b14610249575f80fd5b80638129fc1c146101f05780638513b0ca14610204575f80fd5b806363eda6d111610110578063715018a6116100f6578063715018a6146101b55780637362377b146101c95780638091beae146101dd575f80fd5b806363eda6d11461018f578063666e15a1146101a2575f80fd5b806321fdeb8b1461014157806326cf2691146101565780632c912d6c146101695780635e5b120f1461017c575b5f80fd5b61015461014f3660046121c5565b6102f8565b005b610154610164366004612277565b610409565b6101546101773660046122f5565b6104a2565b61015461018a3660046123c4565b61054e565b61015461019d366004612445565b6105f4565b6101546101b03660046124cc565b610697565b3480156101c0575f80fd5b50610154610777565b3480156101d4575f80fd5b5061015461078a565b6101546101eb366004612534565b61087e565b3480156101fb575f80fd5b50610154610929565b6101546102123660046125cd565b610abd565b61015461022536600461262c565b610b78565b348015610235575f80fd5b506101546102443660046126f7565b610c27565b348015610254575f80fd5b506033546040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61015461028f366004612719565b610cfb565b34801561029f575f80fd5b506101546102ae366004612766565b610de4565b6101546102c13660046127c7565b610ea4565b6101546102d436600461282f565b610fbd565b3480156102e4575f80fd5b506101546102f33660046126f7565b611074565b6103148382608001358461030f8560400135611128565b6111ab565b73ffffffffffffffffffffffffffffffffffffffff821663ad5425c68235602084013560408501356060860135608087013560a088013560c089013560e08a01356103676101208c016101008d016128d2565b6103796101408d016101208e016128d2565b61038b6101608e016101408f016128d2565b6103996101608f018f6128eb565b6040518e63ffffffff1660e01b81526004016103c19d9c9b9a99989796959493929190612993565b5f604051808303815f87803b1580156103d8575f80fd5b505af11580156103ea573d5f803e3d5ffd5b50505050610404826103ff8360400135611128565b6112c9565b505050565b610412866112ee565b6040517fe11013dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86169063e11013dd90889061046c908890889088908890600401612a0e565b5f604051808303818588803b158015610483575f80fd5b505af1158015610495573d5f803e3d5ffd5b5050505050505050505050565b6104ae898989896111ab565b6040517f540abf7300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88169063540abf739061050c908990899089908e908a908a908a90600401612a53565b5f604051808303815f87803b158015610523575f80fd5b505af1158015610535573d5f803e3d5ffd5b5050505061054387876112c9565b505050505050505050565b6105566113bf565b5f610562888886611432565b90508773ffffffffffffffffffffffffffffffffffffffff16632cdf0b95343089898989896040518863ffffffff1660e01b81526004016105a896959493929190612b79565b5f604051808303818588803b1580156105bf575f80fd5b505af11580156105d1573d5f803e3d5ffd5b50505050506105e088826115f4565b506105eb6001606555565b50505050505050565b6105fc6113bf565b5f610608878785611432565b90508673ffffffffffffffffffffffffffffffffffffffff1663695ef6bf3430888888886040518763ffffffff1660e01b815260040161064c959493929190612bcf565b5f604051808303818588803b158015610663575f80fd5b505af1158015610675573d5f803e3d5ffd5b505050505061068487826115f4565b5061068f6001606555565b505050505050565b6106a28484846116f1565b73ffffffffffffffffffffffffffffffffffffffff851663679b6ded6106c88486612c13565b6106d560208501856126f7565b8660208601356106eb60608801604089016126f7565b6106fb6080890160608a016126f7565b608089013560a08a013561071260c08c018c6128eb565b6040518b63ffffffff1660e01b815260040161073699989796959493929190612c51565b60206040518083038185885af1158015610752573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061068f9190612cbb565b61077f61185f565b6107885f6118e0565b565b61079261185f565b5f6107b260335473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16476040515f6040518083038185875af1925050503d805f8114610806576040519150601f19603f3d011682016040523d82523d5f602084013e61080b565b606091505b505090508061087b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4661696c656420746f2073656e6420457468657200000000000000000000000060448201526064015b60405180910390fd5b50565b61088a888888886111ab565b6040517f149f2f2200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87169063149f2f22906108e89087908b90819089905f908a908a90600401612cd2565b5f604051808303815f87803b1580156108ff575f80fd5b505af1158015610911573d5f803e3d5ffd5b5050505061091f86866112c9565b5050505050505050565b5f54610100900460ff161580801561094757505f54600160ff909116105b806109605750303b15801561096057505f5460ff166001145b6109ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610872565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610a48575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a50611956565b610a586119f4565b801561087b575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a150565b610ac9868686866111ab565b6040517f81b4e8b400000000000000000000000000000000000000000000000000000000815263ffffffff83166004820152602481018290526044810186905273ffffffffffffffffffffffffffffffffffffffff8516906381b4e8b490349060640160206040518083038185885af1158015610b48573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610b6d9190612cbb565b5061068f84846112c9565b610b806113bf565b5f610b8c8b8b88611432565b90508a73ffffffffffffffffffffffffffffffffffffffff16635190563634308c8c8c8c8c8c8c8c6040518b63ffffffff1660e01b8152600401610bd899989796959493929190612d21565b5f604051808303818588803b158015610bef575f80fd5b505af1158015610c01573d5f803e3d5ffd5b5050505050610c108b826115f4565b50610c1b6001606555565b50505050505050505050565b610c2f61185f565b61087b610c5160335473ffffffffffffffffffffffffffffffffffffffff1690565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015610cb9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cdd9190612cbb565b73ffffffffffffffffffffffffffffffffffffffff84169190611a92565b610d0881608001356112ee565b73ffffffffffffffffffffffffffffffffffffffff821663ad5425c6608083013583356020850135604086013560608701358460a089013560c08a013560e08b0135610d5c6101208d016101008e016128d2565b610d6e6101408e016101208f016128d2565b8d610140016020810190610d8291906128d2565b8e806101600190610d9391906128eb565b6040518f63ffffffff1660e01b8152600401610dbb9d9c9b9a99989796959493929190612993565b5f604051808303818588803b158015610dd2575f80fd5b505af11580156105eb573d5f803e3d5ffd5b610df0868587846111ab565b6040517f6fd3504e0000000000000000000000000000000000000000000000000000000081526004810185905263ffffffff841660248201526044810183905273ffffffffffffffffffffffffffffffffffffffff8281166064830152861690636fd3504e906084016020604051808303815f875af1158015610e75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e999190612dac565b5061068f85826112c9565b610ebb8460608301358561030f60208601866126f7565b73ffffffffffffffffffffffffffffffffffffffff8216634fb1a07b34610ee560208501856126f7565b610ef560408601602087016126f7565b610f0560608701604088016126f7565b6060870135608088013560a0890135610f2160c08b018b6128eb565b6040518a63ffffffff1660e01b8152600401610f44989796959493929190612dc5565b5f6040518083038185885af1158015610f5f573d5f803e3d5ffd5b50505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610fa59190810190612e75565b50610fb7836103ff60208401846126f7565b50505050565b610fc56113bf565b5f610fd586868660400135611432565b90508573ffffffffffffffffffffffffffffffffffffffff1663c7c7f5b3348686866040518563ffffffff1660e01b815260040161101593929190612f30565b60c06040518083038185885af1158015611031573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906110569190613086565b505061106286826115f4565b5061106d6001606555565b5050505050565b61107c61185f565b73ffffffffffffffffffffffffffffffffffffffff811661111f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610872565b61087b816118e0565b5f73ffffffffffffffffffffffffffffffffffffffff8211156111a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f6f766572666c6f770000000000000000000000000000000000000000000000006044820152606401610872565b5090565b828411611214576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5f746f74616c20736d616c6c6572207468616e205f616d6f756e7400000000006044820152606401610872565b61123673ffffffffffffffffffffffffffffffffffffffff8216333087611b66565b61125773ffffffffffffffffffffffffffffffffffffffff82168385611bc4565b6040513381527f01f2f98802a634db79fdb802b2b1e48f84cfb38cb729e62342a79e847b2d8e459060200160405180910390a160408051338152602081018690527f3fc237908c33fe15c69ac1a1cf1827c3a8bc1902f2905674f842dce90f4e2a28910160405180910390a150505050565b6112ea73ffffffffffffffffffffffffffffffffffffffff8216835f611bc4565b5050565b803411611357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f6d73672e76616c756520736d616c6c6572207468616e205f616d6f756e7400006044820152606401610872565b6040513381527f01f2f98802a634db79fdb802b2b1e48f84cfb38cb729e62342a79e847b2d8e459060200160405180910390a1604080513381523460208201527f3fc237908c33fe15c69ac1a1cf1827c3a8bc1902f2905674f842dce90f4e2a289101610ab2565b60026065540361142b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610872565b6002606555565b5f81831161149c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5f746f74616c20736d616c6c6572207468616e205f616d6f756e7400000000006044820152606401610872565b8373ffffffffffffffffffffffffffffffffffffffff1663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114e5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611509919061310b565b905061152d73ffffffffffffffffffffffffffffffffffffffff8216333086611b66565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146115815761158173ffffffffffffffffffffffffffffffffffffffff82168584611bc4565b6040513381527f01f2f98802a634db79fdb802b2b1e48f84cfb38cb729e62342a79e847b2d8e459060200160405180910390a160408051338152602081018590527f3fc237908c33fe15c69ac1a1cf1827c3a8bc1902f2905674f842dce90f4e2a28910160405180910390a19392505050565b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156116c457506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff83811660248301525f919083169063dd62ed3e90604401602060405180830381865afa15801561169e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116c29190612cbb565b115b156112ea576112ea73ffffffffffffffffffffffffffffffffffffffff8216835f611bc4565b6001606555565b6116fb8184612c13565b3414611789576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f6d73672e76616c756520213d205f746f74616c202b205f6761735061796d656e60448201527f74000000000000000000000000000000000000000000000000000000000000006064820152608401610872565b6117938183612c13565b3411611821576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f6d73672e76616c7565203c205f616d6f756e74202b205f6761735061796d656e60448201527f74000000000000000000000000000000000000000000000000000000000000006064820152608401610872565b60408051338152602081018590527f3fc237908c33fe15c69ac1a1cf1827c3a8bc1902f2905674f842dce90f4e2a28910160405180910390a1505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610872565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f54610100900460ff166119ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610872565b610788611d44565b5f54610100900460ff16611a8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610872565b610788611de3565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526104049084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611e79565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610fb79085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611ae4565b801580611c6257506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611c3c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c609190612cbb565b155b611cee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610872565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526104049084907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611ae4565b5f54610100900460ff16611dda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610872565b610788336118e0565b5f54610100900460ff166116ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610872565b5f611eda826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611f849092919063ffffffff16565b8051909150156104045780806020019051810190611ef89190613126565b610404576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610872565b6060611f9284845f85611f9a565b949350505050565b60608247101561202c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610872565b5f808673ffffffffffffffffffffffffffffffffffffffff1685876040516120549190613145565b5f6040518083038185875af1925050503d805f811461208e576040519150601f19603f3d011682016040523d82523d5f602084013e612093565b606091505b50915091506120a4878383876120af565b979650505050505050565b606083156121445782515f0361213d5773ffffffffffffffffffffffffffffffffffffffff85163b61213d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610872565b5081611f92565b611f9283838151156121595781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108729190613160565b73ffffffffffffffffffffffffffffffffffffffff8116811461087b575f80fd5b5f61018082840312156121bf575f80fd5b50919050565b5f805f606084860312156121d7575f80fd5b8335925060208401356121e98161218d565b9150604084013567ffffffffffffffff811115612204575f80fd5b612210868287016121ae565b9150509250925092565b803563ffffffff8116811461222d575f80fd5b919050565b5f8083601f840112612242575f80fd5b50813567ffffffffffffffff811115612259575f80fd5b602083019150836020828501011115612270575f80fd5b9250929050565b5f805f805f8060a0878903121561228c575f80fd5b86359550602087013561229e8161218d565b945060408701356122ae8161218d565b93506122bc6060880161221a565b9250608087013567ffffffffffffffff8111156122d7575f80fd5b6122e389828a01612232565b979a9699509497509295939492505050565b5f805f805f805f805f6101008a8c03121561230e575f80fd5b8935985060208a0135975060408a01356123278161218d565b965060608a01356123378161218d565b955060808a01356123478161218d565b945060a08a01356123578161218d565b935061236560c08b0161221a565b925060e08a013567ffffffffffffffff811115612380575f80fd5b61238c8c828d01612232565b915080935050809150509295985092959850929598565b803561ffff8116811461222d575f80fd5b5f606082840312156121bf575f80fd5b5f805f805f805f60e0888a0312156123da575f80fd5b87356123e58161218d565b9650602088013595506123fa604089016123a3565b9450606088013593506080880135925060a0880135915060c088013567ffffffffffffffff81111561242a575f80fd5b6124368a828b016123b4565b91505092959891949750929550565b5f805f805f8060c0878903121561245a575f80fd5b86356124658161218d565b95506020870135945061247a604088016123a3565b9350606087013592506080870135915060a087013567ffffffffffffffff8111156124a3575f80fd5b6124af89828a016123b4565b9150509295509295509295565b5f60e082840312156121bf575f80fd5b5f805f805f60a086880312156124e0575f80fd5b85356124eb8161218d565b9450602086013593506040860135925060608601359150608086013567ffffffffffffffff81111561251b575f80fd5b612527888289016124bc565b9150509295509295909350565b5f805f805f805f8060e0898b03121561254b575f80fd5b883597506020890135965060408901356125648161218d565b955060608901356125748161218d565b945060808901356125848161218d565b935061259260a08a0161221a565b925060c089013567ffffffffffffffff8111156125ad575f80fd5b6125b98b828c01612232565b999c989b5096995094979396929594505050565b5f805f805f8060c087890312156125e2575f80fd5b863595506020870135945060408701356125fb8161218d565b9350606087013561260b8161218d565b92506126196080880161221a565b915060a087013590509295509295509295565b5f805f805f805f805f806101008b8d031215612646575f80fd5b8a356126518161218d565b995060208b0135985061266660408c016123a3565b975060608b013567ffffffffffffffff80821115612682575f80fd5b61268e8e838f01612232565b909950975060808d0135965060a08d013591506126aa8261218d565b90945060c08c0135906126bc8261218d565b90935060e08c013590808211156126d1575f80fd5b506126de8d828e01612232565b915080935050809150509295989b9194979a5092959850565b5f60208284031215612707575f80fd5b81356127128161218d565b9392505050565b5f806040838503121561272a575f80fd5b82356127358161218d565b9150602083013567ffffffffffffffff811115612750575f80fd5b61275c858286016121ae565b9150509250929050565b5f805f805f8060c0878903121561277b575f80fd5b86359550602087013561278d8161218d565b9450604087013593506127a26060880161221a565b92506080870135915060a08701356127b98161218d565b809150509295509295509295565b5f805f80608085870312156127da575f80fd5b8435935060208501356127ec8161218d565b925060408501356127fc8161218d565b9150606085013567ffffffffffffffff811115612817575f80fd5b612823878288016124bc565b91505092959194509250565b5f805f805f85870360c0811215612844575f80fd5b863561284f8161218d565b955060208701359450604087013567ffffffffffffffff811115612871575f80fd5b61287d89828a016124bc565b94505060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0820112156128af575f80fd5b5060608601915060a08601356128c48161218d565b809150509295509295909350565b5f602082840312156128e2575f80fd5b6127128261221a565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261291e575f80fd5b83018035915067ffffffffffffffff821115612938575f80fd5b602001915036819003821315612270575f80fd5b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b5f6101808f83528e60208401528d60408401528c60608401528b60808401528a60a08401528960c08401528860e084015263ffffffff80891661010085015280881661012085015280871661014085015250806101608401526129f9818401858761294c565b9150509e9d5050505050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8516815263ffffffff84166020820152606060408201525f612a4960608301848661294c565b9695505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525085606083015263ffffffff8516608083015260c060a0830152612aa660c08301848661294c565b9998505050505050505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612ae6575f80fd5b830160208101925035905067ffffffffffffffff811115612b05575f80fd5b803603821315612270575f80fd5b5f8135612b1f8161218d565b73ffffffffffffffffffffffffffffffffffffffff9081168452602083013590612b488261218d565b166020840152612b5b6040830183612ab3565b60606040860152612b7060608601828461294c565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8716815261ffff8616602082015284604082015283606082015282608082015260c060a08201525f612bc360c0830184612b13565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8616815261ffff8516602082015283604082015282606082015260a060808201525f6120a460a0830184612b13565b80820180821115612c4b577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b92915050565b5f61010073ffffffffffffffffffffffffffffffffffffffff808d1684528b60208501528a6040850152808a1660608501528089166080850152508660a08401528560c08401528060e0840152612cab818401858761294c565b9c9b505050505050505050505050565b5f60208284031215612ccb575f80fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff8816815286602082015285604082015263ffffffff85166060820152831515608082015260c060a08201525f612aa660c08301848661294c565b5f73ffffffffffffffffffffffffffffffffffffffff808c16835261ffff8b16602084015260e06040840152612d5b60e084018a8c61294c565b886060850152818816608085015281871660a085015283810360c0850152612d8481868861294c565b9d9c50505050505050505050505050565b805167ffffffffffffffff8116811461222d575f80fd5b5f60208284031215612dbc575f80fd5b61271282612d95565b5f73ffffffffffffffffffffffffffffffffffffffff808b168352808a1660208401528089166040840152508660608301528560808301528460a083015260e060c0830152612e1860e08301848661294c565b9a9950505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5b83811015612e6d578181015183820152602001612e55565b50505f910152565b5f60208284031215612e85575f80fd5b815167ffffffffffffffff80821115612e9c575f80fd5b818401915084601f830112612eaf575f80fd5b815181811115612ec157612ec1612e26565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612f0757612f07612e26565b81604052828152876020848701011115612f1f575f80fd5b6120a4836020830160208801612e53565b6080815263ffffffff612f428561221a565b166080820152602084013560a0820152604084013560c0820152606084013560e08201525f612f746080860186612ab3565b60e0610100850152612f8b6101608501828461294c565b915050612f9b60a0870187612ab3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808086850301610120870152612fd284838561294c565b9350612fe160c08a018a612ab3565b93509150808685030161014087015250612ffc83838361294c565b9350505050613018602083018580358252602090810135910152565b73ffffffffffffffffffffffffffffffffffffffff83166060830152611f92565b5f60408284031215613049575f80fd5b6040516040810181811067ffffffffffffffff8211171561306c5761306c612e26565b604052825181526020928301519281019290925250919050565b5f8082840360c0811215613098575f80fd5b60808112156130a5575f80fd5b506040516060810181811067ffffffffffffffff821117156130c9576130c9612e26565b604052835181526130dc60208501612d95565b60208201526130ee8560408601613039565b604082015291506131028460808501613039565b90509250929050565b5f6020828403121561311b575f80fd5b81516127128161218d565b5f60208284031215613136575f80fd5b81518015158114612712575f80fd5b5f8251613156818460208701612e53565b9190910192915050565b602081525f825180602084015261317e816040850160208701612e53565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220084301a479fa0e7deb4e80757a9517af5fc0c1860f20f9bb77227c17bcd88eda64736f6c63430008140033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$1.02
Net Worth in ETH
0.00035
Token Allocations
ETH
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $2,905.58 | 0.00035 | $1.02 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.