Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 35331885 | 38 days ago | 0 ETH | |||||
| 35313325 | 39 days ago | 0 ETH | |||||
| 35305416 | 39 days ago | 0 ETH | |||||
| 35299402 | 39 days ago | 0 ETH | |||||
| 35295118 | 39 days ago | 0 ETH | |||||
| 35292078 | 39 days ago | 0 ETH | |||||
| 35262018 | 39 days ago | 0 ETH | |||||
| 35258959 | 39 days ago | 0 ETH | |||||
| 35250153 | 39 days ago | 0 ETH | |||||
| 35247191 | 39 days ago | 0 ETH | |||||
| 35241424 | 39 days ago | 0 ETH | |||||
| 35237897 | 40 days ago | 0 ETH | |||||
| 35229201 | 40 days ago | 0 ETH | |||||
| 35208168 | 40 days ago | 0 ETH | |||||
| 35204562 | 40 days ago | 0 ETH | |||||
| 35165152 | 40 days ago | 0 ETH | |||||
| 35161762 | 40 days ago | 0 ETH | |||||
| 35159098 | 40 days ago | 0 ETH | |||||
| 35151941 | 41 days ago | 0 ETH | |||||
| 35144191 | 41 days ago | 0 ETH | |||||
| 35135997 | 41 days ago | 0 ETH | |||||
| 35132551 | 41 days ago | 0 ETH | |||||
| 35125784 | 41 days ago | 0 ETH | |||||
| 35121935 | 41 days ago | 0 ETH | |||||
| 35083682 | 41 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PheasantNetworkCctpBurn
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 30 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
import { ITokenMessenger } from "./ITokenMessenger.sol";
import { Types } from "../libraries/types/Types.sol";
import { Lib_DefaultValues } from "../libraries/constants/Lib_DefaultValues.sol";
import "solmate/src/utils/SafeTransferLib.sol";
import "solmate/src/tokens/ERC20.sol";
import "solmate/src/auth/Owned.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
contract PheasantNetworkCctpBurn is Initializable, OwnableUpgradeable {
event DepositForBurnCalled(
address indexed sender,
bytes32 indexed recipient,
uint32 indexed destinationDomain,
uint256 index,
uint256 amount,
address token,
uint256 originalAmount
);
event FeeRateUpdateRequested(uint32 indexed destinationDomain, uint256 newRatePpm, uint64 executeAfter);
event FeeRateUpdated(uint32 indexed destinationDomain, uint256 newRatePpm);
/*************
* Variables *
*************/
ITokenMessenger internal tokenMessenger;
address public relayer;
bool internal isActive;
ERC20 internal token;
Types.UserCCTPTrade[] public userTradeList;
uint256 public constant FEE_DENOMINATOR = 1_000_000; // 100 % = 1,000,000 (ppm)
/************
* Mappings *
************/
mapping(address => Types.CCTPTrade[]) internal trades;
mapping(uint32 => uint256) public feeRates; // domain -> ppm
mapping(uint32 => Types.CctpFeeUpdate) public cctpFeeUpdates; // pending update
/**
* @notice Contract constructor
* @param _tokenMessenger Address of the Circle CCTP TokenMessenger contract
* @param _newOwner Address of the initial owner/relayer
* @param _destinationDomains Array of destination domain IDs to initialize fee rates for
* @param _initialFeeRatesPpm Array of initial fee rates in ppm for the corresponding domains
*/
function initialize(
address _tokenMessenger,
address _newOwner,
uint32[] memory _destinationDomains,
uint256[] memory _initialFeeRatesPpm
) public initializer {
_transferOwnership(_newOwner); // Set initial owner
require(_destinationDomains.length == _initialFeeRatesPpm.length, "Input arrays must have the same length");
tokenMessenger = ITokenMessenger(_tokenMessenger);
relayer = _newOwner;
isActive = true;
for (uint256 i = 0; i < _destinationDomains.length; i++) {
uint32 domain = _destinationDomains[i];
uint256 rate = _initialFeeRatesPpm[i];
require(rate < FEE_DENOMINATOR, "Initial rate too high");
feeRates[domain] = rate;
// Emit event for initial setup?
// emit FeeRateUpdated(domain, rate); // Consider if initial setup should emit events
}
}
/**********************
* internal functions *
**********************
*/
function withdrawFee(address tokenAddress, uint256 amount) internal {
token = ERC20(tokenAddress);
require(token.transferFrom(msg.sender, relayer, amount), "Transfer failed");
}
/******************************
* External functions : Burn *
******************************/
/**
* @notice Burn USDC token via CCTP
* @param _amount Burn amount
* @param _mintRecipient Recipient address
* @param _destinationDomain Destination network code
* @param _burnToken Burn token address
*/
function callDepositForBurn(
uint256 _amount,
uint32 _destinationDomain,
bytes32 _mintRecipient,
address _burnToken
) external onlyActiveContract {
require(_amount > 0, "Amount must be greater than zero");
uint256 currentFee = getFee(_amount, _destinationDomain); // Calculate fee dynamically
require(_amount > currentFee, "Amount must be greater than fee"); // Check against dynamic fee
require(_mintRecipient != bytes32(0), "Invalid mint recipient");
require(_burnToken != address(0), "Invalid token address");
token = ERC20(_burnToken);
uint256 tokenBalance = token.balanceOf(address(msg.sender));
require(tokenBalance >= _amount, "Insufficient token balance");
uint256 burnAmount = _amount - currentFee; // Subtract dynamic fee
uint256 tradeIndex = trades[msg.sender].length;
trades[msg.sender].push(
Types.CCTPTrade(
tradeIndex,
msg.sender,
_amount,
block.timestamp,
_mintRecipient,
Lib_DefaultValues.STATUS_START,
currentFee, // Store dynamic fee
_destinationDomain
)
);
userTradeList.push(Types.UserCCTPTrade(msg.sender, tradeIndex));
emit DepositForBurnCalled(
msg.sender,
_mintRecipient,
_destinationDomain,
tradeIndex,
burnAmount,
_burnToken,
_amount
);
require(token.transferFrom(msg.sender, address(this), burnAmount), "Transfer operation failed");
token.approve(address(tokenMessenger), burnAmount);
address tokenMessengerAddress = address(tokenMessenger);
bytes memory callData = abi.encodeWithSignature(
"depositForBurn(uint256,uint32,bytes32,address)",
burnAmount,
_destinationDomain,
_mintRecipient,
_burnToken
);
assembly {
let result := call(gas(), tokenMessengerAddress, 0, add(callData, 0x20), mload(callData), 0, 0)
if iszero(result) {
revert(0, 0)
}
}
//tokenMessenger.depositForBurn(burnAmount, _destinationDomain, _mintRecipient, _burnToken);
withdrawFee(_burnToken, currentFee); // Withdraw dynamic fee
}
/**
* @notice Calculate fee based on amount and destination domain rate
* @param _amount The amount to calculate fee for
* @param _destinationDomain The destination domain
* @return The calculated fee amount
*/
function getFee(uint256 _amount, uint32 _destinationDomain) public view returns (uint256) {
uint256 rate = feeRates[_destinationDomain];
require(rate > 0, "Fee rate not set");
return (_amount * rate) / FEE_DENOMINATOR;
}
/**
* @notice Request to update fee rate for a specific domain
* @dev Only relayer can execute this function
* @param _destinationDomain The domain to update fee rate for
* @param _newRatePpm The new fee rate in ppm (parts per million)
*/
function requestFeeRateUpdate(uint32 _destinationDomain, uint256 _newRatePpm) external onlyRelayer {
require(_newRatePpm < FEE_DENOMINATOR, "Rate too high");
uint64 executeAfter = uint64(block.timestamp + Lib_DefaultValues.UPDATE_PERIOD);
cctpFeeUpdates[_destinationDomain] = Types.CctpFeeUpdate(executeAfter, _newRatePpm);
emit FeeRateUpdateRequested(_destinationDomain, _newRatePpm, executeAfter);
}
/**
* @notice Finalize fee rate update for a specific domain after waiting period
* @param _destinationDomain The domain to finalize fee rate update for
*/
function finalizeFeeRateUpdate(
uint32 _destinationDomain
) external onlyWaitingPeriodOver(cctpFeeUpdates[_destinationDomain].executeAfter) {
uint256 newRate = cctpFeeUpdates[_destinationDomain].newFee;
feeRates[_destinationDomain] = newRate;
emit FeeRateUpdated(_destinationDomain, newRate);
delete cctpFeeUpdates[_destinationDomain];
}
/*************************
* Only Owner : Contract *
*************************/
/**
* @notice Toggles the contract's active state.
* Allows the contract owner to deactivate the contract when a critical issue is discovered
* or when updating the contract.
*/
function toggleContractActive() external onlyOwner {
isActive = !isActive;
}
/*****************************
* View Functions : Contract *
*****************************/
/**
* @notice Check if the contract is active
* @return True if the contcact is active, otherwise false
*/
function getContractStatus() external view returns (bool) {
return isActive;
}
/**************************
* View Functions : Trade *
**************************/
/**
* @notice Get specific user trade
* @param _user Address of user
* @param _index Index of trade from user's trade history
* @return Trade object
*/
function getTrade(address _user, uint256 _index) public view returns (Types.CCTPTrade memory) {
require(trades[_user].length >= _index + 1, "No Trade Exists");
return trades[_user][_index];
}
/**
* @notice Get user trade list
* @return Length of UserTrade object
*/
function getUserTradeListLength() external view returns (uint256) {
return userTradeList.length;
}
/**
* @notice Get user trade list by index
* @param _startIndex Start index of user trade list
* @param _endIndex End index of user trade list
* @return Array of UserTrade object
*/
function getUserTradeListByIndex(
uint256 _startIndex,
uint256 _endIndex
) external view returns (Types.UserCCTPTrade[] memory) {
require(userTradeList.length > _endIndex, "End Index Out of Bounds");
require(_startIndex <= _endIndex, "Invalid Range");
uint256 length = _endIndex - _startIndex + 1;
Types.UserCCTPTrade[] memory result = new Types.UserCCTPTrade[](length);
for (uint256 i = 0; i < length; i++) {
result[i] = userTradeList[_startIndex + i];
}
return result;
}
/**
* @notice Get array of trade from array of UserTrade
* @param _userTrades Array of user UserTrade object
* @return Array of Trade object
*/
function getTrades(Types.UserTrade[] memory _userTrades) external view returns (Types.CCTPTrade[] memory) {
uint256 length = _userTrades.length;
Types.CCTPTrade[] memory tradeList = new Types.CCTPTrade[](length);
for (uint256 i = 0; i < length; i++) {
tradeList[i] = getTrade(_userTrades[i].userAddress, _userTrades[i].index);
}
return tradeList;
}
/************
* Modifier *
************/
/**
* @notice Throw if the contract is in active
*/
modifier onlyActiveContract() {
require(isActive, "Unavailable bridge");
_;
}
/**
* @dev throws if called by any account other than the relayer
*/
modifier onlyRelayer() {
require(relayer == msg.sender, "Only for relayer");
_;
}
/**
* @notice Check if certain period is over
* @param _executeAfter Timestamp of period end
*/
modifier onlyWaitingPeriodOver(uint256 _executeAfter) {
require(uint64(block.timestamp) > _executeAfter && _executeAfter != 0, "Ongoing update period");
_;
}
// ---- storage gap for future variable additions ----
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original
* initialization step. This is essential to configure modules that are added through upgrades and that require
* initialization.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized < type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "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");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(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) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason 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 {
// 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 v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
interface ITokenMessenger {
function depositForBurn(
uint256 _amount,
uint32 _destinationDomain,
bytes32 _mintRecipient,
address _burnToken
) external returns (uint64 _nonce);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
/**
* @title Lib_DefaultValues
*/
library Lib_DefaultValues {
uint8 constant ETH_TOKEN_INDEX = 0;
uint8 constant USDC_TOKEN_INDEX = 1;
uint8 constant USDCe_TOKEN_INDEX = 2;
uint256 constant ETH_NETWORK_CODE = 1001;
uint8 constant STATUS_START = 0;
uint8 constant STATUS_PAID = 2;
uint8 constant STATUS_DISPUTE = 3;
uint8 constant STATUS_SLASHED = 4;
uint8 constant STATUS_PROVED = 5;
uint8 constant STATUS_SLASH_COMPLETED = 6;
uint8 constant STATUS_CANCEL = 99;
bytes constant TRANSFER_METHOD_ID = bytes(hex"a9059cbb");
uint256 constant CANCELABLE_PERIOD = 2 hours;
uint256 constant UPWARD_SLASH_START = 30 minutes;
uint256 constant SLASHABLE_PERIOD = 14 days;
uint256 constant UPDATE_PERIOD = 3 hours;
uint256 constant BLOCKHEADER_TIMESTAMP_INDEX = 11;
uint256 constant TYPE0_TRANSACTION_TO_INDEX = 3;
uint256 constant TYPE0_TRANSACTION_VALUE_INDEX = 4;
uint256 constant TYPE0_TRANSACTION_DATA_INDEX = 5;
uint256 constant TYPE1_TRANSACTION_TO_INDEX = 4;
uint256 constant TYPE1_TRANSACTION_VALUE_INDEX = 5;
uint256 constant TYPE1_TRANSACTION_DATA_INDEX = 6;
uint256 constant TYPE23_TRANSACTION_TO_INDEX = 5;
uint256 constant TYPE23_TRANSACTION_VALUE_INDEX = 6;
uint256 constant TYPE23_TRANSACTION_DATA_INDEX = 7;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
/**
* @title Types
*/
library Types {
/***********
* Structs *
***********/
struct TradeParam {
uint256 tradeThreshold;
uint256 tradeMinimumAmount;
uint256 networkCode;
uint256 tradableBondRatio;
uint256 disputeDepositAmount;
}
struct UserTrade {
address userAddress;
uint256 index;
}
struct Trade {
uint256 index;
address user;
uint8 tokenTypeIndex;
uint256 amount;
uint256 timestamp;
address to;
address relayer;
uint8 status;
uint256 fee;
uint256 destCode;
}
struct UserCCTPTrade {
address userAddress;
uint256 index;
}
struct CCTPTrade {
uint256 index;
address user;
uint256 amount;
uint256 timestamp;
bytes32 to;
uint8 status;
uint256 fee;
uint32 destinationDomain;
}
struct CctpFeeUpdate {
uint64 executeAfter;
uint256 newFee;
}
struct Evidence {
uint256 blockNumber;
bytes32 blockHash;
bytes[] txReceiptProof;
bytes[] txProof;
bytes transaction;
uint8[] path;
bytes txReceipt;
bytes[] rawTx;
bytes[] rawBlockHeader;
uint8 txType;
}
struct Dispute {
address disputer;
uint8 tokenTypeIndex;
uint256 deposit;
uint256 disputedTimestamp;
}
struct FeeRateUpdate {
uint64 executeAfter;
uint256 networkCode;
uint8 tokenTypeIndex;
uint256 newRatePpm; // 100 %=1_000_000
}
struct TradeParamUpdate {
uint64 executeAfter;
uint8 operation;
uint256 networkCode;
uint8 tokenTypeIndex;
uint256 newValue;
}
struct TokenAddressUpdate {
uint64 executeAfter;
uint256[] networkCodes;
uint8[] tokenTypeIndices;
address[] tokenAddresses;
}
struct ManagerUpdate {
uint64 executeAfter;
uint8 operation;
address newManager;
}
struct NetworkSettingUpdate {
uint64 executeAfter;
uint8[] operations;
uint256[] networkCodes;
uint8[] tokenTypeIndices;
bool[] nativeIsNotETH;
}
/// @param data Data of the quoted request.
/// @param toChainId Chain ID of the Swap destination.
/// @param swapToolIndex DEX Protocol index (for administrative use).
/// @param toolContract To address of the quoted request (DEX Protocol contract address).
/// @param fromToken Token address of the Swap source.
/// @param toToken Token address of the Swap destination.
/// @param amount Amount of the Swap source.
/// @param value Value of the quoted request.
/// @param gas Gas of the quoted request.
/// @param quoteTimestamp Timestamp of quote execution for RelayerFee determination.
struct TransactionRequest {
bytes data;
string toChainId;
uint16 swapToolIndex;
address toolContract;
address fromToken;
address toToken;
uint256 amount;
uint256 value;
uint256 gas;
uint256 quoteTimestamp;
}
/// @param data Swap trade result data to be recorded in the event.
/// @param tradeHash keccak256 hash of SwapTrade.
/// @param userAddress Address of the user who executed the execute.
/// @param token Token address of the Swap source.
struct SwapWithdrawRequest {
bytes data;
bytes32 tradeHash;
address userAddress;
address token;
}
/// @param toChainId Chain ID of the Swap destination.
/// @param swapToolIndex DEX Protocol index (for administrative use).
/// @param toolContract To address of the quoted request (DEX Protocol contract address).
/// @param toToken Token address of the Swap destination.
/// @param amount Amount of the Swap source.
/// @param relayerFee RelayerFee calculated from the amount.
/// @param quoteTimestamp Timestamp of quote execution for RelayerFee determination.
struct SwapTrade {
string toChainId;
uint16 swapToolIndex;
address toolContract;
address toToken;
uint256 amount;
uint256 relayerFee;
uint256 timestamp;
}
/// @param data Swap trade result data to be recorded in the event.
/// @param tradeHash keccak256 hash of SwapTrade.
/// @param userAddress Address of the user who executed the execute.
/// @param token Token address of the Swap source.
/// @param amount Amount of RelayerFee.
struct SwapWithdraw {
bytes data;
bytes32 tradeHash;
address userAddress;
address token;
uint256 amount;
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event OwnershipTransferred(address indexed user, address indexed newOwner);
/*//////////////////////////////////////////////////////////////
OWNERSHIP STORAGE
//////////////////////////////////////////////////////////////*/
address public owner;
modifier onlyOwner() virtual {
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner) {
owner = _owner;
emit OwnershipTransferred(address(0), _owner);
}
/*//////////////////////////////////////////////////////////////
OWNERSHIP LOGIC
//////////////////////////////////////////////////////////////*/
function transferOwnership(address newOwner) public virtual onlyOwner {
owner = newOwner;
emit OwnershipTransferred(msg.sender, newOwner);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*//////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*//////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*//////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*//////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*//////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*//////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
library SafeTransferLib {
/*//////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Transfer the ETH and store if it succeeded or not.
success := call(gas(), to, amount, 0, 0, 0, 0)
}
require(success, "ETH_TRANSFER_FAILED");
}
/*//////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
// We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
success := call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data and token has code.
if and(iszero(and(eq(mload(0), 1), gt(returndatasize(), 31))), success) {
success := iszero(or(iszero(extcodesize(token)), returndatasize()))
}
}
require(success, "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
success := call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data and token has code.
if and(iszero(and(eq(mload(0), 1), gt(returndatasize(), 31))), success) {
success := iszero(or(iszero(extcodesize(token)), returndatasize()))
}
}
require(success, "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
success := call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data and token has code.
if and(iszero(and(eq(mload(0), 1), gt(returndatasize(), 31))), success) {
success := iszero(or(iszero(extcodesize(token)), returndatasize()))
}
}
require(success, "APPROVE_FAILED");
}
}{
"viaIR": true,
"optimizer": {
"enabled": true,
"runs": 30,
"details": {
"yul": true
}
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"bytes32","name":"recipient","type":"bytes32"},{"indexed":true,"internalType":"uint32","name":"destinationDomain","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"originalAmount","type":"uint256"}],"name":"DepositForBurnCalled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"destinationDomain","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"newRatePpm","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"executeAfter","type":"uint64"}],"name":"FeeRateUpdateRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"destinationDomain","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"newRatePpm","type":"uint256"}],"name":"FeeRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"FEE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_mintRecipient","type":"bytes32"},{"internalType":"address","name":"_burnToken","type":"address"}],"name":"callDepositForBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"cctpFeeUpdates","outputs":[{"internalType":"uint64","name":"executeAfter","type":"uint64"},{"internalType":"uint256","name":"newFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"feeRates","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"}],"name":"finalizeFeeRateUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getContractStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint32","name":"_destinationDomain","type":"uint32"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getTrade","outputs":[{"components":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint32","name":"destinationDomain","type":"uint32"}],"internalType":"struct Types.CCTPTrade","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"internalType":"struct Types.UserTrade[]","name":"_userTrades","type":"tuple[]"}],"name":"getTrades","outputs":[{"components":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint32","name":"destinationDomain","type":"uint32"}],"internalType":"struct Types.CCTPTrade[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startIndex","type":"uint256"},{"internalType":"uint256","name":"_endIndex","type":"uint256"}],"name":"getUserTradeListByIndex","outputs":[{"components":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"internalType":"struct Types.UserCCTPTrade[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUserTradeListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenMessenger","type":"address"},{"internalType":"address","name":"_newOwner","type":"address"},{"internalType":"uint32[]","name":"_destinationDomains","type":"uint32[]"},{"internalType":"uint256[]","name":"_initialFeeRatesPpm","type":"uint256[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"relayer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"uint256","name":"_newRatePpm","type":"uint256"}],"name":"requestFeeRateUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleContractActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"userTradeList","outputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6080806040523461001657611b16908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b60003560e01c80631385d24c14610147578063201274c114610142578063394e46901461013d5780633b7706d014610138578063715018a6146101335780637906c5f71461012e5780638406c079146101295780638c186d7f146101245780638c94ff8b1461011f5780638da5cb5b1461011a57806394b59cba14610115578063a1fea44a14610110578063a805437f1461010b578063bba4b53214610106578063c032846b14610101578063ca142f75146100fc578063d73792a9146100f7578063ebbeea75146100f25763f2fde38b146100ed57600080fd5b610eee565b610ec0565b610ea2565b610e6b565b610e45565b610e0e565b610d50565b6108b1565b610740565b610717565b6106cb565b610673565b61064a565b61058c565b6103da565b610391565b6102ae565b6101bf565b3461018357600036600319011261018357610160610f7b565b6066805460ff60a01b19811660a091821c60ff161590911b60ff60a01b16179055005b600080fd5b6004359063ffffffff8216820361018357565b6024359063ffffffff8216820361018357565b359063ffffffff8216820361018357565b34610183576020366003190112610183576101d8610188565b63ffffffff8116600052606b6020526001600160401b03806040600020541680914216119081610251575b501561021457610212906117d0565b005b60405162461bcd60e51b815260206004820152601560248201527413db99dbda5b99c81d5c19185d19481c195c9a5bd9605a1b6044820152606490fd5b9050151538610203565b60208082019080835283518092528060408094019401926000905b83821061028557505050505090565b845180516001600160a01b03168752830151868401529485019493820193600190910190610276565b3461018357604036600319011261018357600435602435806068541115610352576102e882826102e36102ed94831115611984565b611461565b6117a6565b6102f6816119c0565b9160005b828110610313576040518061030f868261025b565b0390f35b8061033261032c61032761034d94866117c3565b6106a7565b50611a21565b61033c8287611174565b526103478186611174565b50611160565b6102fa565b60405162461bcd60e51b8152602060048201526017602482015276456e6420496e646578204f7574206f6620426f756e647360481b6044820152606490fd5b346101835760203660031901126101835763ffffffff6103af610188565b16600052606b60205260408060002060016001600160401b0382541691015482519182526020820152f35b3461018357600080600319360112610438576103f4610f7b565b603380546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b80fd5b600435906001600160a01b038216820361018357565b602435906001600160a01b038216820361018357565b606435906001600160a01b038216820361018357565b35906001600160a01b038216820361018357565b634e487b7160e01b600052604160045260246000fd5b604081019081106001600160401b038211176104c257604052565b610491565b90601f801991011681019081106001600160401b038211176104c257604052565b604051906104f5826104a7565b565b6040519061010082018281106001600160401b038211176104c257604052565b6001600160401b0381116104c25760051b60200190565b81601f820112156101835780359161054583610517565b9261055360405194856104c7565b808452602092838086019260051b820101928311610183578301905b82821061057d575050505090565b8135815290830190830161056f565b34610183576080366003190112610183576105a561043b565b6105ad610451565b906044356001600160401b039283821161018357366023830112156101835781600401356105da81610517565b926105e860405194856104c7565b81845260209160248386019160051b8301019136831161018357602401905b82821061063357505050506064359384116101835761062d61021294369060040161052e565b9261101c565b83809161063f846101ae565b815201910190610607565b34610183576000366003190112610183576066546040516001600160a01b039091168152602090f35b34610183576000366003190112610183576020606854604051908152f35b634e487b7160e01b600052603260045260246000fd5b6068548110156106c657606860005260206000209060011b0190600090565b610691565b3461018357602036600319011261018357600435606854811015610183576106f2906106a7565b508054600190910154604080516001600160a01b039093168352602083019190915290f35b34610183576000366003190112610183576033546040516001600160a01b039091168152602090f35b3461018357604036600319011261018357610759610188565b60665460243591906001600160a01b0316330361087957620f42408210156108445763ffffffff7f207a1aa0fe1e4a9c90b8700957f0cc0787d85d98206087b0d086ab11aca926a59161083f6107bd6107b1426117b4565b6001600160401b031690565b61081b6107c86104e8565b6001600160401b03831681528760208201526107f48563ffffffff16600052606b602052604060002090565b9060206001916001600160401b038151166001600160401b03198554161784550151910155565b6040519384931695839092916001600160401b036020916040840195845216910152565b0390a2005b60405162461bcd60e51b815260206004820152600d60248201526c0a4c2e8ca40e8dede40d0d2ced609b1b6044820152606490fd5b60405162461bcd60e51b815260206004820152601060248201526f27b7363c903337b9103932b630bcb2b960811b6044820152606490fd5b34610183576080366003190112610183576004356108cd61019b565b90604435906108da610467565b9260ff60665460a01c1615610c71576108f48215156112dd565b6108fe8183611739565b9261090a848411611328565b610915811515611374565b61094f6001600160a01b03861661092d8115156113b9565b606780546001600160a01b0319166001600160a01b0392909216919091179055565b60675461096c906001600160a01b03165b6001600160a01b031690565b604080516370a0823160e01b8152336004820152602095919391928690829060249082905afa908115610c22576109af918491600091610c44575b501015611418565b86816109bb8885611461565b937f714a89da287fe5c524c38f8c37f72f7e6eec2adcce30042c203d6152c7094c4c610a976109e93361146e565b5492610a478b8d6109f93361146e565b90610a12610a056104f7565b8981523394810194909452565b848d840152426060840152886080840152600060a084015260c0830152610a428d60e084019063ffffffff169052565b6114ba565b610a5f610a526104e8565b338152858d820152611586565b8851938452602084018890526001600160a01b039095166040840152606083019490945263ffffffff88169333929081906080820190565b0390a4606754610aaf906001600160a01b0316610960565b9385845180966323b872dd60e01b825281600081610ad289303360048501611612565b03925af1948515610c2257610b5895610af391600091610c27575b50611634565b60675486908490610b0c906001600160a01b0316610960565b606554610b21906001600160a01b0316610960565b875163095ea7b360e01b81526001600160a01b03909116600482015260248101929092529096879190829060009082906044820190565b03925af1918215610c2257600096610bd58a610be3938a998a97610bf5575b50606554610b8d906001600160a01b0316610960565b98516337e9a82760e11b948101948552602481019890985263ffffffff909516604488015260648701949094526001600160a01b0390931660848601529391829060a4820190565b03601f1981018352826104c7565b51925af115610183576102129161167c565b610c1490853d8711610c1b575b610c0c81836104c7565b8101906115fa565b5038610b77565b503d610c02565b61140c565b610c3e9150883d8a11610c1b57610c0c81836104c7565b38610aed565b610c649150883d8a11610c6a575b610c5c81836104c7565b8101906113fd565b386109a7565b503d610c52565b60405162461bcd60e51b8152602060048201526012602482015271556e617661696c61626c652062726964676560701b6044820152606490fd5b63ffffffff60e080928051855260018060a01b03602082015116602086015260408101516040860152606081015160608601526080810151608086015260ff60a08201511660a086015260c081015160c0860152015116910152565b6020908160408183019282815285518094520193019160005b828110610d2e575050505090565b909192938261010082610d446001948951610cab565b01950193929101610d20565b346101835760208060031936011261018357600435906001600160401b038211610183573660238301121561018357816004013591610d8e83610517565b91604093610d9e855194856104c7565b80845260248285019160061b8401019236841161018357602401905b838210610dd95761030f86610dce87611a48565b905191829182610d07565b8582360312610183578286918251610df0816104a7565b610df98561047d565b81528285013583820152815201910190610dba565b346101835760203660031901126101835763ffffffff610e2c610188565b16600052606a6020526020604060002054604051908152f35b3461018357600036600319011261018357602060ff60665460a01c166040519015158152f35b3461018357604036600319011261018357610100610e93610e8a61043b565b60243590611881565b610ea06040518092610cab565bf35b34610183576000366003190112610183576020604051620f42408152f35b34610183576040366003190112610183576020610ee6610ede61019b565b600435611739565b604051908152f35b3461018357602036600319011261018357610f0761043b565b610f0f610f7b565b6001600160a01b03811615610f275761021290610fd3565b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6033546001600160a01b03163303610f8f57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b603380546001600160a01b039283166001600160a01b0319821681179092559091167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b919290926000549360ff8560081c16158095819661113c575b811561111c575b50156110c0576110629385611059600160ff196000541617600055565b6110a7576111cc565b61106857565b61107861ff001960005416600055565b604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602090a1565b6110bb61010061ff00196000541617600055565b6111cc565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b303b1591508161112e575b503861103c565b6001915060ff161438611127565b600160ff8216109150611035565b634e487b7160e01b600052601160045260246000fd5b600019811461116f5760010190565b61114a565b80518210156106c65760209160051b010190565b1561118f57565b60405162461bcd60e51b8152602060048201526015602482015274092dcd2e8d2c2d840e4c2e8ca40e8dede40d0d2ced605b1b6044820152606490fd5b90939291936111da81610fd3565b845183510361128957606580546001600160a01b039384166001600160a01b031990911617905560668054919092166001600160a81b031990911617600160a01b17905560005b8351811015611283578061124561123b61127e9387611174565b5163ffffffff1690565b6112786112528386611174565b5191611262620f42408410611188565b63ffffffff16600052606a602052604060002090565b55611160565b611221565b50509050565b60405162461bcd60e51b815260206004820152602660248201527f496e70757420617272617973206d7573742068617665207468652073616d65206044820152650d8cadccee8d60d31b6064820152608490fd5b156112e457565b606460405162461bcd60e51b815260206004820152602060248201527f416d6f756e74206d7573742062652067726561746572207468616e207a65726f6044820152fd5b1561132f57565b60405162461bcd60e51b815260206004820152601f60248201527f416d6f756e74206d7573742062652067726561746572207468616e20666565006044820152606490fd5b1561137b57565b60405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081b5a5b9d081c9958da5c1a595b9d60521b6044820152606490fd5b156113c057565b60405162461bcd60e51b8152602060048201526015602482015274496e76616c696420746f6b656e206164647265737360581b6044820152606490fd5b90816020910312610183575190565b6040513d6000823e3d90fd5b1561141f57565b60405162461bcd60e51b815260206004820152601a602482015279496e73756666696369656e7420746f6b656e2062616c616e636560301b6044820152606490fd5b9190820391821161116f57565b6001600160a01b0316600090815260696020526040902090565b80548210156106c65760005260206000209060031b0190600090565b634e487b7160e01b600052600060045260246000fd5b8054600160401b8110156104c2576114d791600182018155611488565b611581578151815560208201516001820180546001600160a01b0319166001600160a01b039092169190911790556104f59160079061156a9060e09060408101516002860155606081015160038601556080810151600486015561155561154260a083015160ff1690565b600587019060ff1660ff19825416179055565b60c08101516006860155015163ffffffff1690565b91019063ffffffff1663ffffffff19825416179055565b6114a4565b606854600160401b8110156104c25760018101806068558110156106c65760686000528151600191821b7fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530180546001600160a01b0319166001600160a01b03929092169190911781559160200151910155565b90816020910312610183575180151581036101835790565b6001600160a01b03918216815291166020820152604081019190915260600190565b1561163b57565b60405162461bcd60e51b8152602060048201526019602482015278151c985b9cd9995c881bdc195c985d1a5bdb8819985a5b1959603a1b6044820152606490fd5b606780546001600160a01b0319166001600160a01b039283169081179091556066546040516323b872dd60e01b815293602093859392849260009284926116c99291163360048501611612565b03925af1908115610c225760009161171b575b50156116e457565b60405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b611733915060203d8111610c1b57610c0c81836104c7565b386116dc565b9063ffffffff16600052606a60205260406000205490811561176e5781810291818304149015171561116f57620f4240900490565b60405162461bcd60e51b815260206004820152601060248201526f119959481c985d19481b9bdd081cd95d60821b6044820152606490fd5b906001820180921161116f57565b90612a30820180921161116f57565b9190820180921161116f57565b63ffffffff16600090808252606b602052807f844fda05fdeddb3f84ffcf8d96eab47fc4c7d0d972df52d1e77af5c60387515360206001604086200154606a8252806040872055604051908152a28152606b6020526001604082208281550155565b6040519061010082018281106001600160401b038211176104c2576040528160e06000918281528260208201528260408201528260608201528260808201528260a08201528260c08201520152565b9061188a611832565b506001600160a01b038216600090815260696020526040902054600182019081831161116f571061194d576118c16118c69261146e565b611488565b5061194a61193d60076118d76104f7565b8454815260018501546001600160a01b031660208201529360028101546040860152600381015460608601526004810154608086015261192861191e600583015460ff1690565b60ff1660a0870152565b600681015460c0860152015463ffffffff1690565b63ffffffff1660e0830152565b90565b60405162461bcd60e51b815260206004820152600f60248201526e4e6f2054726164652045786973747360881b6044820152606490fd5b1561198b57565b60405162461bcd60e51b815260206004820152600d60248201526c496e76616c69642052616e676560981b6044820152606490fd5b906119ca82610517565b6040906119d9825191826104c7565b83815280936119ea601f1991610517565b0191600090815b8481106119ff575050505050565b6020908251611a0d816104a7565b8481528285818301528287010152016119f1565b90604051611a2e816104a7565b82546001600160a01b031681526001909201546020830152565b8051611a5381610517565b91611a6160405193846104c7565b818352601f19611a7083610517565b0160005b818110611ac957505060005b828110611a8d5750505090565b80610332611aaf611aa1611ac49486611174565b51516001600160a01b031690565b6020611abb8487611174565b51015190611881565b611a80565b602090611ad4611832565b82828801015201611a7456fea26469706673582212208144f401284fd542180229e3c14ab1bd3cc2c83bfd4fcde6832558b588c664c764736f6c63430008120033
Deployed Bytecode
0x6080604052600436101561001257600080fd5b60003560e01c80631385d24c14610147578063201274c114610142578063394e46901461013d5780633b7706d014610138578063715018a6146101335780637906c5f71461012e5780638406c079146101295780638c186d7f146101245780638c94ff8b1461011f5780638da5cb5b1461011a57806394b59cba14610115578063a1fea44a14610110578063a805437f1461010b578063bba4b53214610106578063c032846b14610101578063ca142f75146100fc578063d73792a9146100f7578063ebbeea75146100f25763f2fde38b146100ed57600080fd5b610eee565b610ec0565b610ea2565b610e6b565b610e45565b610e0e565b610d50565b6108b1565b610740565b610717565b6106cb565b610673565b61064a565b61058c565b6103da565b610391565b6102ae565b6101bf565b3461018357600036600319011261018357610160610f7b565b6066805460ff60a01b19811660a091821c60ff161590911b60ff60a01b16179055005b600080fd5b6004359063ffffffff8216820361018357565b6024359063ffffffff8216820361018357565b359063ffffffff8216820361018357565b34610183576020366003190112610183576101d8610188565b63ffffffff8116600052606b6020526001600160401b03806040600020541680914216119081610251575b501561021457610212906117d0565b005b60405162461bcd60e51b815260206004820152601560248201527413db99dbda5b99c81d5c19185d19481c195c9a5bd9605a1b6044820152606490fd5b9050151538610203565b60208082019080835283518092528060408094019401926000905b83821061028557505050505090565b845180516001600160a01b03168752830151868401529485019493820193600190910190610276565b3461018357604036600319011261018357600435602435806068541115610352576102e882826102e36102ed94831115611984565b611461565b6117a6565b6102f6816119c0565b9160005b828110610313576040518061030f868261025b565b0390f35b8061033261032c61032761034d94866117c3565b6106a7565b50611a21565b61033c8287611174565b526103478186611174565b50611160565b6102fa565b60405162461bcd60e51b8152602060048201526017602482015276456e6420496e646578204f7574206f6620426f756e647360481b6044820152606490fd5b346101835760203660031901126101835763ffffffff6103af610188565b16600052606b60205260408060002060016001600160401b0382541691015482519182526020820152f35b3461018357600080600319360112610438576103f4610f7b565b603380546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b80fd5b600435906001600160a01b038216820361018357565b602435906001600160a01b038216820361018357565b606435906001600160a01b038216820361018357565b35906001600160a01b038216820361018357565b634e487b7160e01b600052604160045260246000fd5b604081019081106001600160401b038211176104c257604052565b610491565b90601f801991011681019081106001600160401b038211176104c257604052565b604051906104f5826104a7565b565b6040519061010082018281106001600160401b038211176104c257604052565b6001600160401b0381116104c25760051b60200190565b81601f820112156101835780359161054583610517565b9261055360405194856104c7565b808452602092838086019260051b820101928311610183578301905b82821061057d575050505090565b8135815290830190830161056f565b34610183576080366003190112610183576105a561043b565b6105ad610451565b906044356001600160401b039283821161018357366023830112156101835781600401356105da81610517565b926105e860405194856104c7565b81845260209160248386019160051b8301019136831161018357602401905b82821061063357505050506064359384116101835761062d61021294369060040161052e565b9261101c565b83809161063f846101ae565b815201910190610607565b34610183576000366003190112610183576066546040516001600160a01b039091168152602090f35b34610183576000366003190112610183576020606854604051908152f35b634e487b7160e01b600052603260045260246000fd5b6068548110156106c657606860005260206000209060011b0190600090565b610691565b3461018357602036600319011261018357600435606854811015610183576106f2906106a7565b508054600190910154604080516001600160a01b039093168352602083019190915290f35b34610183576000366003190112610183576033546040516001600160a01b039091168152602090f35b3461018357604036600319011261018357610759610188565b60665460243591906001600160a01b0316330361087957620f42408210156108445763ffffffff7f207a1aa0fe1e4a9c90b8700957f0cc0787d85d98206087b0d086ab11aca926a59161083f6107bd6107b1426117b4565b6001600160401b031690565b61081b6107c86104e8565b6001600160401b03831681528760208201526107f48563ffffffff16600052606b602052604060002090565b9060206001916001600160401b038151166001600160401b03198554161784550151910155565b6040519384931695839092916001600160401b036020916040840195845216910152565b0390a2005b60405162461bcd60e51b815260206004820152600d60248201526c0a4c2e8ca40e8dede40d0d2ced609b1b6044820152606490fd5b60405162461bcd60e51b815260206004820152601060248201526f27b7363c903337b9103932b630bcb2b960811b6044820152606490fd5b34610183576080366003190112610183576004356108cd61019b565b90604435906108da610467565b9260ff60665460a01c1615610c71576108f48215156112dd565b6108fe8183611739565b9261090a848411611328565b610915811515611374565b61094f6001600160a01b03861661092d8115156113b9565b606780546001600160a01b0319166001600160a01b0392909216919091179055565b60675461096c906001600160a01b03165b6001600160a01b031690565b604080516370a0823160e01b8152336004820152602095919391928690829060249082905afa908115610c22576109af918491600091610c44575b501015611418565b86816109bb8885611461565b937f714a89da287fe5c524c38f8c37f72f7e6eec2adcce30042c203d6152c7094c4c610a976109e93361146e565b5492610a478b8d6109f93361146e565b90610a12610a056104f7565b8981523394810194909452565b848d840152426060840152886080840152600060a084015260c0830152610a428d60e084019063ffffffff169052565b6114ba565b610a5f610a526104e8565b338152858d820152611586565b8851938452602084018890526001600160a01b039095166040840152606083019490945263ffffffff88169333929081906080820190565b0390a4606754610aaf906001600160a01b0316610960565b9385845180966323b872dd60e01b825281600081610ad289303360048501611612565b03925af1948515610c2257610b5895610af391600091610c27575b50611634565b60675486908490610b0c906001600160a01b0316610960565b606554610b21906001600160a01b0316610960565b875163095ea7b360e01b81526001600160a01b03909116600482015260248101929092529096879190829060009082906044820190565b03925af1918215610c2257600096610bd58a610be3938a998a97610bf5575b50606554610b8d906001600160a01b0316610960565b98516337e9a82760e11b948101948552602481019890985263ffffffff909516604488015260648701949094526001600160a01b0390931660848601529391829060a4820190565b03601f1981018352826104c7565b51925af115610183576102129161167c565b610c1490853d8711610c1b575b610c0c81836104c7565b8101906115fa565b5038610b77565b503d610c02565b61140c565b610c3e9150883d8a11610c1b57610c0c81836104c7565b38610aed565b610c649150883d8a11610c6a575b610c5c81836104c7565b8101906113fd565b386109a7565b503d610c52565b60405162461bcd60e51b8152602060048201526012602482015271556e617661696c61626c652062726964676560701b6044820152606490fd5b63ffffffff60e080928051855260018060a01b03602082015116602086015260408101516040860152606081015160608601526080810151608086015260ff60a08201511660a086015260c081015160c0860152015116910152565b6020908160408183019282815285518094520193019160005b828110610d2e575050505090565b909192938261010082610d446001948951610cab565b01950193929101610d20565b346101835760208060031936011261018357600435906001600160401b038211610183573660238301121561018357816004013591610d8e83610517565b91604093610d9e855194856104c7565b80845260248285019160061b8401019236841161018357602401905b838210610dd95761030f86610dce87611a48565b905191829182610d07565b8582360312610183578286918251610df0816104a7565b610df98561047d565b81528285013583820152815201910190610dba565b346101835760203660031901126101835763ffffffff610e2c610188565b16600052606a6020526020604060002054604051908152f35b3461018357600036600319011261018357602060ff60665460a01c166040519015158152f35b3461018357604036600319011261018357610100610e93610e8a61043b565b60243590611881565b610ea06040518092610cab565bf35b34610183576000366003190112610183576020604051620f42408152f35b34610183576040366003190112610183576020610ee6610ede61019b565b600435611739565b604051908152f35b3461018357602036600319011261018357610f0761043b565b610f0f610f7b565b6001600160a01b03811615610f275761021290610fd3565b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b6033546001600160a01b03163303610f8f57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b603380546001600160a01b039283166001600160a01b0319821681179092559091167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b919290926000549360ff8560081c16158095819661113c575b811561111c575b50156110c0576110629385611059600160ff196000541617600055565b6110a7576111cc565b61106857565b61107861ff001960005416600055565b604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602090a1565b6110bb61010061ff00196000541617600055565b6111cc565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b303b1591508161112e575b503861103c565b6001915060ff161438611127565b600160ff8216109150611035565b634e487b7160e01b600052601160045260246000fd5b600019811461116f5760010190565b61114a565b80518210156106c65760209160051b010190565b1561118f57565b60405162461bcd60e51b8152602060048201526015602482015274092dcd2e8d2c2d840e4c2e8ca40e8dede40d0d2ced605b1b6044820152606490fd5b90939291936111da81610fd3565b845183510361128957606580546001600160a01b039384166001600160a01b031990911617905560668054919092166001600160a81b031990911617600160a01b17905560005b8351811015611283578061124561123b61127e9387611174565b5163ffffffff1690565b6112786112528386611174565b5191611262620f42408410611188565b63ffffffff16600052606a602052604060002090565b55611160565b611221565b50509050565b60405162461bcd60e51b815260206004820152602660248201527f496e70757420617272617973206d7573742068617665207468652073616d65206044820152650d8cadccee8d60d31b6064820152608490fd5b156112e457565b606460405162461bcd60e51b815260206004820152602060248201527f416d6f756e74206d7573742062652067726561746572207468616e207a65726f6044820152fd5b1561132f57565b60405162461bcd60e51b815260206004820152601f60248201527f416d6f756e74206d7573742062652067726561746572207468616e20666565006044820152606490fd5b1561137b57565b60405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081b5a5b9d081c9958da5c1a595b9d60521b6044820152606490fd5b156113c057565b60405162461bcd60e51b8152602060048201526015602482015274496e76616c696420746f6b656e206164647265737360581b6044820152606490fd5b90816020910312610183575190565b6040513d6000823e3d90fd5b1561141f57565b60405162461bcd60e51b815260206004820152601a602482015279496e73756666696369656e7420746f6b656e2062616c616e636560301b6044820152606490fd5b9190820391821161116f57565b6001600160a01b0316600090815260696020526040902090565b80548210156106c65760005260206000209060031b0190600090565b634e487b7160e01b600052600060045260246000fd5b8054600160401b8110156104c2576114d791600182018155611488565b611581578151815560208201516001820180546001600160a01b0319166001600160a01b039092169190911790556104f59160079061156a9060e09060408101516002860155606081015160038601556080810151600486015561155561154260a083015160ff1690565b600587019060ff1660ff19825416179055565b60c08101516006860155015163ffffffff1690565b91019063ffffffff1663ffffffff19825416179055565b6114a4565b606854600160401b8110156104c25760018101806068558110156106c65760686000528151600191821b7fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977530180546001600160a01b0319166001600160a01b03929092169190911781559160200151910155565b90816020910312610183575180151581036101835790565b6001600160a01b03918216815291166020820152604081019190915260600190565b1561163b57565b60405162461bcd60e51b8152602060048201526019602482015278151c985b9cd9995c881bdc195c985d1a5bdb8819985a5b1959603a1b6044820152606490fd5b606780546001600160a01b0319166001600160a01b039283169081179091556066546040516323b872dd60e01b815293602093859392849260009284926116c99291163360048501611612565b03925af1908115610c225760009161171b575b50156116e457565b60405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b611733915060203d8111610c1b57610c0c81836104c7565b386116dc565b9063ffffffff16600052606a60205260406000205490811561176e5781810291818304149015171561116f57620f4240900490565b60405162461bcd60e51b815260206004820152601060248201526f119959481c985d19481b9bdd081cd95d60821b6044820152606490fd5b906001820180921161116f57565b90612a30820180921161116f57565b9190820180921161116f57565b63ffffffff16600090808252606b602052807f844fda05fdeddb3f84ffcf8d96eab47fc4c7d0d972df52d1e77af5c60387515360206001604086200154606a8252806040872055604051908152a28152606b6020526001604082208281550155565b6040519061010082018281106001600160401b038211176104c2576040528160e06000918281528260208201528260408201528260608201528260808201528260a08201528260c08201520152565b9061188a611832565b506001600160a01b038216600090815260696020526040902054600182019081831161116f571061194d576118c16118c69261146e565b611488565b5061194a61193d60076118d76104f7565b8454815260018501546001600160a01b031660208201529360028101546040860152600381015460608601526004810154608086015261192861191e600583015460ff1690565b60ff1660a0870152565b600681015460c0860152015463ffffffff1690565b63ffffffff1660e0830152565b90565b60405162461bcd60e51b815260206004820152600f60248201526e4e6f2054726164652045786973747360881b6044820152606490fd5b1561198b57565b60405162461bcd60e51b815260206004820152600d60248201526c496e76616c69642052616e676560981b6044820152606490fd5b906119ca82610517565b6040906119d9825191826104c7565b83815280936119ea601f1991610517565b0191600090815b8481106119ff575050505050565b6020908251611a0d816104a7565b8481528285818301528287010152016119f1565b90604051611a2e816104a7565b82546001600160a01b031681526001909201546020830152565b8051611a5381610517565b91611a6160405193846104c7565b818352601f19611a7083610517565b0160005b818110611ac957505060005b828110611a8d5750505090565b80610332611aaf611aa1611ac49486611174565b51516001600160a01b031690565b6020611abb8487611174565b51015190611881565b611a80565b602090611ad4611832565b82828801015201611a7456fea26469706673582212208144f401284fd542180229e3c14ab1bd3cc2c83bfd4fcde6832558b588c664c764736f6c63430008120033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.