Contract
0xE3e761127cBD037E18186698a2733d1e71623ebE
1
Contract Overview
Balance:
0 AVAX
AVAX Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x6a02a30661929a90d97d72058d6c0612590e430317ba5974b7b7660e1a9c5e82 | Transfer Ownersh... | 7648440 | 482 days 19 hrs ago | 0x3f09e942b0089b8af73ccb9603da8064b6c4b637 | IN | 0xe3e761127cbd037e18186698a2733d1e71623ebe | 0 AVAX | 0.000803320533 | |
0xefb4f133d6fe8c964318759a87a76f66b5dd25d2c5ad6bde8db4b5ef5cb2a806 | 0x61010060 | 7648424 | 482 days 19 hrs ago | 0x3f09e942b0089b8af73ccb9603da8064b6c4b637 | IN | Create: UniV2LimitsStops | 0 AVAX | 0.074211381765 |
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
UniV2LimitsStops
Compiler Version
v0.8.6+commit.11564f7e
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.8.6; import "IERC20.sol"; import "Ownable.sol"; import "SafeERC20.sol"; import "IUniswapV2Router02.sol"; // Comments referenced throughout // *1: // Reduce amountOutMin proportionally so that the price of execution is the same // as what was intended by the user. This is done so that the trade executes at // the price intended by the user, even though they'll receive less than if // that'd market bought/sold at that price (because they pay for the execution // in regular ETH tx fees with normal Uniswap market orders). The naive way is // to do the trade, then take the output token, and trade some of that for // whatever the fee is paid in - this will execute at the intended price, but // is gas inefficient because it then requires sending the output tokens here // (and then requiring an additional transfer to the user), rather than inputing // the recipient into the Uniswap trade. Instead, we can have 2 Uniswap trades // (in the worst case scenario where the fee token isn't one of the traded tokens) // that sends the fee in the 1st, and reduce amountOutMin in the 2nd proportional // to the fees spent, such that the total execution price is the same as what was // intended by the user, even though there are fewer input tokens to spend on the // trade // *2: // Can't do `tradeInput = (inputAmount - inputSpentOnFee)` because of stack too deep /** * @title UniV2LimitsStops * @notice Wraps around an arbitrary UniV2 router contract and adds conditions * of price to create limit orders and stop losses. Ensures that * only a specific user can call a trade because the Autonomy Registry * forces that the first argument of the calldata is the user's address * and this contract knows that condition is true when the call is coming * from an appropriate proxy * @author Quantaf1re (James Key) */ contract UniV2LimitsStops is Ownable { using SafeERC20 for IERC20; address payable public immutable registry; address public immutable userVeriForwarder; address public immutable userFeeVeriForwarder; address public immutable WETH; FeeInfo private _defaultFeeInfo; uint256 private constant MAX_UINT = type(uint256).max; constructor( address payable registry_, address userVeriForwarder_, address userFeeVeriForwarder_, address WETH_, FeeInfo memory defaultFeeInfo ) Ownable() { registry = registry_; userVeriForwarder = userVeriForwarder_; userFeeVeriForwarder = userFeeVeriForwarder_; WETH = WETH_; _defaultFeeInfo = defaultFeeInfo; } struct FeeInfo { // Need a known instance of UniV2 that is guaranteed to have the token // that the default fee is paid in, along with enough liquidity, since // an arbitrary instance of UniV2 is passed to fcns in this contract IUniswapV2Router02 uni; address[] path; // Whether or not the fee token is AUTO, because that needs to // get sent to the user, since `transferFrom` is used from them directly // in the Registry to charge the fee bool isAUTO; } // Hold arguments for calling Uniswap to avoid stack to deep errors struct UniArgs{ uint inputAmount; uint amountOutMin; uint amountOutMax; address[] path; uint deadline; } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //// //// ////-----------------------ETH to token-----------------------//// //// //// ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// /** * @notice Only calls swapExactAVAXForTokens if the output is above * `amountOutMin` and below `amountOutMax`. `amountOutMax` * is the 'stop price' when used as a stop loss, and * `amountOutMin` is the 'limit price' when used as a limit * order. When using this as a classic limit order, `amountOutMax` * would be sent to the max uint value. When using this * as a classic stop loss, `amountOutMin` would be set to 0. * The min/max can also be used to limit downside during flash * crashes, e.g. `amountOutMin` could be set to 10% lower then * `amountOutMax` for a stop loss, if desired. */ function ethToTokenRange( uint maxGasPrice, IUniswapV2Router02 uni, uint amountOutMin, uint amountOutMax, address[] calldata path, address to, uint deadline ) external payable gasPriceCheck(maxGasPrice) { uint[] memory amounts = uni.swapExactAVAXForTokens{value: msg.value}(amountOutMin, path, to, deadline); require(amounts[amounts.length-1] <= amountOutMax, "LimitsStops: price too high"); } function _ethToTokenPayDefault( address user, uint feeAmount, IUniswapV2Router02 uni, UniArgs memory uniArgs ) private { FeeInfo memory feeInfo = _defaultFeeInfo; if (feeInfo.isAUTO) { feeInfo.path[0] = WETH; } _ethToTokenPaySpecific(user, feeAmount, uni, feeInfo, uniArgs); } function _ethToTokenPaySpecific( address user, uint feeAmount, IUniswapV2Router02 uni, FeeInfo memory feeInfo, UniArgs memory uniArgs ) private { // Pay the execution fee uint tradeInput = msg.value; if (feeInfo.isAUTO) { tradeInput -= feeInfo.uni.swapAVAXForExactTokens{value: msg.value}( feeAmount, feeInfo.path, user, uniArgs.deadline )[0]; } else { registry.transfer(feeAmount); tradeInput -= feeAmount; } // *1, *2 uint[] memory amounts = uni.swapExactAVAXForTokens{value: tradeInput}( uniArgs.amountOutMin * tradeInput / msg.value, uniArgs.path, user, uniArgs.deadline ); require(amounts[amounts.length-1] <= uniArgs.amountOutMax * tradeInput / msg.value, "LimitsStops: price too high"); } /** * @notice Only calls swapExactAVAXForTokens if the output is above * `amountOutMin` and below `amountOutMax`. `amountOutMax` * is the 'stop price' when used as a stop loss, and * `amountOutMin` is the 'limit price' when used as a limit * order. When using this as a classic limit order, `amountOutMax` * would be sent to the max uint value. When using this * as a classic stop loss, `amountOutMin` would be set to 0. * The min/max can also be used to limit downside during flash * crashes, e.g. `amountOutMin` could be set to 10% lower then * `amountOutMax` for a stop loss, if desired. Additionally, * takes part of the trade and uses it to pay `feeAmount`, * in the default fee token, to the registry */ function ethToTokenRangePayDefault( address user, uint feeAmount, uint maxGasPrice, IUniswapV2Router02 uni, uint amountOutMin, uint amountOutMax, address[] calldata path, uint deadline ) external payable gasPriceCheck(maxGasPrice) userFeeVerified { _ethToTokenPayDefault( user, feeAmount, uni, UniArgs(0, amountOutMin, amountOutMax, path, deadline) ); } /** * @notice Only calls swapExactAVAXForTokens if the output is above * `amountOutMin` and below `amountOutMax`. `amountOutMax` * is the 'stop price' when used as a stop loss, and * `amountOutMin` is the 'limit price' when used as a limit * order. When using this as a classic limit order, `amountOutMax` * would be sent to the max uint value. When using this * as a classic stop loss, `amountOutMin` would be set to 0. * The min/max can also be used to limit downside during flash * crashes, e.g. `amountOutMin` could be set to 10% lower then * `amountOutMax` for a stop loss, if desired. Additionally, * takes part of the trade and uses it to pay `feeAmount`, * in the specified fee token, to the registry. * WARNING: only use this if you want to do things non-standard */ function ethToTokenRangePaySpecific( address user, uint feeAmount, uint maxGasPrice, IUniswapV2Router02 uni, FeeInfo memory feeInfo, uint amountOutMin, uint amountOutMax, address[] calldata path, uint deadline ) external payable gasPriceCheck(maxGasPrice) userFeeVerified { _ethToTokenPaySpecific( user, feeAmount, uni, feeInfo, UniArgs(0, amountOutMin, amountOutMax, path, deadline) ); } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //// //// ////-----------------------Token to ETH-----------------------//// //// //// ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// /** * @notice Only calls swapExactTokensForAVAX if the output is above * `amountOutMin` and below `amountOutMax`. `amountOutMax` * is the 'stop price' when used as a stop loss, and * `amountOutMin` is the 'limit price' when used as a limit * order. When using this as a classic limit order, `amountOutMax` * would be sent to the max uint value. When using this * as a classic stop loss, `amountOutMin` would be set to 0. * The min/max can also be used to limit downside during flash * crashes, e.g. `amountOutMin` could be set to 10% lower then * `amountOutMax` for a stop loss, if desired. */ function tokenToEthRange( address user, uint maxGasPrice, IUniswapV2Router02 uni, uint inputAmount, uint amountOutMin, uint amountOutMax, address[] calldata path, address to, uint deadline ) external gasPriceCheck(maxGasPrice) userVerified { transferApproveUnapproved(uni, path[0], inputAmount, user); uint[] memory amounts = uni.swapExactTokensForAVAX(inputAmount, amountOutMin, path, to, deadline); require(amounts[amounts.length-1] <= amountOutMax, "LimitsStops: price too high"); } function _tokenToEthPayDefault( address user, uint feeAmount, IUniswapV2Router02 uni, UniArgs memory uniArgs ) private { FeeInfo memory feeInfo = _defaultFeeInfo; // The fee path only needs to be modified when not paying in ETH (since // the output of the trade is ETH and that can be used) and when the input // token isn't AUTO anyway (since that can be used without a 2nd trade) if (feeInfo.isAUTO && uniArgs.path[0] != feeInfo.path[feeInfo.path.length-1]) { address[] memory newFeePath = new address[](3); newFeePath[0] = uniArgs.path[0]; // src token newFeePath[1] = WETH; // WETH_ since path in tokenToETH ends in WETH_ newFeePath[2] = feeInfo.path[feeInfo.path.length-1]; // AUTO since feePath here ends in AUTO feeInfo.path = newFeePath; } _tokenToEthPaySpecific(user, feeAmount, uni, feeInfo, uniArgs); } function _tokenToEthPaySpecific( address user, uint feeAmount, IUniswapV2Router02 uni, FeeInfo memory feeInfo, UniArgs memory uniArgs ) private { // Pay the execution fee uint tradeInput = uniArgs.inputAmount; if (feeInfo.isAUTO) { // If the src token is AUTO if (uniArgs.path[0] == feeInfo.path[feeInfo.path.length-1]) { // The user already holds inputAmount of AUTO, so don't move them tradeInput -= feeAmount; transferApproveUnapproved(uni, uniArgs.path[0], tradeInput, user); } else { transferApproveUnapproved(uni, uniArgs.path[0], uniArgs.inputAmount, user); approveUnapproved(feeInfo.uni, uniArgs.path[0], uniArgs.inputAmount); tradeInput -= feeInfo.uni.swapTokensForExactTokens(feeAmount, uniArgs.inputAmount, feeInfo.path, user, uniArgs.deadline)[0]; } } else { transferApproveUnapproved(uni, uniArgs.path[0], uniArgs.inputAmount, user); } // *1, *2 uint[] memory amounts = uni.swapExactTokensForAVAX( tradeInput, uniArgs.amountOutMin * tradeInput / uniArgs.inputAmount, uniArgs.path, // Sending it all to the registry means that the fee will be kept // (if it's in ETH) and the excess sent to the user feeInfo.isAUTO ? user : registry, uniArgs.deadline ); require(amounts[amounts.length-1] <= uniArgs.amountOutMax * tradeInput / uniArgs.inputAmount, "LimitsStops: price too high"); } /** * @notice Only calls swapExactTokensForAVAX if the output is above * `amountOutMin` and below `amountOutMax`. `amountOutMax` * is the 'stop price' when used as a stop loss, and * `amountOutMin` is the 'limit price' when used as a limit * order. When using this as a classic limit order, `amountOutMax` * would be sent to the max uint value. When using this * as a classic stop loss, `amountOutMin` would be set to 0. * The min/max can also be used to limit downside during flash * crashes, e.g. `amountOutMin` could be set to 10% lower then * `amountOutMax` for a stop loss, if desired. Additionally, * takes part of the trade and uses it to pay `feeAmount`, * in the default fee token, to the registry */ function tokenToEthRangePayDefault( address user, uint feeAmount, uint maxGasPrice, IUniswapV2Router02 uni, uint inputAmount, uint amountOutMin, uint amountOutMax, address[] calldata path, uint deadline ) external gasPriceCheck(maxGasPrice) userFeeVerified { _tokenToEthPayDefault( user, feeAmount, uni, UniArgs(inputAmount, amountOutMin, amountOutMax, path, deadline) ); } /** * @notice Only calls swapExactTokensForAVAX if the output is above * `amountOutMin` and below `amountOutMax`. `amountOutMax` * is the 'stop price' when used as a stop loss, and * `amountOutMin` is the 'limit price' when used as a limit * order. When using this as a classic limit order, `amountOutMax` * would be sent to the max uint value. When using this * as a classic stop loss, `amountOutMin` would be set to 0. * The min/max can also be used to limit downside during flash * crashes, e.g. `amountOutMin` could be set to 10% lower then * `amountOutMax` for a stop loss, if desired. Additionally, * takes part of the trade and uses it to pay `feeAmount`, * in the specified fee token, to the registry. * WARNING: only use this if you want to do things non-standard */ function tokenToEthRangePaySpecific( address user, uint feeAmount, uint maxGasPrice, IUniswapV2Router02 uni, FeeInfo memory feeInfo, uint inputAmount, uint amountOutMin, uint amountOutMax, address[] calldata path, uint deadline ) external gasPriceCheck(maxGasPrice) userFeeVerified { _tokenToEthPaySpecific( user, feeAmount, uni, feeInfo, UniArgs(inputAmount, amountOutMin, amountOutMax, path, deadline) ); } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //// //// ////----------------------Token to token----------------------//// //// //// ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// /** * @notice Only calls swapExactTokensForTokens if the output is above * `amountOutMin` and below `amountOutMax`. `amountOutMax` * is the 'stop price' when used as a stop loss, and * `amountOutMin` is the 'limit price' when used as a limit * order. When using this as a classic limit order, `amountOutMax` * would be sent to the max uint value. When using this * as a classic stop loss, `amountOutMin` would be set to 0. * The min/max can also be used to limit downside during flash * crashes, e.g. `amountOutMin` could be set to 10% lower then * `amountOutMax` for a stop loss, if desired. */ function tokenToTokenRange( address user, uint maxGasPrice, IUniswapV2Router02 uni, uint inputAmount, uint amountOutMin, uint amountOutMax, address[] calldata path, address to, uint deadline ) external gasPriceCheck(maxGasPrice) userVerified { transferApproveUnapproved(uni, path[0], inputAmount, user); uint[] memory amounts = uni.swapExactTokensForTokens(inputAmount, amountOutMin, path, to, deadline); require(amounts[amounts.length-1] <= amountOutMax, "LimitsStops: price too high"); } function _tokenToTokenPayDefault( address user, uint feeAmount, IUniswapV2Router02 uni, UniArgs memory uniArgs ) private { FeeInfo memory feeInfo = _defaultFeeInfo; // The fee path only needs to be modified when the src/dest tokens aren't // AUTO (if paying in AUTO), and when paying in ETH if (feeInfo.isAUTO && uniArgs.path[0] != feeInfo.path[feeInfo.path.length-1]) { address[] memory newFeePath = new address[](3); newFeePath[0] = uniArgs.path[0]; // src token newFeePath[1] = WETH; // WETH_ since path in tokenToETH ends in WETH_ newFeePath[2] = feeInfo.path[feeInfo.path.length-1]; // AUTO since feePath here ends in AUTO feeInfo.path = newFeePath; } else if (!feeInfo.isAUTO) { feeInfo.path[0] = uniArgs.path[0]; } _tokenToTokenPaySpecific(user, feeAmount, uni, feeInfo, uniArgs); } function _tokenToTokenPaySpecific( address user, uint feeAmount, IUniswapV2Router02 uni, FeeInfo memory feeInfo, UniArgs memory uniArgs ) private { // Pay the execution fee uint tradeInput = uniArgs.inputAmount; if (feeInfo.isAUTO) { // If the src token is AUTO if (uniArgs.path[0] == feeInfo.path[feeInfo.path.length-1]) { // The user already holds inputAmount of AUTO tradeInput -= feeAmount; transferApproveUnapproved(uni, uniArgs.path[0], tradeInput, user); // If the dest token is AUTO } else if (uniArgs.path[uniArgs.path.length-1] == feeInfo.path[feeInfo.path.length-1]) { // Do nothing because it'll all get sent to the user, and the // fee will be taken from them after that transferApproveUnapproved(uni, uniArgs.path[0], uniArgs.inputAmount, user); } else { transferApproveUnapproved(uni, uniArgs.path[0], uniArgs.inputAmount, user); approveUnapproved(feeInfo.uni, uniArgs.path[0], uniArgs.inputAmount); tradeInput -= feeInfo.uni.swapTokensForExactTokens(feeAmount, uniArgs.inputAmount, feeInfo.path, user, uniArgs.deadline)[0]; } } else { transferApproveUnapproved(uni, uniArgs.path[0], uniArgs.inputAmount, user); approveUnapproved(feeInfo.uni, uniArgs.path[0], uniArgs.inputAmount); tradeInput -= feeInfo.uni.swapTokensForExactAVAX(feeAmount, uniArgs.inputAmount, feeInfo.path, registry, uniArgs.deadline)[0]; } // *1, *2 uint[] memory amounts = uni.swapExactTokensForTokens( tradeInput, uniArgs.amountOutMin * tradeInput / uniArgs.inputAmount, uniArgs.path, user, uniArgs.deadline ); require(amounts[amounts.length-1] <= uniArgs.amountOutMax * tradeInput / uniArgs.inputAmount, "LimitsStops: price too high"); } /** * @notice Only calls swapExactTokensForTokens if the output is above * `amountOutMin` and below `amountOutMax`. `amountOutMax` * is the 'stop price' when used as a stop loss, and * `amountOutMin` is the 'limit price' when used as a limit * order. When using this as a classic limit order, `amountOutMax` * would be sent to the max uint value. When using this * as a classic stop loss, `amountOutMin` would be set to 0. * The min/max can also be used to limit downside during flash * crashes, e.g. `amountOutMin` could be set to 10% lower then * `amountOutMax` for a stop loss, if desired. Additionally, * takes part of the trade and uses it to pay `feeAmount`, * in the default fee token, to the registry */ function tokenToTokenRangePayDefault( address user, uint feeAmount, uint maxGasPrice, IUniswapV2Router02 uni, uint inputAmount, uint amountOutMin, uint amountOutMax, address[] calldata path, uint deadline ) external gasPriceCheck(maxGasPrice) userFeeVerified { _tokenToTokenPayDefault( user, feeAmount, uni, UniArgs(inputAmount, amountOutMin, amountOutMax, path, deadline) ); } /** * @notice Only calls swapExactTokensForTokens if the output is above * `amountOutMin` and below `amountOutMax`. `amountOutMax` * is the 'stop price' when used as a stop loss, and * `amountOutMin` is the 'limit price' when used as a limit * order. When using this as a classic limit order, `amountOutMax` * would be sent to the max uint value. When using this * as a classic stop loss, `amountOutMin` would be set to 0. * The min/max can also be used to limit downside during flash * crashes, e.g. `amountOutMin` could be set to 10% lower then * `amountOutMax` for a stop loss, if desired. Additionally, * takes part of the trade and uses it to pay `feeAmount`, * in the specified fee token, to the registry. * WARNING: only use this if you want to do things non-standard */ function tokenToTokenRangePaySpecific( address user, uint feeAmount, uint maxGasPrice, IUniswapV2Router02 uni, FeeInfo memory feeInfo, uint inputAmount, uint amountOutMin, uint amountOutMax, address[] calldata path, uint deadline ) external gasPriceCheck(maxGasPrice) userFeeVerified { _tokenToTokenPaySpecific( user, feeAmount, uni, feeInfo, UniArgs(inputAmount, amountOutMin, amountOutMax, path, deadline) ); } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //// //// ////-------------------------Helpers--------------------------//// //// //// ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// function approveUnapproved(IUniswapV2Router02 uni, address tokenAddr, uint amount) private returns (IERC20 token) { token = IERC20(tokenAddr); if (token.allowance(address(this), address(uni)) < amount) { token.approve(address(uni), MAX_UINT); } } function transferApproveUnapproved(IUniswapV2Router02 uni, address tokenAddr, uint amount, address user) private { IERC20 token = approveUnapproved(uni, tokenAddr, amount); token.safeTransferFrom(user, address(this), amount); } function setDefaultFeeInfo(FeeInfo calldata newDefaultFee) external onlyOwner { _defaultFeeInfo = newDefaultFee; } function getDefaultFeeInfo() external view returns (FeeInfo memory) { return _defaultFeeInfo; } modifier userVerified() { require(msg.sender == userVeriForwarder, "LimitsStops: not userForw"); _; } modifier userFeeVerified() { require(msg.sender == userFeeVeriForwarder, "LimitsStops: not userFeeForw"); _; } modifier gasPriceCheck(uint maxGasPrice) { require(tx.gasprice <= maxGasPrice, "LimitsStops: gasPrice too high"); _; } // Needed to receive excess ETH when calling swapAVAXForExactTokens receive() external payable {} }
// SPDX-License-Identifier: MIT 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 pragma solidity ^0.8.0; import "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() { _setOwner(_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 { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT 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 pragma solidity ^0.8.0; import "IERC20.sol"; import "Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
pragma solidity 0.8.6; import "IUniswapV2Router01.sol"; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
pragma solidity 0.8.6; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactAVAXForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactAVAX(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForAVAX(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapAVAXForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
{ "evmVersion": "istanbul", "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
[{"inputs":[{"internalType":"address payable","name":"registry_","type":"address"},{"internalType":"address","name":"userVeriForwarder_","type":"address"},{"internalType":"address","name":"userFeeVeriForwarder_","type":"address"},{"internalType":"address","name":"WETH_","type":"address"},{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"defaultFeeInfo","type":"tuple"}],"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":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ethToTokenRange","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ethToTokenRangePayDefault","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"feeInfo","type":"tuple"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ethToTokenRangePaySpecific","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getDefaultFeeInfo","outputs":[{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"newDefaultFee","type":"tuple"}],"name":"setDefaultFeeInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToEthRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToEthRangePayDefault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"feeInfo","type":"tuple"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToEthRangePaySpecific","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToTokenRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToTokenRangePayDefault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"feeInfo","type":"tuple"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToTokenRangePaySpecific","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"userFeeVeriForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"userVeriForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101006040523480156200001257600080fd5b50604051620030fe380380620030fe8339810160408190526200003591620001b8565b6200004033620000d1565b606085811b6001600160601b031990811660805285821b811660a05284821b811660c0529083901b1660e0528051600180546001600160a01b0319166001600160a01b039092169190911781556020808301518051849392620000a99260029291019062000121565b50604091909101516002909101805460ff191691151591909117905550620003bc9350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000179579160200282015b828111156200017957825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000142565b50620001879291506200018b565b5090565b5b808211156200018757600081556001016200018c565b80518015158114620001b357600080fd5b919050565b600080600080600060a08688031215620001d157600080fd5b8551620001de81620003a3565b80955050602080870151620001f381620003a3565b60408801519095506200020681620003a3565b60608801519094506200021981620003a3565b60808801519093506001600160401b03808211156200023757600080fd5b908801906060828b0312156200024c57600080fd5b620002566200032f565b82516200026381620003a3565b815282840151828111156200027757600080fd5b8301601f81018c136200028957600080fd5b8051838111156200029e576200029e6200038d565b8060051b9350620002b18685016200035a565b8082825287820191508784018f89888701011115620002cf57600080fd5b600096505b83871015620003025780519450620002ec85620003a3565b84835260019690960195918801918801620002d4565b5084880152506200031991505060408401620001a2565b6040820152809450505050509295509295909350565b604051606081016001600160401b03811182821017156200035457620003546200038d565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200038557620003856200038d565b604052919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114620003b957600080fd5b50565b60805160601c60a05160601c60c05160601c60e05160601c612c9a62000464600039600081816102cc01528181610f5601528181611a3f0152611c1801526000818161012b015281816103cb0152818161068801528181610756015281816108610152818161092f0152610baf015260008181610298015281816104a50152610aca0152600081816101d30152818161130a015281816114f301526118a30152612c9a6000f3fe60806040526004361061010d5760003560e01c806399459cf611610095578063c9f567a111610064578063c9f567a114610301578063ce6db3cc14610323578063d2a9fb3e14610343578063f2fde38b14610363578063f69920631461038357600080fd5b806399459cf614610266578063a5030ded14610286578063ad5c4648146102ba578063bc60b9aa146102ee57600080fd5b80637b103999116100dc5780637b103999146101c157806385183df8146101f55780638c833449146102155780638c99cd3f146102285780638da5cb5b1461024857600080fd5b806306bddfdf1461011957806335ae7b6e1461016a5780633b62609f1461018c578063715018a6146101ac57600080fd5b3661011457005b600080fd5b34801561012557600080fd5b5061014d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561017657600080fd5b5061018a6101853660046124b0565b610396565b005b34801561019857600080fd5b5061018a6101a73660046121dc565b610479565b3480156101b857600080fd5b5061018a610626565b3480156101cd57600080fd5b5061014d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561020157600080fd5b5061018a61021036600461234c565b61065c565b61018a610223366004612289565b61072a565b34801561023457600080fd5b5061018a6102433660046125e9565b6107f9565b34801561025457600080fd5b506000546001600160a01b031661014d565b34801561027257600080fd5b5061018a61028136600461234c565b610835565b34801561029257600080fd5b5061014d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c657600080fd5b5061014d7f000000000000000000000000000000000000000000000000000000000000000081565b61018a6102fc366004612419565b610903565b34801561030d57600080fd5b506103166109dd565b6040516101619190612876565b34801561032f57600080fd5b5061018a61033e3660046121dc565b610a9e565b34801561034f57600080fd5b5061018a61035e3660046124b0565b610b83565b34801561036f57600080fd5b5061018a61037e3660046121bf565b610c50565b61018a61039136600461263c565b610ceb565b87803a11156103c05760405162461bcd60e51b81526004016103b79061283f565b60405180910390fd5b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104085760405162461bcd60e51b81526004016103b79061279c565b61046c8b8b8a6040518060a001604052808c81526020018b81526020018a8152602001898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250505090825250602001879052610de1565b5050505050505050505050565b88803a111561049a5760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461050e5760405162461bcd60e51b81526020600482015260196024820152784c696d69747353746f70733a206e6f742075736572466f727760381b60448201526064016103b7565b610541898686600081811061052557610525612ab7565b905060200201602081019061053a91906121bf565b8a8e61106e565b6040516338ed173960e01b81526000906001600160a01b038b16906338ed17399061057a908c908c908b908b908b908b90600401612928565b600060405180830381600087803b15801561059457600080fd5b505af11580156105a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105d09190810190612535565b90508681600183516105e29190612a5e565b815181106105f2576105f2612ab7565b602002602001015111156106185760405162461bcd60e51b81526004016103b7906127d3565b505050505050505050505050565b6000546001600160a01b031633146106505760405162461bcd60e51b81526004016103b79061280a565b61065a6000611092565b565b88803a111561067d5760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106c55760405162461bcd60e51b81526004016103b79061279c565b6106188c8c8b8b6040518060a001604052808d81526020018c81526020018b81526020018a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506020018890526110e2565b87803a111561074b5760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107935760405162461bcd60e51b81526004016103b79061279c565b61046c8b8b8a8a6040518060a00160405280600081526020018c81526020018b81526020018a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060200188905261141a565b6000546001600160a01b031633146108235760405162461bcd60e51b81526004016103b79061280a565b8060016108308282612b03565b505050565b88803a11156108565760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461089e5760405162461bcd60e51b81526004016103b79061279c565b6106188c8c8b8b6040518060a001604052808d81526020018c81526020018b81526020018a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060200188905261160a565b86803a11156109245760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461096c5760405162461bcd60e51b81526004016103b79061279c565b6109d18a8a896040518060a00160405280600081526020018b81526020018a81526020018989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506020018790526119a5565b50505050505050505050565b610a0c604051806060016040528060006001600160a01b03168152602001606081526020016000151581525090565b60408051606081018252600180546001600160a01b03168252600280548451602082810282018101909652818152939492938386019390929190830182828015610a7f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610a61575b50505091835250506002919091015460ff161515602090910152919050565b88803a1115610abf5760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b335760405162461bcd60e51b81526020600482015260196024820152784c696d69747353746f70733a206e6f742075736572466f727760381b60448201526064016103b7565b610b4a898686600081811061052557610525612ab7565b60405163676528d160e01b81526000906001600160a01b038b169063676528d19061057a908c908c908b908b908b908b90600401612928565b87803a1115610ba45760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610bec5760405162461bcd60e51b81526004016103b79061279c565b61046c8b8b8a6040518060a001604052808c81526020018b81526020018a8152602001898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250505090825250602001879052611aa3565b6000546001600160a01b03163314610c7a5760405162461bcd60e51b81526004016103b79061280a565b6001600160a01b038116610cdf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103b7565b610ce881611092565b50565b87803a1115610d0c5760405162461bcd60e51b81526004016103b79061283f565b6000886001600160a01b031663a2a1623d348a898989896040518763ffffffff1660e01b8152600401610d439594939291906128bc565b6000604051808303818588803b158015610d5c57600080fd5b505af1158015610d70573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f19168201604052610d999190810190612535565b9050868160018351610dab9190612a5e565b81518110610dbb57610dbb612ab7565b602002602001015111156109d15760405162461bcd60e51b81526004016103b7906127d3565b60408051606081018252600180546001600160a01b0316825260028054845160208281028201810190965281815260009580860193919290830182828015610e5257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e34575b50505091835250506002919091015460ff16151560209091015260408101519091508015610eda575060208101518051610e8e90600190612a5e565b81518110610e9e57610e9e612ab7565b60200260200101516001600160a01b03168260600151600081518110610ec657610ec6612ab7565b60200260200101516001600160a01b031614155b15610ffa5760408051600380825260808201909252600091602082016060803683370190505090508260600151600081518110610f1957610f19612ab7565b602002602001015181600081518110610f3457610f34612ab7565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000000000000000000000000000000000000000000081600181518110610f8857610f88612ab7565b6001600160a01b039092166020928302919091018201528201518051610fb090600190612a5e565b81518110610fc057610fc0612ab7565b602002602001015181600281518110610fdb57610fdb612ab7565b6001600160a01b0390921660209283029190910182015282015261105a565b806040015161105a57816060015160008151811061101a5761101a612ab7565b6020026020010151816020015160008151811061103957611039612ab7565b60200260200101906001600160a01b031690816001600160a01b0316815250505b611067858585848661160a565b5050505050565b600061107b858585611cc5565b90506110676001600160a01b038216833086611dda565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516040830151156112ae576020830151805161110190600190612a5e565b8151811061111157611111612ab7565b60200260200101516001600160a01b0316826060015160008151811061113957611139612ab7565b60200260200101516001600160a01b0316141561118b5761115a8582612a5e565b905061118684836060015160008151811061117757611177612ab7565b6020026020010151838961106e565b6112c9565b6111b98483606001516000815181106111a6576111a6612ab7565b602002602001015184600001518961106e565b6111ea836000015183606001516000815181106111d8576111d8612ab7565b60200260200101518460000151611cc5565b508251825160208501516080850151604051634401edf760e11b81526001600160a01b0390941693638803dbee9361122c938b93919290918d91600401612966565b600060405180830381600087803b15801561124657600080fd5b505af115801561125a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112829190810190612535565b60008151811061129457611294612ab7565b6020026020010151816112a79190612a5e565b90506112c9565b6112c98483606001516000815181106111a6576111a6612ab7565b6000846001600160a01b031663676528d18385600001518587602001516112f09190612a3f565b6112fa9190612a1d565b8660600151886040015161132e577f0000000000000000000000000000000000000000000000000000000000000000611330565b8b5b88608001516040518663ffffffff1660e01b8152600401611355959493929190612966565b600060405180830381600087803b15801561136f57600080fd5b505af1158015611383573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113ab9190810190612535565b905082600001518284604001516113c29190612a3f565b6113cc9190612a1d565b81600183516113db9190612a5e565b815181106113eb576113eb612ab7565b602002602001015111156114115760405162461bcd60e51b81526004016103b7906127d3565b50505050505050565b60408201513490156114e657825160208401516080840151604051638a657e6760e01b81526001600160a01b0390931692638a657e67923492611464928b92918d916004016128f3565b6000604051808303818588803b15801561147d57600080fd5b505af1158015611491573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526114ba9190810190612535565b6000815181106114cc576114cc612ab7565b6020026020010151816114df9190612a5e565b905061154a565b6040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169086156108fc029087906000818181858888f1935050505015801561153c573d6000803e3d6000fd5b506115478582612a5e565b90505b6000846001600160a01b031663a2a1623d833485876020015161156d9190612a3f565b6115779190612a1d565b86606001518b88608001516040518663ffffffff1660e01b81526004016115a194939291906128f3565b6000604051808303818588803b1580156115ba57600080fd5b505af11580156115ce573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526115f79190810190612535565b9050348284604001516113c29190612a3f565b805160408301511561182f576020830151805161162990600190612a5e565b8151811061163957611639612ab7565b60200260200101516001600160a01b0316826060015160008151811061166157611661612ab7565b60200260200101516001600160a01b031614156116a4576116828582612a5e565b905061169f84836060015160008151811061117757611177612ab7565b611949565b602083015180516116b790600190612a5e565b815181106116c7576116c7612ab7565b60200260200101516001600160a01b0316826060015160018460600151516116ef9190612a5e565b815181106116ff576116ff612ab7565b60200260200101516001600160a01b031614156117315761169f8483606001516000815181106111a6576111a6612ab7565b61174c8483606001516000815181106111a6576111a6612ab7565b61176b836000015183606001516000815181106111d8576111d8612ab7565b508251825160208501516080850151604051634401edf760e11b81526001600160a01b0390941693638803dbee936117ad938b93919290918d91600401612966565b600060405180830381600087803b1580156117c757600080fd5b505af11580156117db573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118039190810190612535565b60008151811061181557611815612ab7565b6020026020010151816118289190612a5e565b9050611949565b61184a8483606001516000815181106111a6576111a6612ab7565b611869836000015183606001516000815181106111d8576111d8612ab7565b508251825160208501516080850151604051633d2120b560e11b81526001600160a01b0390941693637a42416a936118cb938b93919290917f000000000000000000000000000000000000000000000000000000000000000091600401612966565b600060405180830381600087803b1580156118e557600080fd5b505af11580156118f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119219190810190612535565b60008151811061193357611933612ab7565b6020026020010151816119469190612a5e565b90505b6000846001600160a01b03166338ed17398385600001518587602001516119709190612a3f565b61197a9190612a1d565b86606001518b88608001516040518663ffffffff1660e01b8152600401611355959493929190612966565b60408051606081018252600180546001600160a01b0316825260028054845160208281028201810190965281815260009580860193919290830182828015611a1657602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116119f8575b50505091835250506002919091015460ff161515602090910152604081015190915015611a96577f00000000000000000000000000000000000000000000000000000000000000008160200151600081518110611a7557611a75612ab7565b60200260200101906001600160a01b031690816001600160a01b0316815250505b611067858585848661141a565b60408051606081018252600180546001600160a01b0316825260028054845160208281028201810190965281815260009580860193919290830182828015611b1457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611af6575b50505091835250506002919091015460ff16151560209091015260408101519091508015611b9c575060208101518051611b5090600190612a5e565b81518110611b6057611b60612ab7565b60200260200101516001600160a01b03168260600151600081518110611b8857611b88612ab7565b60200260200101516001600160a01b031614155b15611cb85760408051600380825260808201909252600091602082016060803683370190505090508260600151600081518110611bdb57611bdb612ab7565b602002602001015181600081518110611bf657611bf6612ab7565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000000000000000000000000000000000000000000081600181518110611c4a57611c4a612ab7565b6001600160a01b039092166020928302919091018201528201518051611c7290600190612a5e565b81518110611c8257611c82612ab7565b602002602001015181600281518110611c9d57611c9d612ab7565b6001600160a01b039092166020928302919091018201528201525b61106785858584866110e2565b604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528391839183169063dd62ed3e9060440160206040518083038186803b158015611d1057600080fd5b505afa158015611d24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d489190612623565b1015611dd35760405163095ea7b360e01b81526001600160a01b038581166004830152600019602483015282169063095ea7b390604401602060405180830381600087803b158015611d9957600080fd5b505af1158015611dad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd191906125cc565b505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611e34908590611e3a565b50505050565b6000611e8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611f0c9092919063ffffffff16565b8051909150156108305780806020019051810190611ead91906125cc565b6108305760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103b7565b6060611f1b8484600085611f23565b949350505050565b606082471015611f845760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103b7565b843b611fd25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103b7565b600080866001600160a01b03168587604051611fee919061274d565b60006040518083038185875af1925050503d806000811461202b576040519150601f19603f3d011682016040523d82523d6000602084013e612030565b606091505b509150915061204082828661204b565b979650505050505050565b6060831561205a575081611dd3565b82511561206a5782518084602001fd5b8160405162461bcd60e51b81526004016103b79190612769565b803561208f81612c41565b919050565b60008083601f8401126120a657600080fd5b5081356001600160401b038111156120bd57600080fd5b6020830191508360208260051b85010111156120d857600080fd5b9250929050565b803561208f81612c56565b6000606082840312156120fc57600080fd5b6121046129a2565b9050813561211181612c41565b81526020828101356001600160401b0381111561212d57600080fd5b8301601f8101851361213e57600080fd5b803561215161214c826129fa565b6129ca565b80828252848201915084840188868560051b870101111561217157600080fd5b600094505b8385101561219d57803561218981612c41565b835260019490940193918501918501612176565b50808587015250505050506121b4604083016120df565b604082015292915050565b6000602082840312156121d157600080fd5b8135611dd381612c41565b6000806000806000806000806000806101208b8d0312156121fc57600080fd5b8a3561220781612c41565b995060208b0135985060408b013561221e81612c41565b975060608b0135965060808b0135955060a08b0135945060c08b01356001600160401b0381111561224e57600080fd5b61225a8d828e01612094565b90955093505060e08b013561226e81612c41565b809250506101008b013590509295989b9194979a5092959850565b6000806000806000806000806000806101208b8d0312156122a957600080fd5b8a356122b481612c41565b995060208b0135985060408b0135975060608b01356122d281612c41565b965060808b01356001600160401b03808211156122ee57600080fd5b6122fa8e838f016120ea565b975060a08d0135965060c08d0135955060e08d013591508082111561231e57600080fd5b5061232b8d828e01612094565b915080945050809250506101008b013590509295989b9194979a5092959850565b60008060008060008060008060008060006101408c8e03121561236e57600080fd5b6123778c612084565b9a5060208c0135995060408c0135985061239360608d01612084565b97506001600160401b038060808e013511156123ae57600080fd5b6123be8e60808f01358f016120ea565b975060a08d0135965060c08d0135955060e08d01359450806101008e013511156123e757600080fd5b506123f98d6101008e01358e01612094565b81945080935050506101208c013590509295989b509295989b9093969950565b60008060008060008060008060006101008a8c03121561243857600080fd5b893561244381612c41565b985060208a0135975060408a0135965060608a013561246181612c41565b955060808a0135945060a08a0135935060c08a01356001600160401b0381111561248a57600080fd5b6124968c828d01612094565b9a9d999c50979a9699959894979660e00135949350505050565b6000806000806000806000806000806101208b8d0312156124d057600080fd5b8a356124db81612c41565b995060208b0135985060408b0135975060608b01356124f981612c41565b965060808b0135955060a08b0135945060c08b0135935060e08b01356001600160401b0381111561252957600080fd5b61232b8d828e01612094565b6000602080838503121561254857600080fd5b82516001600160401b0381111561255e57600080fd5b8301601f8101851361256f57600080fd5b805161257d61214c826129fa565b80828252848201915084840188868560051b870101111561259d57600080fd5b600094505b838510156125c05780518352600194909401939185019185016125a2565b50979650505050505050565b6000602082840312156125de57600080fd5b8151611dd381612c56565b6000602082840312156125fb57600080fd5b81356001600160401b0381111561261157600080fd5b820160608185031215611dd357600080fd5b60006020828403121561263557600080fd5b5051919050565b60008060008060008060008060e0898b03121561265857600080fd5b88359750602089013561266a81612c41565b9650604089013595506060890135945060808901356001600160401b0381111561269357600080fd5b61269f8b828c01612094565b90955093505060a08901356126b381612c41565b8092505060c089013590509295985092959890939650565b8183526000602080850194508260005b858110156127095781356126ee81612c41565b6001600160a01b0316875295820195908201906001016126db565b509495945050505050565b600081518084526020808501945080840160005b838110156127095781516001600160a01b031687529582019590820190600101612728565b6000825161275f818460208701612a75565b9190910192915050565b6020815260008251806020840152612788816040850160208701612a75565b601f01601f19169190910160400192915050565b6020808252601c908201527f4c696d69747353746f70733a206e6f742075736572466565466f727700000000604082015260600190565b6020808252601b908201527f4c696d69747353746f70733a20707269636520746f6f20686967680000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601e908201527f4c696d69747353746f70733a20676173507269636520746f6f20686967680000604082015260600190565b602080825282516001600160a01b031682820152820151606060408301526000906128a46080840182612714565b90506040840151151560608401528091505092915050565b8581526080602082015260006128d66080830186886126cb565b6001600160a01b0394909416604083015250606001529392505050565b84815260806020820152600061290c6080830186612714565b6001600160a01b03949094166040830152506060015292915050565b86815285602082015260a06040820152600061294860a0830186886126cb565b6001600160a01b039490941660608301525060800152949350505050565b85815284602082015260a06040820152600061298560a0830186612714565b6001600160a01b0394909416606083015250608001529392505050565b604051606081016001600160401b03811182821017156129c4576129c4612acd565b60405290565b604051601f8201601f191681016001600160401b03811182821017156129f2576129f2612acd565b604052919050565b60006001600160401b03821115612a1357612a13612acd565b5060051b60200190565b600082612a3a57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612a5957612a59612aa1565b500290565b600082821015612a7057612a70612aa1565b500390565b60005b83811015612a90578181015183820152602001612a78565b83811115611e345750506000910152565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60008135612af081612c41565b92915050565b60008135612af081612c56565b8135612b0e81612c41565b81546001600160a01b0319166001600160a01b0391909116178155600181810160208481013536869003601e19018112612b4757600080fd5b850180356001600160401b03811115612b5f57600080fd5b82820191508060051b3603821315612b7657600080fd5b68010000000000000000811115612b8f57612b8f612acd565b835481855580821015612bc35760008581528481208381019083015b80821015612bbf5782825590880190612bab565b5050505b50600093845260208420935b81811015612c0f57612c00612be384612ae3565b86546001600160a01b0319166001600160a01b0391909116178655565b93850193918301918501612bcf565b505050505050612c3d612c2460408401612af6565b6002830160ff1981541660ff8315151681178255505050565b5050565b6001600160a01b0381168114610ce857600080fd5b8015158114610ce857600080fdfea26469706673582212201f1fe54382414dad0acf7a4a7c333a7a74deb98ccbd82c305914a40eac77362364736f6c6343000806003300000000000000000000000068fcbeca74a7e5d386f74e14682c94de0e1bc56b000000000000000000000000d638029a9356db6301462470094786494d1dda39000000000000000000000000c21e82fe258abf9bc3ef68fb38aecda79e472964000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c700000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000e54ca86531e17ef3616d22ca28b0d458b6c891060000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000068fcbeca74a7e5d386f74e14682c94de0e1bc56b000000000000000000000000d638029a9356db6301462470094786494d1dda39000000000000000000000000c21e82fe258abf9bc3ef68fb38aecda79e472964000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c700000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000e54ca86531e17ef3616d22ca28b0d458b6c891060000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7
-----Decoded View---------------
Arg [0] : registry_ (address): 0x68fcbeca74a7e5d386f74e14682c94de0e1bc56b
Arg [1] : userVeriForwarder_ (address): 0xd638029a9356db6301462470094786494d1dda39
Arg [2] : userFeeVeriForwarder_ (address): 0xc21e82fe258abf9bc3ef68fb38aecda79e472964
Arg [3] : WETH_ (address): 0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7
Arg [4] : defaultFeeInfo (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 00000000000000000000000068fcbeca74a7e5d386f74e14682c94de0e1bc56b
Arg [1] : 000000000000000000000000d638029a9356db6301462470094786494d1dda39
Arg [2] : 000000000000000000000000c21e82fe258abf9bc3ef68fb38aecda79e472964
Arg [3] : 000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [5] : 000000000000000000000000e54ca86531e17ef3616d22ca28b0d458b6c89106
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [10] : 000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.