Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
UniswapV2LikeExchange
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../dependencies/uniswap/libraries/UniswapV2Library.sol"; import "../access/Governable.sol"; import "../interfaces/swapper/IExchange.sol"; /** * @notice UniswapV2 Like Exchange */ contract UniswapV2LikeExchange is IExchange, Governable { using SafeERC20 for IERC20; /** * @notice The WETH-Like token (a.k.a. Native Token) * @dev I.e. should be the most liquid token that offer best routers among trade pairs * @dev It's usually the wrapper token of the chain's native coin but it isn't always true * For instance: On Polygon, the `WETH` is more liquid than `WMATIC` on UniV3 protocol. */ address public wethLike; /** * @notice The UniswapV2-Like factory contract */ address public immutable factory; bytes32 internal immutable initCodeHash; /// @notice Emitted when wethLike token is updated event WethLikeTokenUpdated(address oldWethLike, address newWethLike); /** * @dev Doesn't consider router.WETH() as `wethLike` because isn't guaranteed that it's the most liquid token. */ constructor( address factory_, bytes32 initCodeHash_, address wethLike_ ) { factory = factory_; initCodeHash = initCodeHash_; wethLike = wethLike_; } /// @inheritdoc IExchange function getAmountsIn(uint256 amountOut_, bytes memory path_) external view override returns (uint256 _amountIn) { _amountIn = getAmountsIn(amountOut_, _decodePath(path_)); } /// @inheritdoc IExchange function getAmountsOut(uint256 amountIn_, bytes memory path_) external view override returns (uint256 _amountOut) { _amountOut = getAmountsOut(amountIn_, _decodePath(path_)); } /** * @dev getBestAmountIn require a try/catch version of getAmountsIn and try/catch do not work with internal * library functions, hence wrapped library call in this function so that it can be used in try/catch */ function getAmountsIn(uint256 amountOut_, address[] memory path_) public view returns (uint256 _amountIn) { _amountIn = UniswapV2Library.getAmountsIn(factory, initCodeHash, amountOut_, path_)[0]; } /** * @dev getBestAmountOut require a try/catch version of getAmountsOut and try/catch do not work with internal * library functions, hence wrapped library call in this function so that it can be used in try/catch */ function getAmountsOut(uint256 amountIn_, address[] memory path_) public view returns (uint256 _amountOut) { _amountOut = UniswapV2Library.getAmountsOut(factory, initCodeHash, amountIn_, path_)[path_.length - 1]; } /// @inheritdoc IExchange function getBestAmountIn( address tokenIn_, address tokenOut_, uint256 amountOut_ ) external returns (uint256 _amountIn, bytes memory _path) { // 1. Check IN-OUT pair address[] memory _pathA = new address[](2); _pathA[0] = tokenIn_; _pathA[1] = tokenOut_; uint256 _amountInA = _getAmountsIn(amountOut_, _pathA); if (tokenIn_ == wethLike || tokenOut_ == wethLike) { // Returns if one of the token is WETH-Like require(_amountInA > 0, "no-path-found"); return (_amountInA, _encodePath(_pathA)); } // 2. Check IN-WETH-OUT path address[] memory _pathB = new address[](3); _pathB[0] = tokenIn_; _pathB[1] = wethLike; _pathB[2] = tokenOut_; uint256 _amountInB = _getAmountsIn(amountOut_, _pathB); // 3. Get best route between paths A and B require(_amountInA > 0 || _amountInB > 0, "no-path-found"); // Returns A if it's valid and better than B or if B isn't valid if ((_amountInA > 0 && _amountInA < _amountInB) || _amountInB == 0) { return (_amountInA, _encodePath(_pathA)); } return (_amountInB, _encodePath(_pathB)); } /// @inheritdoc IExchange function getBestAmountOut( address tokenIn_, address tokenOut_, uint256 amountIn_ ) external returns (uint256 _amountOut, bytes memory _path) { // 1. Check IN-OUT pair address[] memory _pathA = new address[](2); _pathA[0] = tokenIn_; _pathA[1] = tokenOut_; uint256 _amountOutA = _getAmountsOut(amountIn_, _pathA); if (tokenIn_ == wethLike || tokenOut_ == wethLike) { // Returns if one of the token is WETH-Like require(_amountOutA > 0, "no-path-found"); return (_amountOutA, _encodePath(_pathA)); } // 2. Check IN-WETH-OUT path address[] memory _pathB = new address[](3); _pathB[0] = tokenIn_; _pathB[1] = wethLike; _pathB[2] = tokenOut_; uint256 _amountOutB = _getAmountsOut(amountIn_, _pathB); // 3. Get best route between paths A and B require(_amountOutA > 0 || _amountOutB > 0, "no-path-found"); if (_amountOutA > _amountOutB) return (_amountOutA, _encodePath(_pathA)); return (_amountOutB, _encodePath(_pathB)); } /// @inheritdoc IExchange function swapExactInput( bytes calldata path_, uint256 amountIn_, uint256 amountOutMin_, address outReceiver_ ) external returns (uint256 _amountOut) { address[] memory _path = _decodePath(path_); IERC20 _tokenIn = IERC20(_path[0]); IERC20 _tokenOut = IERC20(_path[_path.length - 1]); _tokenIn.safeTransfer(UniswapV2Library.pairFor(factory, initCodeHash, _path[0], _path[1]), amountIn_); uint256 balanceBefore = _tokenOut.balanceOf(outReceiver_); _swap(_path, outReceiver_); _amountOut = _tokenOut.balanceOf(outReceiver_) - balanceBefore; require(_amountOut >= amountOutMin_, "Too little received"); } /// @inheritdoc IExchange function swapExactOutput( bytes calldata path_, uint256 amountOut_, uint256 amountInMax_, address inSender_, address outRecipient_ ) external returns (uint256 _amountIn) { address[] memory _path = _decodePath(path_); IERC20 _tokenIn = IERC20(_path[0]); _amountIn = UniswapV2Library.getAmountsIn(factory, initCodeHash, amountOut_, _path)[0]; require(_amountIn <= amountInMax_, "Too much requested"); _tokenIn.safeTransfer(UniswapV2Library.pairFor(factory, initCodeHash, _path[0], _path[1]), _amountIn); _swap(_path, outRecipient_); // If swap end up costly less than _amountInMax then return remaining uint256 _remainingAmountIn = amountInMax_ - _amountIn; if (_remainingAmountIn > 0) { _tokenIn.safeTransfer(inSender_, _remainingAmountIn); } } /// @dev Returns `0` if reverts function _getAmountsIn(uint256 _amountOut, address[] memory _path) internal view returns (uint256 _amountIn) { try this.getAmountsIn(_amountOut, _path) returns (uint256 amountIn) { _amountIn = amountIn; } catch {} } /// @dev Returns `0` if reverts function _getAmountsOut(uint256 amountIn_, address[] memory path_) internal view returns (uint256 _amountOut) { try this.getAmountsOut(amountIn_, path_) returns (uint256 amountOut) { _amountOut = amountOut; } catch {} } /** * @notice Encode path from `address[]` to `bytes` */ function _encodePath(address[] memory path_) private pure returns (bytes memory _path) { return abi.encode(path_); } /** * @notice Encode path from `bytes` to `address[]` */ function _decodePath(bytes memory path_) private pure returns (address[] memory _path) { return abi.decode(path_, (address[])); } /** * NOTICE:: This function is being used as is from Uniswap's V2SwapRouter.sol deployed * at 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 and licensed under GPL-2.0-or-later. * - It does supports fee-on-transfer tokens * - It does requires the initial amount to have already been sent to the first pair */ function _swap(address[] memory path, address _to) private { for (uint256 i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0, ) = UniswapV2Library.sortTokens(input, output); IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, initCodeHash, input, output)); uint256 amountInput; uint256 amountOutput; // scope to avoid stack too deep errors { (uint256 reserve0, uint256 reserve1, ) = pair.getReserves(); (uint256 reserveInput, uint256 reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput; amountOutput = UniswapV2Library.getAmountOut(amountInput, reserveInput, reserveOutput); } (uint256 amount0Out, uint256 amount1Out) = input == token0 ? (uint256(0), amountOutput) : (amountOutput, uint256(0)); address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, initCodeHash, output, path[i + 2]) : _to; pair.swap(amount0Out, amount1Out, to, new bytes(0)); } } /** * @notice Update WETH-Like token */ function updateWethLikeToken(address wethLike_) external onlyGovernor { emit WethLikeTokenUpdated(wethLike, wethLike_); wethLike = wethLike_; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/Address.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = _setInitializedVersion(1); if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { bool isTopLevelCall = _setInitializedVersion(version); if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(version); } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { _setInitializedVersion(type(uint8).max); } function _setInitializedVersion(uint8 version) private returns (bool) { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level // of initializers, because in other contexts the contract may have been reentered. if (_initializing) { require( version == 1 && !Address.isContract(address(this)), "Initializable: contract is already initialized" ); return false; } else { require(_initialized < version, "Initializable: contract is already initialized"); _initialized = version; return true; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @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 // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return 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); } } } }
// 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; } }
pragma solidity >=0.5.0; interface IUniswapV2Factory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; }
pragma solidity >=0.5.0; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.0; /// @title Optimized overflow and underflow safe math operations /// @notice Contains methods for doing math operations that revert on overflow or underflow for minimal gas cost library LowGasSafeMath { /// @notice Returns x + y, reverts if sum overflows uint256 /// @param x The augend /// @param y The addend /// @return z The sum of x and y function add(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x + y) >= x); } /// @notice Returns x - y, reverts if underflows /// @param x The minuend /// @param y The subtrahend /// @return z The difference of x and y function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x - y) <= x); } /// @notice Returns x * y, reverts if overflows /// @param x The multiplicand /// @param y The multiplier /// @return z The product of x and y function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { require(x == 0 || (z = x * y) / x == y); } /// @notice Returns x + y, reverts if overflows or underflows /// @param x The augend /// @param y The addend /// @return z The sum of x and y function add(int256 x, int256 y) internal pure returns (int256 z) { require((z = x + y) >= x == (y >= 0)); } /// @notice Returns x - y, reverts if overflows or underflows /// @param x The minuend /// @param y The subtrahend /// @return z The difference of x and y function sub(int256 x, int256 y) internal pure returns (int256 z) { require((z = x - y) <= x == (y >= 0)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import "../interfaces/IGovernable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (governor) that can be granted exclusive access to * specific functions. * * By default, the governor account will be the one that deploys the contract. This * can later be changed with {transferGovernorship}. * */ abstract contract Governable is IGovernable, Context, Initializable { address public governor; address private proposedGovernor; event UpdatedGovernor(address indexed previousGovernor, address indexed proposedGovernor); /** * @dev Initializes the contract setting the deployer as the initial governor. */ constructor() { address msgSender = _msgSender(); governor = msgSender; emit UpdatedGovernor(address(0), msgSender); } /** * @dev If inheriting child is using proxy then child contract can use * __Governable_init() function to initialization this contract */ // solhint-disable-next-line func-name-mixedcase function __Governable_init() internal initializer { address msgSender = _msgSender(); governor = msgSender; emit UpdatedGovernor(address(0), msgSender); } /** * @dev Throws if called by any account other than the governor. */ modifier onlyGovernor() { require(governor == _msgSender(), "not-governor"); _; } /** * @dev Transfers governorship of the contract to a new account (`proposedGovernor`). * Can only be called by the current owner. */ function transferGovernorship(address _proposedGovernor) external onlyGovernor { require(_proposedGovernor != address(0), "proposed-governor-is-zero"); proposedGovernor = _proposedGovernor; } /** * @dev Allows new governor to accept governorship of the contract. */ function acceptGovernorship() external { require(proposedGovernor == _msgSender(), "not-the-proposed-governor"); emit UpdatedGovernor(governor, proposedGovernor); governor = proposedGovernor; proposedGovernor = address(0); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol'; import '@uniswap/v3-core/contracts/libraries/LowGasSafeMath.sol'; /** * This is copied from Uniswap's V2SwapRouter.sol deployed at 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 * and licensed under GPL-2.0-or-later. * Changelog: * - Removed hardcoded initCodeHash and taking as param so that we can support multiple UniswapV2Like exchanges * - Added function getAmountsOut() */ library UniswapV2Library { using LowGasSafeMath for uint256; // returns sorted token addresses, used to handle return values from pairs sorted in this order function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { require(tokenA != tokenB); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0)); } // calculates the CREATE2 address for a pair without making any external calls function pairFor(address factory, bytes32 initCodeHash, address tokenA, address tokenB) internal pure returns (address pair) { (address token0, address token1) = sortTokens(tokenA, tokenB); pair = address(uint160 (uint256(keccak256(abi.encodePacked( hex'ff', factory, keccak256(abi.encodePacked(token0, token1)), initCodeHash ))))); } // fetches and sorts the reserves for a pair function getReserves( address factory, bytes32 initCodeHash, address tokenA, address tokenB ) internal view returns (uint256 reserveA, uint256 reserveB) { (address token0, ) = sortTokens(tokenA, tokenB); (uint256 reserve0, uint256 reserve1, ) = IUniswapV2Pair(pairFor(factory, initCodeHash, tokenA, tokenB)).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) internal pure returns (uint256 amountOut) { require(amountIn > 0, 'INSUFFICIENT_INPUT_AMOUNT'); require(reserveIn > 0 && reserveOut > 0); uint256 amountInWithFee = amountIn.mul(997); uint256 numerator = amountInWithFee.mul(reserveOut); uint256 denominator = reserveIn.mul(1000).add(amountInWithFee); amountOut = numerator / denominator; } // given an output amount of an asset and pair reserves, returns a required input amount of the other asset function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) internal pure returns (uint256 amountIn) { require(amountOut > 0, 'INSUFFICIENT_OUTPUT_AMOUNT'); require(reserveIn > 0 && reserveOut > 0); uint256 numerator = reserveIn.mul(amountOut).mul(1000); uint256 denominator = reserveOut.sub(amountOut).mul(997); amountIn = (numerator / denominator).add(1); } // performs chained getAmountOut calculations on any number of pairs function getAmountsOut( address factory, bytes32 initCodeHash, uint amountIn, address[] memory path ) internal view returns (uint[] memory amounts) { require(path.length >= 2); amounts = new uint[](path.length); amounts[0] = amountIn; for (uint i; i < path.length - 1; i++) { (uint reserveIn, uint reserveOut) = getReserves(factory, initCodeHash, path[i], path[i + 1]); amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut); } } // performs chained getAmountIn calculations on any number of pairs function getAmountsIn( address factory, bytes32 initCodeHash, uint256 amountOut, address[] memory path ) internal view returns (uint256[] memory amounts) { require(path.length >= 2); amounts = new uint256[](path.length); amounts[amounts.length - 1] = amountOut; for (uint256 i = path.length - 1; i > 0; i--) { (uint256 reserveIn, uint256 reserveOut) = getReserves(factory,initCodeHash, path[i - 1], path[i]); amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; /** * @notice Governable interface */ interface IGovernable { function governor() external view returns (address _governor); function transferGovernorship(address _proposedGovernor) external; }
// SPDX-License-Identifier: MIT pragma solidity <=0.8.9; /** * @notice Exchange interface */ interface IExchange { /** * @notice Get *spot* quote * It will return the swap amount based on the current reserves of the given path (i.e. spot price) * @dev It shouldn't be used as oracle!!! */ function getAmountsIn(uint256 _amountOut, bytes memory path_) external returns (uint256 _amountIn); /** * @notice Get *spot* quote * It will return the swap amount based on the current reserves of the given path (i.e. spot price) * @dev It shouldn't be used as oracle!!! */ function getAmountsOut(uint256 amountIn_, bytes memory path_) external returns (uint256 _amountOut); /** * @notice Get *spot* quote * It will return the swap amount based on the current reserves of the best pair/path found (i.e. spot price) * @dev It shouldn't be used as oracle!!! */ function getBestAmountIn( address tokenIn_, address tokenOut_, uint256 amountOut_ ) external returns (uint256 _amountIn, bytes memory _path); /** * @notice Get *spot* quote * It will return the swap amount based on the current reserves of the best pair/path found (i.e. spot price) * @dev It shouldn't be used as oracle!!! */ function getBestAmountOut( address tokenIn_, address tokenOut_, uint256 amountIn_ ) external returns (uint256 _amountOut, bytes memory _path); /** * @notice Perform an exact input swap * @dev Should transfer `amountIn_` before performing swap */ function swapExactInput( bytes calldata path_, uint256 amountIn_, uint256 amountOutMin_, address outReceiver_ ) external returns (uint256 _amountOut); /** * @notice Perform an exact output swap * @dev Should transfer `amountInMax_` before performing swap * @dev Sends swap remains - if any - to the `inSender_` */ function swapExactOutput( bytes calldata path_, uint256 amountOut_, uint256 amountInMax_, address inSender_, address outRecipient_ ) external returns (uint256 _amountIn); }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 5000 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"factory_","type":"address"},{"internalType":"bytes32","name":"initCodeHash_","type":"bytes32"},{"internalType":"address","name":"wethLike_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"proposedGovernor","type":"address"}],"name":"UpdatedGovernor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldWethLike","type":"address"},{"indexed":false,"internalType":"address","name":"newWethLike","type":"address"}],"name":"WethLikeTokenUpdated","type":"event"},{"inputs":[],"name":"acceptGovernorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut_","type":"uint256"},{"internalType":"address[]","name":"path_","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut_","type":"uint256"},{"internalType":"bytes","name":"path_","type":"bytes"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn_","type":"uint256"},{"internalType":"address[]","name":"path_","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn_","type":"uint256"},{"internalType":"bytes","name":"path_","type":"bytes"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn_","type":"address"},{"internalType":"address","name":"tokenOut_","type":"address"},{"internalType":"uint256","name":"amountOut_","type":"uint256"}],"name":"getBestAmountIn","outputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"bytes","name":"_path","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn_","type":"address"},{"internalType":"address","name":"tokenOut_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"}],"name":"getBestAmountOut","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"},{"internalType":"bytes","name":"_path","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"path_","type":"bytes"},{"internalType":"uint256","name":"amountIn_","type":"uint256"},{"internalType":"uint256","name":"amountOutMin_","type":"uint256"},{"internalType":"address","name":"outReceiver_","type":"address"}],"name":"swapExactInput","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"path_","type":"bytes"},{"internalType":"uint256","name":"amountOut_","type":"uint256"},{"internalType":"uint256","name":"amountInMax_","type":"uint256"},{"internalType":"address","name":"inSender_","type":"address"},{"internalType":"address","name":"outRecipient_","type":"address"}],"name":"swapExactOutput","outputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_proposedGovernor","type":"address"}],"name":"transferGovernorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wethLike_","type":"address"}],"name":"updateWethLikeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wethLike","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b50604051620026b6380380620026b68339810160408190526200003491620000ca565b6000805462010000600160b01b03191633620100008102919091178255604051909182917fd4459d5b8b913cab0244230fd9b1c08b6ceace7fe9230e60d0f74cbffdf849d0908290a3506001600160a01b0392831660805260a091909152600280546001600160a01b031916919092161790556200010b565b80516001600160a01b0381168114620000c557600080fd5b919050565b600080600060608486031215620000e057600080fd5b620000eb84620000ad565b9250602084015191506200010260408501620000ad565b90509250925092565b60805160a05161252a6200018c600039600081816105020152818161061701528181610bf701528181610cb201528181610e680152818161140101526116100152600081816101f3015281816104e1015281816105f601528181610bd601528181610c9101528181610e47015281816113e001526115ef015261252a6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80637fbb36e71161008c578063c45a015511610066578063c45a0155146101ee578063d06ca61f14610215578063f3b27bc314610228578063fee9574a1461023057600080fd5b80637fbb36e7146101b35780639d9f384d146101c8578063b6aa515b146101db57600080fd5b806329dbd944116100c857806329dbd944146101675780632aa4a9e51461017a5780634909c29a1461018d57806370b24742146101a057600080fd5b80630c340a24146100ef57806319145798146101255780631f00ca7414610146575b600080fd5b600054610108906201000090046001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610138610133366004611e07565b610243565b60405161011c929190611ea4565b610159610154366004611f41565b6104da565b60405190815260200161011c565b600254610108906001600160a01b031681565b610159610188366004611fec565b61054a565b61015961019b3660046120cd565b610560565b6101386101ae366004611e07565b610822565b6101c66101c1366004612138565b610a8c565b005b6101596101d6366004612155565b610b6e565b6101c66101e9366004612138565b610d4f565b6101087f000000000000000000000000000000000000000000000000000000000000000081565b610159610223366004611f41565b610e40565b6101c6610eac565b61015961023e366004611fec565b610fac565b60408051600280825260608281019093526000929183918160200160208202803683370190505090508581600081518110610280576102806121d1565b60200260200101906001600160a01b031690816001600160a01b03168152505084816001815181106102b4576102b46121d1565b60200260200101906001600160a01b031690816001600160a01b03168152505060006102e08583610fbb565b6002549091506001600160a01b038881169116148061030c57506002546001600160a01b038781169116145b1561037b57600081116103665760405162461bcd60e51b815260206004820152600d60248201527f6e6f2d706174682d666f756e640000000000000000000000000000000000000060448201526064015b60405180910390fd5b8061037083611056565b9350935050506104d2565b604080516003808252608082019092526000916020820160608036833701905050905087816000815181106103b2576103b26121d1565b6001600160a01b0392831660209182029290920101526002548251911690829060019081106103e3576103e36121d1565b60200260200101906001600160a01b031690816001600160a01b0316815250508681600281518110610417576104176121d1565b60200260200101906001600160a01b031690816001600160a01b03168152505060006104438783610fbb565b905060008311806104545750600081115b6104a05760405162461bcd60e51b815260206004820152600d60248201527f6e6f2d706174682d666f756e6400000000000000000000000000000000000000604482015260640161035d565b808311156104bf57826104b285611056565b95509550505050506104d2565b806104c983611056565b95509550505050505b935093915050565b60006105287f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000858561107f565b60008151811061053a5761053a6121d1565b6020026020010151905092915050565b600061055983610154846111d4565b9392505050565b6000806105a287878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111d492505050565b90506000816000815181106105b9576105b96121d1565b60200260200101519050600082600184516105d4919061222f565b815181106105e4576105e46121d1565b602002602001015190506106826106717f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000086600081518110610649576106496121d1565b602002602001015187600181518110610664576106646121d1565b60200260200101516111ea565b6001600160a01b03841690896112e6565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152600091908316906370a082319060240160206040518083038186803b1580156106e057600080fd5b505afa1580156106f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107189190612246565b9050610724848761136b565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301528291908416906370a082319060240160206040518083038186803b15801561078157600080fd5b505afa158015610795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b99190612246565b6107c3919061222f565b9450868510156108155760405162461bcd60e51b815260206004820152601360248201527f546f6f206c6974746c6520726563656976656400000000000000000000000000604482015260640161035d565b5050505095945050505050565b6040805160028082526060828101909352600092918391816020016020820280368337019050509050858160008151811061085f5761085f6121d1565b60200260200101906001600160a01b031690816001600160a01b0316815250508481600181518110610893576108936121d1565b60200260200101906001600160a01b031690816001600160a01b03168152505060006108bf85836116f5565b6002549091506001600160a01b03888116911614806108eb57506002546001600160a01b038781169116145b1561094057600081116103665760405162461bcd60e51b815260206004820152600d60248201527f6e6f2d706174682d666f756e6400000000000000000000000000000000000000604482015260640161035d565b60408051600380825260808201909252600091602082016060803683370190505090508781600081518110610977576109776121d1565b6001600160a01b0392831660209182029290920101526002548251911690829060019081106109a8576109a86121d1565b60200260200101906001600160a01b031690816001600160a01b03168152505086816002815181106109dc576109dc6121d1565b60200260200101906001600160a01b031690816001600160a01b0316815250506000610a0887836116f5565b90506000831180610a195750600081115b610a655760405162461bcd60e51b815260206004820152600d60248201527f6e6f2d706174682d666f756e6400000000000000000000000000000000000000604482015260640161035d565b600083118015610a7457508083105b80610a7d575080155b156104bf57826104b285611056565b6000546001600160a01b0362010000909104163314610aed5760405162461bcd60e51b815260206004820152600c60248201527f6e6f742d676f7665726e6f720000000000000000000000000000000000000000604482015260640161035d565b600254604080516001600160a01b03928316815291831660208301527fa660aa88bd78e0552d7e2b6cb01df732642a0ff595c9c7b2ae67fb9e3db01f55910160405180910390a1600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b600080610bb088888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111d492505050565b9050600081600081518110610bc757610bc76121d1565b60200260200101519050610c1d7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000898561107f565b600081518110610c2f57610c2f6121d1565b6020026020010151925085831115610c895760405162461bcd60e51b815260206004820152601260248201527f546f6f206d756368207265717565737465640000000000000000000000000000604482015260640161035d565b610d10610cff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000085600081518110610ce457610ce46121d1565b602002602001015186600181518110610664576106646121d1565b6001600160a01b03831690856112e6565b610d1a828561136b565b6000610d26848861222f565b90508015610d4257610d426001600160a01b03831687836112e6565b5050509695505050505050565b6000546001600160a01b0362010000909104163314610db05760405162461bcd60e51b815260206004820152600c60248201527f6e6f742d676f7665726e6f720000000000000000000000000000000000000000604482015260640161035d565b6001600160a01b038116610e065760405162461bcd60e51b815260206004820152601960248201527f70726f706f7365642d676f7665726e6f722d69732d7a65726f00000000000000604482015260640161035d565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000610e8e7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008585611736565b60018351610e9c919061222f565b8151811061053a5761053a6121d1565b6001546001600160a01b03163314610f065760405162461bcd60e51b815260206004820152601960248201527f6e6f742d7468652d70726f706f7365642d676f7665726e6f7200000000000000604482015260640161035d565b600154600080546040516001600160a01b039384169362010000909204909116917fd4459d5b8b913cab0244230fd9b1c08b6ceace7fe9230e60d0f74cbffdf849d091a360018054600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff166001600160a01b03831662010000021790557fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600061055983610223846111d4565b6040517fd06ca61f000000000000000000000000000000000000000000000000000000008152600090309063d06ca61f90610ffc90869086906004016122a3565b60206040518083038186803b15801561101457600080fd5b505afa925050508015611044575060408051601f3d908101601f1916820190925261104191810190612246565b60015b61104d57611050565b90505b92915050565b60608160405160200161106991906122bc565b6040516020818303038152906040529050919050565b606060028251101561109057600080fd5b815167ffffffffffffffff8111156110aa576110aa611ebd565b6040519080825280602002602001820160405280156110d3578160200160208202803683370190505b5090508281600183516110e6919061222f565b815181106110f6576110f66121d1565b602002602001018181525050600060018351611112919061222f565b90505b80156111cb5760008061116688888761112f60018861222f565b8151811061113f5761113f6121d1565b6020026020010151888781518110611159576111596121d1565b602002602001015161186a565b9150915061118e84848151811061117f5761117f6121d1565b60200260200101518383611953565b8461119a60018661222f565b815181106111aa576111aa6121d1565b602002602001018181525050505080806111c3906122cf565b915050611115565b50949350505050565b60608180602001905181019061105091906122e6565b60008060006111f98585611a0a565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b1660348201529193509150879060480160405160208183030381529060405280519060200120876040516020016112c3939291907fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b60408051601f198184030181529190528051602090910120979650505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611366908490611a6e565b505050565b60005b6001835161137c919061222f565b81101561136657600080848381518110611398576113986121d1565b6020026020010151858460016113ae9190612375565b815181106113be576113be6121d1565b60200260200101519150915060006113d68383611a0a565b50905060006114277f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000086866111ea565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561146857600080fd5b505afa15801561147c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a091906123b0565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150600080876001600160a01b03168a6001600160a01b0316146114e85782846114eb565b83835b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015292945090925083918c16906370a082319060240160206040518083038186803b15801561154d57600080fd5b505afa158015611561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115859190612246565b61158f919061222f565b955061159c868383611b53565b945050505050600080856001600160a01b0316886001600160a01b0316146115c6578260006115ca565b6000835b91509150600060028c516115de919061222f565b8a106115ea578a61164c565b61164c7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8f61163c8f6002612375565b81518110610664576106646121d1565b604080516000815260208101918290527f022c0d9f000000000000000000000000000000000000000000000000000000009091529091506001600160a01b0387169063022c0d9f906116a79086908690869060248101612400565b600060405180830381600087803b1580156116c157600080fd5b505af11580156116d5573d6000803e3d6000fd5b5050505050505050505050505080806116ed9061242e565b91505061136e565b6040517f1f00ca740000000000000000000000000000000000000000000000000000000081526000903090631f00ca7490610ffc90869086906004016122a3565b606060028251101561174757600080fd5b815167ffffffffffffffff81111561176157611761611ebd565b60405190808252806020026020018201604052801561178a578160200160208202803683370190505b50905082816000815181106117a1576117a16121d1565b60200260200101818152505060005b600183516117be919061222f565b8110156111cb5760008061180588888786815181106117df576117df6121d1565b6020026020010151888760016117f59190612375565b81518110611159576111596121d1565b9150915061182d84848151811061181e5761181e6121d1565b60200260200101518383611b53565b84611839856001612375565b81518110611849576118496121d1565b602002602001018181525050505080806118629061242e565b9150506117b0565b60008060006118798585611a0a565b50905060008061188b898989896111ea565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156118c357600080fd5b505afa1580156118d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fb91906123b0565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826001600160a01b0316876001600160a01b031614611940578082611943565b81815b909a909950975050505050505050565b60008084116119a45760405162461bcd60e51b815260206004820152601a60248201527f494e53554646494349454e545f4f55545055545f414d4f554e54000000000000604482015260640161035d565b6000831180156119b45750600082115b6119bd57600080fd5b60006119d56103e86119cf8688611c04565b90611c04565b905060006119e96103e56119cf8689611c31565b9050611a0060016119fa8385612449565b90611c4c565b9695505050505050565b600080826001600160a01b0316846001600160a01b03161415611a2c57600080fd5b826001600160a01b0316846001600160a01b031610611a4c578284611a4f565b83835b90925090506001600160a01b038216611a6757600080fd5b9250929050565b6000611ac3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611c679092919063ffffffff16565b8051909150156113665780806020019051810190611ae19190612484565b6113665760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161035d565b6000808411611ba45760405162461bcd60e51b815260206004820152601960248201527f494e53554646494349454e545f494e5055545f414d4f554e5400000000000000604482015260640161035d565b600083118015611bb45750600082115b611bbd57600080fd5b6000611bcb856103e5611c04565b90506000611bd98285611c04565b90506000611bed836119fa886103e8611c04565b9050611bf98183612449565b979650505050505050565b6000821580611c2857508183611c1a82826124a6565b9250611c269083612449565b145b61105057600080fd5b600082611c3e838261222f565b915081111561105057600080fd5b600082611c598382612375565b915081101561105057600080fd5b6060611c768484600085611c7e565b949350505050565b606082471015611cf65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161035d565b6001600160a01b0385163b611d4d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161035d565b600080866001600160a01b03168587604051611d6991906124c5565b60006040518083038185875af1925050503d8060008114611da6576040519150601f19603f3d011682016040523d82523d6000602084013e611dab565b606091505b5091509150611bf982828660608315611dc5575081610559565b825115611dd55782518084602001fd5b8160405162461bcd60e51b815260040161035d91906124e1565b6001600160a01b0381168114611e0457600080fd5b50565b600080600060608486031215611e1c57600080fd5b8335611e2781611def565b92506020840135611e3781611def565b929592945050506040919091013590565b60005b83811015611e63578181015183820152602001611e4b565b83811115611e72576000848401525b50505050565b60008151808452611e90816020860160208601611e48565b601f01601f19169290920160200192915050565b828152604060208201526000611c766040830184611e78565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611f1557611f15611ebd565b604052919050565b600067ffffffffffffffff821115611f3757611f37611ebd565b5060051b60200190565b60008060408385031215611f5457600080fd5b8235915060208084013567ffffffffffffffff811115611f7357600080fd5b8401601f81018613611f8457600080fd5b8035611f97611f9282611f1d565b611eec565b81815260059190911b82018301908381019088831115611fb657600080fd5b928401925b82841015611fdd578335611fce81611def565b82529284019290840190611fbb565b80955050505050509250929050565b60008060408385031215611fff57600080fd5b8235915060208084013567ffffffffffffffff8082111561201f57600080fd5b818601915086601f83011261203357600080fd5b81358181111561204557612045611ebd565b61205784601f19601f84011601611eec565b9150808252878482850101111561206d57600080fd5b80848401858401376000848284010152508093505050509250929050565b60008083601f84011261209d57600080fd5b50813567ffffffffffffffff8111156120b557600080fd5b602083019150836020828501011115611a6757600080fd5b6000806000806000608086880312156120e557600080fd5b853567ffffffffffffffff8111156120fc57600080fd5b6121088882890161208b565b9096509450506020860135925060408601359150606086013561212a81611def565b809150509295509295909350565b60006020828403121561214a57600080fd5b813561104d81611def565b60008060008060008060a0878903121561216e57600080fd5b863567ffffffffffffffff81111561218557600080fd5b61219189828a0161208b565b909750955050602087013593506040870135925060608701356121b381611def565b915060808701356121c381611def565b809150509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561224157612241612200565b500390565b60006020828403121561225857600080fd5b5051919050565b600081518084526020808501945080840160005b838110156122985781516001600160a01b031687529582019590820190600101612273565b509495945050505050565b828152604060208201526000611c76604083018461225f565b602081526000610559602083018461225f565b6000816122de576122de612200565b506000190190565b600060208083850312156122f957600080fd5b825167ffffffffffffffff81111561231057600080fd5b8301601f8101851361232157600080fd5b805161232f611f9282611f1d565b81815260059190911b8201830190838101908783111561234e57600080fd5b928401925b82841015611bf957835161236681611def565b82529284019290840190612353565b6000821982111561238857612388612200565b500190565b80516dffffffffffffffffffffffffffff811681146123ab57600080fd5b919050565b6000806000606084860312156123c557600080fd5b6123ce8461238d565b92506123dc6020850161238d565b9150604084015163ffffffff811681146123f557600080fd5b809150509250925092565b8481528360208201526001600160a01b0383166040820152608060608201526000611a006080830184611e78565b600060001982141561244257612442612200565b5060010190565b60008261247f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561249657600080fd5b8151801515811461104d57600080fd5b60008160001904831182151516156124c0576124c0612200565b500290565b600082516124d7818460208701611e48565b9190910192915050565b6020815260006105596020830184611e7856fea2646970667358221220b09c966d64ae890afeaa555aec42ceaf9dd430ff01fa7b13dcb2481149997bfa64736f6c63430008090033000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ace18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80637fbb36e71161008c578063c45a015511610066578063c45a0155146101ee578063d06ca61f14610215578063f3b27bc314610228578063fee9574a1461023057600080fd5b80637fbb36e7146101b35780639d9f384d146101c8578063b6aa515b146101db57600080fd5b806329dbd944116100c857806329dbd944146101675780632aa4a9e51461017a5780634909c29a1461018d57806370b24742146101a057600080fd5b80630c340a24146100ef57806319145798146101255780631f00ca7414610146575b600080fd5b600054610108906201000090046001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610138610133366004611e07565b610243565b60405161011c929190611ea4565b610159610154366004611f41565b6104da565b60405190815260200161011c565b600254610108906001600160a01b031681565b610159610188366004611fec565b61054a565b61015961019b3660046120cd565b610560565b6101386101ae366004611e07565b610822565b6101c66101c1366004612138565b610a8c565b005b6101596101d6366004612155565b610b6e565b6101c66101e9366004612138565b610d4f565b6101087f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac81565b610159610223366004611f41565b610e40565b6101c6610eac565b61015961023e366004611fec565b610fac565b60408051600280825260608281019093526000929183918160200160208202803683370190505090508581600081518110610280576102806121d1565b60200260200101906001600160a01b031690816001600160a01b03168152505084816001815181106102b4576102b46121d1565b60200260200101906001600160a01b031690816001600160a01b03168152505060006102e08583610fbb565b6002549091506001600160a01b038881169116148061030c57506002546001600160a01b038781169116145b1561037b57600081116103665760405162461bcd60e51b815260206004820152600d60248201527f6e6f2d706174682d666f756e640000000000000000000000000000000000000060448201526064015b60405180910390fd5b8061037083611056565b9350935050506104d2565b604080516003808252608082019092526000916020820160608036833701905050905087816000815181106103b2576103b26121d1565b6001600160a01b0392831660209182029290920101526002548251911690829060019081106103e3576103e36121d1565b60200260200101906001600160a01b031690816001600160a01b0316815250508681600281518110610417576104176121d1565b60200260200101906001600160a01b031690816001600160a01b03168152505060006104438783610fbb565b905060008311806104545750600081115b6104a05760405162461bcd60e51b815260206004820152600d60248201527f6e6f2d706174682d666f756e6400000000000000000000000000000000000000604482015260640161035d565b808311156104bf57826104b285611056565b95509550505050506104d2565b806104c983611056565b95509550505050505b935093915050565b60006105287f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac7fe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303858561107f565b60008151811061053a5761053a6121d1565b6020026020010151905092915050565b600061055983610154846111d4565b9392505050565b6000806105a287878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111d492505050565b90506000816000815181106105b9576105b96121d1565b60200260200101519050600082600184516105d4919061222f565b815181106105e4576105e46121d1565b602002602001015190506106826106717f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac7fe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c630386600081518110610649576106496121d1565b602002602001015187600181518110610664576106646121d1565b60200260200101516111ea565b6001600160a01b03841690896112e6565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152600091908316906370a082319060240160206040518083038186803b1580156106e057600080fd5b505afa1580156106f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107189190612246565b9050610724848761136b565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301528291908416906370a082319060240160206040518083038186803b15801561078157600080fd5b505afa158015610795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b99190612246565b6107c3919061222f565b9450868510156108155760405162461bcd60e51b815260206004820152601360248201527f546f6f206c6974746c6520726563656976656400000000000000000000000000604482015260640161035d565b5050505095945050505050565b6040805160028082526060828101909352600092918391816020016020820280368337019050509050858160008151811061085f5761085f6121d1565b60200260200101906001600160a01b031690816001600160a01b0316815250508481600181518110610893576108936121d1565b60200260200101906001600160a01b031690816001600160a01b03168152505060006108bf85836116f5565b6002549091506001600160a01b03888116911614806108eb57506002546001600160a01b038781169116145b1561094057600081116103665760405162461bcd60e51b815260206004820152600d60248201527f6e6f2d706174682d666f756e6400000000000000000000000000000000000000604482015260640161035d565b60408051600380825260808201909252600091602082016060803683370190505090508781600081518110610977576109776121d1565b6001600160a01b0392831660209182029290920101526002548251911690829060019081106109a8576109a86121d1565b60200260200101906001600160a01b031690816001600160a01b03168152505086816002815181106109dc576109dc6121d1565b60200260200101906001600160a01b031690816001600160a01b0316815250506000610a0887836116f5565b90506000831180610a195750600081115b610a655760405162461bcd60e51b815260206004820152600d60248201527f6e6f2d706174682d666f756e6400000000000000000000000000000000000000604482015260640161035d565b600083118015610a7457508083105b80610a7d575080155b156104bf57826104b285611056565b6000546001600160a01b0362010000909104163314610aed5760405162461bcd60e51b815260206004820152600c60248201527f6e6f742d676f7665726e6f720000000000000000000000000000000000000000604482015260640161035d565b600254604080516001600160a01b03928316815291831660208301527fa660aa88bd78e0552d7e2b6cb01df732642a0ff595c9c7b2ae67fb9e3db01f55910160405180910390a1600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b600080610bb088888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111d492505050565b9050600081600081518110610bc757610bc76121d1565b60200260200101519050610c1d7f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac7fe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303898561107f565b600081518110610c2f57610c2f6121d1565b6020026020010151925085831115610c895760405162461bcd60e51b815260206004820152601260248201527f546f6f206d756368207265717565737465640000000000000000000000000000604482015260640161035d565b610d10610cff7f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac7fe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c630385600081518110610ce457610ce46121d1565b602002602001015186600181518110610664576106646121d1565b6001600160a01b03831690856112e6565b610d1a828561136b565b6000610d26848861222f565b90508015610d4257610d426001600160a01b03831687836112e6565b5050509695505050505050565b6000546001600160a01b0362010000909104163314610db05760405162461bcd60e51b815260206004820152600c60248201527f6e6f742d676f7665726e6f720000000000000000000000000000000000000000604482015260640161035d565b6001600160a01b038116610e065760405162461bcd60e51b815260206004820152601960248201527f70726f706f7365642d676f7665726e6f722d69732d7a65726f00000000000000604482015260640161035d565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000610e8e7f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac7fe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c63038585611736565b60018351610e9c919061222f565b8151811061053a5761053a6121d1565b6001546001600160a01b03163314610f065760405162461bcd60e51b815260206004820152601960248201527f6e6f742d7468652d70726f706f7365642d676f7665726e6f7200000000000000604482015260640161035d565b600154600080546040516001600160a01b039384169362010000909204909116917fd4459d5b8b913cab0244230fd9b1c08b6ceace7fe9230e60d0f74cbffdf849d091a360018054600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff166001600160a01b03831662010000021790557fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600061055983610223846111d4565b6040517fd06ca61f000000000000000000000000000000000000000000000000000000008152600090309063d06ca61f90610ffc90869086906004016122a3565b60206040518083038186803b15801561101457600080fd5b505afa925050508015611044575060408051601f3d908101601f1916820190925261104191810190612246565b60015b61104d57611050565b90505b92915050565b60608160405160200161106991906122bc565b6040516020818303038152906040529050919050565b606060028251101561109057600080fd5b815167ffffffffffffffff8111156110aa576110aa611ebd565b6040519080825280602002602001820160405280156110d3578160200160208202803683370190505b5090508281600183516110e6919061222f565b815181106110f6576110f66121d1565b602002602001018181525050600060018351611112919061222f565b90505b80156111cb5760008061116688888761112f60018861222f565b8151811061113f5761113f6121d1565b6020026020010151888781518110611159576111596121d1565b602002602001015161186a565b9150915061118e84848151811061117f5761117f6121d1565b60200260200101518383611953565b8461119a60018661222f565b815181106111aa576111aa6121d1565b602002602001018181525050505080806111c3906122cf565b915050611115565b50949350505050565b60608180602001905181019061105091906122e6565b60008060006111f98585611a0a565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b1660348201529193509150879060480160405160208183030381529060405280519060200120876040516020016112c3939291907fff00000000000000000000000000000000000000000000000000000000000000815260609390931b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830191909152603582015260550190565b60408051601f198184030181529190528051602090910120979650505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052611366908490611a6e565b505050565b60005b6001835161137c919061222f565b81101561136657600080848381518110611398576113986121d1565b6020026020010151858460016113ae9190612375565b815181106113be576113be6121d1565b60200260200101519150915060006113d68383611a0a565b50905060006114277f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac7fe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c630386866111ea565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561146857600080fd5b505afa15801561147c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a091906123b0565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150600080876001600160a01b03168a6001600160a01b0316146114e85782846114eb565b83835b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015292945090925083918c16906370a082319060240160206040518083038186803b15801561154d57600080fd5b505afa158015611561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115859190612246565b61158f919061222f565b955061159c868383611b53565b945050505050600080856001600160a01b0316886001600160a01b0316146115c6578260006115ca565b6000835b91509150600060028c516115de919061222f565b8a106115ea578a61164c565b61164c7f000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac7fe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c63038a8f61163c8f6002612375565b81518110610664576106646121d1565b604080516000815260208101918290527f022c0d9f000000000000000000000000000000000000000000000000000000009091529091506001600160a01b0387169063022c0d9f906116a79086908690869060248101612400565b600060405180830381600087803b1580156116c157600080fd5b505af11580156116d5573d6000803e3d6000fd5b5050505050505050505050505080806116ed9061242e565b91505061136e565b6040517f1f00ca740000000000000000000000000000000000000000000000000000000081526000903090631f00ca7490610ffc90869086906004016122a3565b606060028251101561174757600080fd5b815167ffffffffffffffff81111561176157611761611ebd565b60405190808252806020026020018201604052801561178a578160200160208202803683370190505b50905082816000815181106117a1576117a16121d1565b60200260200101818152505060005b600183516117be919061222f565b8110156111cb5760008061180588888786815181106117df576117df6121d1565b6020026020010151888760016117f59190612375565b81518110611159576111596121d1565b9150915061182d84848151811061181e5761181e6121d1565b60200260200101518383611b53565b84611839856001612375565b81518110611849576118496121d1565b602002602001018181525050505080806118629061242e565b9150506117b0565b60008060006118798585611a0a565b50905060008061188b898989896111ea565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156118c357600080fd5b505afa1580156118d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fb91906123b0565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826001600160a01b0316876001600160a01b031614611940578082611943565b81815b909a909950975050505050505050565b60008084116119a45760405162461bcd60e51b815260206004820152601a60248201527f494e53554646494349454e545f4f55545055545f414d4f554e54000000000000604482015260640161035d565b6000831180156119b45750600082115b6119bd57600080fd5b60006119d56103e86119cf8688611c04565b90611c04565b905060006119e96103e56119cf8689611c31565b9050611a0060016119fa8385612449565b90611c4c565b9695505050505050565b600080826001600160a01b0316846001600160a01b03161415611a2c57600080fd5b826001600160a01b0316846001600160a01b031610611a4c578284611a4f565b83835b90925090506001600160a01b038216611a6757600080fd5b9250929050565b6000611ac3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611c679092919063ffffffff16565b8051909150156113665780806020019051810190611ae19190612484565b6113665760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161035d565b6000808411611ba45760405162461bcd60e51b815260206004820152601960248201527f494e53554646494349454e545f494e5055545f414d4f554e5400000000000000604482015260640161035d565b600083118015611bb45750600082115b611bbd57600080fd5b6000611bcb856103e5611c04565b90506000611bd98285611c04565b90506000611bed836119fa886103e8611c04565b9050611bf98183612449565b979650505050505050565b6000821580611c2857508183611c1a82826124a6565b9250611c269083612449565b145b61105057600080fd5b600082611c3e838261222f565b915081111561105057600080fd5b600082611c598382612375565b915081101561105057600080fd5b6060611c768484600085611c7e565b949350505050565b606082471015611cf65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161035d565b6001600160a01b0385163b611d4d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161035d565b600080866001600160a01b03168587604051611d6991906124c5565b60006040518083038185875af1925050503d8060008114611da6576040519150601f19603f3d011682016040523d82523d6000602084013e611dab565b606091505b5091509150611bf982828660608315611dc5575081610559565b825115611dd55782518084602001fd5b8160405162461bcd60e51b815260040161035d91906124e1565b6001600160a01b0381168114611e0457600080fd5b50565b600080600060608486031215611e1c57600080fd5b8335611e2781611def565b92506020840135611e3781611def565b929592945050506040919091013590565b60005b83811015611e63578181015183820152602001611e4b565b83811115611e72576000848401525b50505050565b60008151808452611e90816020860160208601611e48565b601f01601f19169290920160200192915050565b828152604060208201526000611c766040830184611e78565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611f1557611f15611ebd565b604052919050565b600067ffffffffffffffff821115611f3757611f37611ebd565b5060051b60200190565b60008060408385031215611f5457600080fd5b8235915060208084013567ffffffffffffffff811115611f7357600080fd5b8401601f81018613611f8457600080fd5b8035611f97611f9282611f1d565b611eec565b81815260059190911b82018301908381019088831115611fb657600080fd5b928401925b82841015611fdd578335611fce81611def565b82529284019290840190611fbb565b80955050505050509250929050565b60008060408385031215611fff57600080fd5b8235915060208084013567ffffffffffffffff8082111561201f57600080fd5b818601915086601f83011261203357600080fd5b81358181111561204557612045611ebd565b61205784601f19601f84011601611eec565b9150808252878482850101111561206d57600080fd5b80848401858401376000848284010152508093505050509250929050565b60008083601f84011261209d57600080fd5b50813567ffffffffffffffff8111156120b557600080fd5b602083019150836020828501011115611a6757600080fd5b6000806000806000608086880312156120e557600080fd5b853567ffffffffffffffff8111156120fc57600080fd5b6121088882890161208b565b9096509450506020860135925060408601359150606086013561212a81611def565b809150509295509295909350565b60006020828403121561214a57600080fd5b813561104d81611def565b60008060008060008060a0878903121561216e57600080fd5b863567ffffffffffffffff81111561218557600080fd5b61219189828a0161208b565b909750955050602087013593506040870135925060608701356121b381611def565b915060808701356121c381611def565b809150509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561224157612241612200565b500390565b60006020828403121561225857600080fd5b5051919050565b600081518084526020808501945080840160005b838110156122985781516001600160a01b031687529582019590820190600101612273565b509495945050505050565b828152604060208201526000611c76604083018461225f565b602081526000610559602083018461225f565b6000816122de576122de612200565b506000190190565b600060208083850312156122f957600080fd5b825167ffffffffffffffff81111561231057600080fd5b8301601f8101851361232157600080fd5b805161232f611f9282611f1d565b81815260059190911b8201830190838101908783111561234e57600080fd5b928401925b82841015611bf957835161236681611def565b82529284019290840190612353565b6000821982111561238857612388612200565b500190565b80516dffffffffffffffffffffffffffff811681146123ab57600080fd5b919050565b6000806000606084860312156123c557600080fd5b6123ce8461238d565b92506123dc6020850161238d565b9150604084015163ffffffff811681146123f557600080fd5b809150509250925092565b8481528360208201526001600160a01b0383166040820152608060608201526000611a006080830184611e78565b600060001982141561244257612442612200565b5060010190565b60008261247f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561249657600080fd5b8151801515811461104d57600080fd5b60008160001904831182151516156124c0576124c0612200565b500290565b600082516124d7818460208701611e48565b9190910192915050565b6020815260006105596020830184611e7856fea2646970667358221220b09c966d64ae890afeaa555aec42ceaf9dd430ff01fa7b13dcb2481149997bfa64736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ace18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
-----Decoded View---------------
Arg [0] : factory_ (address): 0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac
Arg [1] : initCodeHash_ (bytes32): 0xe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303
Arg [2] : wethLike_ (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000c0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac
Arg [1] : e18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.