Source Code
Overview
S Balance
0 S
More Info
ContractCreator
Latest 25 from a total of 85 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap Exact Token... | 19528601 | 5 mins ago | IN | 0 S | 0.00012108 | ||||
Remove Liquidity | 19521237 | 49 mins ago | IN | 0 S | 0.00014818 | ||||
Remove Liquidity | 19519338 | 1 hr ago | IN | 0 S | 0.00014818 | ||||
Swap Exact Token... | 19514889 | 1 hr ago | IN | 0 S | 0.00012288 | ||||
Add Liquidity | 19512683 | 1 hr ago | IN | 0 S | 0.00014245 | ||||
Add Liquidity | 19512622 | 1 hr ago | IN | 0 S | 0.00014243 | ||||
Swap Exact Token... | 19511729 | 1 hr ago | IN | 0 S | 0.0001229 | ||||
Swap Exact Token... | 19505991 | 2 hrs ago | IN | 0 S | 0.0001229 | ||||
Swap Exact Token... | 19505515 | 2 hrs ago | IN | 0 S | 0.00012289 | ||||
Swap Exact Token... | 19505377 | 2 hrs ago | IN | 0 S | 0.0001229 | ||||
Swap Exact Token... | 19504354 | 2 hrs ago | IN | 0 S | 0.0001229 | ||||
Remove Liquidity | 19117037 | 40 hrs ago | IN | 0 S | 0.00014818 | ||||
Add Liquidity | 19116711 | 40 hrs ago | IN | 0 S | 0.0001493 | ||||
Swap Exact Token... | 19116526 | 40 hrs ago | IN | 0 S | 0.00012634 | ||||
Add Liquidity | 19090754 | 42 hrs ago | IN | 0 S | 0.00014243 | ||||
Remove Liquidity | 19090428 | 42 hrs ago | IN | 0 S | 0.00005378 | ||||
Remove Liquidity | 19090419 | 42 hrs ago | IN | 0 S | 0.00014818 | ||||
Swap Exact Token... | 19090059 | 42 hrs ago | IN | 0 S | 0.00012636 | ||||
Add Liquidity | 19089747 | 42 hrs ago | IN | 0 S | 0.00014933 | ||||
Add Liquidity | 19079062 | 44 hrs ago | IN | 0 S | 0.00014246 | ||||
Add Liquidity | 19078930 | 44 hrs ago | IN | 0 S | 0.00014243 | ||||
Add Liquidity | 19055312 | 46 hrs ago | IN | 0 S | 0.00014243 | ||||
Add Liquidity | 19051155 | 46 hrs ago | IN | 0 S | 0.00031428 | ||||
Add Liquidity | 19048846 | 46 hrs ago | IN | 0 S | 0.00031429 | ||||
Swap Exact Token... | 19047946 | 47 hrs ago | IN | 0 S | 0.0001229 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
19528601 | 5 mins ago | 0 S | ||||
19528601 | 5 mins ago | 0 S | ||||
19528601 | 5 mins ago | 0 S | ||||
19521237 | 49 mins ago | 0 S | ||||
19521237 | 49 mins ago | 0 S | ||||
19519338 | 1 hr ago | 0 S | ||||
19519338 | 1 hr ago | 0 S | ||||
19514889 | 1 hr ago | 0 S | ||||
19514889 | 1 hr ago | 0 S | ||||
19514889 | 1 hr ago | 0 S | ||||
19512683 | 1 hr ago | 0 S | ||||
19512683 | 1 hr ago | 0 S | ||||
19512683 | 1 hr ago | 0 S | ||||
19512683 | 1 hr ago | 0 S | ||||
19512683 | 1 hr ago | 0 S | ||||
19512622 | 1 hr ago | 0 S | ||||
19512622 | 1 hr ago | 0 S | ||||
19512622 | 1 hr ago | 0 S | ||||
19512622 | 1 hr ago | 0 S | ||||
19512622 | 1 hr ago | 0 S | ||||
19511729 | 1 hr ago | 0 S | ||||
19511729 | 1 hr ago | 0 S | ||||
19511729 | 1 hr ago | 0 S | ||||
19505991 | 2 hrs ago | 0 S | ||||
19505991 | 2 hrs ago | 0 S |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
SlsV1Router
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; import "./interfaces/ISlsV1Factory.sol"; import "./interfaces/ISlsV1Pair.sol"; import "./libraries/SlsV1Library.sol"; import "./interfaces/ISLSErrors.sol"; interface IERC20 { function balanceOf(address) external returns (uint256); function transfer(address to, uint256 amount) external; } contract SlsV1Router is IErrors { error ExcessiveInputAmount(); error InsufficientAAmount(); error InsufficientBAmount(); error InsufficientOutputAmount(); error SafeTransferFailed(); ISlsV1Factory factory; modifier ensure(uint deadline) { require( deadline >= block.timestamp, Sls_Router_Error(SlsError.EXPIRED) ); _; } constructor(address _factory) { factory = ISlsV1Factory(_factory); } function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint deadline ) external ensure(deadline) returns (uint256 amountA, uint256 amountB, uint256 liquidity) { if (factory.pairs(tokenA, tokenB) == address(0)) { factory.createPair(tokenA, tokenB); } (amountA, amountB) = _calculateLiquidity( tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin ); address pairAddress = SlsV1Library.pairFor( address(factory), tokenA, tokenB ); _safeTransferFrom(tokenA, msg.sender, pairAddress, amountA); _safeTransferFrom(tokenB, msg.sender, pairAddress, amountB); liquidity = ISlsV1Pair(pairAddress).mint(to); } function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint deadline ) public ensure(deadline) returns (uint256 amountA, uint256 amountB) { address pair = SlsV1Library.pairFor(address(factory), tokenA, tokenB); ISlsV1Pair(pair).transferFrom(msg.sender, pair, liquidity); (uint amount0, uint amount1) = ISlsV1Pair(pair).burn(to); (address token0, ) = SlsV1Library.sortTokens(tokenA, tokenB); (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0); require( amountA >= amountAMin, Sls_Router_Error(SlsError.INSUFFICIENT_A_AMOUNT) ); require( amountB >= amountBMin, Sls_Router_Error(SlsError.INSUFFICIENT_B_AMOUNT) ); } function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint deadline ) external ensure(deadline) returns (uint256[] memory amounts) { amounts = SlsV1Library.getAmountsOut(address(factory), amountIn, path); require( amounts[amounts.length - 1] >= amountOutMin, Sls_Router_Error(SlsError.INSUFFICIENT_OUTPUT_AMOUNT) ); _safeTransferFrom( path[0], msg.sender, SlsV1Library.pairFor(address(factory), path[0], path[1]), amounts[0] ); _swap(amounts, path, to); } function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint deadline ) external ensure(deadline) returns (uint256[] memory amounts) { amounts = SlsV1Library.getAmountsIn(address(factory), amountOut, path); require( amounts[amounts.length - 1] <= amountInMax, Sls_Router_Error(SlsError.EXCESSIVE_INPUT_AMOUNT) ); _safeTransferFrom( path[0], msg.sender, SlsV1Library.pairFor(address(factory), path[0], path[1]), amounts[0] ); _swap(amounts, path, to); } function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external ensure(deadline) { _safeTransferFrom( path[0], msg.sender, SlsV1Library.pairFor(address(factory), path[0], path[1]), amountIn ); uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); _swapSupportingFeeOnTransferTokens(path, to); require( IERC20(path[path.length - 1]).balanceOf(to) - (balanceBefore) >= amountOutMin, "UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT" ); } function _swapSupportingFeeOnTransferTokens( address[] memory path, address _to ) internal virtual { for (uint256 i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0, ) = SlsV1Library.sortTokens(input, output); ISlsV1Pair pair = ISlsV1Pair( SlsV1Library.pairFor(address(factory), input, output) ); uint256 amountInput; uint256 amountOutput; { // scope to avoid stack too deep errors (uint256 reserve0, uint256 reserve1, ) = pair.getReserves(); (uint256 reserveInput, uint256 reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); amountInput = IERC20(input).balanceOf(address(pair)) - (reserveInput); // amountInput = IERC20(input).balanceOf(address(pair)) - (reserveInput); amountOutput = SlsV1Library.getAmountOut( amountInput, reserveInput, reserveOutput ); } (uint256 amount0Out, uint256 amount1Out) = input == token0 ? (uint256(0), amountOutput) : (amountOutput, uint256(0)); address to = i < path.length - 2 ? SlsV1Library.pairFor(address(factory), output, path[i + 2]) : _to; pair.swap(amount0Out, amount1Out, to); } } // // // // PRIVATE // // // function _swap( uint256[] memory amounts, address[] memory path, address to_ ) internal { for (uint256 i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0, ) = SlsV1Library.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 ? SlsV1Library.pairFor(address(factory), output, path[i + 2]) : to_; ISlsV1Pair(SlsV1Library.pairFor(address(factory), input, output)) .swap(amount0Out, amount1Out, to); } } function _calculateLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin ) internal view returns (uint256 amountA, uint256 amountB) { (uint256 reserveA, uint256 reserveB) = SlsV1Library.getReserves( address(factory), tokenA, tokenB ); if (reserveA == 0 && reserveB == 0) { (amountA, amountB) = (amountADesired, amountBDesired); } else { uint256 amountBOptimal = SlsV1Library.quote( amountADesired, reserveA, reserveB ); if (amountBOptimal <= amountBDesired) { require( amountBOptimal >= amountBMin, Sls_Router_Error(SlsError.INSUFFICIENT_B_AMOUNT) ); (amountA, amountB) = (amountADesired, amountBOptimal); } else { uint256 amountAOptimal = SlsV1Library.quote( amountBDesired, reserveB, reserveA ); assert(amountAOptimal <= amountADesired); require( amountAOptimal >= amountAMin, Sls_Router_Error(SlsError.INSUFFICIENT_A_AMOUNT) ); (amountA, amountB) = (amountAOptimal, amountBDesired); } } } function _safeTransferFrom( address token, address from, address to, uint256 value ) private { (bool success, bytes memory data) = token.call( abi.encodeWithSignature( "transferFrom(address,address,uint256)", from, to, value ) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: SAFE_TRANSFER_FROM_FAILED" ); } // **** LIBRARY FUNCTIONS **** function quote( uint amountA, uint reserveA, uint reserveB ) public pure virtual returns (uint amountB) { return SlsV1Library.quote(amountA, reserveA, reserveB); } function getAmountOut( uint amountIn, uint reserveIn, uint reserveOut ) public pure virtual returns (uint amountOut) { return SlsV1Library.getAmountOut(amountIn, reserveIn, reserveOut); } function getAmountIn( uint amountOut, uint reserveIn, uint reserveOut ) public pure virtual returns (uint amountIn) { return SlsV1Library.getAmountIn(amountOut, reserveIn, reserveOut); } function getAmountsOut( uint amountIn, address[] memory path ) public view virtual returns (uint[] memory amounts) { return SlsV1Library.getAmountsOut(address(factory), amountIn, path); } function getAmountsIn( uint amountOut, address[] memory path ) public view virtual returns (uint[] memory amounts) { return SlsV1Library.getAmountsIn(address(factory), amountOut, path); } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; interface ISlsV1Factory { function pairs(address, address) external pure returns (address); function createPair(address, address) external returns (address); function getPair( address tokenA, address tokenB ) external view returns (address pair); function setFeeTo(address) external; function feePool() external view returns (address); }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; interface ISlsV1Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance( address owner, address spender ) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom( address from, address to, uint value ) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit( address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s ) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn( address indexed sender, uint amount0, uint amount1, address indexed to ); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; import "../interfaces/ISlsV1Factory.sol"; import "../interfaces/ISlsV1Pair.sol"; import {SlsV1Pair} from "../SlsV1Pair.sol"; import "../interfaces/ISLSErrors.sol"; library SlsV1Library { error InsufficientAmount(); error InsufficientLiquidity(); error InvalidPath(); function getReserves( address factoryAddress, address tokenA, address tokenB ) internal view returns (uint256 reserveA, uint256 reserveB) { (address token0, address token1) = sortTokens(tokenA, tokenB); (uint256 reserve0, uint256 reserve1, ) = ISlsV1Pair( pairFor(factoryAddress, token0, token1) ).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } function quote( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) internal pure returns (uint256 amountOut) { require( amountIn > 0, IErrors.Sls_Library_Error(IErrors.SlsError.INSUFFICIENT_A_AMOUNT) ); require( reserveIn > 0 && reserveOut > 0, IErrors.Sls_Library_Error(IErrors.SlsError.INSUFFICIENT_LIQUIDITY) ); return (amountIn * reserveOut) / reserveIn; } function sortTokens( address tokenA, address tokenB ) internal pure returns (address token0, address token1) { return tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); } function pairFor( address factoryAddress, address tokenA, address tokenB ) internal pure returns (address pairAddress) { (address token0, address token1) = sortTokens(tokenA, tokenB); pairAddress = address( uint160( uint256( keccak256( abi.encodePacked( hex"ff", factoryAddress, keccak256(abi.encodePacked(token0, token1)), keccak256(type(SlsV1Pair).creationCode) ) ) ) ) ); } function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) internal pure returns (uint256 amountOut) { require( amountIn > 0, IErrors.Sls_Library_Error( IErrors.SlsError.INSUFFICIENT_INPUT_AMOUNT ) ); require( reserveIn > 0 && reserveOut > 0, IErrors.Sls_Library_Error(IErrors.SlsError.INSUFFICIENT_LIQUIDITY) ); uint256 amountInWithFee = amountIn * 997; uint256 numerator = amountInWithFee * reserveOut; uint256 denominator = (reserveIn * 1000) + amountInWithFee; amountOut = numerator / denominator; require( amountOut > 0, IErrors.Sls_Library_Error( IErrors.SlsError.INSUFFICIENT_OUTPUT_AMOUNT ) ); } function getAmountsOut( address factory, uint256 amountIn, address[] memory path ) internal view returns (uint256[] memory) { require( path.length >= 2, IErrors.Sls_Library_Error(IErrors.SlsError.INVALID_PATH) ); uint256[] memory amounts = new uint256[](path.length); amounts[0] = amountIn; for (uint256 i; i < path.length - 1; i++) { (uint256 reserve0, uint256 reserve1) = getReserves( factory, path[i], path[i + 1] ); amounts[i + 1] = getAmountOut(amounts[i], reserve0, reserve1); } return amounts; } function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) internal pure returns (uint256) { require( amountOut > 0, IErrors.Sls_Library_Error( IErrors.SlsError.INSUFFICIENT_OUTPUT_AMOUNT ) ); require( reserveIn > 0 && reserveOut > 0, IErrors.Sls_Library_Error(IErrors.SlsError.INSUFFICIENT_LIQUIDITY) ); uint256 numerator = reserveIn * amountOut * 1000; uint256 denominator = (reserveOut - amountOut) * 997; return (numerator / denominator) + 1; } function getAmountsIn( address factory, uint256 amountOut, address[] memory path ) internal view returns (uint256[] memory) { require( path.length >= 2, IErrors.Sls_Library_Error(IErrors.SlsError.INVALID_PATH) ); uint256[] memory amounts = new uint256[](path.length); amounts[amounts.length - 1] = amountOut; for (uint256 i = path.length - 1; i > 0; i--) { (uint256 reserve0, uint256 reserve1) = getReserves( factory, path[i - 1], path[i] ); amounts[i - 1] = getAmountIn(amounts[i], reserve0, reserve1); } return amounts; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IErrors { enum SlsError { NO_ERROR, // 0 UNAUTHORIZED, // 1 IDENTICAL_ADDRESSES, // 2 ZERO_ADDRESS, // 3 BAD_INPUT, //4 PAIR_EXISTS, // 5 LOCKED, // 6 FORBIDDEN, // 7 TRANSFER_FAILED, // 8 EXPIRED, // 9 INSUFFICIENT_LIQUIDITY, // 10 INSUFFICIENT_INPUT_AMOUNT, // 11 INSUFFICIENT_OUTPUT_AMOUNT, // 12 INSUFFICIENT_A_AMOUNT, // 13 INSUFFICIENT_B_AMOUNT, //14 INVALID_PATH, // 15 INSUFFICIENT_LIQUIDITY_MINTED, // 16 OVERFLOW, // 17 INSUFFICIENT_LIQUIDITY_BURNED, // 18 INVALID_TO, // 19 K_ERROR, // 20 EXCESSIVE_INPUT_AMOUNT, // 21 ALREADY_INITIALIZED // 22 } error Sls_Error(SlsError errorID); error Sls_Router_Error(SlsError errorID); error Sls_Library_Error(SlsError errorID); }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; import "solmate/tokens/ERC20.sol"; import "./libraries/Math.sol"; import "./libraries/UQ112x112.sol"; import "./interfaces/ISLSErrors.sol"; import "./interfaces/ISlsV1Factory.sol"; interface IERC20 { function balanceOf(address) external returns (uint256); function transfer(address to, uint256 amount) external; } error AlreadyInitialized(); contract SlsV1Pair is ERC20, IErrors, Math { using UQ112x112 for uint224; uint256 constant MINIMUM_LIQUIDITY = 1000; address public factory; address public token0; address public token1; uint112 private reserve0; uint112 private reserve1; uint32 private blockTimestampLast; uint256 public price0CumulativeLast; uint256 public price1CumulativeLast; uint public kLast; bool private isEntered; event Burn( address indexed sender, uint256 amount0, uint256 amount1, address to ); event Mint(address indexed sender, uint256 amount0, uint256 amount1); event Sync(uint256 reserve0, uint256 reserve1); event Swap( address indexed sender, uint256 amount0Out, uint256 amount1Out, address indexed to ); modifier nonReentrant() { require(!isEntered, Sls_Error(SlsError.LOCKED)); isEntered = true; _; isEntered = false; } constructor() ERC20("SLS V1", "SLS-V1", 18) { factory = msg.sender; } function initialize(address token0_, address token1_) public { require( token0 == address(0) && token1 == address(0), Sls_Error(SlsError.ALREADY_INITIALIZED) ); require(msg.sender == factory, Sls_Error(SlsError.FORBIDDEN)); token0 = token0_; token1 = token1_; } function mint( address to ) external nonReentrant returns (uint256 liquidity) { (uint112 reserve0_, uint112 reserve1_, ) = getReserves(); uint256 balance0 = IERC20(token0).balanceOf(address(this)); uint256 balance1 = IERC20(token1).balanceOf(address(this)); uint256 amount0 = balance0 - reserve0_; uint256 amount1 = balance1 - reserve1_; bool feeOn = _mintFee(reserve0_, reserve1_); uint256 _totalSupply = totalSupply; if (_totalSupply == 0) { liquidity = Math.sqrt(amount0 * amount1) - MINIMUM_LIQUIDITY; _mint(address(0), MINIMUM_LIQUIDITY); } else { liquidity = Math.min( (amount0 * _totalSupply) / reserve0_, (amount1 * _totalSupply) / reserve1_ ); } require( liquidity > 0, Sls_Error(SlsError.INSUFFICIENT_LIQUIDITY_MINTED) ); _mint(to, liquidity); _update(balance0, balance1, reserve0_, reserve1_); if (feeOn) { kLast = uint256(reserve0_) * uint256(reserve1_); } emit Mint(to, amount0, amount1); } function _mintFee( uint112 _reserve0, uint112 _reserve1 ) private returns (bool feeOn) { address feeTo = ISlsV1Factory(factory).feePool(); feeOn = feeTo != address(0); uint256 _kLast = kLast; if (feeOn) { if (_kLast != 0) { uint256 rootK = Math.sqrt( uint256(_reserve0) * uint256(_reserve1) ); uint256 rootKLast = Math.sqrt(_kLast); if (rootK > rootKLast) { uint256 numerator = totalSupply * (rootK - rootKLast); uint256 denominator = (rootK * 5) + rootKLast; // 0.3% fee >> 1000 - 997 = 3 (based on bps) uint256 feeLiquidity = numerator / denominator; if (feeLiquidity > 0) { _mint(feeTo, feeLiquidity); } } } } else if (_kLast != 0) { kLast = 0; } } function burn( address to ) external nonReentrant returns (uint256 amount0, uint256 amount1) { (uint112 reserve0_, uint112 reserve1_, ) = getReserves(); uint256 balance0 = IERC20(token0).balanceOf(address(this)); uint256 balance1 = IERC20(token1).balanceOf(address(this)); uint256 liquidity = balanceOf[address(this)]; bool feeOn = _mintFee(reserve0_, reserve1_); uint _totalSupply = totalSupply; amount0 = (liquidity * balance0) / _totalSupply; amount1 = (liquidity * balance1) / _totalSupply; require( amount0 > 0 && amount1 > 0, Sls_Error(SlsError.INSUFFICIENT_LIQUIDITY_BURNED) ); _burn(address(this), liquidity); _safeTransfer(token0, to, amount0); _safeTransfer(token1, to, amount1); balance0 = IERC20(token0).balanceOf(address(this)); balance1 = IERC20(token1).balanceOf(address(this)); _update(balance0, balance1, reserve0_, reserve1_); if (feeOn) { kLast = uint(reserve0_) * uint(reserve1_); } emit Burn(msg.sender, amount0, amount1, to); } function swap( uint256 amount0Out, uint256 amount1Out, address to ) external nonReentrant { require( amount0Out > 0 || amount1Out > 0, Sls_Error(SlsError.INSUFFICIENT_OUTPUT_AMOUNT) ); (uint112 reserve0_, uint112 reserve1_, ) = getReserves(); require( amount0Out < reserve0_ && amount1Out < reserve1_, Sls_Error(SlsError.INSUFFICIENT_LIQUIDITY) ); if (amount0Out > 0) _safeTransfer(token0, to, amount0Out); if (amount1Out > 0) _safeTransfer(token1, to, amount1Out); uint256 balance0 = IERC20(token0).balanceOf(address(this)); uint256 balance1 = IERC20(token1).balanceOf(address(this)); uint256 amount0In = balance0 > reserve0 - amount0Out ? balance0 - (reserve0 - amount0Out) : 0; uint256 amount1In = balance1 > reserve1 - amount1Out ? balance1 - (reserve1 - amount1Out) : 0; require( amount0In > 0 || amount1In > 0, Sls_Error(SlsError.INSUFFICIENT_INPUT_AMOUNT) ); // Adjusted = balance before swap - swap fee; fee stays in the contract uint256 balance0Adjusted = (balance0 * 1000) - (amount0In * 3); uint256 balance1Adjusted = (balance1 * 1000) - (amount1In * 3); require( (balance0Adjusted * balance1Adjusted) >= uint256(reserve0_) * uint256(reserve1_) * (1000 ** 2), Sls_Error(SlsError.K_ERROR) ); _update(balance0, balance1, reserve0_, reserve1_); emit Swap(msg.sender, amount0Out, amount1Out, to); } function sync() external nonReentrant { (uint112 reserve0_, uint112 reserve1_, ) = getReserves(); _update( IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0_, reserve1_ ); } function skim(address to) external nonReentrant { address _token0 = token0; // gas savings address _token1 = token1; // gas savings _safeTransfer( _token0, to, IERC20(_token0).balanceOf(address(this)) - (reserve0) ); _safeTransfer( _token1, to, IERC20(_token1).balanceOf(address(this)) - (reserve1) ); } function getReserves() public view returns (uint112, uint112, uint32) { return (reserve0, reserve1, blockTimestampLast); } // // // // PRIVATE // // // function _update( uint256 balance0, uint256 balance1, uint112 reserve0_, uint112 reserve1_ ) private { require( balance0 <= type(uint112).max && balance1 <= type(uint112).max, Sls_Error(SlsError.OVERFLOW) ); unchecked { uint32 timeElapsed = uint32(block.timestamp) - blockTimestampLast; if (timeElapsed > 0 && reserve0_ > 0 && reserve1_ > 0) { price0CumulativeLast += uint256(UQ112x112.encode(reserve1_).uqdiv(reserve0_)) * timeElapsed; price1CumulativeLast += uint256(UQ112x112.encode(reserve0_).uqdiv(reserve1_)) * timeElapsed; } } reserve0 = uint112(balance0); reserve1 = uint112(balance1); blockTimestampLast = uint32(block.timestamp); emit Sync(reserve0, reserve1); } function _safeTransfer(address token, address to, uint256 value) private { (bool success, bytes memory data) = token.call( abi.encodeWithSignature("transfer(address,uint256)", to, value) ); require( success && (data.length == 0 || abi.decode(data, (bool))), Sls_Error(SlsError.TRANSFER_FAILED) ); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; contract Math { function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; library UQ112x112 { uint224 constant Q112 = 2**112; function encode(uint112 y) internal pure returns (uint224 z) { z = uint224(y) * Q112; } function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { z = x / uint224(y); } }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/", "ds-test/=lib/solmate/lib/ds-test/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": true, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ExcessiveInputAmount","type":"error"},{"inputs":[],"name":"InsufficientAAmount","type":"error"},{"inputs":[],"name":"InsufficientBAmount","type":"error"},{"inputs":[],"name":"InsufficientOutputAmount","type":"error"},{"inputs":[],"name":"SafeTransferFailed","type":"error"},{"inputs":[{"internalType":"enum IErrors.SlsError","name":"errorID","type":"uint8"}],"name":"Sls_Error","type":"error"},{"inputs":[{"internalType":"enum IErrors.SlsError","name":"errorID","type":"uint8"}],"name":"Sls_Library_Error","type":"error"},{"inputs":[{"internalType":"enum IErrors.SlsError","name":"errorID","type":"uint8"}],"name":"Sls_Router_Error","type":"error"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"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":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"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[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","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":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"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":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","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":"address","name":"to","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":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608034606f57601f61372a38819003918201601f19168301916001600160401b03831184841017607357808492602094604052833981010312606f57516001600160a01b03811690819003606f575f80546001600160a01b0319169190911790556040516136a290816100888239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040526004361015610011575f80fd5b5f3560e01c8063054d50d414610b0e5780631f00ca7414610ae757806338ed173914610a735780635c11d7951461063b57806385f8c259146106225780638803dbee14610521578063ad615dec14610500578063baa2abde1461036a578063d06ca61f146103335763e8e3370014610087575f80fd5b346101f8576101003660031901126101f8576100a1610b8f565b6100a9610ba5565b60c4356001600160a01b03811692919060643590604435908590036101f8576100d64260e4351015610d07565b5f546040516334a2a5c360e11b81526001600160a01b038681166004830152858116602483015290911690602081604481855afa908115610204575f91610314575b506001600160a01b0316156102a7575b505f546001600160a01b0316916101408486856114bc565b9080158061029f575b1561020f5750505f9561018160209493878761017a61016f6024979a8b959c8d9a61106c565b978880943390611124565b3390611124565b6040516335313c2160e11b815260048101919091529586928391906001600160a01b03165af1908115610204575f916101cb575b6060935060405192835260208301526040820152f35b90506020833d6020116101fc575b816101e660209383610b41565b810103126101f85760609251906101b5565b5f80fd5b3d91506101d9565b6040513d5f823e3d90fd5b61021d828286959495611460565b92828411610255575050505f9561018160209493878761017a61016f60249761024a60a435821015610d3d565b9a8b959c8d9a61106c565b826102639396959450611460565b90811161028b575f95610181602492878761017a61016f60209961024a608435871015610d22565b634e487b7160e01b5f52600160045260245ffd5b508115610149565b6040516364e329cb60e11b81526001600160a01b0386811660048301528516602482015290602090829060449082905f905af180156102045715610128576103069060203d60201161030d575b6102fe8183610b41565b810190610dc2565b505f610128565b503d6102f4565b61032d915060203d60201161030d576102fe8183610b41565b5f610118565b346101f85761036661035a61034736610c16565b5f549091906001600160a01b0316610fd0565b60405191829182610c5a565b0390f35b346101f85760e03660031901126101f857610383610b8f565b61038b610ba5565b60a4356001600160a01b038116908190036101f8576103ae4260c4351015610d07565b6104036103c5838560018060a01b035f541661106c565b6040516323b872dd60e01b81523360048201526001600160a01b03919091166024820181905260448035908301529091602090839081906064820190565b03815f855af18015610204575f936040936024926104d3575b508351948593849263226bf2d160e21b845260048401525af1918215610204575f915f93610495575b5092610453604094826114a1565b506001600160a01b0391821691160361049057905b610476606435831015610d22565b610484608435821015610d3d565b82519182526020820152f35b610468565b915091506040813d6040116104cb575b816104b260409383610b41565b810103126101f857805160209091015191610453610445565b3d91506104a5565b6104f49060203d6020116104f9575b6104ec8183610b41565b810190610daa565b61041c565b503d6104e2565b346101f857602061051961051336610b27565b91611460565b604051908152f35b346101f85761054061053236610c93565b959092939495421115610d07565b5f546001600160a01b0316946105629061055b368487610bbb565b9087610f19565b9384515f19810190811161060e5761057a9086610d72565b51116105fa5780156105e65761058f83610d96565b9261059981610d96565b9180600110156105e6576105d961035a956105c7610366996105e0966105c160208801610d96565b9161106c565b6105d089610d65565b51913390611124565b3691610bbb565b83611245565b634e487b7160e01b5f52603260045260245ffd5b632828070d60e11b5f52601560045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b346101f857602061051961063536610b27565b916113e3565b346101f85761065d61064c36610c93565b959095949194939293421115610d07565b83156105e65761066c83610d96565b5f546001600160a01b0316919061068285610d96565b86600110156105e6576106a79361069f916105c160208901610d96565b903390611124565b5f1983019183831161060e576001600160a01b036106ce6106c9858785610d86565b610d96565b16604051916370a0823160e01b83526020836024815f60018060a01b038c16968760048401525af1928315610204575f93610a3f575b50610710368783610bbb565b945f5b86515f19810190811161060e5781101561095b576001600160a01b036107398289610d72565b5116906001810180821161060e576001600160a01b039061075a908a610d72565b51169161076783826114a1565b505f546001600160a01b03906107829086908590841661106c565b1660405192630240bc6b60e21b8452606084600481855afa928315610204575f945f94610919575b506001600160a01b031681149391925f926001600160701b03918216911685156109105760209091925b6024604051809681936370a0823160e01b83528960048401525af1928315610204575f936108db575b5061080b8161081094610d58565b610e63565b91156108d4575f91935b8a51600119810190811161060e578410156108cc5760018060a01b035f5416600285019182861161060e57610864926001600160a01b039061085c908f610d72565b51169161106c565b905b803b156101f8576040516336cd320560e11b8152600481019390935260248301949094526001600160a01b03166044820152915f908390606490829084905af1918215610204576001926108bc575b5001610713565b5f6108c691610b41565b8a6108b5565b508b90610866565b5f9361081a565b92506020833d8211610908575b816108f560209383610b41565b810103126101f85791519161080b6107fd565b3d91506108e8565b916020906107d4565b6001600160701b0395505f939450610948869160603d8111610954575b6109408183610b41565b8101906113ad565b509096509493506107aa565b503d610936565b509160246020926109796106c95f97968b60018060a01b0394610d86565b169160405195869384926370a0823160e01b845260048401525af18015610204575f90610a0b575b6109ab9250610d58565b106109b257005b60405162461bcd60e51b815260206004820152602b60248201527f556e69737761705632526f757465723a20494e53554646494349454e545f4f5560448201526a1514155517d05353d5539560aa1b6064820152608490fd5b506020823d602011610a37575b81610a2560209383610b41565b810103126101f8576109ab91516109a1565b3d9150610a18565b9092506020813d602011610a6b575b81610a5b60209383610b41565b810103126101f857519187610704565b3d9150610a4e565b346101f857610a8461053236610c93565b5f546001600160a01b031694610aa690610a9f368487610bbb565b9087610fd0565b9384515f19810190811161060e57610abe9086610d72565b5110610ad35780156105e65761058f83610d96565b632828070d60e11b5f52600c60045260245ffd5b346101f85761036661035a610afb36610c16565b5f549091906001600160a01b0316610f19565b346101f8576020610519610b2136610b27565b91610e63565b60609060031901126101f857600435906024359060443590565b90601f8019910116810190811067ffffffffffffffff821117610b6357604052565b634e487b7160e01b5f52604160045260245ffd5b67ffffffffffffffff8111610b635760051b60200190565b600435906001600160a01b03821682036101f857565b602435906001600160a01b03821682036101f857565b9291610bc682610b77565b93610bd46040519586610b41565b602085848152019260051b81019182116101f857915b818310610bf657505050565b82356001600160a01b03811681036101f857815260209283019201610bea565b9060406003198301126101f857600435916024359067ffffffffffffffff82116101f857806023830112156101f857816024610c5793600401359101610bbb565b90565b60206040818301928281528451809452019201905f5b818110610c7d5750505090565b8251845260209384019390920191600101610c70565b9060a06003198301126101f857600435916024359160443567ffffffffffffffff81116101f857826023820112156101f85780600401359267ffffffffffffffff84116101f85760248460051b830101116101f85760240191906064356001600160a01b03811681036101f8579060843590565b15610d0e57565b632828070d60e11b5f52600960045260245ffd5b15610d2957565b632828070d60e11b5f52600d60045260245ffd5b15610d4457565b632828070d60e11b5f52600e60045260245ffd5b9190820391821161060e57565b8051156105e65760200190565b80518210156105e65760209160051b010190565b91908110156105e65760051b0190565b356001600160a01b03811681036101f85790565b908160209103126101f8575180151581036101f85790565b908160209103126101f857516001600160a01b03811681036101f85790565b15610de857565b63ef0bf2bd60e01b5f52600a60045260245ffd5b15610e0357565b63ef0bf2bd60e01b5f52600c60045260245ffd5b15610e1e57565b63ef0bf2bd60e01b5f52600f60045260245ffd5b8181029291811591840414171561060e57565b8115610e4f570490565b634e487b7160e01b5f52601260045260245ffd5b8015610ed357811592831580610eca575b610e7d90610de1565b6103e582029182046103e50361060e57610e979082610e32565b926103e883029283046103e814171561060e57810180911161060e57610ebc91610e45565b90610ec8821515610dfc565b565b50801515610e74565b63ef0bf2bd60e01b5f52600b60045260245ffd5b90610ef182610b77565b610efe6040519182610b41565b8281528092610f0f601f1991610b77565b0190602036910137565b9091610f29600282511015610e17565b610f338151610ee7565b9283515f19810190811161060e57610f4b9085610d72565b5280515f19810190811161060e57805b610f655750505090565b5f19810181811161060e57610fc0610fb9610fa86001600160a01b03610f8b8588610d72565b51166001600160a01b03610f9f8789610d72565b511690886114bc565b90610fb3868a610d72565b516113e3565b9186610d72565b52801561060e575f190180610f5b565b929192610fe1600285511015610e17565b610feb8451610ee7565b91610ff583610d65565b525f5b84515f19810190811161060e57811015611065576001600160a01b0361101e8287610d72565b5116906001810180821161060e5760019261105e90610fb99061104d906001600160a01b03610f9f868d610d72565b90611058868a610d72565b51610e63565b5201610ff8565b5090925050565b91611076916114a1565b6040519060208201926001600160601b03199060601b1683526001600160601b03199060601b166034820152602881526110b1604882610b41565b5190209061210c6040516110c86020830182610b41565b8181526020810191611561833951902060405192602084019260ff60f81b84526001600160601b03199060601b1660218501526035840152605583015260558252611114607583610b41565b905190206001600160a01b031690565b6040516323b872dd60e01b602082019081526001600160a01b0393841660248301529390921660448301526064808301949094529281525f9283929091839061116e608482610b41565b51925af13d1561123e573d67ffffffffffffffff8111610b6357604051906111a0601f8201601f191660200183610b41565b81523d5f602083013e5b8161120f575b50156111b857565b60405162461bcd60e51b815260206004820152602960248201527f5472616e7366657248656c7065723a20534146455f5452414e534645525f465260448201526813d357d1905253115160ba1b6064820152608490fd5b8051801592508215611224575b50505f6111b0565b6112379250602080918301019101610daa565b5f8061121c565b60606111aa565b909291925f5b81515f19810190811161060e57811015611392576001600160a01b036112718284610d72565b5116906001810180821161060e576001600160a01b036112918286610d72565b51166112a86112a082866114a1565b509287610d72565b51916001600160a01b0316840361138b575f91935b8551600119810190811161060e57841015611381575f546001600160a01b03166002850180861161060e5761131a916113059185906001600160a01b039061085c908c610d72565b925b5f546001600160a01b039390841661106c565b16803b156101f8576040516336cd320560e11b8152600481019390935260248301949094526001600160a01b03166044820152915f908390606490829084905af191821561020457600192611371575b500161124b565b5f61137b91610b41565b5f61136a565b61131a8992611307565b5f936112bd565b5050509050565b51906001600160701b03821682036101f857565b908160609103126101f8576113c181611399565b9160406113d060208401611399565b92015163ffffffff811681036101f85790565b91908261140c916113f5821515610dfc565b80151580611457575b61140790610de1565b610e32565b916103e88302928084046103e8149015171561060e5761142b91610d58565b6103e58102908082046103e5149015171561060e5761144991610e45565b6001810180911161060e5790565b508315156113fe565b801561148d57610c579261147f91831515806114845761140790610de1565b610e45565b508115156113fe565b63ef0bf2bd60e01b5f52600d60045260245ffd5b9091906001600160a01b038084169082161015610c57579190565b9060606004926114cf6114e495846114a1565b90956001600160a01b0392909190879061106c565b1660405193848092630240bc6b60e21b82525afa918215610204575f905f93611531575b506001600160701b03928316939216916001600160a01b0391821691160361152d5791565b9091565b6001600160701b0393508391506115569060603d606011610954576109408183610b41565b509390915061150856fe60e0604052346103ea576040516100176040826103ee565b6006815265534c5320563160d01b60208201526040516100386040826103ee565b6006815265534c532d563160d01b602082015281516001600160401b03811161031d576100655f54610411565b601f811161039b575b50602092601f821160011461033c57928192935f92610331575b50508160011b915f199060031b1c1916175f555b80516001600160401b03811161031d576100b7600154610411565b601f81116102ba575b50602091601f821160011461025a579181925f9261024f575b50508160011b915f199060031b1c1916176001555b60126080524660a0526040515f905f54918161010984610411565b9182825260208201946001811690815f1461023357506001146101e9575b610133925003826103ee565b51902060405160208101917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f835260408201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a081526101a760c0826103ee565b51902060c052600680546001600160a01b03191633179055604051611ca2908161044a8239608051816112d5015260a0518161165f015260c051816116850152f35b505f80805290915f805160206120ec8339815191525b81831061021757505090602061013392820101610127565b60209193508060019154838588010152019101909183926101ff565b60ff191686525061013392151560051b82016020019050610127565b015190505f806100d9565b601f1982169260015f52805f20915f5b8581106102a25750836001951061028a575b505050811b016001556100ee565b01515f1960f88460031b161c191690555f808061027c565b9192602060018192868501518155019401920161026a565b60015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6601f830160051c81019160208410610313575b601f0160051c01905b81811061030857506100c0565b5f81556001016102fb565b90915081906102f2565b634e487b7160e01b5f52604160045260245ffd5b015190505f80610088565b601f198216935f8052805f20915f5b868110610383575083600195961061036b575b505050811b015f5561009c565b01515f1960f88460031b161c191690555f808061035e565b9192602060018192868501518155019401920161034b565b5f80525f805160206120ec833981519152601f830160051c810191602084106103e0575b601f0160051c01905b8181106103d5575061006e565b5f81556001016103c8565b90915081906103bf565b5f80fd5b601f909101601f19168101906001600160401b0382119082101761031d57604052565b90600182811c9216801561043f575b602083101461042b57565b634e487b7160e01b5f52602260045260245ffd5b91607f169161042056fe60806040526004361015610011575f80fd5b5f3560e01c806306fdde03146114c75780630902f1ac14611487578063095ea7b31461140e5780630dfe1681146113e657806318160ddd146113c957806323b872dd146112f9578063313ce567146112bc5780633644e5151461129a578063485cc955146111e55780635909c0d5146111c85780635a3d5493146111ab5780636a62784214610f245780636d9a640a14610b8157806370a0823114610b495780637464fc3d14610b2c5780637ecebe0014610af457806389afcb441461079a57806395d89b41146106c0578063a9059cbb1461064b578063bc25cf77146104ff578063c45a0155146104d7578063d21220a7146104af578063d505accf146102b0578063dd62ed3e146102605763fff6cae91461012c575f80fd5b34610217575f366003190112610217576001600d5461014e60ff8216156117d6565b60ff191617600d555f61015f61162d565b5090602060018060a01b03600754166024604051809681936370a0823160e01b83523060048401525af18015610223575f9061022e575b6008546040516370a0823160e01b81523060048201529450602090859060249082905f906001600160a01b03165af1908115610223575f916101e9575b6101dd94506119fd565b600d805460ff19169055005b90506020843d60201161021b575b81610204602093836115a1565b81010312610217576101dd9351906101d3565b5f80fd5b3d91506101f7565b6040513d5f823e3d90fd5b506020833d602011610258575b81610248602093836115a1565b81010312610217575f9251610196565b3d915061023b565b3461021757604036600319011261021757610279611601565b610281611617565b6001600160a01b039182165f908152600460209081526040808320949093168252928352819020549051908152f35b346102175760e0366003190112610217576102c9611601565b6102d1611617565b6044356064359260843560ff81168091036102175742851061046a5760805f916020936102fc61165c565b9060018060a01b03169687855260058652604085209889549960018b01905560405190878201927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c984528a604084015260018060a01b03169a8b6060840152898784015260a083015260c082015260c0815261037960e0826115a1565b519020604051908682019261190160f01b845260228301526042820152604281526103a56062826115a1565b519020906040519182528482015260a435604082015260c435606082015282805260015afa15610223575f516001600160a01b031680151580610461575b1561042b577f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925916020915f526004825260405f20855f5282528060405f2055604051908152a3005b60405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606490fd5b508281146103e3565b60405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606490fd5b34610217575f366003190112610217576008546040516001600160a01b039091168152602090f35b34610217575f366003190112610217576006546040516001600160a01b039091168152602090f35b3461021757602036600319011261021757610518611601565b6001600d5461052a60ff8216156117d6565b60ff191617600d556007546008546040516370a0823160e01b81523060048201526001600160a01b03918216929091166020826024815f855af19182156102235784905f93610613575b5061058e610594936001600160701b03600954169061164f565b91611b21565b6040516370a0823160e01b8152306004820152916020836024815f865af1928315610223575f936105dd575b5061058e6101dd936001600160701b0360095460701c169061164f565b92506020833d60201161060b575b816105f8602093836115a1565b810103126102175791519161058e6105c0565b3d91506105eb565b9250506020823d602011610643575b8161062f602093836115a1565b81010312610217579051908361058e610574565b3d9150610622565b3461021757604036600319011261021757610664611601565b60243590335f52600360205260405f2061067f83825461164f565b905560018060a01b031690815f52600360205260405f208181540190556040519081525f80516020611c4d83398151915260203392a3602060405160018152f35b34610217575f366003190112610217576040515f6001546106e081611569565b80845290600181169081156107765750600114610718575b61071483610708818503826115a1565b604051918291826115d7565b0390f35b60015f9081527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6939250905b80821061075c575090915081016020016107086106f8565b919260018160209254838588010152019101909291610744565b60ff191660208086019190915291151560051b8401909101915061070890506106f8565b34610217576020366003190112610217576107b3611601565b6001600d546107c560ff8216156117d6565b60ff191617600d555f6107d661162d565b509092602060018060a01b03600754166024604051809681936370a0823160e01b83523060048401525af1918215610223575f92610ac0575b6008546040516370a0823160e01b81523060048201529450602090859060249082905f906001600160a01b03165af1938415610223575f94610a8c575b50305f52600360205260405f20549461088a61087e61087e610883610871868661182f565b976002549384918c6117f1565b611804565b97896117f1565b9385151580610a83575b15610a6f575f80973082526003602052604082206108b382825461164f565b905580600254036002556040519081525f80516020611c4d83398151915260203092a36007546108ef90879086906001600160a01b0316611b21565b60085461090890869086906001600160a01b0316611b21565b6007546040516370a0823160e01b81523060048201529760209189916024918391906001600160a01b03165af1968715610223575f97610a3b575b506008546040516370a0823160e01b815230600482015290602090829060249082905f906001600160a01b03165af1908115610223575f91610a09575b50838361098f9260409a6119fd565b6109ea575b505083519083825282602083015260018060a01b0316848201527fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d8193649660603392a260ff19600d5416600d5582519182526020820152f35b6001600160701b03806109ff931691166117f1565b600c558480610994565b90506020813d602011610a33575b81610a24602093836115a1565b81010312610217575183610980565b3d9150610a17565b9096506020813d602011610a67575b81610a57602093836115a1565b8101031261021757519587610943565b3d9150610a4a565b637a52fb5d60e01b5f52601260045260245ffd5b50841515610894565b9093506020813d602011610ab8575b81610aa8602093836115a1565b810103126102175751928561084c565b3d9150610a9b565b91506020833d602011610aec575b81610adb602093836115a1565b81010312610217575f92519161080f565b3d9150610ace565b34610217576020366003190112610217576001600160a01b03610b15611601565b165f526005602052602060405f2054604051908152f35b34610217575f366003190112610217576020600c54604051908152f35b34610217576020366003190112610217576001600160a01b03610b6a611601565b165f526003602052602060405f2054604051908152f35b34610217576060366003190112610217576044356001600160a01b038116906004359060243590838103610217576001600d54610bc160ff8216156117d6565b60ff191617600d5582159081158092610f1b575b15610f0757610be261162d565b50916001600160701b0382169081871080610ef5575b15610ee1575f94610ec3575b8580610ea6575b50506007546040516370a0823160e01b81523060048201529460209186916024918391906001600160a01b03165af1938415610223575f94610e72575b506008546040516370a0823160e01b81523060048201529190602090839060249082905f906001600160a01b03165af1918215610223575f92610e3e575b50600954866001600160701b03821689610ca0818361164f565b891115610e2d57610cbc610cc2916001600160701b039361164f565b8961164f565b925b60701c16610cd2828261164f565b851115610e2457610cec91610ce69161164f565b8461164f565b905b801590811582610e1b575b15610e07576103e88802918883046103e81489151715610df357600382029182046003141715610df357610d2c9161164f565b906103e88402918483046103e81485151715610df357600382029180830460031490151715610df357610d65610d6b92610d7c9461164f565b906117f1565b916001600160701b038616906117f1565b90620f4240820291808304620f42401490151715610df35710610ddf57610da2936119fd565b60405191825260208201527f2a9237ff5aa599ef4c5ee4b1142b53429d5755e2685fe6288b2e3320202115f560403392a3600d805460ff19169055005b637a52fb5d60e01b5f52601460045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b637a52fb5d60e01b5f52600b60045260245ffd5b50821515610cf9565b50505f90610cee565b50506001600160701b035f92610cc4565b9091506020813d602011610e6a575b81610e5a602093836115a1565b8101031261021757519088610c86565b3d9150610e4d565b9093506020813d602011610e9e575b81610e8e602093836115a1565b810103126102175751925f610c48565b3d9150610e81565b600854610ebc92906001600160a01b0316611b21565b8785610c0b565b600754610edc90889083906001600160a01b0316611b21565b610c04565b637a52fb5d60e01b5f52600a60045260245ffd5b506001600160701b0384168610610bf8565b637a52fb5d60e01b5f52600c60045260245ffd5b50821515610bd5565b3461021757602036600319011261021757610f3d611601565b6001600d54610f4f60ff8216156117d6565b60ff191617600d555f610f6061162d565b509290602060018060a01b03600754166024604051809681936370a0823160e01b83523060048401525af1928315610223575f93611177575b506008546040516370a0823160e01b815230600482015290602090829060249082905f906001600160a01b03165af1908115610223575f91611145575b506001600160701b03821692610fec848661164f565b936001600160701b03871690611002828561164f565b9161100d898761182f565b6002548883858361111357505061102e915085611029916117f1565b611964565b6103e7198101908111610df357986002546103e88101809111610df3576002555f8052600360205260405f206103e881540190555f805f80516020611c4d83398151915260206040516103e88152a35b89156110ff5760209a7f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f986040986110bf936110ba8e8b6119b9565b6119fd565b6110ec575b50508251948552868501526001600160a01b031692a260ff19600d5416600d55604051908152f35b6110f5916117f1565b600c5587806110c4565b637a52fb5d60e01b5f52601060045260245ffd5b61112761087e9161087e8661112e966117f1565b93886117f1565b8082101561113e57505b9861107e565b9050611138565b90506020813d60201161116f575b81611160602093836115a1565b81010312610217575185610fd6565b3d9150611153565b9092506020813d6020116111a3575b81611193602093836115a1565b8101031261021757519184610f99565b3d9150611186565b34610217575f366003190112610217576020600b54604051908152f35b34610217575f366003190112610217576020600a54604051908152f35b34610217576040366003190112610217576111fe611601565b611206611617565b60075490916001600160a01b0382161580611287575b15611273576006546001600160a01b0316330361125f576001600160a01b03199182166001600160a01b0391821617600755600880549092169216919091179055005b637a52fb5d60e01b5f52600760045260245ffd5b637a52fb5d60e01b5f52601660045260245ffd5b506008546001600160a01b03161561121c565b34610217575f3660031901126102175760206112b461165c565b604051908152f35b34610217575f36600319011261021757602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461021757606036600319011261021757611312611601565b61131a611617565b6001600160a01b039091165f818152600460209081526040808320338452825290912054604435935f80516020611c4d833981519152929185600182016113a4575b5050835f526003825260405f2061137486825461164f565b90556001600160a01b03165f818152600383526040908190208054870190555194855293a3602060405160018152f35b6113ad9161164f565b5f8581526004845260408082203383528552902055858561135c565b34610217575f366003190112610217576020600254604051908152f35b34610217575f366003190112610217576007546040516001600160a01b039091168152602090f35b3461021757604036600319011261021757611427611601565b335f8181526004602090815260408083206001600160a01b03909516808452948252918290206024359081905591519182527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a3602060405160018152f35b34610217575f3660031901126102175760606001600160701b0363ffffffff6114ae61162d565b9193908160405195168552166020840152166040820152f35b34610217575f366003190112610217576040515f80546114e681611569565b8084529060018116908115610776575060011461150d5761071483610708818503826115a1565b5f8080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563939250905b80821061154f575090915081016020016107086106f8565b919260018160209254838588010152019101909291611537565b90600182811c92168015611597575b602083101461158357565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611578565b90601f8019910116810190811067ffffffffffffffff8211176115c357604052565b634e487b7160e01b5f52604160045260245ffd5b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361021757565b602435906001600160a01b038216820361021757565b6009546001600160701b038116916001600160701b038260701c169160e01c90565b91908203918211610df357565b467f0000000000000000000000000000000000000000000000000000000000000000036116a7577f000000000000000000000000000000000000000000000000000000000000000090565b6040515f905f5491816116b984611569565b9182825260208201946001811690815f146117ba575060011461175d575b6116e3925003826115a1565b51902060405160208101917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f835260408201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a0815261175760c0826115a1565b51902090565b505f80805290917f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b81831061179e5750509060206116e3928201016116d7565b6020919350806001915483858801015201910190918392611786565b60ff19168652506116e392151560051b820160200190506116d7565b156117dd57565b637a52fb5d60e01b5f52600660045260245ffd5b81810292918115918404141715610df357565b811561180e570490565b634e487b7160e01b5f52601260045260245ffd5b91908201809211610df357565b60065460405163ae2e933b60e01b81529293929190602090839060049082906001600160a01b03165afa918215610223575f92611920575b50600c546001600160a01b03831615801595919290611910578261188c575b50505050565b6110296118a8916001600160701b03806118ae951691166117f1565b91611964565b908181116118bd575b80611886565b6118cd600254610d65848461164f565b90600581029080820460051490151715610df3576118f4926118ee91611822565b90611804565b80611900575b806118b7565b611909916119b9565b5f806118fa565b5050905061191a57565b5f600c55565b9091506020813d60201161195c575b8161193c602093836115a1565b8101031261021757516001600160a01b038116810361021757905f611867565b3d915061192f565b905f60038311156119ac5750818060011c60018101809111610df357905b83821061198d575050565b9092506119a38361199e8184611804565b611822565b60011c90611982565b916119b357565b60019150565b5f80516020611c4d83398151915260205f926119d785600254611822565b6002556001600160a01b03168084526003825260408085208054870190555194855293a3565b91926001600160701b0383111580611b10575b15611afc576001600160701b0360409381927fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a9663ffffffff60095460e01c81421603169182151580611af1575b80611ae6575b611a9d575b50505016918263ffffffff60e01b4260e01b16918360701b9060701b16171780600955835192835260701c166020820152a1565b611ad590836001600160e01b03611abc85611ab785611bf8565b611c2e565b1602600a5401600a55611ab760018060e01b0393611bf8565b1602600b5401600b555f8080611a69565b508481161515611a64565b508482161515611a5e565b637a52fb5d60e01b5f52601160045260245ffd5b506001600160701b03821115611a10565b5f929183809360405190602082019363a9059cbb60e01b855260018060a01b03166024830152604482015260448152611b5b6064826115a1565b51925af13d15611bf1573d67ffffffffffffffff81116115c35760405190611b8d601f8201601f1916602001836115a1565b81523d5f602083013e5b81611bb9575b5015611ba557565b637a52fb5d60e01b5f52600860045260245ffd5b8051801592508215611bce575b50505f611b9d565b819250906020918101031261021757602001518015158103610217575f80611bc6565b6060611b97565b6dffffffffffffffffffffffffffff60701b607082901b16906001600160701b0316808204600160701b1490151715610df35790565b906001600160701b031690811561180e576001600160e01b0316049056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212209be4b1e4c827f9e2fa05ea9e23112b87991050e3fcdeac2858a3cf79e8fb534e64736f6c634300081a0033290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563a264697066735822122031979ab6b6229909450487e057b58aae326f257996b49eb8a4ab9c0bb12dfdc464736f6c634300081a003300000000000000000000000053c8668ca4d913749ce0af7126ef419eb8729882
Deployed Bytecode
0x60806040526004361015610011575f80fd5b5f3560e01c8063054d50d414610b0e5780631f00ca7414610ae757806338ed173914610a735780635c11d7951461063b57806385f8c259146106225780638803dbee14610521578063ad615dec14610500578063baa2abde1461036a578063d06ca61f146103335763e8e3370014610087575f80fd5b346101f8576101003660031901126101f8576100a1610b8f565b6100a9610ba5565b60c4356001600160a01b03811692919060643590604435908590036101f8576100d64260e4351015610d07565b5f546040516334a2a5c360e11b81526001600160a01b038681166004830152858116602483015290911690602081604481855afa908115610204575f91610314575b506001600160a01b0316156102a7575b505f546001600160a01b0316916101408486856114bc565b9080158061029f575b1561020f5750505f9561018160209493878761017a61016f6024979a8b959c8d9a61106c565b978880943390611124565b3390611124565b6040516335313c2160e11b815260048101919091529586928391906001600160a01b03165af1908115610204575f916101cb575b6060935060405192835260208301526040820152f35b90506020833d6020116101fc575b816101e660209383610b41565b810103126101f85760609251906101b5565b5f80fd5b3d91506101d9565b6040513d5f823e3d90fd5b61021d828286959495611460565b92828411610255575050505f9561018160209493878761017a61016f60249761024a60a435821015610d3d565b9a8b959c8d9a61106c565b826102639396959450611460565b90811161028b575f95610181602492878761017a61016f60209961024a608435871015610d22565b634e487b7160e01b5f52600160045260245ffd5b508115610149565b6040516364e329cb60e11b81526001600160a01b0386811660048301528516602482015290602090829060449082905f905af180156102045715610128576103069060203d60201161030d575b6102fe8183610b41565b810190610dc2565b505f610128565b503d6102f4565b61032d915060203d60201161030d576102fe8183610b41565b5f610118565b346101f85761036661035a61034736610c16565b5f549091906001600160a01b0316610fd0565b60405191829182610c5a565b0390f35b346101f85760e03660031901126101f857610383610b8f565b61038b610ba5565b60a4356001600160a01b038116908190036101f8576103ae4260c4351015610d07565b6104036103c5838560018060a01b035f541661106c565b6040516323b872dd60e01b81523360048201526001600160a01b03919091166024820181905260448035908301529091602090839081906064820190565b03815f855af18015610204575f936040936024926104d3575b508351948593849263226bf2d160e21b845260048401525af1918215610204575f915f93610495575b5092610453604094826114a1565b506001600160a01b0391821691160361049057905b610476606435831015610d22565b610484608435821015610d3d565b82519182526020820152f35b610468565b915091506040813d6040116104cb575b816104b260409383610b41565b810103126101f857805160209091015191610453610445565b3d91506104a5565b6104f49060203d6020116104f9575b6104ec8183610b41565b810190610daa565b61041c565b503d6104e2565b346101f857602061051961051336610b27565b91611460565b604051908152f35b346101f85761054061053236610c93565b959092939495421115610d07565b5f546001600160a01b0316946105629061055b368487610bbb565b9087610f19565b9384515f19810190811161060e5761057a9086610d72565b51116105fa5780156105e65761058f83610d96565b9261059981610d96565b9180600110156105e6576105d961035a956105c7610366996105e0966105c160208801610d96565b9161106c565b6105d089610d65565b51913390611124565b3691610bbb565b83611245565b634e487b7160e01b5f52603260045260245ffd5b632828070d60e11b5f52601560045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b346101f857602061051961063536610b27565b916113e3565b346101f85761065d61064c36610c93565b959095949194939293421115610d07565b83156105e65761066c83610d96565b5f546001600160a01b0316919061068285610d96565b86600110156105e6576106a79361069f916105c160208901610d96565b903390611124565b5f1983019183831161060e576001600160a01b036106ce6106c9858785610d86565b610d96565b16604051916370a0823160e01b83526020836024815f60018060a01b038c16968760048401525af1928315610204575f93610a3f575b50610710368783610bbb565b945f5b86515f19810190811161060e5781101561095b576001600160a01b036107398289610d72565b5116906001810180821161060e576001600160a01b039061075a908a610d72565b51169161076783826114a1565b505f546001600160a01b03906107829086908590841661106c565b1660405192630240bc6b60e21b8452606084600481855afa928315610204575f945f94610919575b506001600160a01b031681149391925f926001600160701b03918216911685156109105760209091925b6024604051809681936370a0823160e01b83528960048401525af1928315610204575f936108db575b5061080b8161081094610d58565b610e63565b91156108d4575f91935b8a51600119810190811161060e578410156108cc5760018060a01b035f5416600285019182861161060e57610864926001600160a01b039061085c908f610d72565b51169161106c565b905b803b156101f8576040516336cd320560e11b8152600481019390935260248301949094526001600160a01b03166044820152915f908390606490829084905af1918215610204576001926108bc575b5001610713565b5f6108c691610b41565b8a6108b5565b508b90610866565b5f9361081a565b92506020833d8211610908575b816108f560209383610b41565b810103126101f85791519161080b6107fd565b3d91506108e8565b916020906107d4565b6001600160701b0395505f939450610948869160603d8111610954575b6109408183610b41565b8101906113ad565b509096509493506107aa565b503d610936565b509160246020926109796106c95f97968b60018060a01b0394610d86565b169160405195869384926370a0823160e01b845260048401525af18015610204575f90610a0b575b6109ab9250610d58565b106109b257005b60405162461bcd60e51b815260206004820152602b60248201527f556e69737761705632526f757465723a20494e53554646494349454e545f4f5560448201526a1514155517d05353d5539560aa1b6064820152608490fd5b506020823d602011610a37575b81610a2560209383610b41565b810103126101f8576109ab91516109a1565b3d9150610a18565b9092506020813d602011610a6b575b81610a5b60209383610b41565b810103126101f857519187610704565b3d9150610a4e565b346101f857610a8461053236610c93565b5f546001600160a01b031694610aa690610a9f368487610bbb565b9087610fd0565b9384515f19810190811161060e57610abe9086610d72565b5110610ad35780156105e65761058f83610d96565b632828070d60e11b5f52600c60045260245ffd5b346101f85761036661035a610afb36610c16565b5f549091906001600160a01b0316610f19565b346101f8576020610519610b2136610b27565b91610e63565b60609060031901126101f857600435906024359060443590565b90601f8019910116810190811067ffffffffffffffff821117610b6357604052565b634e487b7160e01b5f52604160045260245ffd5b67ffffffffffffffff8111610b635760051b60200190565b600435906001600160a01b03821682036101f857565b602435906001600160a01b03821682036101f857565b9291610bc682610b77565b93610bd46040519586610b41565b602085848152019260051b81019182116101f857915b818310610bf657505050565b82356001600160a01b03811681036101f857815260209283019201610bea565b9060406003198301126101f857600435916024359067ffffffffffffffff82116101f857806023830112156101f857816024610c5793600401359101610bbb565b90565b60206040818301928281528451809452019201905f5b818110610c7d5750505090565b8251845260209384019390920191600101610c70565b9060a06003198301126101f857600435916024359160443567ffffffffffffffff81116101f857826023820112156101f85780600401359267ffffffffffffffff84116101f85760248460051b830101116101f85760240191906064356001600160a01b03811681036101f8579060843590565b15610d0e57565b632828070d60e11b5f52600960045260245ffd5b15610d2957565b632828070d60e11b5f52600d60045260245ffd5b15610d4457565b632828070d60e11b5f52600e60045260245ffd5b9190820391821161060e57565b8051156105e65760200190565b80518210156105e65760209160051b010190565b91908110156105e65760051b0190565b356001600160a01b03811681036101f85790565b908160209103126101f8575180151581036101f85790565b908160209103126101f857516001600160a01b03811681036101f85790565b15610de857565b63ef0bf2bd60e01b5f52600a60045260245ffd5b15610e0357565b63ef0bf2bd60e01b5f52600c60045260245ffd5b15610e1e57565b63ef0bf2bd60e01b5f52600f60045260245ffd5b8181029291811591840414171561060e57565b8115610e4f570490565b634e487b7160e01b5f52601260045260245ffd5b8015610ed357811592831580610eca575b610e7d90610de1565b6103e582029182046103e50361060e57610e979082610e32565b926103e883029283046103e814171561060e57810180911161060e57610ebc91610e45565b90610ec8821515610dfc565b565b50801515610e74565b63ef0bf2bd60e01b5f52600b60045260245ffd5b90610ef182610b77565b610efe6040519182610b41565b8281528092610f0f601f1991610b77565b0190602036910137565b9091610f29600282511015610e17565b610f338151610ee7565b9283515f19810190811161060e57610f4b9085610d72565b5280515f19810190811161060e57805b610f655750505090565b5f19810181811161060e57610fc0610fb9610fa86001600160a01b03610f8b8588610d72565b51166001600160a01b03610f9f8789610d72565b511690886114bc565b90610fb3868a610d72565b516113e3565b9186610d72565b52801561060e575f190180610f5b565b929192610fe1600285511015610e17565b610feb8451610ee7565b91610ff583610d65565b525f5b84515f19810190811161060e57811015611065576001600160a01b0361101e8287610d72565b5116906001810180821161060e5760019261105e90610fb99061104d906001600160a01b03610f9f868d610d72565b90611058868a610d72565b51610e63565b5201610ff8565b5090925050565b91611076916114a1565b6040519060208201926001600160601b03199060601b1683526001600160601b03199060601b166034820152602881526110b1604882610b41565b5190209061210c6040516110c86020830182610b41565b8181526020810191611561833951902060405192602084019260ff60f81b84526001600160601b03199060601b1660218501526035840152605583015260558252611114607583610b41565b905190206001600160a01b031690565b6040516323b872dd60e01b602082019081526001600160a01b0393841660248301529390921660448301526064808301949094529281525f9283929091839061116e608482610b41565b51925af13d1561123e573d67ffffffffffffffff8111610b6357604051906111a0601f8201601f191660200183610b41565b81523d5f602083013e5b8161120f575b50156111b857565b60405162461bcd60e51b815260206004820152602960248201527f5472616e7366657248656c7065723a20534146455f5452414e534645525f465260448201526813d357d1905253115160ba1b6064820152608490fd5b8051801592508215611224575b50505f6111b0565b6112379250602080918301019101610daa565b5f8061121c565b60606111aa565b909291925f5b81515f19810190811161060e57811015611392576001600160a01b036112718284610d72565b5116906001810180821161060e576001600160a01b036112918286610d72565b51166112a86112a082866114a1565b509287610d72565b51916001600160a01b0316840361138b575f91935b8551600119810190811161060e57841015611381575f546001600160a01b03166002850180861161060e5761131a916113059185906001600160a01b039061085c908c610d72565b925b5f546001600160a01b039390841661106c565b16803b156101f8576040516336cd320560e11b8152600481019390935260248301949094526001600160a01b03166044820152915f908390606490829084905af191821561020457600192611371575b500161124b565b5f61137b91610b41565b5f61136a565b61131a8992611307565b5f936112bd565b5050509050565b51906001600160701b03821682036101f857565b908160609103126101f8576113c181611399565b9160406113d060208401611399565b92015163ffffffff811681036101f85790565b91908261140c916113f5821515610dfc565b80151580611457575b61140790610de1565b610e32565b916103e88302928084046103e8149015171561060e5761142b91610d58565b6103e58102908082046103e5149015171561060e5761144991610e45565b6001810180911161060e5790565b508315156113fe565b801561148d57610c579261147f91831515806114845761140790610de1565b610e45565b508115156113fe565b63ef0bf2bd60e01b5f52600d60045260245ffd5b9091906001600160a01b038084169082161015610c57579190565b9060606004926114cf6114e495846114a1565b90956001600160a01b0392909190879061106c565b1660405193848092630240bc6b60e21b82525afa918215610204575f905f93611531575b506001600160701b03928316939216916001600160a01b0391821691160361152d5791565b9091565b6001600160701b0393508391506115569060603d606011610954576109408183610b41565b509390915061150856fe60e0604052346103ea576040516100176040826103ee565b6006815265534c5320563160d01b60208201526040516100386040826103ee565b6006815265534c532d563160d01b602082015281516001600160401b03811161031d576100655f54610411565b601f811161039b575b50602092601f821160011461033c57928192935f92610331575b50508160011b915f199060031b1c1916175f555b80516001600160401b03811161031d576100b7600154610411565b601f81116102ba575b50602091601f821160011461025a579181925f9261024f575b50508160011b915f199060031b1c1916176001555b60126080524660a0526040515f905f54918161010984610411565b9182825260208201946001811690815f1461023357506001146101e9575b610133925003826103ee565b51902060405160208101917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f835260408201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a081526101a760c0826103ee565b51902060c052600680546001600160a01b03191633179055604051611ca2908161044a8239608051816112d5015260a0518161165f015260c051816116850152f35b505f80805290915f805160206120ec8339815191525b81831061021757505090602061013392820101610127565b60209193508060019154838588010152019101909183926101ff565b60ff191686525061013392151560051b82016020019050610127565b015190505f806100d9565b601f1982169260015f52805f20915f5b8581106102a25750836001951061028a575b505050811b016001556100ee565b01515f1960f88460031b161c191690555f808061027c565b9192602060018192868501518155019401920161026a565b60015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6601f830160051c81019160208410610313575b601f0160051c01905b81811061030857506100c0565b5f81556001016102fb565b90915081906102f2565b634e487b7160e01b5f52604160045260245ffd5b015190505f80610088565b601f198216935f8052805f20915f5b868110610383575083600195961061036b575b505050811b015f5561009c565b01515f1960f88460031b161c191690555f808061035e565b9192602060018192868501518155019401920161034b565b5f80525f805160206120ec833981519152601f830160051c810191602084106103e0575b601f0160051c01905b8181106103d5575061006e565b5f81556001016103c8565b90915081906103bf565b5f80fd5b601f909101601f19168101906001600160401b0382119082101761031d57604052565b90600182811c9216801561043f575b602083101461042b57565b634e487b7160e01b5f52602260045260245ffd5b91607f169161042056fe60806040526004361015610011575f80fd5b5f3560e01c806306fdde03146114c75780630902f1ac14611487578063095ea7b31461140e5780630dfe1681146113e657806318160ddd146113c957806323b872dd146112f9578063313ce567146112bc5780633644e5151461129a578063485cc955146111e55780635909c0d5146111c85780635a3d5493146111ab5780636a62784214610f245780636d9a640a14610b8157806370a0823114610b495780637464fc3d14610b2c5780637ecebe0014610af457806389afcb441461079a57806395d89b41146106c0578063a9059cbb1461064b578063bc25cf77146104ff578063c45a0155146104d7578063d21220a7146104af578063d505accf146102b0578063dd62ed3e146102605763fff6cae91461012c575f80fd5b34610217575f366003190112610217576001600d5461014e60ff8216156117d6565b60ff191617600d555f61015f61162d565b5090602060018060a01b03600754166024604051809681936370a0823160e01b83523060048401525af18015610223575f9061022e575b6008546040516370a0823160e01b81523060048201529450602090859060249082905f906001600160a01b03165af1908115610223575f916101e9575b6101dd94506119fd565b600d805460ff19169055005b90506020843d60201161021b575b81610204602093836115a1565b81010312610217576101dd9351906101d3565b5f80fd5b3d91506101f7565b6040513d5f823e3d90fd5b506020833d602011610258575b81610248602093836115a1565b81010312610217575f9251610196565b3d915061023b565b3461021757604036600319011261021757610279611601565b610281611617565b6001600160a01b039182165f908152600460209081526040808320949093168252928352819020549051908152f35b346102175760e0366003190112610217576102c9611601565b6102d1611617565b6044356064359260843560ff81168091036102175742851061046a5760805f916020936102fc61165c565b9060018060a01b03169687855260058652604085209889549960018b01905560405190878201927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c984528a604084015260018060a01b03169a8b6060840152898784015260a083015260c082015260c0815261037960e0826115a1565b519020604051908682019261190160f01b845260228301526042820152604281526103a56062826115a1565b519020906040519182528482015260a435604082015260c435606082015282805260015afa15610223575f516001600160a01b031680151580610461575b1561042b577f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925916020915f526004825260405f20855f5282528060405f2055604051908152a3005b60405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606490fd5b508281146103e3565b60405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606490fd5b34610217575f366003190112610217576008546040516001600160a01b039091168152602090f35b34610217575f366003190112610217576006546040516001600160a01b039091168152602090f35b3461021757602036600319011261021757610518611601565b6001600d5461052a60ff8216156117d6565b60ff191617600d556007546008546040516370a0823160e01b81523060048201526001600160a01b03918216929091166020826024815f855af19182156102235784905f93610613575b5061058e610594936001600160701b03600954169061164f565b91611b21565b6040516370a0823160e01b8152306004820152916020836024815f865af1928315610223575f936105dd575b5061058e6101dd936001600160701b0360095460701c169061164f565b92506020833d60201161060b575b816105f8602093836115a1565b810103126102175791519161058e6105c0565b3d91506105eb565b9250506020823d602011610643575b8161062f602093836115a1565b81010312610217579051908361058e610574565b3d9150610622565b3461021757604036600319011261021757610664611601565b60243590335f52600360205260405f2061067f83825461164f565b905560018060a01b031690815f52600360205260405f208181540190556040519081525f80516020611c4d83398151915260203392a3602060405160018152f35b34610217575f366003190112610217576040515f6001546106e081611569565b80845290600181169081156107765750600114610718575b61071483610708818503826115a1565b604051918291826115d7565b0390f35b60015f9081527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6939250905b80821061075c575090915081016020016107086106f8565b919260018160209254838588010152019101909291610744565b60ff191660208086019190915291151560051b8401909101915061070890506106f8565b34610217576020366003190112610217576107b3611601565b6001600d546107c560ff8216156117d6565b60ff191617600d555f6107d661162d565b509092602060018060a01b03600754166024604051809681936370a0823160e01b83523060048401525af1918215610223575f92610ac0575b6008546040516370a0823160e01b81523060048201529450602090859060249082905f906001600160a01b03165af1938415610223575f94610a8c575b50305f52600360205260405f20549461088a61087e61087e610883610871868661182f565b976002549384918c6117f1565b611804565b97896117f1565b9385151580610a83575b15610a6f575f80973082526003602052604082206108b382825461164f565b905580600254036002556040519081525f80516020611c4d83398151915260203092a36007546108ef90879086906001600160a01b0316611b21565b60085461090890869086906001600160a01b0316611b21565b6007546040516370a0823160e01b81523060048201529760209189916024918391906001600160a01b03165af1968715610223575f97610a3b575b506008546040516370a0823160e01b815230600482015290602090829060249082905f906001600160a01b03165af1908115610223575f91610a09575b50838361098f9260409a6119fd565b6109ea575b505083519083825282602083015260018060a01b0316848201527fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d8193649660603392a260ff19600d5416600d5582519182526020820152f35b6001600160701b03806109ff931691166117f1565b600c558480610994565b90506020813d602011610a33575b81610a24602093836115a1565b81010312610217575183610980565b3d9150610a17565b9096506020813d602011610a67575b81610a57602093836115a1565b8101031261021757519587610943565b3d9150610a4a565b637a52fb5d60e01b5f52601260045260245ffd5b50841515610894565b9093506020813d602011610ab8575b81610aa8602093836115a1565b810103126102175751928561084c565b3d9150610a9b565b91506020833d602011610aec575b81610adb602093836115a1565b81010312610217575f92519161080f565b3d9150610ace565b34610217576020366003190112610217576001600160a01b03610b15611601565b165f526005602052602060405f2054604051908152f35b34610217575f366003190112610217576020600c54604051908152f35b34610217576020366003190112610217576001600160a01b03610b6a611601565b165f526003602052602060405f2054604051908152f35b34610217576060366003190112610217576044356001600160a01b038116906004359060243590838103610217576001600d54610bc160ff8216156117d6565b60ff191617600d5582159081158092610f1b575b15610f0757610be261162d565b50916001600160701b0382169081871080610ef5575b15610ee1575f94610ec3575b8580610ea6575b50506007546040516370a0823160e01b81523060048201529460209186916024918391906001600160a01b03165af1938415610223575f94610e72575b506008546040516370a0823160e01b81523060048201529190602090839060249082905f906001600160a01b03165af1918215610223575f92610e3e575b50600954866001600160701b03821689610ca0818361164f565b891115610e2d57610cbc610cc2916001600160701b039361164f565b8961164f565b925b60701c16610cd2828261164f565b851115610e2457610cec91610ce69161164f565b8461164f565b905b801590811582610e1b575b15610e07576103e88802918883046103e81489151715610df357600382029182046003141715610df357610d2c9161164f565b906103e88402918483046103e81485151715610df357600382029180830460031490151715610df357610d65610d6b92610d7c9461164f565b906117f1565b916001600160701b038616906117f1565b90620f4240820291808304620f42401490151715610df35710610ddf57610da2936119fd565b60405191825260208201527f2a9237ff5aa599ef4c5ee4b1142b53429d5755e2685fe6288b2e3320202115f560403392a3600d805460ff19169055005b637a52fb5d60e01b5f52601460045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b637a52fb5d60e01b5f52600b60045260245ffd5b50821515610cf9565b50505f90610cee565b50506001600160701b035f92610cc4565b9091506020813d602011610e6a575b81610e5a602093836115a1565b8101031261021757519088610c86565b3d9150610e4d565b9093506020813d602011610e9e575b81610e8e602093836115a1565b810103126102175751925f610c48565b3d9150610e81565b600854610ebc92906001600160a01b0316611b21565b8785610c0b565b600754610edc90889083906001600160a01b0316611b21565b610c04565b637a52fb5d60e01b5f52600a60045260245ffd5b506001600160701b0384168610610bf8565b637a52fb5d60e01b5f52600c60045260245ffd5b50821515610bd5565b3461021757602036600319011261021757610f3d611601565b6001600d54610f4f60ff8216156117d6565b60ff191617600d555f610f6061162d565b509290602060018060a01b03600754166024604051809681936370a0823160e01b83523060048401525af1928315610223575f93611177575b506008546040516370a0823160e01b815230600482015290602090829060249082905f906001600160a01b03165af1908115610223575f91611145575b506001600160701b03821692610fec848661164f565b936001600160701b03871690611002828561164f565b9161100d898761182f565b6002548883858361111357505061102e915085611029916117f1565b611964565b6103e7198101908111610df357986002546103e88101809111610df3576002555f8052600360205260405f206103e881540190555f805f80516020611c4d83398151915260206040516103e88152a35b89156110ff5760209a7f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f986040986110bf936110ba8e8b6119b9565b6119fd565b6110ec575b50508251948552868501526001600160a01b031692a260ff19600d5416600d55604051908152f35b6110f5916117f1565b600c5587806110c4565b637a52fb5d60e01b5f52601060045260245ffd5b61112761087e9161087e8661112e966117f1565b93886117f1565b8082101561113e57505b9861107e565b9050611138565b90506020813d60201161116f575b81611160602093836115a1565b81010312610217575185610fd6565b3d9150611153565b9092506020813d6020116111a3575b81611193602093836115a1565b8101031261021757519184610f99565b3d9150611186565b34610217575f366003190112610217576020600b54604051908152f35b34610217575f366003190112610217576020600a54604051908152f35b34610217576040366003190112610217576111fe611601565b611206611617565b60075490916001600160a01b0382161580611287575b15611273576006546001600160a01b0316330361125f576001600160a01b03199182166001600160a01b0391821617600755600880549092169216919091179055005b637a52fb5d60e01b5f52600760045260245ffd5b637a52fb5d60e01b5f52601660045260245ffd5b506008546001600160a01b03161561121c565b34610217575f3660031901126102175760206112b461165c565b604051908152f35b34610217575f36600319011261021757602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461021757606036600319011261021757611312611601565b61131a611617565b6001600160a01b039091165f818152600460209081526040808320338452825290912054604435935f80516020611c4d833981519152929185600182016113a4575b5050835f526003825260405f2061137486825461164f565b90556001600160a01b03165f818152600383526040908190208054870190555194855293a3602060405160018152f35b6113ad9161164f565b5f8581526004845260408082203383528552902055858561135c565b34610217575f366003190112610217576020600254604051908152f35b34610217575f366003190112610217576007546040516001600160a01b039091168152602090f35b3461021757604036600319011261021757611427611601565b335f8181526004602090815260408083206001600160a01b03909516808452948252918290206024359081905591519182527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a3602060405160018152f35b34610217575f3660031901126102175760606001600160701b0363ffffffff6114ae61162d565b9193908160405195168552166020840152166040820152f35b34610217575f366003190112610217576040515f80546114e681611569565b8084529060018116908115610776575060011461150d5761071483610708818503826115a1565b5f8080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563939250905b80821061154f575090915081016020016107086106f8565b919260018160209254838588010152019101909291611537565b90600182811c92168015611597575b602083101461158357565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611578565b90601f8019910116810190811067ffffffffffffffff8211176115c357604052565b634e487b7160e01b5f52604160045260245ffd5b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361021757565b602435906001600160a01b038216820361021757565b6009546001600160701b038116916001600160701b038260701c169160e01c90565b91908203918211610df357565b467f0000000000000000000000000000000000000000000000000000000000000000036116a7577f000000000000000000000000000000000000000000000000000000000000000090565b6040515f905f5491816116b984611569565b9182825260208201946001811690815f146117ba575060011461175d575b6116e3925003826115a1565b51902060405160208101917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f835260408201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a0815261175760c0826115a1565b51902090565b505f80805290917f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b81831061179e5750509060206116e3928201016116d7565b6020919350806001915483858801015201910190918392611786565b60ff19168652506116e392151560051b820160200190506116d7565b156117dd57565b637a52fb5d60e01b5f52600660045260245ffd5b81810292918115918404141715610df357565b811561180e570490565b634e487b7160e01b5f52601260045260245ffd5b91908201809211610df357565b60065460405163ae2e933b60e01b81529293929190602090839060049082906001600160a01b03165afa918215610223575f92611920575b50600c546001600160a01b03831615801595919290611910578261188c575b50505050565b6110296118a8916001600160701b03806118ae951691166117f1565b91611964565b908181116118bd575b80611886565b6118cd600254610d65848461164f565b90600581029080820460051490151715610df3576118f4926118ee91611822565b90611804565b80611900575b806118b7565b611909916119b9565b5f806118fa565b5050905061191a57565b5f600c55565b9091506020813d60201161195c575b8161193c602093836115a1565b8101031261021757516001600160a01b038116810361021757905f611867565b3d915061192f565b905f60038311156119ac5750818060011c60018101809111610df357905b83821061198d575050565b9092506119a38361199e8184611804565b611822565b60011c90611982565b916119b357565b60019150565b5f80516020611c4d83398151915260205f926119d785600254611822565b6002556001600160a01b03168084526003825260408085208054870190555194855293a3565b91926001600160701b0383111580611b10575b15611afc576001600160701b0360409381927fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a9663ffffffff60095460e01c81421603169182151580611af1575b80611ae6575b611a9d575b50505016918263ffffffff60e01b4260e01b16918360701b9060701b16171780600955835192835260701c166020820152a1565b611ad590836001600160e01b03611abc85611ab785611bf8565b611c2e565b1602600a5401600a55611ab760018060e01b0393611bf8565b1602600b5401600b555f8080611a69565b508481161515611a64565b508482161515611a5e565b637a52fb5d60e01b5f52601160045260245ffd5b506001600160701b03821115611a10565b5f929183809360405190602082019363a9059cbb60e01b855260018060a01b03166024830152604482015260448152611b5b6064826115a1565b51925af13d15611bf1573d67ffffffffffffffff81116115c35760405190611b8d601f8201601f1916602001836115a1565b81523d5f602083013e5b81611bb9575b5015611ba557565b637a52fb5d60e01b5f52600860045260245ffd5b8051801592508215611bce575b50505f611b9d565b819250906020918101031261021757602001518015158103610217575f80611bc6565b6060611b97565b6dffffffffffffffffffffffffffff60701b607082901b16906001600160701b0316808204600160701b1490151715610df35790565b906001600160701b031690811561180e576001600160e01b0316049056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212209be4b1e4c827f9e2fa05ea9e23112b87991050e3fcdeac2858a3cf79e8fb534e64736f6c634300081a0033290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563a264697066735822122031979ab6b6229909450487e057b58aae326f257996b49eb8a4ab9c0bb12dfdc464736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000053c8668ca4d913749ce0af7126ef419eb8729882
-----Decoded View---------------
Arg [0] : _factory (address): 0x53C8668cA4D913749Ce0aF7126eF419eb8729882
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000053c8668ca4d913749ce0af7126ef419eb8729882
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.