Source Code
Overview
S Balance
More Info
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
24703252 | 4 days ago | Contract Creation | 0 S |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
OutrunAMMRouter
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 100000 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.28; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IWETH} from "../libraries/IWETH.sol"; import {TransferHelper} from "../libraries/TransferHelper.sol"; import {OutrunAMMLibrary} from "../libraries/OutrunAMMLibrary.sol"; import {IOutrunAMMRouter} from "./interfaces/IOutrunAMMRouter.sol"; import {IOutrunAMMPair} from "../core/interfaces/IOutrunAMMPair.sol"; import {IOutrunAMMERC20} from "../core/interfaces/IOutrunAMMERC20.sol"; import {IOutrunAMMFactory} from "../core/interfaces/IOutrunAMMFactory.sol"; contract OutrunAMMRouter is IOutrunAMMRouter { uint256 public constant RATIO = 10000; address public immutable WETH; mapping(uint256 feeRate => address) public factories; modifier ensure(uint256 deadline) { require(deadline >= block.timestamp, Expired()); _; } constructor(address _factory0, address _factory1, address _WETH) { factories[30] = _factory0; // 0.3% factories[100] = _factory1; // 1% WETH = _WETH; } receive() external payable { // only accept ETH via fallback from the WETH contract require(msg.sender == WETH, InvalidETHSender()); } /** * ADD LIQUIDITY * */ function _addLiquidity( address tokenA, address tokenB, uint256 feeRate, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin ) internal virtual returns (uint256 amountA, uint256 amountB) { address factory = factories[feeRate]; // create the pair if it doesn't exist yet if (IOutrunAMMFactory(factory).getPair(tokenA, tokenB) == address(0)) { IOutrunAMMFactory(factory).createPair(tokenA, tokenB); } (uint256 reserveA, uint256 reserveB) = getReserves(factory, tokenA, tokenB, feeRate); if (reserveA == 0 && reserveB == 0) { (amountA, amountB) = (amountADesired, amountBDesired); } else { uint256 amountBOptimal = quote(amountADesired, reserveA, reserveB); if (amountBOptimal <= amountBDesired) { require(amountBOptimal >= amountBMin, InsufficientBAmount()); (amountA, amountB) = (amountADesired, amountBOptimal); } else { uint256 amountAOptimal = quote(amountBDesired, reserveB, reserveA); assert(amountAOptimal <= amountADesired); require(amountAOptimal >= amountAMin, InsufficientAAmount()); (amountA, amountB) = (amountAOptimal, amountBDesired); } } } function addLiquidity( address tokenA, address tokenB, uint256 feeRate, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external virtual override ensure(deadline) returns (uint256 amountA, uint256 amountB, uint256 liquidity) { (amountA, amountB) = _addLiquidity(tokenA, tokenB, feeRate, amountADesired, amountBDesired, amountAMin, amountBMin); address pair = OutrunAMMLibrary.pairFor(factories[feeRate], tokenA, tokenB, feeRate); TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA); TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB); liquidity = IOutrunAMMPair(pair).mint(to); } function addLiquidityETH( address token, uint256 feeRate, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable virtual override ensure(deadline) returns (uint256 amountToken, uint256 amountETH, uint256 liquidity) { (amountToken, amountETH) = _addLiquidity(token, WETH, feeRate, amountTokenDesired, msg.value, amountTokenMin, amountETHMin); address pair = OutrunAMMLibrary.pairFor(factories[feeRate], token, WETH, feeRate); TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken); IWETH(WETH).deposit{value: amountETH}(); assert(IWETH(WETH).transfer(pair, amountETH)); liquidity = IOutrunAMMPair(pair).mint(to); // refund dust eth, if any if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH); } // **** REMOVE LIQUIDITY **** function removeLiquidity( address tokenA, address tokenB, uint256 feeRate, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) public virtual override ensure(deadline) returns (uint256 amountA, uint256 amountB) { address pair = OutrunAMMLibrary.pairFor(factories[feeRate], tokenA, tokenB, feeRate); IOutrunAMMERC20(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair (uint256 amount0, uint256 amount1) = IOutrunAMMPair(pair).burn(to); (address token0,) = OutrunAMMLibrary.sortTokens(tokenA, tokenB); (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0); require(amountA >= amountAMin, InsufficientAAmount()); require(amountB >= amountBMin, InsufficientBAmount()); } function removeLiquidityETH( address token, uint256 feeRate, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) public virtual override ensure(deadline) returns (uint256 amountToken, uint256 amountETH) { (amountToken, amountETH) = removeLiquidity(token, WETH, feeRate, liquidity, amountTokenMin, amountETHMin, address(this), deadline); TransferHelper.safeTransfer(token, to, amountToken); IWETH(WETH).withdraw(amountETH); TransferHelper.safeTransferETH(to, amountETH); } /** * REMOVE LIQUIDITY (supporting fee-on-transfer tokens) * */ function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint256 feeRate, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) public virtual override ensure(deadline) returns (uint256 amountETH) { (, amountETH) = removeLiquidity(token, WETH, feeRate, liquidity, amountTokenMin, amountETHMin, address(this), deadline); TransferHelper.safeTransfer(token, to, IERC20(token).balanceOf(address(this))); IWETH(WETH).withdraw(amountETH); TransferHelper.safeTransferETH(to, amountETH); } /** * SWAP * */ // requires the initial amount to have already been sent to the first pair function _swap( uint256[] memory amounts, address[] memory path, uint256[] memory feeRates, address _to, address referrer ) internal virtual { for (uint256 i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0,) = OutrunAMMLibrary.sortTokens(input, output); uint256 amountOut = amounts[i + 1]; (uint256 amount0Out, uint256 amount1Out) = input == token0 ? (uint256(0), amountOut) : (amountOut, uint256(0)); address to = i < path.length - 2 ? OutrunAMMLibrary.pairFor(factories[feeRates[i + 1]], output, path[i + 2], feeRates[i + 1]) : _to; IOutrunAMMPair(OutrunAMMLibrary.pairFor(factories[feeRates[i]], input, output, feeRates[i])).swap( amount0Out, amount1Out, to, referrer, new bytes(0) ); } } function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external virtual override ensure(deadline) returns (uint256[] memory amounts) { amounts = getAmountsOut(amountIn, path, feeRates); require(amounts[amounts.length - 1] >= amountOutMin, InsufficientOutputAmount()); TransferHelper.safeTransferFrom( path[0], msg.sender, OutrunAMMLibrary.pairFor(factories[feeRates[0]], path[0], path[1], feeRates[0]), amounts[0] ); _swap(amounts, path, feeRates, to, referrer); } function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external virtual override ensure(deadline) returns (uint256[] memory amounts) { amounts = getAmountsIn( amountOut, path, feeRates); require(amounts[0] <= amountInMax, ExcessiveInputAmount()); TransferHelper.safeTransferFrom( path[0], msg.sender, OutrunAMMLibrary.pairFor(factories[feeRates[0]], path[0], path[1], feeRates[0]), amounts[0] ); _swap(amounts, path, feeRates, to, referrer); } function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external payable virtual override ensure(deadline) returns (uint256[] memory amounts) { require(path[0] == WETH, InvalidPath()); amounts = getAmountsOut(msg.value, path, feeRates); require(amounts[amounts.length - 1] >= amountOutMin, InsufficientOutputAmount()); IWETH(WETH).deposit{value: amounts[0]}(); assert(IWETH(WETH).transfer(OutrunAMMLibrary.pairFor(factories[feeRates[0]], path[0], path[1], feeRates[0]), amounts[0])); _swap(amounts, path, feeRates, to, referrer); } function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external virtual override ensure(deadline) returns (uint256[] memory amounts) { require(path[path.length - 1] == WETH, InvalidPath()); amounts = getAmountsIn(amountOut, path, feeRates); require(amounts[0] <= amountInMax, ExcessiveInputAmount()); TransferHelper.safeTransferFrom( path[0], msg.sender, OutrunAMMLibrary.pairFor(factories[feeRates[0]], path[0], path[1], feeRates[0]), amounts[0] ); _swap(amounts, path, feeRates, address(this), referrer); IWETH(WETH).withdraw(amounts[amounts.length - 1]); TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); } function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external virtual override ensure(deadline) returns (uint256[] memory amounts) { require(path[path.length - 1] == WETH, InvalidPath()); amounts = getAmountsOut(amountIn, path, feeRates); require(amounts[amounts.length - 1] >= amountOutMin, InsufficientOutputAmount()); TransferHelper.safeTransferFrom( path[0], msg.sender, OutrunAMMLibrary.pairFor(factories[feeRates[0]], path[0], path[1], feeRates[0]), amounts[0] ); _swap(amounts, path, feeRates, address(this), referrer); IWETH(WETH).withdraw(amounts[amounts.length - 1]); TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); } function swapETHForExactTokens( uint256 amountOut, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external payable virtual override ensure(deadline) returns (uint256[] memory amounts) { require(path[0] == WETH, InvalidPath()); amounts = getAmountsIn(amountOut, path, feeRates); require(amounts[0] <= msg.value, ExcessiveInputAmount()); IWETH(WETH).deposit{value: amounts[0]}(); assert(IWETH(WETH).transfer(OutrunAMMLibrary.pairFor(factories[feeRates[0]], path[0], path[1], feeRates[0]), amounts[0])); _swap(amounts, path, feeRates, to, referrer); // refund dust eth, if any if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]); } /** * SWAP (supporting fee-on-transfer tokens) * */ // requires the initial amount to have already been sent to the first pair function _swapSupportingFeeOnTransferTokens(address[] memory path, uint256[] memory feeRates, address _to, address referrer) internal virtual { for (uint256 i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0,) = OutrunAMMLibrary.sortTokens(input, output); IOutrunAMMPair pair = IOutrunAMMPair(OutrunAMMLibrary.pairFor(factories[feeRates[i]], input, output, feeRates[i])); 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 = getAmountOut(amountInput, reserveInput, reserveOutput, feeRates[i]); } (uint256 amount0Out, uint256 amount1Out) = input == token0 ? (uint256(0), amountOutput) : (amountOutput, uint256(0)); address to = i < path.length - 2 ? OutrunAMMLibrary.pairFor(factories[feeRates[i + 1]], output, path[i + 2], feeRates[i + 1]) : _to; pair.swap(amount0Out, amount1Out, to, referrer, new bytes(0)); } } function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external virtual override ensure(deadline) { TransferHelper.safeTransferFrom( path[0], msg.sender, OutrunAMMLibrary.pairFor(factories[feeRates[0]], path[0], path[1], feeRates[0]), amountIn ); uint256 balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); _swapSupportingFeeOnTransferTokens(path, feeRates, to, referrer); require( IERC20(path[path.length - 1]).balanceOf(to) - balanceBefore >= amountOutMin, InsufficientOutputAmount() ); } function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external payable virtual override ensure(deadline) { require(path[0] == WETH, InvalidPath()); uint256 amountIn = msg.value; IWETH(WETH).deposit{value: amountIn}(); assert(IWETH(WETH).transfer(OutrunAMMLibrary.pairFor(factories[feeRates[0]], path[0], path[1], feeRates[0]), amountIn)); uint256 balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); _swapSupportingFeeOnTransferTokens(path, feeRates, to, referrer); require( IERC20(path[path.length - 1]).balanceOf(to) - balanceBefore >= amountOutMin, InsufficientOutputAmount() ); } function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external virtual override ensure(deadline) { require(path[path.length - 1] == WETH, InvalidPath()); TransferHelper.safeTransferFrom( path[0], msg.sender, OutrunAMMLibrary.pairFor(factories[feeRates[0]], path[0], path[1], feeRates[0]), amountIn ); _swapSupportingFeeOnTransferTokens(path, feeRates, address(this), referrer); uint256 amountOut = IERC20(WETH).balanceOf(address(this)); require(amountOut >= amountOutMin, InsufficientOutputAmount()); IWETH(WETH).withdraw(amountOut); TransferHelper.safeTransferETH(to, amountOut); } // **** LIBRARY FUNCTIONS **** function quote( uint256 amountA, uint256 reserveA, uint256 reserveB ) public view virtual override returns (uint256 amountB) { require(amountA > 0, InsufficientAmount()); require(reserveA > 0 && reserveB > 0, InsufficientLiquidity()); amountB = amountA * reserveB / reserveA; } function getReserves( address factory, address tokenA, address tokenB, uint256 feeRate ) public view virtual override returns (uint256 reserveA, uint256 reserveB) { (address token0,) = OutrunAMMLibrary.sortTokens(tokenA, tokenB); (uint256 reserve0, uint256 reserve1,) = IOutrunAMMPair(OutrunAMMLibrary.pairFor(factory, tokenA, tokenB, feeRate)).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint256 feeRate ) public view virtual override returns (uint256 amountOut) { require(amountIn > 0, InsufficientInputAmount()); require(reserveIn > 0 && reserveOut > 0, InsufficientLiquidity()); uint256 amountInWithFee = amountIn * (RATIO - feeRate); uint256 numerator = amountInWithFee * reserveOut; uint256 denominator = reserveIn * RATIO + amountInWithFee; amountOut = numerator / denominator; } function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut, uint256 feeRate ) public view virtual override returns (uint256 amountIn) { require(amountOut > 0, InsufficientOutputAmount()); require(reserveIn > 0 && reserveOut > 0, InsufficientLiquidity()); uint256 numerator = reserveIn * amountOut * RATIO; uint256 denominator = (reserveOut - amountOut) * (RATIO - feeRate); amountIn = (numerator / denominator) + 1; } function getAmountsOut( uint256 amountIn, address[] memory path, uint256[] memory feeRates ) public view virtual override returns (uint256[] memory amounts) { require( path.length >= 2 && feeRates.length >= 1 && path.length == feeRates.length + 1, InvalidPath() ); amounts = new uint256[](path.length); amounts[0] = amountIn; for (uint256 i; i < path.length - 1; i++) { (uint256 reserveIn, uint256 reserveOut) = getReserves(factories[feeRates[i]], path[i], path[i + 1], feeRates[i]); amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut, feeRates[i]); } } function getAmountsIn( uint256 amountOut, address[] memory path, uint256[] memory feeRates ) public view virtual override returns (uint256[] memory amounts) { require( path.length >= 2 && feeRates.length >= 1 && path.length == feeRates.length + 1, InvalidPath() ); amounts = new uint256[](path.length); amounts[amounts.length - 1] = amountOut; for (uint256 i = path.length - 1; i > 0; i--) { (uint256 reserveIn, uint256 reserveOut) = getReserves(factories[feeRates[i]], path[i - 1], path[i], feeRates[i - 1]); amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut, feeRates[i - 1]); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); }
//SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.28; /** * @title WETH interface */ interface IWETH { function deposit() external payable; function withdraw(uint256 amount) external; function transfer(address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.28; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { error ApproveFailed(); error TransferFailed(); error ETHTransferFailed(); error TransferFromFailed(); function safeApprove(address token, address to, uint256 value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), ApproveFailed()); } function safeTransfer(address token, address to, uint256 value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), TransferFailed()); } function safeTransferFrom(address token, address from, address to, uint256 value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), TransferFromFailed()); } function safeTransferETH(address to, uint256 value) internal { (bool success,) = to.call{value: value}(new bytes(0)); require(success, ETHTransferFailed()); } }
//SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.28; import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {IOutrunAMMFactory} from "../core/interfaces/IOutrunAMMFactory.sol"; library OutrunAMMLibrary { /** * @notice Zero address. */ error ZeroAddress(); /** * @notice Identical addresses. */ error IdenticalAddresses(); /** * @notice Sort the tokens. * @param tokenA - The first token address. * @param tokenB - The second token address. * @return token0 - The first token address. * @return token1 - The second token address. */ function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { require(tokenA != tokenB, IdenticalAddresses()); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), ZeroAddress()); } /** * @notice Calculate the pair address. * @param factory - The factory address. * @param tokenA - The first token address. * @param tokenB - The second token address. * @param swapFeeRate - The swap fee rate. * @return pair - The pair address. */ function pairFor(address factory, address tokenA, address tokenB, uint256 swapFeeRate) internal view returns (address pair) { (address token0, address token1) = sortTokens(tokenA, tokenB); pair = Clones.predictDeterministicAddress( IOutrunAMMFactory(factory).pairImplementation(), keccak256(abi.encodePacked(token0, token1, swapFeeRate)), factory ); } }
//SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.28; interface IOutrunAMMRouter { function factories(uint256 feeRate) external view returns (address); function WETH() external view returns (address); /** * addLiquidity * */ function addLiquidity( address tokenA, address tokenB, uint256 feeRate, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity); function addLiquidityETH( address token, uint256 feeRate, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity); /** * removeLiquidity * */ function removeLiquidity( address tokenA, address tokenB, uint256 feeRate, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETH( address token, uint256 feeRate, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountToken, uint256 amountETH); function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint256 feeRate, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountETH); /** * swap * */ function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external returns (uint256[] memory amounts); function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external returns (uint256[] memory amounts); function swapETHForExactTokens( uint256 amountOut, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, uint256[] calldata feeRates, address to, address referrer, uint256 deadline ) external; function quote( uint256 amountA, uint256 reserveA, uint256 reserveB ) external view returns (uint256 amountB); function getReserves( address factory, address tokenA, address tokenB, uint256 feeRate ) external view returns (uint256 reserveA, uint256 reserveB); function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint256 feeRate ) external view returns (uint256 amountOut); function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut, uint256 feeRate ) external view returns (uint256 amountIn); function getAmountsOut( uint256 amountIn, address[] memory path, uint256[] memory feeRates ) external view returns (uint256[] memory amounts); function getAmountsIn( uint256 amountOut, address[] memory path, uint256[] memory feeRates ) external view returns (uint256[] memory amounts); error Expired(); error InvalidPath(); error InvalidETHSender(); error InsufficientAmount(); error InsufficientBAmount(); error InsufficientAAmount(); error ExcessiveInputAmount(); error InsufficientLiquidity(); error InsufficientInputAmount(); error InsufficientOutputAmount(); }
//SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.28; interface IOutrunAMMPair { function MINIMUM_LIQUIDITY() external pure returns (uint256); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function price0CumulativeLast() external view returns (uint256); function price1CumulativeLast() external view returns (uint256); function kLast() external view returns (uint256); function feeGrowthX128() external view returns (uint256); function getPairTokens() external view returns (address _token0, address _token1); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function previewMakerFee() external view returns (uint256 amount0, uint256 amount1); function initialize(address token0, address token1, uint256 swapFeeRate) external; function mint(address to) external returns (uint256 liquidity); function burn(address to) external returns (uint256 amount0, uint256 amount1); function swap(uint256 amount0Out, uint256 amount1Out, address to, address referrer, bytes calldata data) external; function skim(address to) external; function sync() external; function claimMakerFee() external returns (uint256 amount0, uint256 amount1); error Locked(); error Overflow(); error Forbidden(); error InvalidTo(); error ProductKLoss(); error TransferFailed(); error FeeRateOverflow(); error InsufficientLiquidity(); error InsufficientInputAmount(); error InsufficientOutputAmount(); error InsufficientUnclaimedFee(); error InsufficientLiquidityMinted(); error InsufficientLiquidityBurned(); error InsufficientMakerFeeClaimed(); event Mint(address indexed sender, address indexed to, uint256 amount0, uint256 amount1); event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to); event Swap( address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to ); event ProtocolFee( address indexed referrer, uint256 rebateFee0, uint256 rebateFee1, uint256 protocolFee0, uint256 protocolFee1 ); event Sync(uint112 reserve0, uint112 reserve1); }
//SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.28; interface IOutrunAMMERC20 { 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 (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); }
//SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.28; interface IOutrunAMMFactory { function swapFeeRate() external view returns (uint256); function pairImplementation() external view returns (address); function feeTo() external view returns (address); function allPairs(uint256) external view returns (address pair); function allPairsLength() external view returns (uint256); function getPair(address tokenA, address tokenB) external view returns (address pair); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; error ZeroAddress(); error PairExists(); error IdenticalAddresses(); event PairCreated(address indexed token0, address indexed token1, address pair, uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/Clones.sol) pragma solidity ^0.8.20; /** * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. */ library Clones { /** * @dev A clone instance deployment failed. */ error ERC1167FailedCreateClone(); /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create(0, 0x09, 0x37) } if (instance == address(0)) { revert ERC1167FailedCreateClone(); } } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create2(0, 0x09, 0x37, salt) } if (instance == address(0)) { revert ERC1167FailedCreateClone(); } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(add(ptr, 0x38), deployer) mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff) mstore(add(ptr, 0x14), implementation) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73) mstore(add(ptr, 0x58), salt) mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37)) predicted := keccak256(add(ptr, 0x43), 0x55) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt ) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/solmate/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 100000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": true, "libraries": {} }
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_factory0","type":"address"},{"internalType":"address","name":"_factory1","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ETHTransferFailed","type":"error"},{"inputs":[],"name":"ExcessiveInputAmount","type":"error"},{"inputs":[],"name":"Expired","type":"error"},{"inputs":[],"name":"IdenticalAddresses","type":"error"},{"inputs":[],"name":"InsufficientAAmount","type":"error"},{"inputs":[],"name":"InsufficientAmount","type":"error"},{"inputs":[],"name":"InsufficientBAmount","type":"error"},{"inputs":[],"name":"InsufficientInputAmount","type":"error"},{"inputs":[],"name":"InsufficientLiquidity","type":"error"},{"inputs":[],"name":"InsufficientOutputAmount","type":"error"},{"inputs":[],"name":"InvalidETHSender","type":"error"},{"inputs":[],"name":"InvalidPath","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"TransferFromFailed","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"feeRate","type":"uint256"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"feeRate","type":"uint256"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"feeRate","type":"uint256"}],"name":"factories","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"},{"internalType":"uint256","name":"feeRate","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"},{"internalType":"uint256","name":"feeRate","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"factory","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"feeRate","type":"uint256"}],"name":"getReserves","outputs":[{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"feeRate","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"feeRate","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"feeRate","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256[]","name":"feeRates","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a03461013957601f613ebf38819003918201601f19168301916001600160401b0383118484101761013d578084926060946040528339810103126101395761004781610151565b90610060604061005960208401610151565b9201610151565b5f60208190527f24d30d6da666a4009a2a398534c9f4ad83932433c3c6d78b8e8d1c3efb30a9bc80546001600160a01b039586166001600160a01b03199182161790915560649091527f9db7038e59677010ca8f72fa448bad1b4f3c53346b666689163ccac31db46772805493909416921691909117909155608052604051613d5990816101668239608051818181602f015281816101c10152818161082a01528181610ad601528181610e410152818161115d015281816111f50152818161179e0152818161185901528181611e9601526120f20152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036101395756fe6080604052600436101561007f575b3615610018575f80fd5b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016330361005757005b7fe811a0c2000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f5f3560e01c80630831dcea1461233b578063163051dc146120b35780631678faab14611e52578063426e40b114611ca157806352707d8c14611c8457806356191a5914611c6f578063571fd01214611c5257806359e741d214611c175780636210ee0014611b68578063672383c414611b0b5780638c160d1214611a995780638d2468e41461181d578063911a9fa81461172a57806396adb337146114dd578063a8977cd214611181578063ad5c464814611112578063ad615dec146110cf578063b677fd5c146110b4578063ba3690cb14610e1b578063c194f86114610ab0578063cd8f4feb146107b4578063de7aae27146106675763ea35e51f14610187575061000e565b6101903661258b565b95919295421161063f5784156106125773ffffffffffffffffffffffffffffffffffffffff6101be8361290e565b817f00000000000000000000000000000000000000000000000000000000000000001691829116036105ea57803b156105db57886040517fd0e30db0000000000000000000000000000000000000000000000000000000008152818160048134875af180156105df576105c6575b50508615610599578435808a528960205273ffffffffffffffffffffffffffffffffffffffff60408b2054166102618561290e565b886001101561056c57926102886020936102e0938e96610282878b0161290e565b91613031565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015234602482015293849283919082906044820190565b03925af18015610561576102fb918a91610532575b50612947565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501928584116105055773ffffffffffffffffffffffffffffffffffffffff61034e6103498689876128fe565b61290e565b1696604051957f70a0823100000000000000000000000000000000000000000000000000000000875260208760248173ffffffffffffffffffffffffffffffffffffffff87169c8d60048301525afa9687156104fa578b976104b4575b50936103f06103499473ffffffffffffffffffffffffffffffffffffffff97946020999a946103ea6103f5996103e2368989612708565b923691612770565b9061381a565b6128fe565b16926024604051809581937f70a0823100000000000000000000000000000000000000000000000000000000835260048301525afa80156104a9578490610471575b61044192506128d0565b106104495780f35b807f42301c230000000000000000000000000000000000000000000000000000000060049252fd5b506020823d6020116104a1575b8161048b60209383612682565b8101031261049d576104419151610437565b5f80fd5b3d915061047e565b6040513d86823e3d90fd5b96509690929491936020873d6020116104f2575b816104d560209383612682565b8101031261049d57955190969095919491939192906103f06103ab565b3d91506104c8565b6040513d8d823e3d90fd5b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b610554915060203d60201161055a575b61054c8183612682565b81019061292f565b5f6102f5565b503d610542565b6040513d8b823e3d90fd5b60248c7f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b816105d091612682565b6105db57885f61022c565b8880fd5b6040513d84823e3d90fd5b6004897f20db8267000000000000000000000000000000000000000000000000000000008152fd5b6024887f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b6004887f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50346107b15761067636612494565b9790969795929491954211610789576106a590610694368486612708565b61069f368888612770565b91612acd565b966106af886128dd565b5111610761578015610612576106c48261290e565b8415610599578335808a528960205273ffffffffffffffffffffffffffffffffffffffff60408b2054166106f78561290e565b90846001101561056c576103e293610731879461075d9e6107519d9c9b9a98956107439561072a602061074a9d0161290e565b9250613031565b61073a8d6128dd565b519133906131c8565b3691612708565b908561334b565b60405191829182612552565b0390f35b6004887fe1b0da4f000000000000000000000000000000000000000000000000000000008152fd5b6004897f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b80fd5b50346107b1576107c336612494565b98979896959196949094939293421161063f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810198818a116105055761082761034973ffffffffffffffffffffffffffffffffffffffff98999a9b84866128fe565b877f0000000000000000000000000000000000000000000000000000000000000000169788911603610a88578115610a5b576108628361290e565b8515610a2e578435808c528b60205273ffffffffffffffffffffffffffffffffffffffff60408d2054166108958661290e565b908560011015610a01579386936108c78f946103ea9895610743956108cf996108d99f9e9d9c602061072a910161290e565b9033906131c8565b9130933691612770565b604051917f70a08231000000000000000000000000000000000000000000000000000000008352306004840152602083602481855afa9283156109f65785936109c2575b50821061099a578084913b15610996578180916024604051809481937f2e1a7d4d0000000000000000000000000000000000000000000000000000000083528860048401525af180156105df5761097d575b505061097a91613599565b80f35b8161098791612682565b61099257825f61096f565b8280fd5b5080fd5b6004847f42301c23000000000000000000000000000000000000000000000000000000008152fd5b9092506020813d6020116109ee575b816109de60209383612682565b8101031261049d5751915f61091d565b3d91506109d1565b6040513d87823e3d90fd5b60248e7f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b60248a7f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b60048a7f20db8267000000000000000000000000000000000000000000000000000000008152fd5b50346107b157610abf3661284e565b969492959390964211610df357610b7d6020610b1e7f000000000000000000000000000000000000000000000000000000000000000095808952888352868873ffffffffffffffffffffffffffffffffffffffff60408c205416613031565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201819052604482019490945291829081906064820190565b038189865af18015610de85791604091879493610dcb575b5060248251809581937f89afcb440000000000000000000000000000000000000000000000000000000083523060048401525af19586156109f65785928697610d8c575b50610be48486613b9a565b5073ffffffffffffffffffffffffffffffffffffffff8681169491168403610d86575b10610d5e578510610d36576020602491604051928380927f70a082310000000000000000000000000000000000000000000000000000000082523060048301525afa9081156104a95786908592610cee575b5090610c7a9173ffffffffffffffffffffffffffffffffffffffff94613c4e565b16803b15610996578180916024604051809481937f2e1a7d4d0000000000000000000000000000000000000000000000000000000083528860048401525af180156105df57610cd9575b602083610cd18187613599565b604051908152f35b610ce4828092612682565b6107b15780610cc4565b9150506020813d602011610d2e575b81610d0a60209383612682565b8101031261049d57518573ffffffffffffffffffffffffffffffffffffffff610c59565b3d9150610cfd565b6004847fef71d091000000000000000000000000000000000000000000000000000000008152fd5b6004857f8dc525d1000000000000000000000000000000000000000000000000000000008152fd5b96610c07565b925095506040823d604011610dc3575b81610da960409383612682565b81010312610dbf5760208251920151955f610bd9565b8480fd5b3d9150610d9c565b610de39060203d60201161055a5761054c8183612682565b610b95565b6040513d88823e3d90fd5b6004857f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50346107b157610e2a3661284e565b96959294939096421161108c57610e896020610b1e7f000000000000000000000000000000000000000000000000000000000000000096808a52898352878773ffffffffffffffffffffffffffffffffffffffff60408d205416613031565b03818a865af1801561108157916040918896959493611064575b5060248251809981937f89afcb440000000000000000000000000000000000000000000000000000000083523060048401525af19586156104a95784908597611026575b5073ffffffffffffffffffffffffffffffffffffffff610f078585613b9a565b501673ffffffffffffffffffffffffffffffffffffffff8416145f146110205795945b8610610ff8578410610fd05790610f57858773ffffffffffffffffffffffffffffffffffffffff94613c4e565b16803b15610996578180916024604051809481937f2e1a7d4d0000000000000000000000000000000000000000000000000000000083528860048401525af180156105df57610fbb575b5050610faf81604094613599565b82519182526020820152f35b610fc6828092612682565b6107b15780610fa1565b6004837fef71d091000000000000000000000000000000000000000000000000000000008152fd5b6004847f8dc525d1000000000000000000000000000000000000000000000000000000008152fd5b94610f2a565b9650506040863d60401161105c575b8161104260409383612682565b810103126110585760208651960151955f610ee7565b8380fd5b3d9150611035565b61107c9060203d60201161055a5761054c8183612682565b610ea3565b6040513d89823e3d90fd5b6004867f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50346107b15761075d6107516110c9366127bc565b91612eb7565b50346107b15760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b1576020610cd1604435602435600435612e60565b50346107b157807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b157602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346107b15761119036612494565b9895919798949094939293421161108c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810198818a116114b0576111f261034973ffffffffffffffffffffffffffffffffffffffff98999a9b84866128fe565b877f0000000000000000000000000000000000000000000000000000000000000000169788911603611488576112389061122d368486612708565b6110c9368888612770565b9788517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081116105055761126f908a6128ea565b5110611460578015611433576112848261290e565b84156106125783358089528860205273ffffffffffffffffffffffffffffffffffffffff60408a2054166112b78561290e565b908460011015610a2e576108cf938c61073a6112eb89968f6112f19a976112f89f9e9d9c9761072a60206107439a0161290e565b916128dd565b908761334b565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081116114065761132e90846128ea565b51813b156109925782916024839260405194859384927f2e1a7d4d00000000000000000000000000000000000000000000000000000000845260048401525af180156105df579082916113f1575b50508151907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82019182116113c4575061075d926113bd61075192846128ea565b5190613599565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b816113fb91612682565b6107b157805f61137c565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b6004877f42301c23000000000000000000000000000000000000000000000000000000008152fd5b6004887f20db8267000000000000000000000000000000000000000000000000000000008152fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b50346107b1576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b15761151661244e565b61151e612471565b9060443560c4359073ffffffffffffffffffffffffffffffffffffffff8216809203610dbf574260e43510610df357849291611580826115e693865285602052868573ffffffffffffffffffffffffffffffffffffffff604089205416613031565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820181905260648035604484015291939092916020918591829190820190565b038188865af19081156109f65760409360249261170d575b50835195869384927f89afcb4400000000000000000000000000000000000000000000000000000000845260048401525af19283156104a957849285946116bd575b5073ffffffffffffffffffffffffffffffffffffffff611661819284613b9a565b50169116145f146116b857905b60843582106116905760a4358110610fd0576040809350519182526020820152f35b6004837f8dc525d1000000000000000000000000000000000000000000000000000000008152fd5b61166e565b925092506040823d604011611705575b816116da60409383612682565b810103126110585781516020909201519273ffffffffffffffffffffffffffffffffffffffff611640565b3d91506116cd565b6117259060203d60201161055a5761054c8183612682565b6115fe565b50346107b15761173936612494565b9895919798949094939293421161108c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810198818a116114b05761179b61034973ffffffffffffffffffffffffffffffffffffffff98999a9b84866128fe565b877f0000000000000000000000000000000000000000000000000000000000000000169788911603611488576117d690610694368486612708565b976117e0896128dd565b51116117f5578015611433576112848261290e565b6004877fe1b0da4f000000000000000000000000000000000000000000000000000000008152fd5b506118273661284e565b9693969594959290924211611a7157956118a461188373ffffffffffffffffffffffffffffffffffffffff9361189b997f00000000000000000000000000000000000000000000000000000000000000009434908b878c6135f5565b9888829988528760205284898760408b205416613031565b809733906131c8565b16803b15610992576040517fd0e30db000000000000000000000000000000000000000000000000000000000815283816004818a865af180156104a957908491611a5c575b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260248101879052906020908290604490829087905af1908115611a515760209261197573ffffffffffffffffffffffffffffffffffffffff936024938791611a3a5750612947565b848360405197889586947f6a627842000000000000000000000000000000000000000000000000000000008652166004850152165af1908115611a2e57906119fa575b61075d91508334116119e2575b604051938493846040919493926060820195825260208201520152565b6119f56119ef85346128d0565b33613599565b6119c5565b506020813d602011611a26575b81611a1460209383612682565b8101031261049d5761075d90516119b8565b3d9150611a07565b604051903d90823e3d90fd5b6105549150863d881161055a5761054c8183612682565b6040513d85823e3d90fd5b81611a6691612682565b61099257825f6118e9565b6004847f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50346107b15760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b157611ad161244e565b90611ada612471565b6044359173ffffffffffffffffffffffffffffffffffffffff831683036107b1576040610faf606435858588612d57565b50346107b15760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b15773ffffffffffffffffffffffffffffffffffffffff60406020926004358152808452205416604051908152f35b50346107b157611b7736612494565b979091939495929697421161078957851561059957611b958361290e565b8715610a5b578535808b528a60205273ffffffffffffffffffffffffffffffffffffffff60408c205416611bc88661290e565b908960011015611bea57918c6108c7926102fb96959461072a60208b0161290e565b60248d7f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b50346107b157807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b15760206040516127108152f35b50346107b1576020610cd1611c6636612646565b92919091612c8e565b50346107b15761075d61075161069f366127bc565b50346107b1576020610cd1611c9836612646565b929190916129c5565b50346107b1576101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b157611cda61244e565b90611ce3612471565b906044359160e4359073ffffffffffffffffffffffffffffffffffffffff821680920361099257426101043510611e2a578492918291611d3060c43560a4356084356064358a868b6135f5565b9790968085528460205282604086205473ffffffffffffffffffffffffffffffffffffffff1692611d6093613031565b94868633611d6d936131c8565b868533611d79936131c8565b6040519384917f6a627842000000000000000000000000000000000000000000000000000000008352600483015273ffffffffffffffffffffffffffffffffffffffff16815a93602492602095f1908115611a2e5790611df6575b61075d9150604051938493846040919493926060820195825260208201520152565b506020813d602011611e22575b81611e1060209383612682565b8101031261049d5761075d9051611dd4565b3d9150611e03565b6004837f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50611e5c3661258b565b9796979591949095939293421161208b5780156114335773ffffffffffffffffffffffffffffffffffffffff9697611e938361290e565b887f00000000000000000000000000000000000000000000000000000000000000001698899116036105ea57611ece90610694368486612708565b96611ed8886128dd565b5134106120635788611ee9896128dd565b51823b156109965781600491604051928380927fd0e30db0000000000000000000000000000000000000000000000000000000008252875af180156105df5761204e575b50508415610599578335808a528960205273ffffffffffffffffffffffffffffffffffffffff60408b205416611f628561290e565b90846001101561056c576020928c611fe99593611f849361072a878b0161290e565b90611f8e8b6128dd565b51918c6040518096819582947fa9059cbb000000000000000000000000000000000000000000000000000000008452600484016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af1908115610561579261201797969594926107436103e29361074a9661075d9d916105325750612947565b612020816128dd565b5134116120335760405191829182612552565b6120496119ef612042836128dd565b51346128d0565b610751565b8161205891612682565b6105db57885f611f2d565b6004897fe1b0da4f000000000000000000000000000000000000000000000000000000008152fd5b6004877f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b506120bd3661258b565b959194909593929342116123135780156122e65773ffffffffffffffffffffffffffffffffffffffff6120ef8361290e565b817f00000000000000000000000000000000000000000000000000000000000000001691829116036122be5761213b612129368486612708565b612134368888612770565b9034612eb7565b9788517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161229157612172908a6128ea565b511061226957612181886128dd565b51813b1561049d575f600491604051928380927fd0e30db0000000000000000000000000000000000000000000000000000000008252865af1801561225e57612249575b508415610599578335808a528960205273ffffffffffffffffffffffffffffffffffffffff60408b2054166121f98561290e565b90846001101561056c576020928c61221b9593611f849361072a878b0161290e565b03925af1908115610561579261075197969594926107436103e29361074a9661075d9d916105325750612947565b6122569199505f90612682565b5f975f6121c5565b6040513d5f823e3d90fd5b7f42301c23000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b7f20db8267000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f203d82d8000000000000000000000000000000000000000000000000000000005f5260045ffd5b3461049d5761234936612494565b979094919395974211612313576123709061236536848b612708565b6110c936868a612770565b9586517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908111612291576123a790886128ea565b51106122695780156122e6576123bc8761290e565b9482156122e6578035805f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f205416986123f18161290e565b9380600110156122e657610743610751996107316103e29561075d9e61074a996102826020890161290e565b9181601f8401121561049d5782359167ffffffffffffffff831161049d576020808501948460051b01011161049d57565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361049d57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361049d57565b60e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc82011261049d57600435916024359160443567ffffffffffffffff811161049d57816124e59160040161241d565b929092916064359067ffffffffffffffff821161049d576125089160040161241d565b909160843573ffffffffffffffffffffffffffffffffffffffff8116810361049d579060a43573ffffffffffffffffffffffffffffffffffffffff8116810361049d579060c43590565b60206040818301928281528451809452019201905f5b8181106125755750505090565b8251845260209384019390920191600101612568565b9060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261049d576004359160243567ffffffffffffffff811161049d57816125d99160040161241d565b929092916044359067ffffffffffffffff821161049d576125fc9160040161241d565b909160643573ffffffffffffffffffffffffffffffffffffffff8116810361049d579060843573ffffffffffffffffffffffffffffffffffffffff8116810361049d579060a43590565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc608091011261049d5760043590602435906044359060643590565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176126c357604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b67ffffffffffffffff81116126c35760051b60200190565b9291612713826126f0565b936127216040519586612682565b602085848152019260051b810191821161049d57915b81831061274357505050565b823573ffffffffffffffffffffffffffffffffffffffff8116810361049d57815260209283019201612737565b92919061277c816126f0565b9361278a6040519586612682565b602085838152019160051b810192831161049d57905b8282106127ac57505050565b81358152602091820191016127a0565b60607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc82011261049d576004359160243567ffffffffffffffff811161049d578260238201121561049d578281602461281a93600401359101612708565b916044359067ffffffffffffffff821161049d578060238301121561049d5781602461284b93600401359101612770565b90565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60e091011261049d5760043573ffffffffffffffffffffffffffffffffffffffff8116810361049d57906024359060443590606435906084359060a43573ffffffffffffffffffffffffffffffffffffffff8116810361049d579060c43590565b9190820391821161229157565b8051156122e65760200190565b80518210156122e65760209160051b010190565b91908110156122e65760051b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361049d5790565b9081602091031261049d5751801515810361049d5790565b1561294e57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b8181029291811591840414171561229157565b8115612998570490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b9190918015612a5657821593841580612a4d575b15612a25576127100390612710821161229157612a00916129f99161297b565b918261297b565b9261271083029283046127101417156122915781018091116122915761284b9161298e565b7fbb55fd27000000000000000000000000000000000000000000000000000000005f5260045ffd5b508215156129d9565b7f098fb561000000000000000000000000000000000000000000000000000000005f5260045ffd5b90612a88826126f0565b612a956040519182612682565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0612ac382946126f0565b0190602036910137565b929190805160028110159081612c80575b81612c6b575b50156122be57612af48151612a7e565b9384517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161229157612b2b90866128ea565b5280517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161229157805b612b6357505050565b612b6d81846128ea565b515f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f2054167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82019082821161229157612c35612c18612c3c9273ffffffffffffffffffffffffffffffffffffffff612be386896128ea565b511673ffffffffffffffffffffffffffffffffffffffff612c04888a6128ea565b511690612c11878b6128ea565b5192612d57565b612c22868b6128ea565b5191612c2e868a6128ea565b5192612c8e565b91876128ea565b528015612291577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180612b5a565b8351600181019250821061229157145f612ae4565b905060018351101590612ade565b919082156122695780151580612cfd575b15612a255782612cae9161297b565b91612710830292808404612710149015171561229157612ccd916128d0565b916127100391612710831161229157612cef92612ce99161297b565b9061298e565b600181018091116122915790565b50811515612c9f565b51906dffffffffffffffffffffffffffff8216820361049d57565b9081606091031261049d57612d3581612d06565b916040612d4460208401612d06565b92015163ffffffff8116810361049d5790565b9273ffffffffffffffffffffffffffffffffffffffff612d8860609260049585612d818282613b9a565b5098613031565b16604051938480927f0902f1ac0000000000000000000000000000000000000000000000000000000082525afa91821561225e575f905f93612e02575b5073ffffffffffffffffffffffffffffffffffffffff6dffffffffffffffffffffffffffff80829316941694169116145f14612dfe5791565b9091565b6dffffffffffffffffffffffffffff80945073ffffffffffffffffffffffffffffffffffffffff9250612e4d839260603d606011612e59575b612e458183612682565b810190612d21565b50959093505050612dc5565b503d612e3b565b8015612e8f5781151580612e86575b15612a255761284b92612e819161297b565b61298e565b50821515612e6f565b7f5945ea56000000000000000000000000000000000000000000000000000000005f5260045ffd5b909291835160028110159081612ff7575b81612fe2575b50156122be57612ede8451612a7e565b91612ee8836128dd565b525f5b84517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161229157811015612fdc57612f2881836128ea565b515f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f2054169073ffffffffffffffffffffffffffffffffffffffff612f6a82886128ea565b5116600182019081831161229157612fce612fb1600195612fd59373ffffffffffffffffffffffffffffffffffffffff612fa4878e6128ea565b511690612c11888b6128ea565b612fbb868a6128ea565b5191612fc7878a6128ea565b51926129c5565b91866128ea565b5201612eeb565b50509150565b8251600181019250821061229157145f612ece565b905060018251101590612ec8565b9081602091031261049d575173ffffffffffffffffffffffffffffffffffffffff8116810361049d5790565b9161303b91613b9a565b6040517f71f3c596000000000000000000000000000000000000000000000000000000008152929160208460048173ffffffffffffffffffffffffffffffffffffffff87165afa91821561225e576055956043955f9461313a575b507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000006040519281602085019560601b16855260601b1660348301526048820152604881526130e5606882612682565b519020906040519260388401526f5af43d82803e903d91602b57fd5bf3ff60248401526014830152733d602d80600a3d3981f3363d3d373d3d3d363d73825260588201526037600c8201206078820152012090565b61315d91945060203d602011613164575b6131558183612682565b810190613005565b925f613096565b503d61314b565b3d156131c3573d9067ffffffffffffffff82116126c357604051916131b8601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200184612682565b82523d5f602084013e565b606090565b905f8094613260829561323460405193849260208401977f23b872dd0000000000000000000000000000000000000000000000000000000089526024850173ffffffffffffffffffffffffffffffffffffffff6040929594938160608401971683521660208201520152565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612682565b51925af161326c61316b565b816132a2575b501561327a57565b7f7939f424000000000000000000000000000000000000000000000000000000005f5260045ffd5b80518015925082156132b7575b50505f613272565b6132ca925060208091830101910161292f565b5f806132af565b939473ffffffffffffffffffffffffffffffffffffffff60c096817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe096601f966020968a52868a015216604088015216606086015260a0608086015280519182918260a0880152018686015e5f8582860101520116010190565b9394939290915f9190602090835b85517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081116122915781101561358e5773ffffffffffffffffffffffffffffffffffffffff6133ab82886128ea565b51169060018101918282116122915773ffffffffffffffffffffffffffffffffffffffff6133d9848a6128ea565b51166133e58183613b9a565b509173ffffffffffffffffffffffffffffffffffffffff613406868d6128ea565b5193168103613587575f92945b8a517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8101908111612291578510156135665761345081886128ea565b515f525f885273ffffffffffffffffffffffffffffffffffffffff60405f20541691600286018087116122915773ffffffffffffffffffffffffffffffffffffffff936134de93868f876134aa6134ba966134b3936128ea565b5116928d6128ea565b5192613031565b935b6134c6878a6128ea565b515f525f8a528360405f205416916134b3888b6128ea565b16604051946134ed8887612682565b5f8652893689880137813b1561049d575f80948f9761353c90604051998a97889687957fd7dc4e43000000000000000000000000000000000000000000000000000000008752600487016132d1565b03925af191821561225e57600192613556575b5001613359565b5f61356091612682565b5f61354f565b506134de73ffffffffffffffffffffffffffffffffffffffff9189936134bc565b5f94613413565b505050505050509050565b5f91908291604051906135ad602083612682565b83825260208201915f36843751925af16135c561316b565b50156135cd57565b7fb12d13eb000000000000000000000000000000000000000000000000000000005f5260045ffd5b9190959295949394815f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f205416926040517fe6a439050000000000000000000000000000000000000000000000000000000081526020818061367d86866004840190929173ffffffffffffffffffffffffffffffffffffffff60209181604085019616845216910152565b0381885afa801561225e5773ffffffffffffffffffffffffffffffffffffffff915f916137fb575b50161561376f575b6136b693612d57565b9290801580613767575b156136cd57505050509091565b6136dc84828897959697612e60565b9483861161371a575050505081106136f2579091565b7fef71d091000000000000000000000000000000000000000000000000000000005f5260045ffd5b8361373594965061372c939550612e60565b93841115612947565b821061373f579091565b7f8dc525d1000000000000000000000000000000000000000000000000000000005f5260045ffd5b5083156136c0565b6040517fc9c6539600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff828116600483015283166024820152936020856044815f855af194851561225e576136b6956137dc575b5093506136ad565b6137f49060203d602011613164576131558183612682565b505f6137d4565b613814915060203d602011613164576131558183612682565b5f6136a5565b929392915f91906020835b85517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161229157811015613b905773ffffffffffffffffffffffffffffffffffffffff61387782886128ea565b51169060018101918282116122915773ffffffffffffffffffffffffffffffffffffffff6138a5848a6128ea565b5116906138b28282613b9a565b50916138be84896128ea565b515f525f865273ffffffffffffffffffffffffffffffffffffffff6138f08983856134b3898660405f205416946128ea565b1690604051937f0902f1ac000000000000000000000000000000000000000000000000000000008552606085600481865afa93841561225e57885f965f96613b3d575b5073ffffffffffffffffffffffffffffffffffffffff6dffffffffffffffffffffffffffff806024969798991698169316821496875f14613b375792915b604051948580927f70a082310000000000000000000000000000000000000000000000000000000082528960048301525afa92831561225e575f93613b06575b506139bf826139ca946128d0565b91612fc7888d6128ea565b9215613aff575f92945b8a517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe810190811161229157851015613af657613a11818a6128ea565b515f525f875273ffffffffffffffffffffffffffffffffffffffff60405f205416906002860192838711612291576134b373ffffffffffffffffffffffffffffffffffffffff613a658f96613a6e976128ea565b5116928c6128ea565b905b60405194613a7e8787612682565b5f8652893688880137813b1561049d575f8094613acc8f98604051998a97889687957fd7dc4e43000000000000000000000000000000000000000000000000000000008752600487016132d1565b03925af191821561225e57600192613ae6575b5001613825565b5f613af091612682565b5f613adf565b50508590613a70565b5f946139d4565b92508883813d8311613b30575b613b1d8183612682565b8101031261049d579151916139bf6139b1565b503d613b13565b91613971565b6dffffffffffffffffffffffffffff809850602495969750613b8173ffffffffffffffffffffffffffffffffffffffff9260603d8111612e5957612e458183612682565b50999099989796505050613933565b5050505050509050565b91909173ffffffffffffffffffffffffffffffffffffffff831673ffffffffffffffffffffffffffffffffffffffff8216818114613c26571015613c2157915b9073ffffffffffffffffffffffffffffffffffffffff831615613bf957565b7fd92e233d000000000000000000000000000000000000000000000000000000005f5260045ffd5b613bda565b7fbd969eb0000000000000000000000000000000000000000000000000000000005f5260045ffd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff909316602482015260448101939093525f928392908390613cb28160648101613234565b51925af1613cbe61316b565b81613cf4575b5015613ccc57565b7f90b8ec18000000000000000000000000000000000000000000000000000000005f5260045ffd5b8051801592508215613d09575b50505f613cc4565b613d1c925060208091830101910161292f565b5f80613d0156fea2646970667358221220ea9276e06c9937cf4ca5969242648d9248cef13ee33ec43e7c88b6c61bf2350264736f6c634300081c003300000000000000000000000083f4ac7d5d8edfc2103563a7a7347e803a870aaf000000000000000000000000eadd335f1420328e9532d1198170ae7ce21fe3cf000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
Deployed Bytecode
0x6080604052600436101561007f575b3615610018575f80fd5b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3816330361005757005b7fe811a0c2000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f5f3560e01c80630831dcea1461233b578063163051dc146120b35780631678faab14611e52578063426e40b114611ca157806352707d8c14611c8457806356191a5914611c6f578063571fd01214611c5257806359e741d214611c175780636210ee0014611b68578063672383c414611b0b5780638c160d1214611a995780638d2468e41461181d578063911a9fa81461172a57806396adb337146114dd578063a8977cd214611181578063ad5c464814611112578063ad615dec146110cf578063b677fd5c146110b4578063ba3690cb14610e1b578063c194f86114610ab0578063cd8f4feb146107b4578063de7aae27146106675763ea35e51f14610187575061000e565b6101903661258b565b95919295421161063f5784156106125773ffffffffffffffffffffffffffffffffffffffff6101be8361290e565b817f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad381691829116036105ea57803b156105db57886040517fd0e30db0000000000000000000000000000000000000000000000000000000008152818160048134875af180156105df576105c6575b50508615610599578435808a528960205273ffffffffffffffffffffffffffffffffffffffff60408b2054166102618561290e565b886001101561056c57926102886020936102e0938e96610282878b0161290e565b91613031565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015234602482015293849283919082906044820190565b03925af18015610561576102fb918a91610532575b50612947565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501928584116105055773ffffffffffffffffffffffffffffffffffffffff61034e6103498689876128fe565b61290e565b1696604051957f70a0823100000000000000000000000000000000000000000000000000000000875260208760248173ffffffffffffffffffffffffffffffffffffffff87169c8d60048301525afa9687156104fa578b976104b4575b50936103f06103499473ffffffffffffffffffffffffffffffffffffffff97946020999a946103ea6103f5996103e2368989612708565b923691612770565b9061381a565b6128fe565b16926024604051809581937f70a0823100000000000000000000000000000000000000000000000000000000835260048301525afa80156104a9578490610471575b61044192506128d0565b106104495780f35b807f42301c230000000000000000000000000000000000000000000000000000000060049252fd5b506020823d6020116104a1575b8161048b60209383612682565b8101031261049d576104419151610437565b5f80fd5b3d915061047e565b6040513d86823e3d90fd5b96509690929491936020873d6020116104f2575b816104d560209383612682565b8101031261049d57955190969095919491939192906103f06103ab565b3d91506104c8565b6040513d8d823e3d90fd5b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b610554915060203d60201161055a575b61054c8183612682565b81019061292f565b5f6102f5565b503d610542565b6040513d8b823e3d90fd5b60248c7f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b816105d091612682565b6105db57885f61022c565b8880fd5b6040513d84823e3d90fd5b6004897f20db8267000000000000000000000000000000000000000000000000000000008152fd5b6024887f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b6004887f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50346107b15761067636612494565b9790969795929491954211610789576106a590610694368486612708565b61069f368888612770565b91612acd565b966106af886128dd565b5111610761578015610612576106c48261290e565b8415610599578335808a528960205273ffffffffffffffffffffffffffffffffffffffff60408b2054166106f78561290e565b90846001101561056c576103e293610731879461075d9e6107519d9c9b9a98956107439561072a602061074a9d0161290e565b9250613031565b61073a8d6128dd565b519133906131c8565b3691612708565b908561334b565b60405191829182612552565b0390f35b6004887fe1b0da4f000000000000000000000000000000000000000000000000000000008152fd5b6004897f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b80fd5b50346107b1576107c336612494565b98979896959196949094939293421161063f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810198818a116105055761082761034973ffffffffffffffffffffffffffffffffffffffff98999a9b84866128fe565b877f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38169788911603610a88578115610a5b576108628361290e565b8515610a2e578435808c528b60205273ffffffffffffffffffffffffffffffffffffffff60408d2054166108958661290e565b908560011015610a01579386936108c78f946103ea9895610743956108cf996108d99f9e9d9c602061072a910161290e565b9033906131c8565b9130933691612770565b604051917f70a08231000000000000000000000000000000000000000000000000000000008352306004840152602083602481855afa9283156109f65785936109c2575b50821061099a578084913b15610996578180916024604051809481937f2e1a7d4d0000000000000000000000000000000000000000000000000000000083528860048401525af180156105df5761097d575b505061097a91613599565b80f35b8161098791612682565b61099257825f61096f565b8280fd5b5080fd5b6004847f42301c23000000000000000000000000000000000000000000000000000000008152fd5b9092506020813d6020116109ee575b816109de60209383612682565b8101031261049d5751915f61091d565b3d91506109d1565b6040513d87823e3d90fd5b60248e7f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b60248a7f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b60048a7f20db8267000000000000000000000000000000000000000000000000000000008152fd5b50346107b157610abf3661284e565b969492959390964211610df357610b7d6020610b1e7f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3895808952888352868873ffffffffffffffffffffffffffffffffffffffff60408c205416613031565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201819052604482019490945291829081906064820190565b038189865af18015610de85791604091879493610dcb575b5060248251809581937f89afcb440000000000000000000000000000000000000000000000000000000083523060048401525af19586156109f65785928697610d8c575b50610be48486613b9a565b5073ffffffffffffffffffffffffffffffffffffffff8681169491168403610d86575b10610d5e578510610d36576020602491604051928380927f70a082310000000000000000000000000000000000000000000000000000000082523060048301525afa9081156104a95786908592610cee575b5090610c7a9173ffffffffffffffffffffffffffffffffffffffff94613c4e565b16803b15610996578180916024604051809481937f2e1a7d4d0000000000000000000000000000000000000000000000000000000083528860048401525af180156105df57610cd9575b602083610cd18187613599565b604051908152f35b610ce4828092612682565b6107b15780610cc4565b9150506020813d602011610d2e575b81610d0a60209383612682565b8101031261049d57518573ffffffffffffffffffffffffffffffffffffffff610c59565b3d9150610cfd565b6004847fef71d091000000000000000000000000000000000000000000000000000000008152fd5b6004857f8dc525d1000000000000000000000000000000000000000000000000000000008152fd5b96610c07565b925095506040823d604011610dc3575b81610da960409383612682565b81010312610dbf5760208251920151955f610bd9565b8480fd5b3d9150610d9c565b610de39060203d60201161055a5761054c8183612682565b610b95565b6040513d88823e3d90fd5b6004857f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50346107b157610e2a3661284e565b96959294939096421161108c57610e896020610b1e7f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3896808a52898352878773ffffffffffffffffffffffffffffffffffffffff60408d205416613031565b03818a865af1801561108157916040918896959493611064575b5060248251809981937f89afcb440000000000000000000000000000000000000000000000000000000083523060048401525af19586156104a95784908597611026575b5073ffffffffffffffffffffffffffffffffffffffff610f078585613b9a565b501673ffffffffffffffffffffffffffffffffffffffff8416145f146110205795945b8610610ff8578410610fd05790610f57858773ffffffffffffffffffffffffffffffffffffffff94613c4e565b16803b15610996578180916024604051809481937f2e1a7d4d0000000000000000000000000000000000000000000000000000000083528860048401525af180156105df57610fbb575b5050610faf81604094613599565b82519182526020820152f35b610fc6828092612682565b6107b15780610fa1565b6004837fef71d091000000000000000000000000000000000000000000000000000000008152fd5b6004847f8dc525d1000000000000000000000000000000000000000000000000000000008152fd5b94610f2a565b9650506040863d60401161105c575b8161104260409383612682565b810103126110585760208651960151955f610ee7565b8380fd5b3d9150611035565b61107c9060203d60201161055a5761054c8183612682565b610ea3565b6040513d89823e3d90fd5b6004867f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50346107b15761075d6107516110c9366127bc565b91612eb7565b50346107b15760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b1576020610cd1604435602435600435612e60565b50346107b157807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b157602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38168152f35b50346107b15761119036612494565b9895919798949094939293421161108c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810198818a116114b0576111f261034973ffffffffffffffffffffffffffffffffffffffff98999a9b84866128fe565b877f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38169788911603611488576112389061122d368486612708565b6110c9368888612770565b9788517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081116105055761126f908a6128ea565b5110611460578015611433576112848261290e565b84156106125783358089528860205273ffffffffffffffffffffffffffffffffffffffff60408a2054166112b78561290e565b908460011015610a2e576108cf938c61073a6112eb89968f6112f19a976112f89f9e9d9c9761072a60206107439a0161290e565b916128dd565b908761334b565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081116114065761132e90846128ea565b51813b156109925782916024839260405194859384927f2e1a7d4d00000000000000000000000000000000000000000000000000000000845260048401525af180156105df579082916113f1575b50508151907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82019182116113c4575061075d926113bd61075192846128ea565b5190613599565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b816113fb91612682565b6107b157805f61137c565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b6004877f42301c23000000000000000000000000000000000000000000000000000000008152fd5b6004887f20db8267000000000000000000000000000000000000000000000000000000008152fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b50346107b1576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b15761151661244e565b61151e612471565b9060443560c4359073ffffffffffffffffffffffffffffffffffffffff8216809203610dbf574260e43510610df357849291611580826115e693865285602052868573ffffffffffffffffffffffffffffffffffffffff604089205416613031565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820181905260648035604484015291939092916020918591829190820190565b038188865af19081156109f65760409360249261170d575b50835195869384927f89afcb4400000000000000000000000000000000000000000000000000000000845260048401525af19283156104a957849285946116bd575b5073ffffffffffffffffffffffffffffffffffffffff611661819284613b9a565b50169116145f146116b857905b60843582106116905760a4358110610fd0576040809350519182526020820152f35b6004837f8dc525d1000000000000000000000000000000000000000000000000000000008152fd5b61166e565b925092506040823d604011611705575b816116da60409383612682565b810103126110585781516020909201519273ffffffffffffffffffffffffffffffffffffffff611640565b3d91506116cd565b6117259060203d60201161055a5761054c8183612682565b6115fe565b50346107b15761173936612494565b9895919798949094939293421161108c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810198818a116114b05761179b61034973ffffffffffffffffffffffffffffffffffffffff98999a9b84866128fe565b877f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38169788911603611488576117d690610694368486612708565b976117e0896128dd565b51116117f5578015611433576112848261290e565b6004877fe1b0da4f000000000000000000000000000000000000000000000000000000008152fd5b506118273661284e565b9693969594959290924211611a7157956118a461188373ffffffffffffffffffffffffffffffffffffffff9361189b997f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad389434908b878c6135f5565b9888829988528760205284898760408b205416613031565b809733906131c8565b16803b15610992576040517fd0e30db000000000000000000000000000000000000000000000000000000000815283816004818a865af180156104a957908491611a5c575b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260248101879052906020908290604490829087905af1908115611a515760209261197573ffffffffffffffffffffffffffffffffffffffff936024938791611a3a5750612947565b848360405197889586947f6a627842000000000000000000000000000000000000000000000000000000008652166004850152165af1908115611a2e57906119fa575b61075d91508334116119e2575b604051938493846040919493926060820195825260208201520152565b6119f56119ef85346128d0565b33613599565b6119c5565b506020813d602011611a26575b81611a1460209383612682565b8101031261049d5761075d90516119b8565b3d9150611a07565b604051903d90823e3d90fd5b6105549150863d881161055a5761054c8183612682565b6040513d85823e3d90fd5b81611a6691612682565b61099257825f6118e9565b6004847f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50346107b15760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b157611ad161244e565b90611ada612471565b6044359173ffffffffffffffffffffffffffffffffffffffff831683036107b1576040610faf606435858588612d57565b50346107b15760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b15773ffffffffffffffffffffffffffffffffffffffff60406020926004358152808452205416604051908152f35b50346107b157611b7736612494565b979091939495929697421161078957851561059957611b958361290e565b8715610a5b578535808b528a60205273ffffffffffffffffffffffffffffffffffffffff60408c205416611bc88661290e565b908960011015611bea57918c6108c7926102fb96959461072a60208b0161290e565b60248d7f4e487b710000000000000000000000000000000000000000000000000000000081526032600452fd5b50346107b157807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b15760206040516127108152f35b50346107b1576020610cd1611c6636612646565b92919091612c8e565b50346107b15761075d61075161069f366127bc565b50346107b1576020610cd1611c9836612646565b929190916129c5565b50346107b1576101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107b157611cda61244e565b90611ce3612471565b906044359160e4359073ffffffffffffffffffffffffffffffffffffffff821680920361099257426101043510611e2a578492918291611d3060c43560a4356084356064358a868b6135f5565b9790968085528460205282604086205473ffffffffffffffffffffffffffffffffffffffff1692611d6093613031565b94868633611d6d936131c8565b868533611d79936131c8565b6040519384917f6a627842000000000000000000000000000000000000000000000000000000008352600483015273ffffffffffffffffffffffffffffffffffffffff16815a93602492602095f1908115611a2e5790611df6575b61075d9150604051938493846040919493926060820195825260208201520152565b506020813d602011611e22575b81611e1060209383612682565b8101031261049d5761075d9051611dd4565b3d9150611e03565b6004837f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b50611e5c3661258b565b9796979591949095939293421161208b5780156114335773ffffffffffffffffffffffffffffffffffffffff9697611e938361290e565b887f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad381698899116036105ea57611ece90610694368486612708565b96611ed8886128dd565b5134106120635788611ee9896128dd565b51823b156109965781600491604051928380927fd0e30db0000000000000000000000000000000000000000000000000000000008252875af180156105df5761204e575b50508415610599578335808a528960205273ffffffffffffffffffffffffffffffffffffffff60408b205416611f628561290e565b90846001101561056c576020928c611fe99593611f849361072a878b0161290e565b90611f8e8b6128dd565b51918c6040518096819582947fa9059cbb000000000000000000000000000000000000000000000000000000008452600484016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af1908115610561579261201797969594926107436103e29361074a9661075d9d916105325750612947565b612020816128dd565b5134116120335760405191829182612552565b6120496119ef612042836128dd565b51346128d0565b610751565b8161205891612682565b6105db57885f611f2d565b6004897fe1b0da4f000000000000000000000000000000000000000000000000000000008152fd5b6004877f203d82d8000000000000000000000000000000000000000000000000000000008152fd5b506120bd3661258b565b959194909593929342116123135780156122e65773ffffffffffffffffffffffffffffffffffffffff6120ef8361290e565b817f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad381691829116036122be5761213b612129368486612708565b612134368888612770565b9034612eb7565b9788517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161229157612172908a6128ea565b511061226957612181886128dd565b51813b1561049d575f600491604051928380927fd0e30db0000000000000000000000000000000000000000000000000000000008252865af1801561225e57612249575b508415610599578335808a528960205273ffffffffffffffffffffffffffffffffffffffff60408b2054166121f98561290e565b90846001101561056c576020928c61221b9593611f849361072a878b0161290e565b03925af1908115610561579261075197969594926107436103e29361074a9661075d9d916105325750612947565b6122569199505f90612682565b5f975f6121c5565b6040513d5f823e3d90fd5b7f42301c23000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b7f20db8267000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f203d82d8000000000000000000000000000000000000000000000000000000005f5260045ffd5b3461049d5761234936612494565b979094919395974211612313576123709061236536848b612708565b6110c936868a612770565b9586517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908111612291576123a790886128ea565b51106122695780156122e6576123bc8761290e565b9482156122e6578035805f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f205416986123f18161290e565b9380600110156122e657610743610751996107316103e29561075d9e61074a996102826020890161290e565b9181601f8401121561049d5782359167ffffffffffffffff831161049d576020808501948460051b01011161049d57565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361049d57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361049d57565b60e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc82011261049d57600435916024359160443567ffffffffffffffff811161049d57816124e59160040161241d565b929092916064359067ffffffffffffffff821161049d576125089160040161241d565b909160843573ffffffffffffffffffffffffffffffffffffffff8116810361049d579060a43573ffffffffffffffffffffffffffffffffffffffff8116810361049d579060c43590565b60206040818301928281528451809452019201905f5b8181106125755750505090565b8251845260209384019390920191600101612568565b9060c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261049d576004359160243567ffffffffffffffff811161049d57816125d99160040161241d565b929092916044359067ffffffffffffffff821161049d576125fc9160040161241d565b909160643573ffffffffffffffffffffffffffffffffffffffff8116810361049d579060843573ffffffffffffffffffffffffffffffffffffffff8116810361049d579060a43590565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc608091011261049d5760043590602435906044359060643590565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176126c357604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b67ffffffffffffffff81116126c35760051b60200190565b9291612713826126f0565b936127216040519586612682565b602085848152019260051b810191821161049d57915b81831061274357505050565b823573ffffffffffffffffffffffffffffffffffffffff8116810361049d57815260209283019201612737565b92919061277c816126f0565b9361278a6040519586612682565b602085838152019160051b810192831161049d57905b8282106127ac57505050565b81358152602091820191016127a0565b60607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc82011261049d576004359160243567ffffffffffffffff811161049d578260238201121561049d578281602461281a93600401359101612708565b916044359067ffffffffffffffff821161049d578060238301121561049d5781602461284b93600401359101612770565b90565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60e091011261049d5760043573ffffffffffffffffffffffffffffffffffffffff8116810361049d57906024359060443590606435906084359060a43573ffffffffffffffffffffffffffffffffffffffff8116810361049d579060c43590565b9190820391821161229157565b8051156122e65760200190565b80518210156122e65760209160051b010190565b91908110156122e65760051b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361049d5790565b9081602091031261049d5751801515810361049d5790565b1561294e57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b8181029291811591840414171561229157565b8115612998570490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b9190918015612a5657821593841580612a4d575b15612a25576127100390612710821161229157612a00916129f99161297b565b918261297b565b9261271083029283046127101417156122915781018091116122915761284b9161298e565b7fbb55fd27000000000000000000000000000000000000000000000000000000005f5260045ffd5b508215156129d9565b7f098fb561000000000000000000000000000000000000000000000000000000005f5260045ffd5b90612a88826126f0565b612a956040519182612682565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0612ac382946126f0565b0190602036910137565b929190805160028110159081612c80575b81612c6b575b50156122be57612af48151612a7e565b9384517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161229157612b2b90866128ea565b5280517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161229157805b612b6357505050565b612b6d81846128ea565b515f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f2054167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82019082821161229157612c35612c18612c3c9273ffffffffffffffffffffffffffffffffffffffff612be386896128ea565b511673ffffffffffffffffffffffffffffffffffffffff612c04888a6128ea565b511690612c11878b6128ea565b5192612d57565b612c22868b6128ea565b5191612c2e868a6128ea565b5192612c8e565b91876128ea565b528015612291577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180612b5a565b8351600181019250821061229157145f612ae4565b905060018351101590612ade565b919082156122695780151580612cfd575b15612a255782612cae9161297b565b91612710830292808404612710149015171561229157612ccd916128d0565b916127100391612710831161229157612cef92612ce99161297b565b9061298e565b600181018091116122915790565b50811515612c9f565b51906dffffffffffffffffffffffffffff8216820361049d57565b9081606091031261049d57612d3581612d06565b916040612d4460208401612d06565b92015163ffffffff8116810361049d5790565b9273ffffffffffffffffffffffffffffffffffffffff612d8860609260049585612d818282613b9a565b5098613031565b16604051938480927f0902f1ac0000000000000000000000000000000000000000000000000000000082525afa91821561225e575f905f93612e02575b5073ffffffffffffffffffffffffffffffffffffffff6dffffffffffffffffffffffffffff80829316941694169116145f14612dfe5791565b9091565b6dffffffffffffffffffffffffffff80945073ffffffffffffffffffffffffffffffffffffffff9250612e4d839260603d606011612e59575b612e458183612682565b810190612d21565b50959093505050612dc5565b503d612e3b565b8015612e8f5781151580612e86575b15612a255761284b92612e819161297b565b61298e565b50821515612e6f565b7f5945ea56000000000000000000000000000000000000000000000000000000005f5260045ffd5b909291835160028110159081612ff7575b81612fe2575b50156122be57612ede8451612a7e565b91612ee8836128dd565b525f5b84517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161229157811015612fdc57612f2881836128ea565b515f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f2054169073ffffffffffffffffffffffffffffffffffffffff612f6a82886128ea565b5116600182019081831161229157612fce612fb1600195612fd59373ffffffffffffffffffffffffffffffffffffffff612fa4878e6128ea565b511690612c11888b6128ea565b612fbb868a6128ea565b5191612fc7878a6128ea565b51926129c5565b91866128ea565b5201612eeb565b50509150565b8251600181019250821061229157145f612ece565b905060018251101590612ec8565b9081602091031261049d575173ffffffffffffffffffffffffffffffffffffffff8116810361049d5790565b9161303b91613b9a565b6040517f71f3c596000000000000000000000000000000000000000000000000000000008152929160208460048173ffffffffffffffffffffffffffffffffffffffff87165afa91821561225e576055956043955f9461313a575b507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000006040519281602085019560601b16855260601b1660348301526048820152604881526130e5606882612682565b519020906040519260388401526f5af43d82803e903d91602b57fd5bf3ff60248401526014830152733d602d80600a3d3981f3363d3d373d3d3d363d73825260588201526037600c8201206078820152012090565b61315d91945060203d602011613164575b6131558183612682565b810190613005565b925f613096565b503d61314b565b3d156131c3573d9067ffffffffffffffff82116126c357604051916131b8601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200184612682565b82523d5f602084013e565b606090565b905f8094613260829561323460405193849260208401977f23b872dd0000000000000000000000000000000000000000000000000000000089526024850173ffffffffffffffffffffffffffffffffffffffff6040929594938160608401971683521660208201520152565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612682565b51925af161326c61316b565b816132a2575b501561327a57565b7f7939f424000000000000000000000000000000000000000000000000000000005f5260045ffd5b80518015925082156132b7575b50505f613272565b6132ca925060208091830101910161292f565b5f806132af565b939473ffffffffffffffffffffffffffffffffffffffff60c096817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe096601f966020968a52868a015216604088015216606086015260a0608086015280519182918260a0880152018686015e5f8582860101520116010190565b9394939290915f9190602090835b85517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081116122915781101561358e5773ffffffffffffffffffffffffffffffffffffffff6133ab82886128ea565b51169060018101918282116122915773ffffffffffffffffffffffffffffffffffffffff6133d9848a6128ea565b51166133e58183613b9a565b509173ffffffffffffffffffffffffffffffffffffffff613406868d6128ea565b5193168103613587575f92945b8a517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8101908111612291578510156135665761345081886128ea565b515f525f885273ffffffffffffffffffffffffffffffffffffffff60405f20541691600286018087116122915773ffffffffffffffffffffffffffffffffffffffff936134de93868f876134aa6134ba966134b3936128ea565b5116928d6128ea565b5192613031565b935b6134c6878a6128ea565b515f525f8a528360405f205416916134b3888b6128ea565b16604051946134ed8887612682565b5f8652893689880137813b1561049d575f80948f9761353c90604051998a97889687957fd7dc4e43000000000000000000000000000000000000000000000000000000008752600487016132d1565b03925af191821561225e57600192613556575b5001613359565b5f61356091612682565b5f61354f565b506134de73ffffffffffffffffffffffffffffffffffffffff9189936134bc565b5f94613413565b505050505050509050565b5f91908291604051906135ad602083612682565b83825260208201915f36843751925af16135c561316b565b50156135cd57565b7fb12d13eb000000000000000000000000000000000000000000000000000000005f5260045ffd5b9190959295949394815f525f60205273ffffffffffffffffffffffffffffffffffffffff60405f205416926040517fe6a439050000000000000000000000000000000000000000000000000000000081526020818061367d86866004840190929173ffffffffffffffffffffffffffffffffffffffff60209181604085019616845216910152565b0381885afa801561225e5773ffffffffffffffffffffffffffffffffffffffff915f916137fb575b50161561376f575b6136b693612d57565b9290801580613767575b156136cd57505050509091565b6136dc84828897959697612e60565b9483861161371a575050505081106136f2579091565b7fef71d091000000000000000000000000000000000000000000000000000000005f5260045ffd5b8361373594965061372c939550612e60565b93841115612947565b821061373f579091565b7f8dc525d1000000000000000000000000000000000000000000000000000000005f5260045ffd5b5083156136c0565b6040517fc9c6539600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff828116600483015283166024820152936020856044815f855af194851561225e576136b6956137dc575b5093506136ad565b6137f49060203d602011613164576131558183612682565b505f6137d4565b613814915060203d602011613164576131558183612682565b5f6136a5565b929392915f91906020835b85517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161229157811015613b905773ffffffffffffffffffffffffffffffffffffffff61387782886128ea565b51169060018101918282116122915773ffffffffffffffffffffffffffffffffffffffff6138a5848a6128ea565b5116906138b28282613b9a565b50916138be84896128ea565b515f525f865273ffffffffffffffffffffffffffffffffffffffff6138f08983856134b3898660405f205416946128ea565b1690604051937f0902f1ac000000000000000000000000000000000000000000000000000000008552606085600481865afa93841561225e57885f965f96613b3d575b5073ffffffffffffffffffffffffffffffffffffffff6dffffffffffffffffffffffffffff806024969798991698169316821496875f14613b375792915b604051948580927f70a082310000000000000000000000000000000000000000000000000000000082528960048301525afa92831561225e575f93613b06575b506139bf826139ca946128d0565b91612fc7888d6128ea565b9215613aff575f92945b8a517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe810190811161229157851015613af657613a11818a6128ea565b515f525f875273ffffffffffffffffffffffffffffffffffffffff60405f205416906002860192838711612291576134b373ffffffffffffffffffffffffffffffffffffffff613a658f96613a6e976128ea565b5116928c6128ea565b905b60405194613a7e8787612682565b5f8652893688880137813b1561049d575f8094613acc8f98604051998a97889687957fd7dc4e43000000000000000000000000000000000000000000000000000000008752600487016132d1565b03925af191821561225e57600192613ae6575b5001613825565b5f613af091612682565b5f613adf565b50508590613a70565b5f946139d4565b92508883813d8311613b30575b613b1d8183612682565b8101031261049d579151916139bf6139b1565b503d613b13565b91613971565b6dffffffffffffffffffffffffffff809850602495969750613b8173ffffffffffffffffffffffffffffffffffffffff9260603d8111612e5957612e458183612682565b50999099989796505050613933565b5050505050509050565b91909173ffffffffffffffffffffffffffffffffffffffff831673ffffffffffffffffffffffffffffffffffffffff8216818114613c26571015613c2157915b9073ffffffffffffffffffffffffffffffffffffffff831615613bf957565b7fd92e233d000000000000000000000000000000000000000000000000000000005f5260045ffd5b613bda565b7fbd969eb0000000000000000000000000000000000000000000000000000000005f5260045ffd5b6040517fa9059cbb000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff909316602482015260448101939093525f928392908390613cb28160648101613234565b51925af1613cbe61316b565b81613cf4575b5015613ccc57565b7f90b8ec18000000000000000000000000000000000000000000000000000000005f5260045ffd5b8051801592508215613d09575b50505f613cc4565b613d1c925060208091830101910161292f565b5f80613d0156fea2646970667358221220ea9276e06c9937cf4ca5969242648d9248cef13ee33ec43e7c88b6c61bf2350264736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000083f4ac7d5d8edfc2103563a7a7347e803a870aaf000000000000000000000000eadd335f1420328e9532d1198170ae7ce21fe3cf000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
-----Decoded View---------------
Arg [0] : _factory0 (address): 0x83F4AC7d5d8EDFC2103563a7a7347e803A870AaF
Arg [1] : _factory1 (address): 0xEadD335f1420328E9532d1198170ae7Ce21Fe3cF
Arg [2] : _WETH (address): 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000083f4ac7d5d8edfc2103563a7a7347e803a870aaf
Arg [1] : 000000000000000000000000eadd335f1420328e9532d1198170ae7ce21fe3cf
Arg [2] : 000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.