Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 37,381 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
Amount
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer ETH | 9852149 | 28 days ago | IN | 0.52002449 ETH | 0.00018625 | ||||
| Transfer ETH | 9845890 | 29 days ago | IN | 0.52002596 ETH | 0.0000012 | ||||
| Transfer ETH | 9844285 | 29 days ago | IN | 0.50002656 ETH | 0.00000065 | ||||
| Transfer ETH | 9839487 | 30 days ago | IN | 0.52002981 ETH | 0.00000106 | ||||
| Transfer ETH | 9838309 | 30 days ago | IN | 0.51002954 ETH | 0.00000042 | ||||
| Transfer ETH | 9833268 | 31 days ago | IN | 2.50002787 ETH | 0.0000004 | ||||
| Transfer ETH | 9831513 | 31 days ago | IN | 2.50002764 ETH | 0.00000042 | ||||
| Transfer ETH | 9829320 | 31 days ago | IN | 0.0100277 ETH | 0.00000042 | ||||
| Transfer ETH | 9825982 | 32 days ago | IN | 2.50002914 ETH | 0.00000038 | ||||
| Transfer ETH | 9823544 | 32 days ago | IN | 2.50002885 ETH | 0.00151639 | ||||
| Transfer ETH | 9817886 | 33 days ago | IN | 2.50002549 ETH | 0.00000042 | ||||
| Transfer ETH | 9817271 | 33 days ago | IN | 2.50002555 ETH | 0.00000038 | ||||
| Transfer ETH | 9811546 | 34 days ago | IN | 2.5000269 ETH | 0.00000354 | ||||
| Transfer ETH | 9809995 | 34 days ago | IN | 2.50002711 ETH | 0.00000038 | ||||
| Transfer ETH | 9808272 | 34 days ago | IN | 5.00002748 ETH | 0.00000042 | ||||
| Transfer ETH | 9797587 | 36 days ago | IN | 2.60002474 ETH | 0.00000042 | ||||
| Transfer ETH | 9796195 | 36 days ago | IN | 2.40002488 ETH | 0.0000138 | ||||
| Transfer ETH | 9789852 | 37 days ago | IN | 2.60002494 ETH | 0.00000035 | ||||
| Transfer ETH | 9788112 | 37 days ago | IN | 2.400025 ETH | 0.00000211 | ||||
| Transfer ETH | 9782342 | 38 days ago | IN | 2.63002556 ETH | 0.0000036 | ||||
| Transfer ETH | 9781776 | 38 days ago | IN | 25.00002539 ETH | 0.00000041 | ||||
| Transfer ETH | 9781166 | 38 days ago | IN | 28.00002518 ETH | 0.00053178 | ||||
| Transfer ETH | 9780734 | 38 days ago | IN | 4.16002524 ETH | 0.0000007 | ||||
| Transfer ETH | 9780159 | 38 days ago | IN | 3.00002535 ETH | 0.00000035 | ||||
| Transfer ETH | 9775291 | 39 days ago | IN | 2.64002479 ETH | 0.00000053 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
To
|
Amount
|
||
|---|---|---|---|---|---|---|---|
| Request Executio... | 9852149 | 28 days ago | 0.00000411 ETH | ||||
| Transfer | 9852149 | 28 days ago | 0.00002037 ETH | ||||
| Deposit | 9852149 | 28 days ago | 0.52 ETH | ||||
| Request Executio... | 9845890 | 29 days ago | 0.00000386 ETH | ||||
| Transfer | 9845890 | 29 days ago | 0.00002209 ETH | ||||
| Deposit | 9845890 | 29 days ago | 0.52 ETH | ||||
| Request Executio... | 9844285 | 29 days ago | 0.00000389 ETH | ||||
| Transfer | 9844285 | 29 days ago | 0.00002267 ETH | ||||
| Deposit | 9844285 | 29 days ago | 0.5 ETH | ||||
| Request Executio... | 9839487 | 30 days ago | 0.00000397 ETH | ||||
| Transfer | 9839487 | 30 days ago | 0.00002584 ETH | ||||
| Deposit | 9839487 | 30 days ago | 0.52 ETH | ||||
| Request Executio... | 9838309 | 30 days ago | 0.00000392 ETH | ||||
| Transfer | 9838309 | 30 days ago | 0.00002561 ETH | ||||
| Deposit | 9838309 | 30 days ago | 0.51 ETH | ||||
| Request Executio... | 9833268 | 31 days ago | 0.00000398 ETH | ||||
| Transfer | 9833268 | 31 days ago | 0.00002388 ETH | ||||
| Deposit | 9833268 | 31 days ago | 2.5 ETH | ||||
| Request Executio... | 9831513 | 31 days ago | 0.00000397 ETH | ||||
| Transfer | 9831513 | 31 days ago | 0.00002366 ETH | ||||
| Deposit | 9831513 | 31 days ago | 2.5 ETH | ||||
| Request Executio... | 9829320 | 31 days ago | 0.000004 ETH | ||||
| Transfer | 9829320 | 31 days ago | 0.0000237 ETH | ||||
| Deposit | 9829320 | 31 days ago | 0.01 ETH | ||||
| Request Executio... | 9825982 | 32 days ago | 0.00000404 ETH |
Loading...
Loading
Loading...
Loading
Contract Name:
MultiTokenNttWithExecutor
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.19;
import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
import "example-messaging-executor/evm/src/interfaces/IExecutor.sol";
import "example-messaging-executor/evm/src/libraries/ExecutorMessages.sol";
import "native-token-transfers/evm/src/libraries/TrimmedAmount.sol";
import "./interfaces/IMultiTokenNtt.sol";
import "./interfaces/IMultiTokenNttWithExecutor.sol";
string constant MultiTokenNttWithExecutorVersion = "MultiTokenNttWithExecutor-0.0.1";
/// @title MultiTokenNttWithExecutor
/// @author Wormhole Project Contributors.
/// @notice The MultiTokenNttWithExecutor contract is a shim contract that initiates
/// a Monad Bridge transfer using the executor for relaying.
contract MultiTokenNttWithExecutor is IMultiTokenNttWithExecutor {
using TrimmedAmountLib for uint256;
using TrimmedAmountLib for TrimmedAmount;
uint16 public immutable chainId;
IExecutor public immutable executor;
string public constant VERSION = MultiTokenNttWithExecutorVersion;
constructor(uint16 _chainId, address _executor) {
assert(_chainId != 0);
assert(_executor != address(0));
chainId = _chainId;
executor = IExecutor(_executor);
}
// ==================== External Interface ===============================================
function transfer(
address multiTokenNtt,
address token,
uint256 amount,
uint16 recipientChain,
bytes32 recipient,
bytes32 refundAddress,
bytes memory transceiverInstructions,
ExecutorArgs calldata executorArgs,
FeeArgs calldata feeArgs
) external payable returns (uint64 sequence) {
// TODO: Is it confusing having two refund addresses (the function arg and the executor arg)?
// Can we use the arg everywhere (converting it to address for the executor)?
IMultiTokenNtt mtNtt = IMultiTokenNtt(multiTokenNtt);
uint8 decimals = _getDecimals(token);
// Custody the tokens in this contract and approve the Monad bridge to spend them.
// Not worrying about dust here since the bridge will revert in that case.
amount = _custodyTokens(token, amount);
// Transfer the fee to the referrer.
amount = _payFee(token, decimals, amount, feeArgs);
// Approve the bridge to spend the tokens.
_maxApproveIfNeeded(token, multiTokenNtt, amount);
// Initiate the transfer.
sequence = mtNtt.transfer{value: msg.value - executorArgs.value}(
IMultiTokenNtt.TransferArgs(
token, amount, recipientChain, recipient, refundAddress, false, transceiverInstructions, bytes("")
)
);
// Generate the executor event.
executor.requestExecution{value: executorArgs.value}(
recipientChain,
mtNtt.getPeer(recipientChain).peerAddress,
executorArgs.refundAddress,
executorArgs.signedQuote,
ExecutorMessages.makeNTTv1Request(
chainId, bytes32(uint256(uint160(address(mtNtt)))), bytes32(uint256(sequence))
),
executorArgs.instructions
);
// Refund any excess value.
uint256 currentBalance = address(this).balance;
if (currentBalance > 0) {
(bool refundSuccessful,) = payable(executorArgs.refundAddress).call{value: currentBalance}("");
if (!refundSuccessful) {
revert RefundFailed(currentBalance);
}
}
}
function transferETH(
address multiTokenNtt,
uint256 amount,
uint16 recipientChain,
bytes32 recipient,
bytes32 refundAddress,
bytes memory transceiverInstructions,
ExecutorArgs calldata executorArgs,
FeeArgs calldata feeArgs
) external payable returns (uint64 sequence) {
IMultiTokenNtt mtNtt = IMultiTokenNtt(multiTokenNtt);
IWETH weth = mtNtt.WETH();
address token = address(weth);
require(token != address(0), "WETH does not exist");
uint8 decimals = _getDecimals(token);
// This requires the amount + wormhole fee + executionAmount to exactly equal msg.value
// because `transferTokensWithRelay` will revert if there is any extra.
require(msg.value >= amount + executorArgs.value, "Not enough msg value");
uint256 remainingValue = msg.value - (amount + executorArgs.value);
// Trim any dust.
amount = _trim(decimals, amount);
// Deposit the amount to be transferred into WETH.
weth.deposit{value: amount}();
// Transfer the fee to the referrer.
amount = _payFee(token, decimals, amount, feeArgs);
// Approve the bridge to spend the tokens.
_maxApproveIfNeeded(token, multiTokenNtt, amount);
// Initiate the transfer.
sequence = mtNtt.transfer{value: remainingValue}(
IMultiTokenNtt.TransferArgs(
token, amount, recipientChain, recipient, refundAddress, false, transceiverInstructions, bytes("")
)
);
// Generate the executor event.
executor.requestExecution{value: executorArgs.value}(
recipientChain,
mtNtt.getPeer(recipientChain).peerAddress,
executorArgs.refundAddress,
executorArgs.signedQuote,
ExecutorMessages.makeNTTv1Request(
chainId, bytes32(uint256(uint160(address(mtNtt)))), bytes32(uint256(sequence))
),
executorArgs.instructions
);
// Refund any excess value.
uint256 currentBalance = address(this).balance;
if (currentBalance > 0) {
(bool refundSuccessful,) = payable(executorArgs.refundAddress).call{value: currentBalance}("");
if (!refundSuccessful) {
revert RefundFailed(currentBalance);
}
}
}
// necessary for receiving native assets
receive() external payable {}
// ==================== Internal Functions ==============================================
function _custodyTokens(address token, uint256 amount) internal returns (uint256) {
// query own token balance before transfer
uint256 balanceBefore = _getBalance(token);
// deposit tokens
SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount);
// return the balance difference
return _getBalance(token) - balanceBefore;
}
function _getBalance(address token) internal view returns (uint256 balance) {
// fetch the specified token balance for this contract
(, bytes memory queriedBalance) =
token.staticcall(abi.encodeWithSelector(IERC20.balanceOf.selector, address(this)));
balance = abi.decode(queriedBalance, (uint256));
}
// @dev The fee is calculated as a percentage of the amount being transferred.
function _payFee(address token, uint8 decimals, uint256 amount, FeeArgs calldata feeArgs)
internal
returns (uint256)
{
uint256 fee = calculateFee(amount, feeArgs.dbps);
fee = _trim(decimals, fee);
if (fee > 0) {
// Don't need to check for fee greater than or equal to amount because it can never be (since dbps is a uint16).
amount -= fee;
SafeERC20.safeTransfer(IERC20(token), feeArgs.payee, fee);
}
return amount;
}
function calculateFee(uint256 amount, uint16 dbps) public pure returns (uint256 fee) {
unchecked {
uint256 q = amount / 100000;
uint256 r = amount % 100000;
fee = q * dbps + (r * dbps) / 100000;
}
}
function _trim(uint8 decimals, uint256 amount) internal pure returns (uint256 newFee) {
// The prologue of `MultiTokenNtt` says the number of decimals on the local token
// must match the number of decimals on the foreign token. So using the same value for both.
TrimmedAmount trimmedAmount = amount.trim(decimals, decimals);
newFee = trimmedAmount.untrim(decimals);
}
function _getDecimals(address token) internal view returns (uint8) {
(, bytes memory queriedDecimals) = token.staticcall(abi.encodeWithSignature("decimals()"));
return abi.decode(queriedDecimals, (uint8));
}
/// @dev This is based on what is in the MayanForwarder contract here: https://github.com/mayan-finance/swap-bridge/blob/main/src/MayanForwarder.sol
function _maxApproveIfNeeded(address tokenAddr, address spender, uint256 amount) internal {
IERC20 token = IERC20(tokenAddr);
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < amount) {
SafeERC20.safeApprove(token, spender, 0);
SafeERC20.safeApprove(token, spender, type(uint256).max);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.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");
}
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
interface IExecutor {
struct SignedQuoteHeader {
bytes4 prefix;
address quoterAddress;
bytes32 payeeAddress;
uint16 srcChain;
uint16 dstChain;
uint64 expiryTime;
}
event RequestForExecution(
address indexed quoterAddress,
uint256 amtPaid,
uint16 dstChain,
bytes32 dstAddr,
address refundAddr,
bytes signedQuote,
bytes requestBytes,
bytes relayInstructions
);
function requestExecution(
uint16 dstChain,
bytes32 dstAddr,
address refundAddr,
bytes calldata signedQuote,
bytes calldata requestBytes,
bytes calldata relayInstructions
) external payable;
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
library ExecutorMessages {
bytes4 private constant REQ_MM = "ERM1";
bytes4 private constant REQ_VAA_V1 = "ERV1";
bytes4 private constant REQ_NTT_V1 = "ERN1";
bytes4 private constant REQ_CCTP_V1 = "ERC1";
bytes4 private constant REQ_CCTP_V2 = "ERC2";
/// @notice Payload length will not fit in a uint32.
/// @dev Selector: 492f620d.
error PayloadTooLarge();
/// @notice Encodes a modular messaging request payload.
/// @param srcChain The source chain for the message (usually this chain).
/// @param srcAddr The source address for the message.
/// @param sequence The sequence number returned by `endpoint.sendMessage`.
/// @param payload The full payload, the keccak of which was sent to `endpoint.sendMessage`.
/// @return bytes The encoded request.
function makeMMRequest(uint16 srcChain, address srcAddr, uint64 sequence, bytes memory payload)
internal
pure
returns (bytes memory)
{
if (payload.length > type(uint32).max) {
revert PayloadTooLarge();
}
return abi.encodePacked(
REQ_MM, srcChain, bytes32(uint256(uint160(srcAddr))), sequence, uint32(payload.length), payload
);
}
/// @notice Encodes a version 1 VAA request payload.
/// @param emitterChain The emitter chain from the VAA.
/// @param emitterAddress The emitter address from the VAA.
/// @param sequence The sequence number from the VAA.
/// @return bytes The encoded request.
function makeVAAv1Request(uint16 emitterChain, bytes32 emitterAddress, uint64 sequence)
internal
pure
returns (bytes memory)
{
return abi.encodePacked(REQ_VAA_V1, emitterChain, emitterAddress, sequence);
}
/// @notice Encodes a version 1 NTT request payload.
/// @param srcChain The source chain for the NTT transfer.
/// @param srcManager The source manager for the NTT transfer.
/// @param messageId The manager message id for the NTT transfer.
/// @return bytes The encoded request.
function makeNTTv1Request(uint16 srcChain, bytes32 srcManager, bytes32 messageId)
internal
pure
returns (bytes memory)
{
return abi.encodePacked(REQ_NTT_V1, srcChain, srcManager, messageId);
}
/// @notice Encodes a version 1 CCTP request payload.
/// @param sourceDomain The source chain for the CCTP transfer.
/// @param nonce The nonce of the CCTP transfer.
/// @return bytes The encoded request.
function makeCCTPv1Request(uint32 sourceDomain, uint64 nonce) internal pure returns (bytes memory) {
return abi.encodePacked(REQ_CCTP_V1, sourceDomain, nonce);
}
/// @notice Encodes a version 2 CCTP request payload.
/// This request currently assumes the Executor will auto detect the event off chain.
/// That may change in the future, in which case this interface would change.
/// @return bytes The encoded request.
function makeCCTPv2Request() internal pure returns (bytes memory) {
return abi.encodePacked(REQ_CCTP_V2, uint8(1));
}
}// SPDX-License-Identifier: Apache 2
/// @dev TrimmedAmount is a utility library to handle token amounts with different decimals
pragma solidity >=0.8.8 <0.9.0;
import "openzeppelin-contracts/contracts/utils/math/SafeCast.sol";
/// @dev TrimmedAmount is a bit-packed representation of a token amount and its decimals.
/// @dev 64 bits: [0 - 64] amount
/// @dev 8 bits: [64 - 72] decimals
type TrimmedAmount is uint72;
using {gt as >, lt as <, sub as -, add as +, eq as ==, min, unwrap} for TrimmedAmount global;
function minUint8(uint8 a, uint8 b) pure returns (uint8) {
return a < b ? a : b;
}
/// @notice Error when the decimals of two TrimmedAmounts are not equal
/// @dev Selector. b9cdb6c2
/// @param decimals the decimals of the first TrimmedAmount
/// @param decimalsOther the decimals of the second TrimmedAmount
error NumberOfDecimalsNotEqual(uint8 decimals, uint8 decimalsOther);
uint8 constant TRIMMED_DECIMALS = 8;
function unwrap(
TrimmedAmount a
) pure returns (uint72) {
return TrimmedAmount.unwrap(a);
}
function packTrimmedAmount(uint64 amt, uint8 decimals) pure returns (TrimmedAmount) {
// cast to u72 first to prevent overflow
uint72 amount = uint72(amt);
uint72 dec = uint72(decimals);
// shift the amount to the left 8 bits
amount <<= 8;
return TrimmedAmount.wrap(amount | dec);
}
function eq(TrimmedAmount a, TrimmedAmount b) pure returns (bool) {
return TrimmedAmountLib.getAmount(a) == TrimmedAmountLib.getAmount(b)
&& TrimmedAmountLib.getDecimals(a) == TrimmedAmountLib.getDecimals(b);
}
function checkDecimals(TrimmedAmount a, TrimmedAmount b) pure {
uint8 aDecimals = TrimmedAmountLib.getDecimals(a);
uint8 bDecimals = TrimmedAmountLib.getDecimals(b);
if (aDecimals != bDecimals) {
revert NumberOfDecimalsNotEqual(aDecimals, bDecimals);
}
}
function gt(TrimmedAmount a, TrimmedAmount b) pure returns (bool) {
checkDecimals(a, b);
return TrimmedAmountLib.getAmount(a) > TrimmedAmountLib.getAmount(b);
}
function lt(TrimmedAmount a, TrimmedAmount b) pure returns (bool) {
checkDecimals(a, b);
return TrimmedAmountLib.getAmount(a) < TrimmedAmountLib.getAmount(b);
}
function sub(TrimmedAmount a, TrimmedAmount b) pure returns (TrimmedAmount) {
checkDecimals(a, b);
return packTrimmedAmount(
TrimmedAmountLib.getAmount(a) - TrimmedAmountLib.getAmount(b),
TrimmedAmountLib.getDecimals(a)
);
}
function add(TrimmedAmount a, TrimmedAmount b) pure returns (TrimmedAmount) {
checkDecimals(a, b);
return packTrimmedAmount(
TrimmedAmountLib.getAmount(a) + TrimmedAmountLib.getAmount(b),
TrimmedAmountLib.getDecimals(b)
);
}
function min(TrimmedAmount a, TrimmedAmount b) pure returns (TrimmedAmount) {
checkDecimals(a, b);
return TrimmedAmountLib.getAmount(a) < TrimmedAmountLib.getAmount(b) ? a : b;
}
library TrimmedAmountLib {
/// @notice Error when the amount to be trimmed is greater than u64MAX.
/// @dev Selector 0x08083b2a.
/// @param amount The amount to be trimmed.
error AmountTooLarge(uint256 amount);
function getAmount(
TrimmedAmount a
) internal pure returns (uint64) {
// Extract the raw integer value from TrimmedAmount
uint72 rawValue = TrimmedAmount.unwrap(a);
// Right shift to keep only the higher 64 bits
uint64 result = uint64(rawValue >> 8);
return result;
}
function getDecimals(
TrimmedAmount a
) internal pure returns (uint8) {
return uint8(TrimmedAmount.unwrap(a) & 0xFF);
}
/// @dev Set the decimals of the TrimmedAmount.
/// This function should only be used for testing purposes, as it
/// should not be necessary to change the decimals of a TrimmedAmount
/// under normal circumstances.
function setDecimals(TrimmedAmount a, uint8 decimals) internal pure returns (TrimmedAmount) {
return TrimmedAmount.wrap((TrimmedAmount.unwrap(a) & ~uint72(0xFF)) | decimals);
}
function isNull(
TrimmedAmount a
) internal pure returns (bool) {
return (getAmount(a) == 0 && getDecimals(a) == 0);
}
function saturatingAdd(
TrimmedAmount a,
TrimmedAmount b
) internal pure returns (TrimmedAmount) {
checkDecimals(a, b);
uint256 saturatedSum;
uint64 aAmount = getAmount(a);
uint64 bAmount = getAmount(b);
unchecked {
saturatedSum = uint256(aAmount) + uint256(bAmount);
saturatedSum = saturatedSum > type(uint64).max ? type(uint64).max : saturatedSum;
}
return packTrimmedAmount(SafeCast.toUint64(saturatedSum), getDecimals(a));
}
/// @dev scale the amount from original decimals to target decimals (base 10)
function scale(
uint256 amount,
uint8 fromDecimals,
uint8 toDecimals
) internal pure returns (uint256) {
if (fromDecimals == toDecimals) {
return amount;
}
if (fromDecimals > toDecimals) {
return amount / (10 ** (fromDecimals - toDecimals));
} else {
return amount * (10 ** (toDecimals - fromDecimals));
}
}
function shift(TrimmedAmount amount, uint8 toDecimals) internal pure returns (TrimmedAmount) {
uint8 actualToDecimals = minUint8(TRIMMED_DECIMALS, toDecimals);
return packTrimmedAmount(
SafeCast.toUint64(scale(getAmount(amount), getDecimals(amount), actualToDecimals)),
actualToDecimals
);
}
function max(
uint8 decimals
) internal pure returns (TrimmedAmount) {
uint8 actualDecimals = minUint8(TRIMMED_DECIMALS, decimals);
return packTrimmedAmount(type(uint64).max, actualDecimals);
}
/// @dev trim the amount to target decimals.
/// The actual resulting decimals is the minimum of TRIMMED_DECIMALS,
/// fromDecimals, and toDecimals. This ensures that no dust is
/// destroyed on either side of the transfer.
/// @param amt the amount to be trimmed
/// @param fromDecimals the original decimals of the amount
/// @param toDecimals the target decimals of the amount
/// @return TrimmedAmount uint72 value type bit-packed with decimals
function trim(
uint256 amt,
uint8 fromDecimals,
uint8 toDecimals
) internal pure returns (TrimmedAmount) {
uint8 actualToDecimals = minUint8(minUint8(TRIMMED_DECIMALS, fromDecimals), toDecimals);
uint256 amountScaled = scale(amt, fromDecimals, actualToDecimals);
// NOTE: amt after trimming must fit into uint64 (that's the point of
// trimming, as Solana only supports uint64 for token amts)
return packTrimmedAmount(SafeCast.toUint64(amountScaled), actualToDecimals);
}
function untrim(TrimmedAmount amt, uint8 toDecimals) internal pure returns (uint256) {
uint256 deNorm = uint256(getAmount(amt));
uint8 fromDecimals = getDecimals(amt);
uint256 amountScaled = scale(deNorm, fromDecimals, toDecimals);
return amountScaled;
}
}// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.17;
import "./IWETH.sol";
/// @notice This is based on the Monad Bridge MultiTokenNtt contract as defined here: https://github.com/wormholelabs-xyz/Monad-Bridge/blob/multi-token/evm/src/MultiTokenNtt/MultiTokenNtt.sol
/// We only define what is used by `MultiTokenNttWithExecutor`.
interface IMultiTokenNtt {
/// @notice Transfer tokens to another chain with comprehensive parameter support
struct TransferArgs {
address token;
uint256 amount;
uint16 recipientChain;
bytes32 recipient;
bytes32 refundAddress;
bool shouldQueue;
bytes transceiverInstructions;
bytes additionalPayload;
}
function transfer(TransferArgs memory args) external payable returns (uint64);
struct Peer {
bytes32 peerAddress;
}
function getPeer(uint16 chainId_) external view returns (Peer memory);
function WETH() external returns (IWETH);
}// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.19;
struct ExecutorArgs {
// The msg value to be passed into the Executor.
uint256 value;
// The refund address used by the Executor.
address refundAddress;
// The signed quote to be passed into the Executor.
bytes signedQuote;
// The relay instructions to be passed into the Executor.
bytes instructions;
}
struct FeeArgs {
// The fee in tenths of basis points.
uint16 dbps;
// To whom the fee should be paid (the "referrer").
address payee;
}
interface IMultiTokenNttWithExecutor {
/// @notice Error when the refund to the sender fails.
/// @dev Selector 0x2ca23714.
/// @param refundAmount The refund amount.
error RefundFailed(uint256 refundAmount);
function transfer(
address multiTokenNtt,
address token,
uint256 amount,
uint16 recipientChain,
bytes32 recipient,
bytes32 refundAddress,
bytes memory transceiverInstructions,
ExecutorArgs calldata executorArgs,
FeeArgs calldata feeArgs
) external payable returns (uint64);
function transferETH(
address multiTokenNtt,
uint256 amount,
uint16 recipientChain,
bytes32 recipient,
bytes32 refundAddress,
bytes memory transceiverInstructions,
ExecutorArgs calldata executorArgs,
FeeArgs calldata feeArgs
) external payable returns (uint64);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @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);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.17;
import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
interface IWETH is IERC20 {
function deposit() external payable;
function transfer(address to, uint256 value) external returns (bool);
function withdraw(uint256) external;
}{
"remappings": [
"ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
"example-messaging-executor/=lib/example-messaging-executor/",
"forge-std/=lib/forge-std/src/",
"native-token-transfers/=lib/native-token-transfers/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"solidity-bytes-utils/=lib/native-token-transfers/evm/lib/solidity-bytes-utils/contracts/",
"wormhole-solidity-sdk/=lib/native-token-transfers/evm/lib/wormhole-solidity-sdk/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"viaIR": true
}Contract ABI
API[{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"_executor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"refundAmount","type":"uint256"}],"name":"RefundFailed","type":"error"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint16","name":"dbps","type":"uint16"}],"name":"calculateFee","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"executor","outputs":[{"internalType":"contract IExecutor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"multiTokenNtt","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint16","name":"recipientChain","type":"uint16"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"refundAddress","type":"bytes32"},{"internalType":"bytes","name":"transceiverInstructions","type":"bytes"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"},{"internalType":"bytes","name":"signedQuote","type":"bytes"},{"internalType":"bytes","name":"instructions","type":"bytes"}],"internalType":"struct ExecutorArgs","name":"executorArgs","type":"tuple"},{"components":[{"internalType":"uint16","name":"dbps","type":"uint16"},{"internalType":"address","name":"payee","type":"address"}],"internalType":"struct FeeArgs","name":"feeArgs","type":"tuple"}],"name":"transfer","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"multiTokenNtt","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint16","name":"recipientChain","type":"uint16"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"refundAddress","type":"bytes32"},{"internalType":"bytes","name":"transceiverInstructions","type":"bytes"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"},{"internalType":"bytes","name":"signedQuote","type":"bytes"},{"internalType":"bytes","name":"instructions","type":"bytes"}],"internalType":"struct ExecutorArgs","name":"executorArgs","type":"tuple"},{"components":[{"internalType":"uint16","name":"dbps","type":"uint16"},{"internalType":"address","name":"payee","type":"address"}],"internalType":"struct FeeArgs","name":"feeArgs","type":"tuple"}],"name":"transferETH","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60c0346100b457601f61146138819003918201601f19168301916001600160401b038311848410176100b95780849260409485528339810103126100b457805161ffff8116918282036100b457602001516001600160a01b03811692908390036100b45761006e9015156100cf565b6100798215156100cf565b60805260a05260405161137490816100ed82396080518181816103b701526106ad015260a05181818160e60152818161034001526108b80152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b156100d657565b634e487b7160e01b600052600160045260246000fdfe6080604052600436101561001b575b361561001957600080fd5b005b6000803560e01c80630fed70a214610a51578063924105c3146106d15780639a8a059214610692578063be2fa91014610115578063c34c08e5146100d05763ffa1ad7414610069575061000e565b346100cd57806003193601126100cd57506100c960405161008b604082610ae7565b601f81527f4d756c7469546f6b656e4e7474576974684578656375746f722d302e302e31006020820152604051918291602083526020830190610b6a565b0390f35b80fd5b50346100cd57806003193601126100cd576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b506101203660031901126100cd5761012b610a9a565b906024356044359161ffff83168084036104935760a4356001600160401b03811161068e5761015e903690600401610b23565b9360c435916001600160401b03831161068a578260040191608060031985360301126106865760403660e3190112610686576040516315ab88c960e31b81526001600160a01b03891696906020816004818a8c5af190811561050d578791610640575b506001600160a01b0316978815610605576101db89610d9a565b988535926101e98482610d8d565b34106105c9576102278b610211818061020b6102058a88610d8d565b34610bab565b95611067565b6001600160401b0360ff82169160081c1661122f565b823b156105ba57604051630d0e30db60e41b81528a8160048185885af180156105be57908b916105a5575b5050809b60e43561ffff811681036104a25790610211818061028961028e95879061ffff16620186a0808281850602049204020190565b611067565b9081610518575b50506102ab8b809d6103159a9b9c9d5084610dea565b60209b8c93604051916102be8684610ae7565b8c8352604051946102ce86610ab5565b855285850152876040850152606435606085015260843560808501528b60a085015260c084015260e083015260405180809981946329185d6160e21b835260048301610bed565b03918c5af194851561050d5787956104de575b50604051630c128d1760e41b815260048101939093527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169289816024818c5afa9081156104d35788916104a6575b50519160248701966001600160401b036103e361039b8a610ca0565b9760646103db6103ae6044870184610cb4565b95909c169e8f907f0000000000000000000000000000000000000000000000000000000000000000610fdb565b940190610cb4565b929091873b156104a257918b98979695949391610417936040519b8c9a8b998a9863c513d43760e01b8a5260048a01610d07565b03925af180156104975790839161047e575b505047908161043e575b505050604051908152f35b82808084819461045460018060a01b0391610ca0565b165af161045f610d5d565b501561046b5780610433565b630b288dc560e21b825260045260249150fd5b8161048891610ae7565b610493578138610429565b5080fd5b6040513d85823e3d90fd5b8b80fd5b6104c691508a3d8c116104cc575b6104be8183610ae7565b810190610c72565b3861037f565b503d6104b4565b6040513d8a823e3d90fd5b6104ff919550893d8b11610506575b6104f78183610ae7565b810190610bce565b9338610328565b503d6104ed565b6040513d89823e3d90fd5b819c509061052591610bab565b9a610104356001600160a01b03811681036105a15760405163a9059cbb60e01b60208201526001600160a01b03909116602482015260448101919091529a9b999a98999798610315986102ab918e91906105969061059081606481015b03601f198101835282610ae7565b86611122565b9d9c9b9a9950610295565b8a80fd5b816105af91610ae7565b6105ba578938610252565b8980fd5b6040513d8d823e3d90fd5b60405162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f756768206d73672076616c756560601b6044820152606490fd5b60405162461bcd60e51b815260206004820152601360248201527215d1551208191bd95cc81b9bdd08195e1a5cdd606a1b6044820152606490fd5b90506020813d60201161067e575b8161065b60209383610ae7565b8101031261067a57516001600160a01b038116810361067a57386101c1565b8680fd5b3d915061064e565b8480fd5b8380fd5b8280fd5b50346100cd57806003193601126100cd57602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b506101403660031901126100cd576106e7610a9a565b602435916001600160a01b038316908184036100cd576064359061ffff8216928383036104935760c4356001600160401b03811161068e5761072d903690600401610b23565b9360e435936001600160401b03851161068a5784600401926080600319873603011261068657604036610103190112610686576001600160a01b038816966107748a610d9a565b986107c56107818c611017565b6107b76040516323b872dd60e01b6020820152336024820152306044820152604435606482015260648152610590608482610ae7565b6107c08d611017565b610bab565b996101043561ffff81168103610a4d579061021181806102898f956107fb969061ffff16620186a0808281850602049204020190565b806109cc575b508961081691819c61088d999a9b9c50610dea565b8435916108238334610bab565b60209b8c93604051916108368684610ae7565b8b83526040519461084686610ab5565b855285850152876040850152608435606085015260a43560808501528a60a085015260c084015260e083015260405180809981946329185d6160e21b835260048301610bed565b03918c5af19485156109c15786956109a2575b50604051630c128d1760e41b815260048101939093527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169289816024818c5afa90811561050d578791610985575b50519160248801976001600160401b0361091361039b8b610ca0565b929091873b156105a157918a98979695949391610947936040519b8c9a8b998a9863c513d43760e01b8a5260048a01610d07565b03925af1801561097a5761096a575b509047908161043e57505050604051908152f35b8161097491610ae7565b38610956565b6040513d84823e3d90fd5b61099c91508a3d8c116104cc576104be8183610ae7565b386108f7565b6109ba919550893d8b11610506576104f78183610ae7565b93386108a0565b6040513d88823e3d90fd5b998a6109d791610bab565b99610124356001600160a01b0381168103610a4d5760405163a9059cbb60e01b60208201526001600160a01b0390911660248201526044810191909152999a98999798969761088d97610816928d92909190610a4090610a3a8160648101610582565b87611122565b9c9b9a9998509150610801565b8880fd5b50346100cd5760403660031901126100cd576024359061ffff821682036100cd576020610a92836004359061ffff16620186a0808281850602049204020190565b604051908152f35b600435906001600160a01b0382168203610ab057565b600080fd5b61010081019081106001600160401b03821117610ad157604052565b634e487b7160e01b600052604160045260246000fd5b90601f801991011681019081106001600160401b03821117610ad157604052565b6001600160401b038111610ad157601f01601f191660200190565b81601f82011215610ab057803590610b3a82610b08565b92610b486040519485610ae7565b82845260208383010111610ab057816000926020809301838601378301015290565b919082519283825260005b848110610b96575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201610b75565b91908203918211610bb857565b634e487b7160e01b600052601160045260246000fd5b90816020910312610ab057516001600160401b0381168103610ab05790565b90610c6f916020815260018060a01b0382511660208201526020820151604082015261ffff604083015116606082015260608201516080820152608082015160a082015260a0820151151560c082015260e0610c5960c084015161010083850152610120840190610b6a565b92015190610100601f1982850301910152610b6a565b90565b90816020910312610ab05760405190602082018281106001600160401b03821117610ad15760405251815290565b356001600160a01b0381168103610ab05790565b903590601e1981360301821215610ab057018035906001600160401b038211610ab057602001918136038313610ab057565b908060209392818452848401376000828201840152601f01601f1916010190565b9694610c6f989693610d419361ffff610d4f9794168a5260208a015260018060a01b0316604089015260c0606089015260c0880191610ce6565b908582036080870152610b6a565b9260a0818503910152610ce6565b3d15610d88573d90610d6e82610b08565b91610d7c6040519384610ae7565b82523d6000602084013e565b606090565b91908201809211610bb857565b60008091604051602081019063313ce56760e01b825260048152610dbf602482610ae7565b51915afa50610dcc610d5d565b602081805181010312610ab0576020015160ff81168103610ab05790565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301529190911692602082604481875afa8015610fcf576000928391610f9d575b5010610e3657505050565b5060405163095ea7b360e01b60208201526001600160a01b03821660248201819052600060448084019190915282529190610e7c90610e76606482610ae7565b84611122565b604051636eb1769f60e11b81523060048201526001600160a01b03919091166024820152600090602081604481875afa918215610f91578092610f5c575b5050610ef857610ef6916040519163095ea7b360e01b60208401526024830152600019604483015260448252610ef1606483610ae7565b611122565b565b60405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608490fd5b9091506020823d602011610f89575b81610f7860209383610ae7565b810103126100cd5750513880610eba565b3d9150610f6b565b604051903d90823e3d90fd5b90506020813d602011610fc7575b81610fb860209383610ae7565b8101031261068e575138610e2b565b3d9150610fab565b6040513d6000823e3d90fd5b9190604051926345524e3160e01b602085015261ffff60f01b9060f01b1660248401526026830152604682015260468152610c6f606682610ae7565b6000809160405160208101906370a0823160e01b825230602482015260248152611042604482610ae7565b51915afa5061104f610d5d565b60208151918180820193849201010312610ab0575190565b611097919260ff841660081060001461111b576008905b60ff811660ff831610600014611111575092839161122f565b906001600160401b0382116110bd5760ff68ffffffffffffffff0091169160081b161790565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608490fd5b905092839161122f565b839061107e565b604080519092611187926001600160a01b03169060009081906111458786610ae7565b602085527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564602086015260208151910182855af1611181610d5d565b916112a1565b80518061119357505050565b8160209181010312610ab05760200151801590811503610ab0576111b45750565b5162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b9060ff8091169116039060ff8211610bb857565b60ff16604d8111610bb857600a0a90565b919060ff821660ff821681811461129a57111561127957611258916112539161120a565b61121e565b908115611263570490565b634e487b7160e01b600052601260045260246000fd5b611253906112869261120a565b90818102918183041490151715610bb85790565b5050505090565b9192901561130357508151156112b5575090565b3b156112be5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156113165750805190602001fd5b60405162461bcd60e51b81526020600482015290819061133a906024830190610b6a565b0390fdfea264697066735822122067d4d22d723954e2140f731b0a94c823f4a7f092172f707777021c43381dec3e64736f6c634300081c00330000000000000000000000000000000000000000000000000000000000002712000000000000000000000000d0fb39f5a3361f21457653cb70f9d0c9bd86b66b
Deployed Bytecode
0x6080604052600436101561001b575b361561001957600080fd5b005b6000803560e01c80630fed70a214610a51578063924105c3146106d15780639a8a059214610692578063be2fa91014610115578063c34c08e5146100d05763ffa1ad7414610069575061000e565b346100cd57806003193601126100cd57506100c960405161008b604082610ae7565b601f81527f4d756c7469546f6b656e4e7474576974684578656375746f722d302e302e31006020820152604051918291602083526020830190610b6a565b0390f35b80fd5b50346100cd57806003193601126100cd576040517f000000000000000000000000d0fb39f5a3361f21457653cb70f9d0c9bd86b66b6001600160a01b03168152602090f35b506101203660031901126100cd5761012b610a9a565b906024356044359161ffff83168084036104935760a4356001600160401b03811161068e5761015e903690600401610b23565b9360c435916001600160401b03831161068a578260040191608060031985360301126106865760403660e3190112610686576040516315ab88c960e31b81526001600160a01b03891696906020816004818a8c5af190811561050d578791610640575b506001600160a01b0316978815610605576101db89610d9a565b988535926101e98482610d8d565b34106105c9576102278b610211818061020b6102058a88610d8d565b34610bab565b95611067565b6001600160401b0360ff82169160081c1661122f565b823b156105ba57604051630d0e30db60e41b81528a8160048185885af180156105be57908b916105a5575b5050809b60e43561ffff811681036104a25790610211818061028961028e95879061ffff16620186a0808281850602049204020190565b611067565b9081610518575b50506102ab8b809d6103159a9b9c9d5084610dea565b60209b8c93604051916102be8684610ae7565b8c8352604051946102ce86610ab5565b855285850152876040850152606435606085015260843560808501528b60a085015260c084015260e083015260405180809981946329185d6160e21b835260048301610bed565b03918c5af194851561050d5787956104de575b50604051630c128d1760e41b815260048101939093527f000000000000000000000000d0fb39f5a3361f21457653cb70f9d0c9bd86b66b6001600160a01b03169289816024818c5afa9081156104d35788916104a6575b50519160248701966001600160401b036103e361039b8a610ca0565b9760646103db6103ae6044870184610cb4565b95909c169e8f907f0000000000000000000000000000000000000000000000000000000000002712610fdb565b940190610cb4565b929091873b156104a257918b98979695949391610417936040519b8c9a8b998a9863c513d43760e01b8a5260048a01610d07565b03925af180156104975790839161047e575b505047908161043e575b505050604051908152f35b82808084819461045460018060a01b0391610ca0565b165af161045f610d5d565b501561046b5780610433565b630b288dc560e21b825260045260249150fd5b8161048891610ae7565b610493578138610429565b5080fd5b6040513d85823e3d90fd5b8b80fd5b6104c691508a3d8c116104cc575b6104be8183610ae7565b810190610c72565b3861037f565b503d6104b4565b6040513d8a823e3d90fd5b6104ff919550893d8b11610506575b6104f78183610ae7565b810190610bce565b9338610328565b503d6104ed565b6040513d89823e3d90fd5b819c509061052591610bab565b9a610104356001600160a01b03811681036105a15760405163a9059cbb60e01b60208201526001600160a01b03909116602482015260448101919091529a9b999a98999798610315986102ab918e91906105969061059081606481015b03601f198101835282610ae7565b86611122565b9d9c9b9a9950610295565b8a80fd5b816105af91610ae7565b6105ba578938610252565b8980fd5b6040513d8d823e3d90fd5b60405162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f756768206d73672076616c756560601b6044820152606490fd5b60405162461bcd60e51b815260206004820152601360248201527215d1551208191bd95cc81b9bdd08195e1a5cdd606a1b6044820152606490fd5b90506020813d60201161067e575b8161065b60209383610ae7565b8101031261067a57516001600160a01b038116810361067a57386101c1565b8680fd5b3d915061064e565b8480fd5b8380fd5b8280fd5b50346100cd57806003193601126100cd57602060405161ffff7f0000000000000000000000000000000000000000000000000000000000002712168152f35b506101403660031901126100cd576106e7610a9a565b602435916001600160a01b038316908184036100cd576064359061ffff8216928383036104935760c4356001600160401b03811161068e5761072d903690600401610b23565b9360e435936001600160401b03851161068a5784600401926080600319873603011261068657604036610103190112610686576001600160a01b038816966107748a610d9a565b986107c56107818c611017565b6107b76040516323b872dd60e01b6020820152336024820152306044820152604435606482015260648152610590608482610ae7565b6107c08d611017565b610bab565b996101043561ffff81168103610a4d579061021181806102898f956107fb969061ffff16620186a0808281850602049204020190565b806109cc575b508961081691819c61088d999a9b9c50610dea565b8435916108238334610bab565b60209b8c93604051916108368684610ae7565b8b83526040519461084686610ab5565b855285850152876040850152608435606085015260a43560808501528a60a085015260c084015260e083015260405180809981946329185d6160e21b835260048301610bed565b03918c5af19485156109c15786956109a2575b50604051630c128d1760e41b815260048101939093527f000000000000000000000000d0fb39f5a3361f21457653cb70f9d0c9bd86b66b6001600160a01b03169289816024818c5afa90811561050d578791610985575b50519160248801976001600160401b0361091361039b8b610ca0565b929091873b156105a157918a98979695949391610947936040519b8c9a8b998a9863c513d43760e01b8a5260048a01610d07565b03925af1801561097a5761096a575b509047908161043e57505050604051908152f35b8161097491610ae7565b38610956565b6040513d84823e3d90fd5b61099c91508a3d8c116104cc576104be8183610ae7565b386108f7565b6109ba919550893d8b11610506576104f78183610ae7565b93386108a0565b6040513d88823e3d90fd5b998a6109d791610bab565b99610124356001600160a01b0381168103610a4d5760405163a9059cbb60e01b60208201526001600160a01b0390911660248201526044810191909152999a98999798969761088d97610816928d92909190610a4090610a3a8160648101610582565b87611122565b9c9b9a9998509150610801565b8880fd5b50346100cd5760403660031901126100cd576024359061ffff821682036100cd576020610a92836004359061ffff16620186a0808281850602049204020190565b604051908152f35b600435906001600160a01b0382168203610ab057565b600080fd5b61010081019081106001600160401b03821117610ad157604052565b634e487b7160e01b600052604160045260246000fd5b90601f801991011681019081106001600160401b03821117610ad157604052565b6001600160401b038111610ad157601f01601f191660200190565b81601f82011215610ab057803590610b3a82610b08565b92610b486040519485610ae7565b82845260208383010111610ab057816000926020809301838601378301015290565b919082519283825260005b848110610b96575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201610b75565b91908203918211610bb857565b634e487b7160e01b600052601160045260246000fd5b90816020910312610ab057516001600160401b0381168103610ab05790565b90610c6f916020815260018060a01b0382511660208201526020820151604082015261ffff604083015116606082015260608201516080820152608082015160a082015260a0820151151560c082015260e0610c5960c084015161010083850152610120840190610b6a565b92015190610100601f1982850301910152610b6a565b90565b90816020910312610ab05760405190602082018281106001600160401b03821117610ad15760405251815290565b356001600160a01b0381168103610ab05790565b903590601e1981360301821215610ab057018035906001600160401b038211610ab057602001918136038313610ab057565b908060209392818452848401376000828201840152601f01601f1916010190565b9694610c6f989693610d419361ffff610d4f9794168a5260208a015260018060a01b0316604089015260c0606089015260c0880191610ce6565b908582036080870152610b6a565b9260a0818503910152610ce6565b3d15610d88573d90610d6e82610b08565b91610d7c6040519384610ae7565b82523d6000602084013e565b606090565b91908201809211610bb857565b60008091604051602081019063313ce56760e01b825260048152610dbf602482610ae7565b51915afa50610dcc610d5d565b602081805181010312610ab0576020015160ff81168103610ab05790565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301529190911692602082604481875afa8015610fcf576000928391610f9d575b5010610e3657505050565b5060405163095ea7b360e01b60208201526001600160a01b03821660248201819052600060448084019190915282529190610e7c90610e76606482610ae7565b84611122565b604051636eb1769f60e11b81523060048201526001600160a01b03919091166024820152600090602081604481875afa918215610f91578092610f5c575b5050610ef857610ef6916040519163095ea7b360e01b60208401526024830152600019604483015260448252610ef1606483610ae7565b611122565b565b60405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608490fd5b9091506020823d602011610f89575b81610f7860209383610ae7565b810103126100cd5750513880610eba565b3d9150610f6b565b604051903d90823e3d90fd5b90506020813d602011610fc7575b81610fb860209383610ae7565b8101031261068e575138610e2b565b3d9150610fab565b6040513d6000823e3d90fd5b9190604051926345524e3160e01b602085015261ffff60f01b9060f01b1660248401526026830152604682015260468152610c6f606682610ae7565b6000809160405160208101906370a0823160e01b825230602482015260248152611042604482610ae7565b51915afa5061104f610d5d565b60208151918180820193849201010312610ab0575190565b611097919260ff841660081060001461111b576008905b60ff811660ff831610600014611111575092839161122f565b906001600160401b0382116110bd5760ff68ffffffffffffffff0091169160081b161790565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608490fd5b905092839161122f565b839061107e565b604080519092611187926001600160a01b03169060009081906111458786610ae7565b602085527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564602086015260208151910182855af1611181610d5d565b916112a1565b80518061119357505050565b8160209181010312610ab05760200151801590811503610ab0576111b45750565b5162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b9060ff8091169116039060ff8211610bb857565b60ff16604d8111610bb857600a0a90565b919060ff821660ff821681811461129a57111561127957611258916112539161120a565b61121e565b908115611263570490565b634e487b7160e01b600052601260045260246000fd5b611253906112869261120a565b90818102918183041490151715610bb85790565b5050505090565b9192901561130357508151156112b5575090565b3b156112be5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156113165750805190602001fd5b60405162461bcd60e51b81526020600482015290819061133a906024830190610b6a565b0390fdfea264697066735822122067d4d22d723954e2140f731b0a94c823f4a7f092172f707777021c43381dec3e64736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000002712000000000000000000000000d0fb39f5a3361f21457653cb70f9d0c9bd86b66b
-----Decoded View---------------
Arg [0] : _chainId (uint16): 10002
Arg [1] : _executor (address): 0xD0fb39f5a3361F21457653cB70F9D0C9bD86B66B
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000002712
Arg [1] : 000000000000000000000000d0fb39f5a3361f21457653cb70f9d0c9bd86b66b
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.