Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x7fc40194...4D17EbFFb The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
Factory
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.7; import "../controller/ControllerInterface.sol"; import "./FactoryInterface.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; /// @title AMKT Factory /// @author Alongside Finance /// @notice Allows Merchants to initiate burn/mint requests and allows issuers to approve or deny them contract Factory is FactoryInterface, OwnableUpgradeable, PausableUpgradeable { ///============================================================================================= /// State Variables ///============================================================================================= ControllerInterface public controller; // mapping between merchant to its per-mint limit. mapping(address => uint256) public merchantMintLimit; // mapping between merchant to its per-burn limit. mapping(address => uint256) public merchantBurnLimit; // mapping between merchant to the corresponding issuer deposit address, used in the minting process. // by using a different deposit address per merchant the issuer can identify which merchant deposited. mapping(address => string) public issuerDepositAddress; // mapping between merchant to the its deposit address where the asset should be moved to, used in the burning process. mapping(address => string) public merchantDepositAddress; // mapping between a mint request hash and the corresponding request nonce. mapping(bytes32 => uint256) public mintRequestNonce; // mapping between a burn request hash and the corresponding request nonce. mapping(bytes32 => uint256) public burnRequestNonce; Request[] public mintRequests; Request[] public burnRequests; ///============================================================================================= /// Initializer ///============================================================================================= function initialize(address _controller) external initializer { controller = ControllerInterface(_controller); __Ownable_init(); __Pausable_init(); transferOwnership(_controller); } ///============================================================================================= /// Modifiers ///============================================================================================= modifier onlyMerchant() { require(controller.isMerchant(msg.sender), "sender not a merchant."); _; } modifier onlyIssuer() { require(controller.isIssuer(msg.sender), "sender not a issuer."); _; } ///============================================================================================= /// Setters ///============================================================================================= /// @notice sets the address for the merchant to deposit thier assets /// @param merchant address /// @param depositAddress string /// @return bool function setIssuerDepositAddress(address merchant, string memory depositAddress) external override onlyIssuer returns (bool) { require(merchant != address(0), "invalid merchant address"); require(controller.isMerchant(merchant), "merchant address is not a real merchant."); require(!isEmptyString(depositAddress), "invalid asset deposit address"); issuerDepositAddress[merchant] = depositAddress; emit IssuerDepositAddressSet(merchant, msg.sender, depositAddress); return true; } /// @notice Allows a merchant to relay what address they receive assets to /// @param depositAddress string /// @return bool function setMerchantDepositAddress(string memory depositAddress) external override onlyMerchant returns (bool) { require(!isEmptyString(depositAddress), "invalid asset deposit address"); merchantDepositAddress[msg.sender] = depositAddress; emit MerchantDepositAddressSet(msg.sender, depositAddress); return true; } /// @notice Sets the maximum mint limit allowed per merchant /// @param merchant address /// @param amount uint256 /// @return bool function setMerchantMintLimit(address merchant, uint256 amount) external override onlyIssuer returns (bool) { merchantMintLimit[merchant] = amount; return true; } /// @notice Sets the maximum burn limit allowed per merchant /// @param merchant address /// @param amount uint256 /// @return bool function setMerchantBurnLimit(address merchant, uint256 amount) external override onlyIssuer returns (bool) { merchantBurnLimit[merchant] = amount; return true; } ///============================================================================================= /// Merchant Mint Logic ///============================================================================================= /// @notice Allows a merchant to initiate a mint request /// @param amount uint256 /// @param txid string /// @param depositAddress string /// @return bool function addMintRequest( uint256 amount, string memory txid, string memory depositAddress ) external override onlyMerchant whenNotPaused returns (uint256) { require(!isEmptyString(depositAddress), "invalid asset deposit address"); require(compareStrings(depositAddress, issuerDepositAddress[msg.sender]), "wrong asset deposit address"); require(amount <= merchantMintLimit[msg.sender], "exceeds mint limit"); uint256 nonce = mintRequests.length; uint256 timestamp = getTimestamp(); Request memory request = Request({ requester: msg.sender, amount: amount, depositAddress: depositAddress, txid: txid, nonce: nonce, timestamp: timestamp, status: RequestStatus.PENDING }); bytes32 requestHash = calcRequestHash(request); mintRequestNonce[requestHash] = nonce; mintRequests.push(request); emit MintRequestAdd(nonce, msg.sender, amount, depositAddress, txid, timestamp, requestHash); return nonce; } /// @notice Allows a merchant to cancel a mint request /// @param requestHash bytes32 /// @return bool function cancelMintRequest(bytes32 requestHash) external override onlyMerchant whenNotPaused returns (bool) { uint256 nonce; Request memory request; (nonce, request) = getPendingMintRequest(requestHash); require(msg.sender == request.requester, "cancel sender is different than pending request initiator"); mintRequests[nonce].status = RequestStatus.CANCELED; emit MintRequestCancel(nonce, msg.sender, requestHash); return true; } ///============================================================================================= /// Issuer Mint Logic ///============================================================================================= /// @notice Allows a issuer to confirm a mint request /// @param requestHash bytes32 /// @return bool function confirmMintRequest(bytes32 requestHash) external override onlyIssuer returns (bool) { uint256 nonce; Request memory request; (nonce, request) = getPendingMintRequest(requestHash); mintRequests[nonce].status = RequestStatus.APPROVED; require(controller.mint(request.requester, request.amount), "mint failed"); require(merchantMintLimit[request.requester] >= request.amount, "exceeds merchant limits"); merchantMintLimit[request.requester] -= request.amount; emit MintConfirmed( request.nonce, request.requester, request.amount, request.depositAddress, request.txid, request.timestamp, requestHash ); return true; } /// @notice Allows a issuer to reject a mint request /// @param requestHash bytes32 /// @return bool function rejectMintRequest(bytes32 requestHash) external override onlyIssuer returns (bool) { uint256 nonce; Request memory request; (nonce, request) = getPendingMintRequest(requestHash); mintRequests[nonce].status = RequestStatus.REJECTED; emit MintRejected( request.nonce, request.requester, request.amount, request.depositAddress, request.txid, request.timestamp, requestHash ); return true; } ///============================================================================================= /// Merchant Burn Logic ///============================================================================================= /// @notice Allows a merchant to initiate a burn request /// @param amount uint256 /// @return bool function burn(uint256 amount, string memory txid) external override onlyMerchant whenNotPaused returns (bool) { require(amount <= merchantBurnLimit[msg.sender], "exceeds burn limit"); string memory depositAddress = merchantDepositAddress[msg.sender]; require(!isEmptyString(depositAddress), "merchant asset deposit address was not set"); uint256 nonce = burnRequests.length; uint256 timestamp = getTimestamp(); Request memory request = Request({ requester: msg.sender, amount: amount, depositAddress: depositAddress, txid: txid, nonce: nonce, timestamp: timestamp, status: RequestStatus.PENDING }); bytes32 requestHash = calcRequestHash(request); burnRequestNonce[requestHash] = nonce; burnRequests.push(request); require(controller.burn(msg.sender, amount), "burn failed"); emit Burned(nonce, msg.sender, amount, depositAddress, timestamp, requestHash); return true; } ///============================================================================================= /// Issuer Burn Logic ///============================================================================================= /// @notice Allows a issuer to confirm a burn request /// @param requestHash bytes32 /// @return bool function confirmBurnRequest(bytes32 requestHash) external override onlyIssuer returns (bool) { uint256 nonce; Request memory request; (nonce, request) = getPendingBurnRequest(requestHash); burnRequests[nonce].status = RequestStatus.APPROVED; require(merchantBurnLimit[request.requester] >= request.amount, "exceeds merchant limits"); merchantBurnLimit[request.requester] -= request.amount; emit BurnConfirmed( request.nonce, request.requester, request.amount, request.depositAddress, request.txid, request.timestamp, requestHash ); return true; } ///============================================================================================= /// Pause Logic ///============================================================================================= function pause() external override onlyOwner { _pause(); } function unpause() external override onlyOwner { _unpause(); } ///============================================================================================= /// Non Mutable ///============================================================================================= function getBurnRequestsLength() external view override returns (uint256 length) { return burnRequests.length; } /// @notice Gets a burn request by nonce /// @dev Returns the fields present in the request struct and also the request hash /// @param nonce uint256 function getBurnRequest(uint256 nonce) external view override returns ( uint256 requestNonce, address requester, uint256 amount, string memory depositAddress, string memory txid, uint256 timestamp, string memory status, bytes32 requestHash ) { Request storage request = burnRequests[nonce]; string memory statusString = getStatusString(request.status); requestNonce = request.nonce; requester = request.requester; amount = request.amount; depositAddress = request.depositAddress; txid = request.txid; timestamp = request.timestamp; status = statusString; requestHash = calcRequestHash(request); } /// @notice Gets a mint request by nonce /// @dev Returns the fields present in the request struct and also the request hash /// @param nonce uint256 function getMintRequest(uint256 nonce) external view override returns ( uint256 requestNonce, address requester, uint256 amount, string memory depositAddress, string memory txid, uint256 timestamp, string memory status, bytes32 requestHash ) { Request memory request = mintRequests[nonce]; string memory statusString = getStatusString(request.status); requestNonce = request.nonce; requester = request.requester; amount = request.amount; depositAddress = request.depositAddress; txid = request.txid; timestamp = request.timestamp; status = statusString; requestHash = calcRequestHash(request); } function getTimestamp() internal view returns (uint256) { // timestamp is only used for data maintaining purpose, it is not relied on for critical logic. return block.timestamp; // solhint-disable-line not-rely-on-time } function getPendingMintRequest(bytes32 requestHash) internal view returns (uint256 nonce, Request memory request) { require(requestHash != 0, "request hash is 0"); nonce = mintRequestNonce[requestHash]; request = mintRequests[nonce]; validatePendingRequest(request, requestHash); } function getPendingBurnRequest(bytes32 requestHash) internal view returns (uint256 nonce, Request memory request) { require(requestHash != 0, "request hash is 0"); nonce = burnRequestNonce[requestHash]; request = burnRequests[nonce]; validatePendingRequest(request, requestHash); } function getMintRequestsLength() external view override returns (uint256 length) { return mintRequests.length; } function validatePendingRequest(Request memory request, bytes32 requestHash) internal pure { require(request.status == RequestStatus.PENDING, "request is not pending"); require(requestHash == calcRequestHash(request), "given request hash does not match a pending request"); } function calcRequestHash(Request memory request) internal pure returns (bytes32) { return keccak256( abi.encode( request.requester, request.amount, request.depositAddress, request.txid, request.nonce, request.timestamp ) ); } function compareStrings(string memory a, string memory b) internal pure returns (bool) { return (keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b))); } function isEmptyString(string memory a) internal pure returns (bool) { return (compareStrings(a, "")); } function getStatusString(RequestStatus status) internal pure returns (string memory) { if (status == RequestStatus.PENDING) { return "pending"; } else if (status == RequestStatus.CANCELED) { return "canceled"; } else if (status == RequestStatus.APPROVED) { return "approved"; } else if (status == RequestStatus.REJECTED) { return "rejected"; } else { // this fallback can never be reached. return "unknown"; } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.7; import "../factory/MembersInterface.sol"; import "../factory/FactoryInterface.sol"; interface ControllerInterface { event MembersSet(MembersInterface indexed members); event FactorySet(FactoryInterface indexed factory); event FactoryPause(bool pause); function mint(address to, uint256 amount) external returns (bool); function burn(address from, uint256 value) external returns (bool); function factoryPause(bool pause) external returns (bool); function isIssuer(address addr) external view returns (bool); function isMerchant(address addr) external view returns (bool); function getToken() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.7; interface FactoryInterface { event IssuerDepositAddressSet(address indexed merchant, address indexed sender, string depositAddress); event MerchantDepositAddressSet(address indexed merchant, string depositAddress); event MintRequestAdd( uint256 indexed nonce, address indexed requester, uint256 amount, string depositAddress, string txid, uint256 timestamp, bytes32 requestHash ); event MintRequestCancel(uint256 indexed nonce, address indexed requester, bytes32 requestHash); event MintConfirmed( uint256 indexed nonce, address indexed requester, uint256 amount, string depositAddress, string txid, uint256 timestamp, bytes32 requestHash ); event MintRejected( uint256 indexed nonce, address indexed requester, uint256 amount, string depositAddress, string txid, uint256 timestamp, bytes32 requestHash ); event Burned( uint256 indexed nonce, address indexed requester, uint256 amount, string depositAddress, uint256 timestamp, bytes32 requestHash ); event BurnConfirmed( uint256 indexed nonce, address indexed requester, uint256 amount, string depositAddress, string txid, uint256 timestamp, bytes32 inputRequestHash ); ///============================================================================================= /// Data Structres ///============================================================================================= enum RequestStatus { NULL, PENDING, CANCELED, APPROVED, REJECTED } struct Request { address requester; // sender of the request. uint256 amount; // amount of token to mint/burn. string depositAddress; // issuer's asset address in mint, merchant's asset address in burn. string txid; // asset txid for sending/redeeming asset in the mint/burn process. uint256 nonce; // serial number allocated for each request. uint256 timestamp; // time of the request creation. RequestStatus status; // status of the request. } function pause() external; function unpause() external; function setIssuerDepositAddress(address merchant, string memory depositAddress) external returns (bool); function setMerchantDepositAddress(string memory depositAddress) external returns (bool); function setMerchantMintLimit(address merchant, uint256 amount) external returns (bool); function setMerchantBurnLimit(address merchant, uint256 amount) external returns (bool); function addMintRequest( uint256 amount, string memory txid, string memory depositAddress ) external returns (uint256); function cancelMintRequest(bytes32 requestHash) external returns (bool); function confirmMintRequest(bytes32 requestHash) external returns (bool); function rejectMintRequest(bytes32 requestHash) external returns (bool); function burn(uint256 amount, string memory txid) external returns (bool); function confirmBurnRequest(bytes32 requestHash) external returns (bool); function getMintRequestsLength() external view returns (uint256 length); function getBurnRequestsLength() external view returns (uint256 length); function getBurnRequest(uint256 nonce) external view returns ( uint256 requestNonce, address requester, uint256 amount, string memory depositAddress, string memory txid, uint256 timestamp, string memory status, bytes32 requestHash ); function getMintRequest(uint256 nonce) external view returns ( uint256 requestNonce, address requester, uint256 amount, string memory depositAddress, string memory txid, uint256 timestamp, string memory status, bytes32 requestHash ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @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) (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 pragma solidity 0.8.7; interface MembersInterface { ///============================================================================================= /// Events ///============================================================================================= event IssuerSet(address indexed issuer); event MerchantAdd(address indexed merchant); event MerchantRemove(address indexed merchant); function setIssuer(address _issuer) external returns (bool); function addMerchant(address merchant) external returns (bool); function removeMerchant(address merchant) external returns (bool); function isIssuer(address addr) external view returns (bool); function isMerchant(address addr) external view returns (bool); function getMerchants() external view returns (address[] memory); function merchantsLength() external view returns (uint256); }
// 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 // 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 functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
{ "remappings": [ "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"depositAddress","type":"string"},{"indexed":false,"internalType":"string","name":"txid","type":"string"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"inputRequestHash","type":"bytes32"}],"name":"BurnConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"depositAddress","type":"string"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"Burned","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":"merchant","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"string","name":"depositAddress","type":"string"}],"name":"IssuerDepositAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"merchant","type":"address"},{"indexed":false,"internalType":"string","name":"depositAddress","type":"string"}],"name":"MerchantDepositAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"depositAddress","type":"string"},{"indexed":false,"internalType":"string","name":"txid","type":"string"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"MintConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"depositAddress","type":"string"},{"indexed":false,"internalType":"string","name":"txid","type":"string"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"MintRejected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"depositAddress","type":"string"},{"indexed":false,"internalType":"string","name":"txid","type":"string"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"MintRequestAdd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"MintRequestCancel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"txid","type":"string"},{"internalType":"string","name":"depositAddress","type":"string"}],"name":"addMintRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"txid","type":"string"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"burnRequestNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"burnRequests","outputs":[{"internalType":"address","name":"requester","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"depositAddress","type":"string"},{"internalType":"string","name":"txid","type":"string"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"enum FactoryInterface.RequestStatus","name":"status","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"cancelMintRequest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"confirmBurnRequest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"confirmMintRequest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract ControllerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"getBurnRequest","outputs":[{"internalType":"uint256","name":"requestNonce","type":"uint256"},{"internalType":"address","name":"requester","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"depositAddress","type":"string"},{"internalType":"string","name":"txid","type":"string"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"string","name":"status","type":"string"},{"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBurnRequestsLength","outputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"getMintRequest","outputs":[{"internalType":"uint256","name":"requestNonce","type":"uint256"},{"internalType":"address","name":"requester","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"depositAddress","type":"string"},{"internalType":"string","name":"txid","type":"string"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"string","name":"status","type":"string"},{"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMintRequestsLength","outputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"issuerDepositAddress","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"merchantBurnLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"merchantDepositAddress","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"merchantMintLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"mintRequestNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mintRequests","outputs":[{"internalType":"address","name":"requester","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"depositAddress","type":"string"},{"internalType":"string","name":"txid","type":"string"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"enum FactoryInterface.RequestStatus","name":"status","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"rejectMintRequest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"merchant","type":"address"},{"internalType":"string","name":"depositAddress","type":"string"}],"name":"setIssuerDepositAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"merchant","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMerchantBurnLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"depositAddress","type":"string"}],"name":"setMerchantDepositAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"merchant","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMerchantMintLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80637ff4ce7511610104578063b69b22d8116100a2578063e02c645d11610071578063e02c645d14610429578063e21c40c01461043c578063f2fde38b1461044f578063f77c47911461046257600080fd5b8063b69b22d8146103bc578063c06e2d24146103e3578063c4d66de8146103f6578063c72551be1461040957600080fd5b80638da5cb5b116100de5780638da5cb5b146103445780638e24a764146103695780638fc4d5e41461037c5780639ad4b86b1461039c57600080fd5b80637ff4ce75146103165780638456cb5914610329578063861f92a81461033157600080fd5b80635faf63e91161017c5780636ea9be801161014b5780636ea9be80146102d3578063715018a6146102f357806372f69a72146102fb5780637641e6f31461030357600080fd5b80635faf63e91461028757806360daba331461029a5780636406c10c146102ad57806365bf365d146102c057600080fd5b80633f4ba83a116101b85780633f4ba83a1461022c578063424e65751461023657806353a6bd441461025c5780635c975abb1461027c57600080fd5b80632bf90baa146101df578063311104f3146102075780633a0fa69014610219575b600080fd5b6101f26101ed366004612d63565b610475565b60405190151581526020015b60405180910390f35b609e545b6040519081526020016101fe565b6101f2610227366004612d7c565b61074d565b610234610874565b005b610249610244366004612d63565b610886565b6040516101fe9796959493929190612eee565b61026f61026a366004612ca7565b6109f4565b6040516101fe9190612f66565b60655460ff166101f2565b6101f2610295366004612d17565b610a8e565b6101f26102a8366004612d63565b610b47565b6102496102bb366004612d63565b610d3b565b6101f26102ce366004612cc9565b610d4b565b61020b6102e1366004612ca7565b60996020526000908152604090205481565b610234610fb7565b609f5461020b565b6101f2610311366004612db9565b610fc9565b6101f2610324366004612d17565b61144a565b610234611503565b6101f261033f366004612d63565b611513565b6033546001600160a01b03165b6040516001600160a01b0390911681526020016101fe565b61020b610377366004612dea565b611667565b61020b61038a366004612ca7565b60986020526000908152604090205481565b61020b6103aa366004612d63565b609c6020526000908152604090205481565b6103cf6103ca366004612d63565b611a3c565b6040516101fe989796959493929190613059565b6101f26103f1366004612d63565b611c73565b610234610404366004612ca7565b611e25565b61020b610417366004612d63565b609d6020526000908152604090205481565b61026f610437366004612ca7565b611f63565b6103cf61044a366004612d63565b611f7c565b61023461045d366004612ca7565b6122ab565b609754610351906001600160a01b031681565b60975460405163877b9a6760e01b81523360048201526000916001600160a01b03169063877b9a679060240160206040518083038186803b1580156104b957600080fd5b505afa1580156104cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f19190612d41565b6105165760405162461bcd60e51b815260040161050d90612fb0565b60405180910390fd5b6000610520612b14565b61052984612324565b80925081935050506003609e8381548110610546576105466131e1565b60009182526020909120600660079092020101805460ff19166001836004811115610573576105736131cb565b0217905550609754815160208301516040516340c10f1960e01b81526001600160a01b03928316600482015260248101919091529116906340c10f1990604401602060405180830381600087803b1580156105cd57600080fd5b505af11580156105e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106059190612d41565b61063f5760405162461bcd60e51b815260206004820152600b60248201526a1b5a5b9d0819985a5b195960aa1b604482015260640161050d565b60208082015182516001600160a01b03166000908152609890925260409091205410156106a85760405162461bcd60e51b815260206004820152601760248201527665786365656473206d65726368616e74206c696d69747360481b604482015260640161050d565b60208082015182516001600160a01b031660009081526098909252604082208054919290916106d890849061313b565b9250508190555080600001516001600160a01b031681608001517f051f4ba27061b0e6dc829669a7baa8bba9cf7f6cd2f95e1f0bdd9c22126d8b218360200151846040015185606001518660a001518a6040516107399594939291906130cf565b60405180910390a36001925050505b919050565b609754604051631a2f716760e01b81523360048201526000916001600160a01b031690631a2f71679060240160206040518083038186803b15801561079157600080fd5b505afa1580156107a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c99190612d41565b6107e55760405162461bcd60e51b815260040161050d90612fde565b6107ee82612563565b1561080b5760405162461bcd60e51b815260040161050d90612f79565b336000908152609b60209081526040909120835161082b92850190612b6a565b50336001600160a01b03167e2710e4743caa591c537cdab906e6a5d0f6466c6dcff14aeadeb4165f4252e3836040516108649190612f66565b60405180910390a2506001919050565b61087c612584565b6108846125de565b565b609e818154811061089657600080fd5b60009182526020909120600790910201805460018201546002830180546001600160a01b0390931694509092916108cc90613190565b80601f01602080910402602001604051908101604052809291908181526020018280546108f890613190565b80156109455780601f1061091a57610100808354040283529160200191610945565b820191906000526020600020905b81548152906001019060200180831161092857829003601f168201915b50505050509080600301805461095a90613190565b80601f016020809104026020016040519081016040528092919081815260200182805461098690613190565b80156109d35780601f106109a8576101008083540402835291602001916109d3565b820191906000526020600020905b8154815290600101906020018083116109b657829003601f168201915b50505050600483015460058401546006909401549293909290915060ff1687565b609b6020526000908152604090208054610a0d90613190565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3990613190565b8015610a865780601f10610a5b57610100808354040283529160200191610a86565b820191906000526020600020905b815481529060010190602001808311610a6957829003601f168201915b505050505081565b60975460405163877b9a6760e01b81523360048201526000916001600160a01b03169063877b9a679060240160206040518083038186803b158015610ad257600080fd5b505afa158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a9190612d41565b610b265760405162461bcd60e51b815260040161050d90612fb0565b506001600160a01b0391909116600090815260996020526040902055600190565b60975460405163877b9a6760e01b81523360048201526000916001600160a01b03169063877b9a679060240160206040518083038186803b158015610b8b57600080fd5b505afa158015610b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc39190612d41565b610bdf5760405162461bcd60e51b815260040161050d90612fb0565b6000610be9612b14565b610bf284612630565b80925081935050506003609f8381548110610c0f57610c0f6131e1565b60009182526020909120600660079092020101805460ff19166001836004811115610c3c57610c3c6131cb565b021790555060208082015182516001600160a01b0316600090815260999092526040909120541015610caa5760405162461bcd60e51b815260206004820152601760248201527665786365656473206d65726368616e74206c696d69747360481b604482015260640161050d565b60208082015182516001600160a01b03166000908152609990925260408220805491929091610cda90849061313b565b9250508190555080600001516001600160a01b031681608001517f1949e77206780c38f7c6487c926f8a51280fcdbf63397a01a3428dbfccd2b09f8360200151846040015185606001518660a001518a6040516107399594939291906130cf565b609f818154811061089657600080fd5b60975460405163877b9a6760e01b81523360048201526000916001600160a01b03169063877b9a679060240160206040518083038186803b158015610d8f57600080fd5b505afa158015610da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc79190612d41565b610de35760405162461bcd60e51b815260040161050d90612fb0565b6001600160a01b038316610e395760405162461bcd60e51b815260206004820152601860248201527f696e76616c6964206d65726368616e7420616464726573730000000000000000604482015260640161050d565b609754604051631a2f716760e01b81526001600160a01b03858116600483015290911690631a2f71679060240160206040518083038186803b158015610e7e57600080fd5b505afa158015610e92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb69190612d41565b610f135760405162461bcd60e51b815260206004820152602860248201527f6d65726368616e742061646472657373206973206e6f742061207265616c206d60448201526732b931b430b73a1760c11b606482015260840161050d565b610f1c82612563565b15610f395760405162461bcd60e51b815260040161050d90612f79565b6001600160a01b0383166000908152609a602090815260409091208351610f6292850190612b6a565b50336001600160a01b0316836001600160a01b03167f07d5a2155468a86efbf358a53211f66c37ab9db71d9390514a787311584ec5e184604051610fa69190612f66565b60405180910390a350600192915050565b610fbf612584565b61088460006126a2565b609754604051631a2f716760e01b81523360048201526000916001600160a01b031690631a2f71679060240160206040518083038186803b15801561100d57600080fd5b505afa158015611021573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110459190612d41565b6110615760405162461bcd60e51b815260040161050d90612fde565b6110696126f4565b336000908152609960205260409020548311156110bd5760405162461bcd60e51b8152602060048201526012602482015271195e18d959591cc8189d5c9b881b1a5b5a5d60721b604482015260640161050d565b336000908152609b6020526040812080546110d790613190565b80601f016020809104026020016040519081016040528092919081815260200182805461110390613190565b80156111505780601f1061112557610100808354040283529160200191611150565b820191906000526020600020905b81548152906001019060200180831161113357829003601f168201915b5050505050905061116081612563565b156111c05760405162461bcd60e51b815260206004820152602a60248201527f6d65726368616e74206173736574206465706f73697420616464726573732077604482015269185cc81b9bdd081cd95d60b21b606482015260840161050d565b609f546040805160e0810182523381526020810187905290810183905260608101859052608081018290524260a08201819052600160c08301529060006112068261273a565b6000818152609d60209081526040808320889055609f8054600181018255935285517f0bc14066c33013fe88f66e314e4cf150b0b2d4d6451a1a51dbbd1c27cd11de28600790940293840180546001600160a01b0319166001600160a01b03909216919091178155868301517f0bc14066c33013fe88f66e314e4cf150b0b2d4d6451a1a51dbbd1c27cd11de29850155908601518051949550869491936112d4937f0bc14066c33013fe88f66e314e4cf150b0b2d4d6451a1a51dbbd1c27cd11de2a90910192910190612b6a565b50606082015180516112f0916003840191602090910190612b6a565b506080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff0219169083600481111561132f5761132f6131cb565b021790555050609754604051632770a7eb60e21b8152336004820152602481018b90526001600160a01b039091169150639dc29fac90604401602060405180830381600087803b15801561138257600080fd5b505af1158015611396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ba9190612d41565b6113f45760405162461bcd60e51b815260206004820152600b60248201526a189d5c9b8819985a5b195960aa1b604482015260640161050d565b336001600160a01b0316847f865e64c3fa22a0daee479fc02875d3e97d581930b9679232344d4d5dcce6a7b28a888786604051611434949392919061310f565b60405180910390a3506001979650505050505050565b60975460405163877b9a6760e01b81523360048201526000916001600160a01b03169063877b9a679060240160206040518083038186803b15801561148e57600080fd5b505afa1580156114a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c69190612d41565b6114e25760405162461bcd60e51b815260040161050d90612fb0565b506001600160a01b0391909116600090815260986020526040902055600190565b61150b612584565b610884612787565b60975460405163877b9a6760e01b81523360048201526000916001600160a01b03169063877b9a679060240160206040518083038186803b15801561155757600080fd5b505afa15801561156b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158f9190612d41565b6115ab5760405162461bcd60e51b815260040161050d90612fb0565b60006115b5612b14565b6115be84612324565b80925081935050506004609e83815481106115db576115db6131e1565b60009182526020909120600660079092020101805460ff19166001836004811115611608576116086131cb565b021790555080600001516001600160a01b031681608001517fdadc06f5b98131083e96b856c044184efd23ae2e797a876fd80aa5dae4f724558360200151846040015185606001518660a001518a6040516107399594939291906130cf565b609754604051631a2f716760e01b81523360048201526000916001600160a01b031690631a2f71679060240160206040518083038186803b1580156116ab57600080fd5b505afa1580156116bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e39190612d41565b6116ff5760405162461bcd60e51b815260040161050d90612fde565b6117076126f4565b61171082612563565b1561172d5760405162461bcd60e51b815260040161050d90612f79565b336000908152609a6020526040902080546117d091849161174d90613190565b80601f016020809104026020016040519081016040528092919081815260200182805461177990613190565b80156117c65780601f1061179b576101008083540402835291602001916117c6565b820191906000526020600020905b8154815290600101906020018083116117a957829003601f168201915b50505050506127c4565b61181c5760405162461bcd60e51b815260206004820152601b60248201527f77726f6e67206173736574206465706f73697420616464726573730000000000604482015260640161050d565b336000908152609860205260409020548411156118705760405162461bcd60e51b8152602060048201526012602482015271195e18d959591cc81b5a5b9d081b1a5b5a5d60721b604482015260640161050d565b609e546040805160e0810182523381526020810187905290810184905260608101859052608081018290524260a08201819052600160c08301529060006118b68261273a565b6000818152609c60209081526040808320889055609e8054600181018255935285517fcfe2a20ff701a1f3e14f63bd70d6c6bc6fba8172ec6d5a505cdab3927c0a9de6600790940293840180546001600160a01b0319166001600160a01b03909216919091178155868301517fcfe2a20ff701a1f3e14f63bd70d6c6bc6fba8172ec6d5a505cdab3927c0a9de785015590860151805194955086949193611984937fcfe2a20ff701a1f3e14f63bd70d6c6bc6fba8172ec6d5a505cdab3927c0a9de890910192910190612b6a565b50606082015180516119a0916003840191602090910190612b6a565b506080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff021916908360048111156119df576119df6131cb565b02179055505050336001600160a01b0316847f09e00024b3e14e42d4e78c05bf370a34c2e4ce4027dad38abafdb1bf49da432f8a898b8887604051611a289594939291906130cf565b60405180910390a350919695505050505050565b600080600060608060006060600080609e8a81548110611a5e57611a5e6131e1565b90600052602060002090600702016040518060e00160405290816000820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160018201548152602001600282018054611ac090613190565b80601f0160208091040260200160405190810160405280929190818152602001828054611aec90613190565b8015611b395780601f10611b0e57610100808354040283529160200191611b39565b820191906000526020600020905b815481529060010190602001808311611b1c57829003601f168201915b50505050508152602001600382018054611b5290613190565b80601f0160208091040260200160405190810160405280929190818152602001828054611b7e90613190565b8015611bcb5780601f10611ba057610100808354040283529160200191611bcb565b820191906000526020600020905b815481529060010190602001808311611bae57829003601f168201915b5050509183525050600482810154602083015260058301546040830152600683015460609092019160ff1690811115611c0657611c066131cb565b6004811115611c1757611c176131cb565b8152505090506000611c2c8260c0015161281d565b905081608001519950816000015198508160200151975081604001519650816060015195508160a001519450809350611c648261273a565b92505050919395975091939597565b609754604051631a2f716760e01b81523360048201526000916001600160a01b031690631a2f71679060240160206040518083038186803b158015611cb757600080fd5b505afa158015611ccb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cef9190612d41565b611d0b5760405162461bcd60e51b815260040161050d90612fde565b611d136126f4565b6000611d1d612b14565b611d2684612324565b805191935091506001600160a01b03163314611daa5760405162461bcd60e51b815260206004820152603960248201527f63616e63656c2073656e64657220697320646966666572656e74207468616e2060448201527f70656e64696e67207265717565737420696e69746961746f7200000000000000606482015260840161050d565b6002609e8381548110611dbf57611dbf6131e1565b60009182526020909120600660079092020101805460ff19166001836004811115611dec57611dec6131cb565b0217905550604051848152339083907fb419f275eebfa354bbab2709955ee0c0e25ca95fae50a8e3672c5e3d9c931f5890602001610739565b600054610100900460ff1615808015611e455750600054600160ff909116105b80611e5f5750303b158015611e5f575060005460ff166001145b611ec25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161050d565b6000805460ff191660011790558015611ee5576000805461ff0019166101001790555b609780546001600160a01b0319166001600160a01b038416179055611f08612939565b611f10612968565b611f19826122ab565b8015611f5f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b609a6020526000908152604090208054610a0d90613190565b600080600060608060006060600080609f8a81548110611f9e57611f9e6131e1565b600091825260208220600660079092020190810154909250611fc29060ff1661281d565b600483015483546001850154600286018054939e506001600160a01b039092169c509a50919250611ff290613190565b80601f016020809104026020016040519081016040528092919081815260200182805461201e90613190565b801561206b5780601f106120405761010080835404028352916020019161206b565b820191906000526020600020905b81548152906001019060200180831161204e57829003601f168201915b5050505050965081600301805461208190613190565b80601f01602080910402602001604051908101604052809291908181526020018280546120ad90613190565b80156120fa5780601f106120cf576101008083540402835291602001916120fa565b820191906000526020600020905b8154815290600101906020018083116120dd57829003601f168201915b50505060058501546040805160e08101825287546001600160a01b0316815260018801546020820152600288018054969c50929a509598508895611c6495909450879350908401919061214c90613190565b80601f016020809104026020016040519081016040528092919081815260200182805461217890613190565b80156121c55780601f1061219a576101008083540402835291602001916121c5565b820191906000526020600020905b8154815290600101906020018083116121a857829003601f168201915b505050505081526020016003820180546121de90613190565b80601f016020809104026020016040519081016040528092919081815260200182805461220a90613190565b80156122575780601f1061222c57610100808354040283529160200191612257565b820191906000526020600020905b81548152906001019060200180831161223a57829003601f168201915b5050509183525050600482810154602083015260058301546040830152600683015460609092019160ff1690811115612292576122926131cb565b60048111156122a3576122a36131cb565b90525061273a565b6122b3612584565b6001600160a01b0381166123185760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161050d565b612321816126a2565b50565b600061232e612b14565b8261236f5760405162461bcd60e51b81526020600482015260116024820152700726571756573742068617368206973203607c1b604482015260640161050d565b6000838152609c6020526040902054609e80549193509083908110612396576123966131e1565b90600052602060002090600702016040518060e00160405290816000820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600182015481526020016002820180546123f890613190565b80601f016020809104026020016040519081016040528092919081815260200182805461242490613190565b80156124715780601f1061244657610100808354040283529160200191612471565b820191906000526020600020905b81548152906001019060200180831161245457829003601f168201915b5050505050815260200160038201805461248a90613190565b80601f01602080910402602001604051908101604052809291908181526020018280546124b690613190565b80156125035780601f106124d857610100808354040283529160200191612503565b820191906000526020600020905b8154815290600101906020018083116124e657829003601f168201915b5050509183525050600482810154602083015260058301546040830152600683015460609092019160ff169081111561253e5761253e6131cb565b600481111561254f5761254f6131cb565b905250905061255e8184612997565b915091565b600061257e82604051806020016040528060008152506127c4565b92915050565b6033546001600160a01b031633146108845760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050d565b6125e6612a68565b6065805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600061263a612b14565b8261267b5760405162461bcd60e51b81526020600482015260116024820152700726571756573742068617368206973203607c1b604482015260640161050d565b6000838152609d6020526040902054609f80549193509083908110612396576123966131e1565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60655460ff16156108845760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161050d565b80516020808301516040808501516060860151608087015160a0880151935160009761276a979096959101612e9f565b604051602081830303815290604052805190602001209050919050565b61278f6126f4565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586126133390565b6000816040516020016127d79190612e83565b60405160208183030381529060405280519060200120836040516020016127fe9190612e83565b6040516020818303038152906040528051906020012014905092915050565b60606001826004811115612833576128336131cb565b141561285c57505060408051808201909152600781526670656e64696e6760c81b602082015290565b6002826004811115612870576128706131cb565b141561289a57505060408051808201909152600881526718d85b98d95b195960c21b602082015290565b60038260048111156128ae576128ae6131cb565b14156128d8575050604080518082019091526008815267185c1c1c9bdd995960c21b602082015290565b60048260048111156128ec576128ec6131cb565b14156129165750506040805180820190915260088152671c995a9958dd195960c21b602082015290565b50506040805180820190915260078152663ab735b737bbb760c91b602082015290565b600054610100900460ff166129605760405162461bcd60e51b815260040161050d9061300e565b610884612ab1565b600054610100900460ff1661298f5760405162461bcd60e51b815260040161050d9061300e565b610884612ae1565b60018260c0015160048111156129af576129af6131cb565b146129f55760405162461bcd60e51b815260206004820152601660248201527572657175657374206973206e6f742070656e64696e6760501b604482015260640161050d565b6129fe8261273a565b8114611f5f5760405162461bcd60e51b815260206004820152603360248201527f676976656e2072657175657374206861736820646f6573206e6f74206d6174636044820152721a0818481c195b991a5b99c81c995c5d595cdd606a1b606482015260840161050d565b60655460ff166108845760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161050d565b600054610100900460ff16612ad85760405162461bcd60e51b815260040161050d9061300e565b610884336126a2565b600054610100900460ff16612b085760405162461bcd60e51b815260040161050d9061300e565b6065805460ff19169055565b6040518060e0016040528060006001600160a01b03168152602001600081526020016060815260200160608152602001600081526020016000815260200160006004811115612b6557612b656131cb565b905290565b828054612b7690613190565b90600052602060002090601f016020900481019282612b985760008555612bde565b82601f10612bb157805160ff1916838001178555612bde565b82800160010185558215612bde579182015b82811115612bde578251825591602001919060010190612bc3565b50612bea929150612bee565b5090565b5b80821115612bea5760008155600101612bef565b80356001600160a01b038116811461074857600080fd5b600082601f830112612c2b57600080fd5b813567ffffffffffffffff80821115612c4657612c466131f7565b604051601f8301601f19908116603f01168101908282118183101715612c6e57612c6e6131f7565b81604052838152866020858801011115612c8757600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612cb957600080fd5b612cc282612c03565b9392505050565b60008060408385031215612cdc57600080fd5b612ce583612c03565b9150602083013567ffffffffffffffff811115612d0157600080fd5b612d0d85828601612c1a565b9150509250929050565b60008060408385031215612d2a57600080fd5b612d3383612c03565b946020939093013593505050565b600060208284031215612d5357600080fd5b81518015158114612cc257600080fd5b600060208284031215612d7557600080fd5b5035919050565b600060208284031215612d8e57600080fd5b813567ffffffffffffffff811115612da557600080fd5b612db184828501612c1a565b949350505050565b60008060408385031215612dcc57600080fd5b82359150602083013567ffffffffffffffff811115612d0157600080fd5b600080600060608486031215612dff57600080fd5b83359250602084013567ffffffffffffffff80821115612e1e57600080fd5b612e2a87838801612c1a565b93506040860135915080821115612e4057600080fd5b50612e4d86828701612c1a565b9150509250925092565b60008151808452612e6f816020860160208601613160565b601f01601f19169290920160200192915050565b60008251612e95818460208701613160565b9190910192915050565b60018060a01b038716815285602082015260c060408201526000612ec660c0830187612e57565b8281036060840152612ed88187612e57565b6080840195909552505060a00152949350505050565b60018060a01b038816815286602082015260e060408201526000612f1560e0830188612e57565b8281036060840152612f278188612e57565b9150508460808301528360a083015260058310612f5457634e487b7160e01b600052602160045260246000fd5b8260c083015298975050505050505050565b602081526000612cc26020830184612e57565b6020808252601d908201527f696e76616c6964206173736574206465706f7369742061646472657373000000604082015260600190565b60208082526014908201527339b2b73232b9103737ba10309034b9b9bab2b91760611b604082015260600190565b60208082526016908201527539b2b73232b9103737ba10309036b2b931b430b73a1760511b604082015260600190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8881526001600160a01b0388166020820152604081018790526101006060820181905260009061308b83820189612e57565b9050828103608084015261309f8188612e57565b90508560a084015282810360c08401526130b98186612e57565b9150508260e08301529998505050505050505050565b85815260a0602082015260006130e860a0830187612e57565b82810360408401526130fa8187612e57565b60608401959095525050608001529392505050565b8481526080602082015260006131286080830186612e57565b6040830194909452506060015292915050565b60008282101561315b57634e487b7160e01b600052601160045260246000fd5b500390565b60005b8381101561317b578181015183820152602001613163565b8381111561318a576000848401525b50505050565b600181811c908216806131a457607f821691505b602082108114156131c557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220ad2c54d8223833fa780bbe5182c42cea2306d664ace0a5e890fe9a72ef78ad4064736f6c63430008070033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.