More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 474 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap Transfer Wi... | 21464536 | 5 days ago | IN | 0 ETH | 0.00238424 | ||||
Swap Transfer Wi... | 21449865 | 7 days ago | IN | 0 ETH | 0.00294922 | ||||
Swap Transfer Wi... | 21403199 | 14 days ago | IN | 0 ETH | 0.00220675 | ||||
Swap Transfer Wi... | 21396532 | 14 days ago | IN | 0 ETH | 0.00336291 | ||||
Swap Transfer Wi... | 21395217 | 15 days ago | IN | 0 ETH | 0.00579479 | ||||
Swap Transfer Wi... | 21389257 | 15 days ago | IN | 0 ETH | 0.00623031 | ||||
Swap Transfer Wi... | 21337667 | 23 days ago | IN | 0 ETH | 0.00742871 | ||||
Swap Transfer Wi... | 21334487 | 23 days ago | IN | 0 ETH | 0.00607174 | ||||
Swap Transfer Wi... | 21334395 | 23 days ago | IN | 0 ETH | 0.00517718 | ||||
Swap Transfer Wi... | 21334381 | 23 days ago | IN | 0 ETH | 0.00541988 | ||||
Swap Transfer Wi... | 21323339 | 25 days ago | IN | 0 ETH | 0.00881928 | ||||
Swap Transfer Wi... | 21310653 | 26 days ago | IN | 0 ETH | 0.00393705 | ||||
Swap Transfer Wi... | 21310036 | 27 days ago | IN | 0 ETH | 0.00696242 | ||||
Swap Transfer Wi... | 21285961 | 30 days ago | IN | 0 ETH | 0.0020039 | ||||
Swap Transfer Wi... | 21285302 | 30 days ago | IN | 0 ETH | 0.00216652 | ||||
Swap Transfer Wi... | 21284258 | 30 days ago | IN | 0 ETH | 0.00283606 | ||||
Swap Transfer Wi... | 21273408 | 32 days ago | IN | 0 ETH | 0.00348778 | ||||
Swap Transfer Wi... | 21238596 | 37 days ago | IN | 0 ETH | 0.00571292 | ||||
Swap Transfer Wi... | 21235830 | 37 days ago | IN | 0 ETH | 0.00438125 | ||||
Swap Transfer Wi... | 21224079 | 39 days ago | IN | 0 ETH | 0.00533056 | ||||
Swap Transfer Wi... | 21214727 | 40 days ago | IN | 0 ETH | 0.00308579 | ||||
Swap Transfer Wi... | 21206235 | 41 days ago | IN | 0 ETH | 0.00292002 | ||||
Swap Transfer Wi... | 21193526 | 43 days ago | IN | 0 ETH | 0.00893622 | ||||
Swap Transfer Wi... | 21193513 | 43 days ago | IN | 0 ETH | 0.00994942 | ||||
Swap Transfer Wi... | 21186959 | 44 days ago | IN | 0 ETH | 0.00914556 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
14660280 | 977 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
ERC20SwapToConversion
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts/access/Ownable.sol'; import './lib/SafeERC20.sol'; import './interfaces/IERC20ConversionProxy.sol'; import './ChainlinkConversionPath.sol'; interface ISwapRouter { function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); } /** * @title ERC20SwapToConversion * @notice This contract swaps ERC20 tokens before paying a request thanks to a payment proxy */ contract ERC20SwapToConversion is Ownable { using SafeERC20 for IERC20; ISwapRouter public swapRouter; ChainlinkConversionPath public chainlinkConversionPath; // Fees taken by request when a payment is made through swap. Range 0-1000. 10 => 1% fees. uint256 public requestSwapFees; constructor(address _owner) { _transferOwnership(_owner); } /** * @notice Performs a request payment, denominated in a token or currency A, * where the issuer expects a token B, and the payer uses a token C. * The conversion rate from A to B is done using Chainlink. * The token swap is done using UniswapV2 or equivalent. * @param _paymentProxy Address of the ERC20ConversionProxy which will perform the payment. * @param _to Transfer recipient = request issuer * @param _requestAmount Amount to transfer in request currency * @param _amountInMax Maximum amount allowed to spend for currency swap, in payment network currency. This amount should take into account the fees. @param _swapRouterPath, path of ERC20 tokens to swap from spentToken to expectedToken. The first address of the path should be the spent currency. The last element should be the expected currency. @param _chainlinkPath, path of currencies to convert from invoicing currency to expectedToken. The first address of the path should be the invoicing currency. The last element should be the expected currency. * @param _paymentReference Reference of the payment related * @param _requestFeeAmount Amount of the fee in request currency * @param _feeAddress Where to pay the fee * @param _deadline Deadline for the swap to be valid * @param _chainlinkMaxRateTimespan Max time span with the oldestrate, ignored if zero */ function swapTransferWithReference( address _paymentProxy, address _to, uint256 _requestAmount, // requestCurrency uint256 _amountInMax, // SpentToken address[] memory _swapRouterPath, // from spentToken to expectedToken on the swap router address[] memory _chainlinkPath, // from invoicingCurrency to expectedToken on chainlink bytes memory _paymentReference, uint256 _requestFeeAmount, // requestCurrency address _feeAddress, uint256 _deadline, uint256 _chainlinkMaxRateTimespan ) external { require( _swapRouterPath[_swapRouterPath.length - 1] == _chainlinkPath[_chainlinkPath.length - 1], 'the requested token on the swap router must be the payment currency' ); require(_feeAddress != address(0), 'Invalid fee addres'); // Get the amount to pay in paymentNetworkToken uint256 paymentNetworkTotalAmount = _getConversion( _chainlinkPath, _requestAmount, _requestFeeAmount ); // Compute the request swap fees uint256 requestSwapFeesAmount = (paymentNetworkTotalAmount * requestSwapFees) / 1000; require( IERC20(_swapRouterPath[0]).safeTransferFrom(msg.sender, address(this), _amountInMax), 'Could not transfer payment token from swapper-payer' ); _swapAndApproveIfNeeded( _paymentProxy, _amountInMax, _swapRouterPath, _deadline, paymentNetworkTotalAmount + requestSwapFeesAmount ); IERC20ConversionProxy paymentProxy = IERC20ConversionProxy(_paymentProxy); // Pay the request and fees try paymentProxy.transferFromWithReferenceAndFee( _to, _requestAmount, _chainlinkPath, _paymentReference, _requestFeeAmount, _feeAddress, paymentNetworkTotalAmount, // _maxToSpend _chainlinkMaxRateTimespan ) {} catch ( bytes memory /*lowLevelData*/ ) { revert('Invalid payment proxy'); } // Pay the request swap fees IERC20(_swapRouterPath[_swapRouterPath.length - 1]).safeTransfer( _feeAddress, requestSwapFeesAmount ); // Give the change back to the payer, in both currencies (only spent token should remain) if (IERC20(_swapRouterPath[0]).balanceOf(address(this)) > 0) { IERC20(_swapRouterPath[0]).safeTransfer( msg.sender, IERC20(_swapRouterPath[0]).balanceOf(address(this)) ); } if (IERC20(_swapRouterPath[_swapRouterPath.length - 1]).balanceOf(address(this)) > 0) { IERC20(_swapRouterPath[_swapRouterPath.length - 1]).safeTransfer( msg.sender, IERC20(_swapRouterPath[_swapRouterPath.length - 1]).balanceOf(address(this)) ); } } /** * @notice Authorizes the proxy to spend a new request currency (ERC20). * @param _erc20Address Address of an ERC20 used as a request currency * @param _paymentProxy Address of the payment proxy to approve */ function approvePaymentProxyToSpend(address _erc20Address, address _paymentProxy) public { IERC20 erc20 = IERC20(_erc20Address); uint256 max = 2**256 - 1; erc20.safeApprove(_paymentProxy, max); } /** * @notice Authorizes the swap router to spend a new payment currency (ERC20). * @param _erc20Address Address of an ERC20 used for payment */ function approveRouterToSpend(address _erc20Address) public { IERC20 erc20 = IERC20(_erc20Address); uint256 max = 2**256 - 1; erc20.safeApprove(address(swapRouter), max); } /* * Admin functions to edit the router address, the fees amount and the fees collector address */ function setRouter(address _newSwapRouterAddress) public onlyOwner { swapRouter = ISwapRouter(_newSwapRouterAddress); } function updateRequestSwapFees(uint256 _newRequestSwapFees) public onlyOwner { requestSwapFees = _newRequestSwapFees; } function updateConversionPathAddress(address _chainlinkConversionPath) public onlyOwner { chainlinkConversionPath = ChainlinkConversionPath(_chainlinkConversionPath); } /* * Internal functions to reduce the stack in swapTransferWithReference() */ function _getConversion( address[] memory _path, uint256 _requestAmount, uint256 _requestFeeAmount ) internal view returns (uint256 conversion) { (conversion, ) = chainlinkConversionPath.getConversion( _requestAmount + _requestFeeAmount, _path ); } /** * Internal functions to reduce the stack in swapTransferWithReference() * Approve the SwapRouter to spend the spentToken if needed * Swap the spentToken in exchange for the expectedToken * Approve the payment proxy to spend the expected token if needed. */ function _swapAndApproveIfNeeded( address _paymentProxy, uint256 _amountInMax, // SpentToken address[] memory _swapRouterPath, // from spentToken to expectedToken on the swap router uint256 _deadline, uint256 _paymentNetworkTotalAmount ) internal { IERC20 spentToken = IERC20(_swapRouterPath[0]); // Allow the router to spend all this contract's spentToken if (spentToken.allowance(address(this), address(swapRouter)) < _amountInMax) { approveRouterToSpend(address(spentToken)); } swapRouter.swapTokensForExactTokens( _paymentNetworkTotalAmount, _amountInMax, _swapRouterPath, address(this), _deadline ); IERC20 requestedToken = IERC20(_swapRouterPath[_swapRouterPath.length - 1]); // Allow the payment network to spend all this contract's requestedToken if (requestedToken.allowance(address(this), _paymentProxy) < _paymentNetworkTotalAmount) { approvePaymentProxyToSpend(address(requestedToken), _paymentProxy); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { 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); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/ERC20.sol'; /** * @title SafeERC20 * @notice Works around implementations of ERC20 with transferFrom not returning success status. */ library SafeERC20 { /** * @notice Call transferFrom ERC20 function and validates the return data of a ERC20 contract call. * @dev This is necessary because of non-standard ERC20 tokens that don't have a return value. * @return result The return value of the ERC20 call, returning true for non-standard tokens */ function safeTransferFrom( IERC20 _token, address _from, address _to, uint256 _amount ) internal returns (bool result) { // solium-disable-next-line security/no-low-level-calls (bool success, bytes memory data) = address(_token).call( abi.encodeWithSignature('transferFrom(address,address,uint256)', _from, _to, _amount) ); return success && (data.length == 0 || abi.decode(data, (bool))); } /** * @notice Call approve ERC20 function and validates the return data of a ERC20 contract call. * @dev This is necessary because of non-standard ERC20 tokens that don't have a return value. * @return result The return value of the ERC20 call, returning true for non-standard tokens */ function safeApprove( IERC20 _token, address _spender, uint256 _amount ) internal returns (bool result) { // solium-disable-next-line security/no-low-level-calls (bool success, bytes memory data) = address(_token).call( abi.encodeWithSignature('approve(address,uint256)', _spender, _amount) ); return success && (data.length == 0 || abi.decode(data, (bool))); } /** * @notice Call transfer ERC20 function and validates the return data of a ERC20 contract call. * @dev This is necessary because of non-standard ERC20 tokens that don't have a return value. * @return result The return value of the ERC20 call, returning true for non-standard tokens */ function safeTransfer( IERC20 _token, address _to, uint256 _amount ) internal returns (bool result) { // solium-disable-next-line security/no-low-level-calls (bool success, bytes memory data) = address(_token).call( abi.encodeWithSignature('transfer(address,uint256)', _to, _amount) ); return success && (data.length == 0 || abi.decode(data, (bool))); } }
pragma solidity ^0.8.0; interface IERC20ConversionProxy { // Event to declare a conversion with a reference event TransferWithConversionAndReference( uint256 amount, address currency, bytes indexed paymentReference, uint256 feeAmount, uint256 maxRateTimespan ); // Event to declare a transfer with a reference event TransferWithReferenceAndFee( address tokenAddress, address to, uint256 amount, bytes indexed paymentReference, uint256 feeAmount, address feeAddress ); function transferFromWithReferenceAndFee( address _to, uint256 _requestAmount, address[] calldata _path, bytes calldata _paymentReference, uint256 _feeAmount, address _feeAddress, uint256 _maxToSpend, uint256 _maxRateTimespan ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import './legacy_openzeppelin/contracts/access/roles/WhitelistAdminRole.sol'; interface ERC20fraction { function decimals() external view returns (uint8); } interface AggregatorFraction { function decimals() external view returns (uint8); function latestAnswer() external view returns (int256); function latestTimestamp() external view returns (uint256); } /** * @title ChainlinkConversionPath * * @notice ChainlinkConversionPath is a contract computing currency conversion rates based on Chainlink aggretators */ contract ChainlinkConversionPath is WhitelistAdminRole { uint256 constant PRECISION = 1e18; uint256 constant NATIVE_TOKEN_DECIMALS = 18; uint256 constant FIAT_DECIMALS = 8; address public nativeTokenHash; /** * @param _nativeTokenHash hash of the native token */ constructor(address _nativeTokenHash) { nativeTokenHash = _nativeTokenHash; } // Mapping of Chainlink aggregators (input currency => output currency => contract address) // input & output currencies are the addresses of the ERC20 contracts OR the sha3("currency code") mapping(address => mapping(address => address)) public allAggregators; // declare a new aggregator event AggregatorUpdated(address _input, address _output, address _aggregator); /** * @notice Update an aggregator * @param _input address representing the input currency * @param _output address representing the output currency * @param _aggregator address of the aggregator contract */ function updateAggregator( address _input, address _output, address _aggregator ) external onlyWhitelistAdmin { allAggregators[_input][_output] = _aggregator; emit AggregatorUpdated(_input, _output, _aggregator); } /** * @notice Update a list of aggregators * @param _inputs list of addresses representing the input currencies * @param _outputs list of addresses representing the output currencies * @param _aggregators list of addresses of the aggregator contracts */ function updateAggregatorsList( address[] calldata _inputs, address[] calldata _outputs, address[] calldata _aggregators ) external onlyWhitelistAdmin { require(_inputs.length == _outputs.length, 'arrays must have the same length'); require(_inputs.length == _aggregators.length, 'arrays must have the same length'); // For every conversions of the path for (uint256 i; i < _inputs.length; i++) { allAggregators[_inputs[i]][_outputs[i]] = _aggregators[i]; emit AggregatorUpdated(_inputs[i], _outputs[i], _aggregators[i]); } } /** * @notice Computes the conversion of an amount through a list of intermediate conversions * @param _amountIn Amount to convert * @param _path List of addresses representing the currencies for the intermediate conversions * @return result The result after all the conversions * @return oldestRateTimestamp The oldest timestamp of the path */ function getConversion(uint256 _amountIn, address[] calldata _path) external view returns (uint256 result, uint256 oldestRateTimestamp) { (uint256 rate, uint256 timestamp, uint256 decimals) = getRate(_path); // initialize the result result = (_amountIn * rate) / decimals; oldestRateTimestamp = timestamp; } /** * @notice Computes the conversion rate from a list of currencies * @param _path List of addresses representing the currencies for the conversions * @return rate The rate * @return oldestRateTimestamp The oldest timestamp of the path * @return decimals of the conversion rate */ function getRate(address[] memory _path) public view returns ( uint256 rate, uint256 oldestRateTimestamp, uint256 decimals ) { // initialize the result with 18 decimals (for more precision) rate = PRECISION; decimals = PRECISION; oldestRateTimestamp = block.timestamp; // For every conversion of the path for (uint256 i; i < _path.length - 1; i++) { ( AggregatorFraction aggregator, bool reverseAggregator, uint256 decimalsInput, uint256 decimalsOutput ) = getAggregatorAndDecimals(_path[i], _path[i + 1]); // store the latest timestamp of the path uint256 currentTimestamp = aggregator.latestTimestamp(); if (currentTimestamp < oldestRateTimestamp) { oldestRateTimestamp = currentTimestamp; } // get the rate of the current step uint256 currentRate = uint256(aggregator.latestAnswer()); // get the number of decimals of the current rate uint256 decimalsAggregator = uint256(aggregator.decimals()); // mul with the difference of decimals before the current rate computation (for more precision) if (decimalsAggregator > decimalsInput) { rate = rate * (10**(decimalsAggregator - decimalsInput)); } if (decimalsAggregator < decimalsOutput) { rate = rate * (10**(decimalsOutput - decimalsAggregator)); } // Apply the current rate (if path uses an aggregator in the reverse way, div instead of mul) if (reverseAggregator) { rate = (rate * (10**decimalsAggregator)) / currentRate; } else { rate = (rate * currentRate) / (10**decimalsAggregator); } // div with the difference of decimals AFTER the current rate computation (for more precision) if (decimalsAggregator < decimalsInput) { rate = rate / (10**(decimalsInput - decimalsAggregator)); } if (decimalsAggregator > decimalsOutput) { rate = rate / (10**(decimalsAggregator - decimalsOutput)); } } } /** * @notice Gets aggregators and decimals of two currencies * @param _input input Address * @param _output output Address * @return aggregator to get the rate between the two currencies * @return reverseAggregator true if the aggregator returned give the rate from _output to _input * @return decimalsInput decimals of _input * @return decimalsOutput decimals of _output */ function getAggregatorAndDecimals(address _input, address _output) private view returns ( AggregatorFraction aggregator, bool reverseAggregator, uint256 decimalsInput, uint256 decimalsOutput ) { // Try to get the right aggregator for the conversion aggregator = AggregatorFraction(allAggregators[_input][_output]); reverseAggregator = false; // if no aggregator found we try to find an aggregator in the reverse way if (address(aggregator) == address(0x00)) { aggregator = AggregatorFraction(allAggregators[_output][_input]); reverseAggregator = true; } require(address(aggregator) != address(0x00), 'No aggregator found'); // get the decimals for the two currencies decimalsInput = getDecimals(_input); decimalsOutput = getDecimals(_output); } /** * @notice Gets decimals from an address currency * @param _addr address to check * @return decimals number of decimals */ function getDecimals(address _addr) private view returns (uint256 decimals) { // by default we assume it is fiat decimals = FIAT_DECIMALS; // if address is the hash of the ETH currency if (_addr == nativeTokenHash) { decimals = NATIVE_TOKEN_DECIMALS; } else if (isContract(_addr)) { // otherwise, we get the decimals from the erc20 directly decimals = ERC20fraction(_addr).decimals(); } } /** * @notice Checks if an address is a contract * @param _addr Address to check * @return true if the address hosts a contract, false otherwise */ function isContract(address _addr) private view returns (bool) { uint32 size; // solium-disable security/no-inline-assembly assembly { size := extcodesize(_addr) } return (size > 0); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '@openzeppelin/contracts/utils/Context.sol'; import '../Roles.sol'; /** * @title WhitelistAdminRole * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts. */ abstract contract WhitelistAdminRole is Context { using Roles for Roles.Role; event WhitelistAdminAdded(address indexed account); event WhitelistAdminRemoved(address indexed account); Roles.Role private _whitelistAdmins; constructor() { _addWhitelistAdmin(_msgSender()); } modifier onlyWhitelistAdmin() { require( isWhitelistAdmin(_msgSender()), 'WhitelistAdminRole: caller does not have the WhitelistAdmin role' ); _; } function isWhitelistAdmin(address account) public view returns (bool) { return _whitelistAdmins.has(account); } function addWhitelistAdmin(address account) public onlyWhitelistAdmin { _addWhitelistAdmin(account); } function renounceWhitelistAdmin() public { _removeWhitelistAdmin(_msgSender()); } function _addWhitelistAdmin(address account) internal { _whitelistAdmins.add(account); emit WhitelistAdminAdded(account); } function _removeWhitelistAdmin(address account) internal { _whitelistAdmins.remove(account); emit WhitelistAdminRemoved(account); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Roles * @dev Library for managing addresses assigned to a Role. */ library Roles { struct Role { mapping(address => bool) bearer; } /** * @dev Give an account access to this role. */ function add(Role storage role, address account) internal { require(!has(role, account), 'Roles: account already has role'); role.bearer[account] = true; } /** * @dev Remove an account's access to this role. */ function remove(Role storage role, address account) internal { require(has(role, account), 'Roles: account does not have role'); role.bearer[account] = false; } /** * @dev Check if an account has this role. * @return bool */ function has(Role storage role, address account) internal view returns (bool) { require(account != address(0), 'Roles: account is the zero address'); return role.bearer[account]; } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"_erc20Address","type":"address"},{"internalType":"address","name":"_paymentProxy","type":"address"}],"name":"approvePaymentProxyToSpend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_erc20Address","type":"address"}],"name":"approveRouterToSpend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"chainlinkConversionPath","outputs":[{"internalType":"contract ChainlinkConversionPath","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestSwapFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newSwapRouterAddress","type":"address"}],"name":"setRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapRouter","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_paymentProxy","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_requestAmount","type":"uint256"},{"internalType":"uint256","name":"_amountInMax","type":"uint256"},{"internalType":"address[]","name":"_swapRouterPath","type":"address[]"},{"internalType":"address[]","name":"_chainlinkPath","type":"address[]"},{"internalType":"bytes","name":"_paymentReference","type":"bytes"},{"internalType":"uint256","name":"_requestFeeAmount","type":"uint256"},{"internalType":"address","name":"_feeAddress","type":"address"},{"internalType":"uint256","name":"_deadline","type":"uint256"},{"internalType":"uint256","name":"_chainlinkMaxRateTimespan","type":"uint256"}],"name":"swapTransferWithReference","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_chainlinkConversionPath","type":"address"}],"name":"updateConversionPathAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRequestSwapFees","type":"uint256"}],"name":"updateRequestSwapFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620026c7380380620026c78339818101604052810190620000379190620001a5565b620000576200004b6200006f60201b60201c565b6200007760201b60201c565b62000068816200007760201b60201c565b50620001d7565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200016d8262000140565b9050919050565b6200017f8162000160565b81146200018b57600080fd5b50565b6000815190506200019f8162000174565b92915050565b600060208284031215620001be57620001bd6200013b565b5b6000620001ce848285016200018e565b91505092915050565b6124e080620001e76000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063946647f111610071578063946647f114610153578063ad2f5be614610171578063ad6d61061461018d578063c0d78655146101a9578063c31c9c07146101c5578063f2fde38b146101e3576100b4565b80631d7bc74b146100b957806330e175c9146100d55780633e952c1a146100f1578063715018a61461010f5780637a38d1cb146101195780638da5cb5b14610135575b600080fd5b6100d360048036038101906100ce9190611554565b6101ff565b005b6100ef60048036038101906100ea91906115df565b610285565b005b6100f9610302565b604051610106919061161b565b60405180910390f35b610117610308565b005b610133600480360381019061012e91906115df565b610390565b005b61013d610450565b60405161014a9190611645565b60405180910390f35b61015b610479565b60405161016891906116bf565b60405180910390f35b61018b600480360381019061018691906116da565b61049f565b005b6101a760048036038101906101a29190611928565b6104fb565b005b6101c360048036038101906101be91906115df565b610b91565b005b6101cd610c51565b6040516101da9190611a91565b60405180910390f35b6101fd60048036038101906101f891906115df565b610c77565b005b610207610d6f565b73ffffffffffffffffffffffffffffffffffffffff16610225610450565b73ffffffffffffffffffffffffffffffffffffffff161461027b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027290611b09565b60405180910390fd5b8060038190555050565b600081905060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90506102fc600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828473ffffffffffffffffffffffffffffffffffffffff16610d779092919063ffffffff16565b50505050565b60035481565b610310610d6f565b73ffffffffffffffffffffffffffffffffffffffff1661032e610450565b73ffffffffffffffffffffffffffffffffffffffff1614610384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161037b90611b09565b60405180910390fd5b61038e6000610eab565b565b610398610d6f565b73ffffffffffffffffffffffffffffffffffffffff166103b6610450565b73ffffffffffffffffffffffffffffffffffffffff161461040c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040390611b09565b60405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600082905060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90506104f483828473ffffffffffffffffffffffffffffffffffffffff16610d779092919063ffffffff16565b5050505050565b856001875161050a9190611b58565b8151811061051b5761051a611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600189516105489190611b58565b8151811061055957610558611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16146105b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ae90611c53565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610627576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161061e90611cbf565b60405180910390fd5b6000610634878b87610f6f565b905060006103e8600354836106499190611cdf565b6106539190611d68565b905061069d33308c8c60008151811061066f5761066e611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611034909392919063ffffffff16565b6106dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106d390611e0b565b60405180910390fd5b6106f48d8b8b8785876106ef9190611e2b565b61116b565b60008d90508073ffffffffffffffffffffffffffffffffffffffff16633af2c0128e8e8c8c8c8c8a8c6040518963ffffffff1660e01b8152600401610740989796959493929190611fc7565b600060405180830381600087803b15801561075a57600080fd5b505af192505050801561076b575060015b6107dc573d806000811461079b576040519150601f19603f3d011682016040523d82523d6000602084013e6107a0565b606091505b506040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d39061209f565b60405180910390fd5b61082e86838c60018e516107f09190611b58565b8151811061080157610800611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166113d69092919063ffffffff16565b5060008a60008151811061084557610844611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016108859190611645565b60206040518083038186803b15801561089d57600080fd5b505afa1580156108b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d591906120d4565b11156109c6576109c4338b6000815181106108f3576108f2611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109339190611645565b60206040518083038186803b15801561094b57600080fd5b505afa15801561095f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098391906120d4565b8c60008151811061099757610996611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166113d69092919063ffffffff16565b505b60008a60018c516109d79190611b58565b815181106109e8576109e7611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610a289190611645565b60206040518083038186803b158015610a4057600080fd5b505afa158015610a54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7891906120d4565b1115610b8157610b7f338b60018d51610a919190611b58565b81518110610aa257610aa1611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ae29190611645565b60206040518083038186803b158015610afa57600080fd5b505afa158015610b0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3291906120d4565b8c60018e51610b419190611b58565b81518110610b5257610b51611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166113d69092919063ffffffff16565b505b5050505050505050505050505050565b610b99610d6f565b73ffffffffffffffffffffffffffffffffffffffff16610bb7610450565b73ffffffffffffffffffffffffffffffffffffffff1614610c0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0490611b09565b60405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610c7f610d6f565b73ffffffffffffffffffffffffffffffffffffffff16610c9d610450565b73ffffffffffffffffffffffffffffffffffffffff1614610cf3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cea90611b09565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5a90612173565b60405180910390fd5b610d6c81610eab565b50565b600033905090565b60008060008573ffffffffffffffffffffffffffffffffffffffff168585604051602401610da6929190612193565b6040516020818303038152906040527f095ea7b3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610e3091906121f8565b6000604051808303816000865af19150503d8060008114610e6d576040519150601f19603f3d011682016040523d82523d6000602084013e610e72565b606091505b5091509150818015610ea05750600081511480610e9f575080806020019051810190610e9e9190612247565b5b5b925050509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fbd4122a8385610fbb9190611e2b565b866040518363ffffffff1660e01b8152600401610fd9929190612274565b604080518083038186803b158015610ff057600080fd5b505afa158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906122a4565b50809150509392505050565b60008060008673ffffffffffffffffffffffffffffffffffffffff16868686604051602401611065939291906122e4565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516110ef91906121f8565b6000604051808303816000865af19150503d806000811461112c576040519150601f19603f3d011682016040523d82523d6000602084013e611131565b606091505b509150915081801561115f575060008151148061115e57508080602001905181019061115d9190612247565b5b5b92505050949350505050565b60008360008151811061118157611180611b8c565b5b60200260200101519050848173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b81526004016111e992919061231b565b60206040518083038186803b15801561120157600080fd5b505afa158015611215573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123991906120d4565b10156112495761124881610285565b5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638803dbee83878730886040518663ffffffff1660e01b81526004016112ac959493929190612344565b600060405180830381600087803b1580156112c657600080fd5b505af11580156112da573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906113039190612461565b50600084600186516113159190611b58565b8151811061132657611325611b8c565b5b60200260200101519050828173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308a6040518363ffffffff1660e01b815260040161136c92919061231b565b60206040518083038186803b15801561138457600080fd5b505afa158015611398573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bc91906120d4565b10156113cd576113cc818861049f565b5b50505050505050565b60008060008573ffffffffffffffffffffffffffffffffffffffff168585604051602401611405929190612193565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161148f91906121f8565b6000604051808303816000865af19150503d80600081146114cc576040519150601f19603f3d011682016040523d82523d6000602084013e6114d1565b606091505b50915091508180156114ff57506000815114806114fe5750808060200190518101906114fd9190612247565b5b5b925050509392505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6115318161151e565b811461153c57600080fd5b50565b60008135905061154e81611528565b92915050565b60006020828403121561156a57611569611514565b5b60006115788482850161153f565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006115ac82611581565b9050919050565b6115bc816115a1565b81146115c757600080fd5b50565b6000813590506115d9816115b3565b92915050565b6000602082840312156115f5576115f4611514565b5b6000611603848285016115ca565b91505092915050565b6116158161151e565b82525050565b6000602082019050611630600083018461160c565b92915050565b61163f816115a1565b82525050565b600060208201905061165a6000830184611636565b92915050565b6000819050919050565b600061168561168061167b84611581565b611660565b611581565b9050919050565b60006116978261166a565b9050919050565b60006116a98261168c565b9050919050565b6116b98161169e565b82525050565b60006020820190506116d460008301846116b0565b92915050565b600080604083850312156116f1576116f0611514565b5b60006116ff858286016115ca565b9250506020611710858286016115ca565b9150509250929050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6117688261171f565b810181811067ffffffffffffffff8211171561178757611786611730565b5b80604052505050565b600061179a61150a565b90506117a6828261175f565b919050565b600067ffffffffffffffff8211156117c6576117c5611730565b5b602082029050602081019050919050565b600080fd5b60006117ef6117ea846117ab565b611790565b90508083825260208201905060208402830185811115611812576118116117d7565b5b835b8181101561183b578061182788826115ca565b845260208401935050602081019050611814565b5050509392505050565b600082601f83011261185a5761185961171a565b5b813561186a8482602086016117dc565b91505092915050565b600080fd5b600067ffffffffffffffff82111561189357611892611730565b5b61189c8261171f565b9050602081019050919050565b82818337600083830152505050565b60006118cb6118c684611878565b611790565b9050828152602081018484840111156118e7576118e6611873565b5b6118f28482856118a9565b509392505050565b600082601f83011261190f5761190e61171a565b5b813561191f8482602086016118b8565b91505092915050565b60008060008060008060008060008060006101608c8e03121561194e5761194d611514565b5b600061195c8e828f016115ca565b9b5050602061196d8e828f016115ca565b9a5050604061197e8e828f0161153f565b995050606061198f8e828f0161153f565b98505060808c013567ffffffffffffffff8111156119b0576119af611519565b5b6119bc8e828f01611845565b97505060a08c013567ffffffffffffffff8111156119dd576119dc611519565b5b6119e98e828f01611845565b96505060c08c013567ffffffffffffffff811115611a0a57611a09611519565b5b611a168e828f016118fa565b95505060e0611a278e828f0161153f565b945050610100611a398e828f016115ca565b935050610120611a4b8e828f0161153f565b925050610140611a5d8e828f0161153f565b9150509295989b509295989b9093969950565b6000611a7b8261168c565b9050919050565b611a8b81611a70565b82525050565b6000602082019050611aa66000830184611a82565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000611af3602083611aac565b9150611afe82611abd565b602082019050919050565b60006020820190508181036000830152611b2281611ae6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611b638261151e565b9150611b6e8361151e565b925082821015611b8157611b80611b29565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f7468652072657175657374656420746f6b656e206f6e2074686520737761702060008201527f726f75746572206d75737420626520746865207061796d656e7420637572726560208201527f6e63790000000000000000000000000000000000000000000000000000000000604082015250565b6000611c3d604383611aac565b9150611c4882611bbb565b606082019050919050565b60006020820190508181036000830152611c6c81611c30565b9050919050565b7f496e76616c696420666565206164647265730000000000000000000000000000600082015250565b6000611ca9601283611aac565b9150611cb482611c73565b602082019050919050565b60006020820190508181036000830152611cd881611c9c565b9050919050565b6000611cea8261151e565b9150611cf58361151e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611d2e57611d2d611b29565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000611d738261151e565b9150611d7e8361151e565b925082611d8e57611d8d611d39565b5b828204905092915050565b7f436f756c64206e6f74207472616e73666572207061796d656e7420746f6b656e60008201527f2066726f6d20737761707065722d706179657200000000000000000000000000602082015250565b6000611df5603383611aac565b9150611e0082611d99565b604082019050919050565b60006020820190508181036000830152611e2481611de8565b9050919050565b6000611e368261151e565b9150611e418361151e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611e7657611e75611b29565b5b828201905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611eb6816115a1565b82525050565b6000611ec88383611ead565b60208301905092915050565b6000602082019050919050565b6000611eec82611e81565b611ef68185611e8c565b9350611f0183611e9d565b8060005b83811015611f32578151611f198882611ebc565b9750611f2483611ed4565b925050600181019050611f05565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f79578082015181840152602081019050611f5e565b83811115611f88576000848401525b50505050565b6000611f9982611f3f565b611fa38185611f4a565b9350611fb3818560208601611f5b565b611fbc8161171f565b840191505092915050565b600061010082019050611fdd600083018b611636565b611fea602083018a61160c565b8181036040830152611ffc8189611ee1565b905081810360608301526120108188611f8e565b905061201f608083018761160c565b61202c60a0830186611636565b61203960c083018561160c565b61204660e083018461160c565b9998505050505050505050565b7f496e76616c6964207061796d656e742070726f78790000000000000000000000600082015250565b6000612089601583611aac565b915061209482612053565b602082019050919050565b600060208201905081810360008301526120b88161207c565b9050919050565b6000815190506120ce81611528565b92915050565b6000602082840312156120ea576120e9611514565b5b60006120f8848285016120bf565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061215d602683611aac565b915061216882612101565b604082019050919050565b6000602082019050818103600083015261218c81612150565b9050919050565b60006040820190506121a86000830185611636565b6121b5602083018461160c565b9392505050565b600081905092915050565b60006121d282611f3f565b6121dc81856121bc565b93506121ec818560208601611f5b565b80840191505092915050565b600061220482846121c7565b915081905092915050565b60008115159050919050565b6122248161220f565b811461222f57600080fd5b50565b6000815190506122418161221b565b92915050565b60006020828403121561225d5761225c611514565b5b600061226b84828501612232565b91505092915050565b6000604082019050612289600083018561160c565b818103602083015261229b8184611ee1565b90509392505050565b600080604083850312156122bb576122ba611514565b5b60006122c9858286016120bf565b92505060206122da858286016120bf565b9150509250929050565b60006060820190506122f96000830186611636565b6123066020830185611636565b612313604083018461160c565b949350505050565b60006040820190506123306000830185611636565b61233d6020830184611636565b9392505050565b600060a082019050612359600083018861160c565b612366602083018761160c565b81810360408301526123788186611ee1565b90506123876060830185611636565b612394608083018461160c565b9695505050505050565b600067ffffffffffffffff8211156123b9576123b8611730565b5b602082029050602081019050919050565b60006123dd6123d88461239e565b611790565b90508083825260208201905060208402830185811115612400576123ff6117d7565b5b835b81811015612429578061241588826120bf565b845260208401935050602081019050612402565b5050509392505050565b600082601f8301126124485761244761171a565b5b81516124588482602086016123ca565b91505092915050565b60006020828403121561247757612476611514565b5b600082015167ffffffffffffffff81111561249557612494611519565b5b6124a184828501612433565b9150509291505056fea26469706673582212207dca6640f9f7c6efbbc63e24d307c8e42c74cbdab2effc4340482043a31e58d764736f6c634300080900330000000000000000000000004e64c2d06d19d13061e62e291b2c4e9fe5679b93
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063946647f111610071578063946647f114610153578063ad2f5be614610171578063ad6d61061461018d578063c0d78655146101a9578063c31c9c07146101c5578063f2fde38b146101e3576100b4565b80631d7bc74b146100b957806330e175c9146100d55780633e952c1a146100f1578063715018a61461010f5780637a38d1cb146101195780638da5cb5b14610135575b600080fd5b6100d360048036038101906100ce9190611554565b6101ff565b005b6100ef60048036038101906100ea91906115df565b610285565b005b6100f9610302565b604051610106919061161b565b60405180910390f35b610117610308565b005b610133600480360381019061012e91906115df565b610390565b005b61013d610450565b60405161014a9190611645565b60405180910390f35b61015b610479565b60405161016891906116bf565b60405180910390f35b61018b600480360381019061018691906116da565b61049f565b005b6101a760048036038101906101a29190611928565b6104fb565b005b6101c360048036038101906101be91906115df565b610b91565b005b6101cd610c51565b6040516101da9190611a91565b60405180910390f35b6101fd60048036038101906101f891906115df565b610c77565b005b610207610d6f565b73ffffffffffffffffffffffffffffffffffffffff16610225610450565b73ffffffffffffffffffffffffffffffffffffffff161461027b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161027290611b09565b60405180910390fd5b8060038190555050565b600081905060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90506102fc600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828473ffffffffffffffffffffffffffffffffffffffff16610d779092919063ffffffff16565b50505050565b60035481565b610310610d6f565b73ffffffffffffffffffffffffffffffffffffffff1661032e610450565b73ffffffffffffffffffffffffffffffffffffffff1614610384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161037b90611b09565b60405180910390fd5b61038e6000610eab565b565b610398610d6f565b73ffffffffffffffffffffffffffffffffffffffff166103b6610450565b73ffffffffffffffffffffffffffffffffffffffff161461040c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040390611b09565b60405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600082905060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90506104f483828473ffffffffffffffffffffffffffffffffffffffff16610d779092919063ffffffff16565b5050505050565b856001875161050a9190611b58565b8151811061051b5761051a611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1687600189516105489190611b58565b8151811061055957610558611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16146105b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ae90611c53565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610627576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161061e90611cbf565b60405180910390fd5b6000610634878b87610f6f565b905060006103e8600354836106499190611cdf565b6106539190611d68565b905061069d33308c8c60008151811061066f5761066e611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611034909392919063ffffffff16565b6106dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106d390611e0b565b60405180910390fd5b6106f48d8b8b8785876106ef9190611e2b565b61116b565b60008d90508073ffffffffffffffffffffffffffffffffffffffff16633af2c0128e8e8c8c8c8c8a8c6040518963ffffffff1660e01b8152600401610740989796959493929190611fc7565b600060405180830381600087803b15801561075a57600080fd5b505af192505050801561076b575060015b6107dc573d806000811461079b576040519150601f19603f3d011682016040523d82523d6000602084013e6107a0565b606091505b506040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107d39061209f565b60405180910390fd5b61082e86838c60018e516107f09190611b58565b8151811061080157610800611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166113d69092919063ffffffff16565b5060008a60008151811061084557610844611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016108859190611645565b60206040518083038186803b15801561089d57600080fd5b505afa1580156108b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d591906120d4565b11156109c6576109c4338b6000815181106108f3576108f2611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109339190611645565b60206040518083038186803b15801561094b57600080fd5b505afa15801561095f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098391906120d4565b8c60008151811061099757610996611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166113d69092919063ffffffff16565b505b60008a60018c516109d79190611b58565b815181106109e8576109e7611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610a289190611645565b60206040518083038186803b158015610a4057600080fd5b505afa158015610a54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7891906120d4565b1115610b8157610b7f338b60018d51610a919190611b58565b81518110610aa257610aa1611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ae29190611645565b60206040518083038186803b158015610afa57600080fd5b505afa158015610b0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3291906120d4565b8c60018e51610b419190611b58565b81518110610b5257610b51611b8c565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166113d69092919063ffffffff16565b505b5050505050505050505050505050565b610b99610d6f565b73ffffffffffffffffffffffffffffffffffffffff16610bb7610450565b73ffffffffffffffffffffffffffffffffffffffff1614610c0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0490611b09565b60405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610c7f610d6f565b73ffffffffffffffffffffffffffffffffffffffff16610c9d610450565b73ffffffffffffffffffffffffffffffffffffffff1614610cf3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cea90611b09565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5a90612173565b60405180910390fd5b610d6c81610eab565b50565b600033905090565b60008060008573ffffffffffffffffffffffffffffffffffffffff168585604051602401610da6929190612193565b6040516020818303038152906040527f095ea7b3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610e3091906121f8565b6000604051808303816000865af19150503d8060008114610e6d576040519150601f19603f3d011682016040523d82523d6000602084013e610e72565b606091505b5091509150818015610ea05750600081511480610e9f575080806020019051810190610e9e9190612247565b5b5b925050509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fbd4122a8385610fbb9190611e2b565b866040518363ffffffff1660e01b8152600401610fd9929190612274565b604080518083038186803b158015610ff057600080fd5b505afa158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906122a4565b50809150509392505050565b60008060008673ffffffffffffffffffffffffffffffffffffffff16868686604051602401611065939291906122e4565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516110ef91906121f8565b6000604051808303816000865af19150503d806000811461112c576040519150601f19603f3d011682016040523d82523d6000602084013e611131565b606091505b509150915081801561115f575060008151148061115e57508080602001905181019061115d9190612247565b5b5b92505050949350505050565b60008360008151811061118157611180611b8c565b5b60200260200101519050848173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b81526004016111e992919061231b565b60206040518083038186803b15801561120157600080fd5b505afa158015611215573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123991906120d4565b10156112495761124881610285565b5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638803dbee83878730886040518663ffffffff1660e01b81526004016112ac959493929190612344565b600060405180830381600087803b1580156112c657600080fd5b505af11580156112da573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906113039190612461565b50600084600186516113159190611b58565b8151811061132657611325611b8c565b5b60200260200101519050828173ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e308a6040518363ffffffff1660e01b815260040161136c92919061231b565b60206040518083038186803b15801561138457600080fd5b505afa158015611398573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bc91906120d4565b10156113cd576113cc818861049f565b5b50505050505050565b60008060008573ffffffffffffffffffffffffffffffffffffffff168585604051602401611405929190612193565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161148f91906121f8565b6000604051808303816000865af19150503d80600081146114cc576040519150601f19603f3d011682016040523d82523d6000602084013e6114d1565b606091505b50915091508180156114ff57506000815114806114fe5750808060200190518101906114fd9190612247565b5b5b925050509392505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6115318161151e565b811461153c57600080fd5b50565b60008135905061154e81611528565b92915050565b60006020828403121561156a57611569611514565b5b60006115788482850161153f565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006115ac82611581565b9050919050565b6115bc816115a1565b81146115c757600080fd5b50565b6000813590506115d9816115b3565b92915050565b6000602082840312156115f5576115f4611514565b5b6000611603848285016115ca565b91505092915050565b6116158161151e565b82525050565b6000602082019050611630600083018461160c565b92915050565b61163f816115a1565b82525050565b600060208201905061165a6000830184611636565b92915050565b6000819050919050565b600061168561168061167b84611581565b611660565b611581565b9050919050565b60006116978261166a565b9050919050565b60006116a98261168c565b9050919050565b6116b98161169e565b82525050565b60006020820190506116d460008301846116b0565b92915050565b600080604083850312156116f1576116f0611514565b5b60006116ff858286016115ca565b9250506020611710858286016115ca565b9150509250929050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6117688261171f565b810181811067ffffffffffffffff8211171561178757611786611730565b5b80604052505050565b600061179a61150a565b90506117a6828261175f565b919050565b600067ffffffffffffffff8211156117c6576117c5611730565b5b602082029050602081019050919050565b600080fd5b60006117ef6117ea846117ab565b611790565b90508083825260208201905060208402830185811115611812576118116117d7565b5b835b8181101561183b578061182788826115ca565b845260208401935050602081019050611814565b5050509392505050565b600082601f83011261185a5761185961171a565b5b813561186a8482602086016117dc565b91505092915050565b600080fd5b600067ffffffffffffffff82111561189357611892611730565b5b61189c8261171f565b9050602081019050919050565b82818337600083830152505050565b60006118cb6118c684611878565b611790565b9050828152602081018484840111156118e7576118e6611873565b5b6118f28482856118a9565b509392505050565b600082601f83011261190f5761190e61171a565b5b813561191f8482602086016118b8565b91505092915050565b60008060008060008060008060008060006101608c8e03121561194e5761194d611514565b5b600061195c8e828f016115ca565b9b5050602061196d8e828f016115ca565b9a5050604061197e8e828f0161153f565b995050606061198f8e828f0161153f565b98505060808c013567ffffffffffffffff8111156119b0576119af611519565b5b6119bc8e828f01611845565b97505060a08c013567ffffffffffffffff8111156119dd576119dc611519565b5b6119e98e828f01611845565b96505060c08c013567ffffffffffffffff811115611a0a57611a09611519565b5b611a168e828f016118fa565b95505060e0611a278e828f0161153f565b945050610100611a398e828f016115ca565b935050610120611a4b8e828f0161153f565b925050610140611a5d8e828f0161153f565b9150509295989b509295989b9093969950565b6000611a7b8261168c565b9050919050565b611a8b81611a70565b82525050565b6000602082019050611aa66000830184611a82565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000611af3602083611aac565b9150611afe82611abd565b602082019050919050565b60006020820190508181036000830152611b2281611ae6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611b638261151e565b9150611b6e8361151e565b925082821015611b8157611b80611b29565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f7468652072657175657374656420746f6b656e206f6e2074686520737761702060008201527f726f75746572206d75737420626520746865207061796d656e7420637572726560208201527f6e63790000000000000000000000000000000000000000000000000000000000604082015250565b6000611c3d604383611aac565b9150611c4882611bbb565b606082019050919050565b60006020820190508181036000830152611c6c81611c30565b9050919050565b7f496e76616c696420666565206164647265730000000000000000000000000000600082015250565b6000611ca9601283611aac565b9150611cb482611c73565b602082019050919050565b60006020820190508181036000830152611cd881611c9c565b9050919050565b6000611cea8261151e565b9150611cf58361151e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611d2e57611d2d611b29565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000611d738261151e565b9150611d7e8361151e565b925082611d8e57611d8d611d39565b5b828204905092915050565b7f436f756c64206e6f74207472616e73666572207061796d656e7420746f6b656e60008201527f2066726f6d20737761707065722d706179657200000000000000000000000000602082015250565b6000611df5603383611aac565b9150611e0082611d99565b604082019050919050565b60006020820190508181036000830152611e2481611de8565b9050919050565b6000611e368261151e565b9150611e418361151e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611e7657611e75611b29565b5b828201905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611eb6816115a1565b82525050565b6000611ec88383611ead565b60208301905092915050565b6000602082019050919050565b6000611eec82611e81565b611ef68185611e8c565b9350611f0183611e9d565b8060005b83811015611f32578151611f198882611ebc565b9750611f2483611ed4565b925050600181019050611f05565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f79578082015181840152602081019050611f5e565b83811115611f88576000848401525b50505050565b6000611f9982611f3f565b611fa38185611f4a565b9350611fb3818560208601611f5b565b611fbc8161171f565b840191505092915050565b600061010082019050611fdd600083018b611636565b611fea602083018a61160c565b8181036040830152611ffc8189611ee1565b905081810360608301526120108188611f8e565b905061201f608083018761160c565b61202c60a0830186611636565b61203960c083018561160c565b61204660e083018461160c565b9998505050505050505050565b7f496e76616c6964207061796d656e742070726f78790000000000000000000000600082015250565b6000612089601583611aac565b915061209482612053565b602082019050919050565b600060208201905081810360008301526120b88161207c565b9050919050565b6000815190506120ce81611528565b92915050565b6000602082840312156120ea576120e9611514565b5b60006120f8848285016120bf565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061215d602683611aac565b915061216882612101565b604082019050919050565b6000602082019050818103600083015261218c81612150565b9050919050565b60006040820190506121a86000830185611636565b6121b5602083018461160c565b9392505050565b600081905092915050565b60006121d282611f3f565b6121dc81856121bc565b93506121ec818560208601611f5b565b80840191505092915050565b600061220482846121c7565b915081905092915050565b60008115159050919050565b6122248161220f565b811461222f57600080fd5b50565b6000815190506122418161221b565b92915050565b60006020828403121561225d5761225c611514565b5b600061226b84828501612232565b91505092915050565b6000604082019050612289600083018561160c565b818103602083015261229b8184611ee1565b90509392505050565b600080604083850312156122bb576122ba611514565b5b60006122c9858286016120bf565b92505060206122da858286016120bf565b9150509250929050565b60006060820190506122f96000830186611636565b6123066020830185611636565b612313604083018461160c565b949350505050565b60006040820190506123306000830185611636565b61233d6020830184611636565b9392505050565b600060a082019050612359600083018861160c565b612366602083018761160c565b81810360408301526123788186611ee1565b90506123876060830185611636565b612394608083018461160c565b9695505050505050565b600067ffffffffffffffff8211156123b9576123b8611730565b5b602082029050602081019050919050565b60006123dd6123d88461239e565b611790565b90508083825260208201905060208402830185811115612400576123ff6117d7565b5b835b81811015612429578061241588826120bf565b845260208401935050602081019050612402565b5050509392505050565b600082601f8301126124485761244761171a565b5b81516124588482602086016123ca565b91505092915050565b60006020828403121561247757612476611514565b5b600082015167ffffffffffffffff81111561249557612494611519565b5b6124a184828501612433565b9150509291505056fea26469706673582212207dca6640f9f7c6efbbc63e24d307c8e42c74cbdab2effc4340482043a31e58d764736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004e64c2d06d19d13061e62e291b2c4e9fe5679b93
-----Decoded View---------------
Arg [0] : _owner (address): 0x4E64C2d06d19D13061e62E291b2C4e9fe5679b93
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000004e64c2d06d19d13061e62e291b2c4e9fe5679b93
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.