Sonic Blaze Testnet

Contract

0xCB650F865272b54d60B8B6FFd8371A6523453958

Overview

S Balance

Sonic Blaze LogoSonic Blaze LogoSonic Blaze Logo0 S

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Swap Exact Token...195286012025-02-11 7:56:245 mins ago1739260584IN
0xCB650F86...523453958
0 S0.000121081.1
Remove Liquidity195212372025-02-11 7:13:1249 mins ago1739257992IN
0xCB650F86...523453958
0 S0.000148181.1
Remove Liquidity195193382025-02-11 7:01:431 hr ago1739257303IN
0xCB650F86...523453958
0 S0.000148181.1
Swap Exact Token...195148892025-02-11 6:35:241 hr ago1739255724IN
0xCB650F86...523453958
0 S0.000122881.1
Add Liquidity195126832025-02-11 6:22:281 hr ago1739254948IN
0xCB650F86...523453958
0 S0.000142451.1
Add Liquidity195126222025-02-11 6:22:061 hr ago1739254926IN
0xCB650F86...523453958
0 S0.000142431.1
Swap Exact Token...195117292025-02-11 6:16:431 hr ago1739254603IN
0xCB650F86...523453958
0 S0.00012291.1
Swap Exact Token...195059912025-02-11 5:42:542 hrs ago1739252574IN
0xCB650F86...523453958
0 S0.00012291.1
Swap Exact Token...195055152025-02-11 5:40:042 hrs ago1739252404IN
0xCB650F86...523453958
0 S0.000122891.1
Swap Exact Token...195053772025-02-11 5:39:152 hrs ago1739252355IN
0xCB650F86...523453958
0 S0.00012291.1
Swap Exact Token...195043542025-02-11 5:33:062 hrs ago1739251986IN
0xCB650F86...523453958
0 S0.00012291.1
Remove Liquidity191170372025-02-09 15:42:5740 hrs ago1739115777IN
0xCB650F86...523453958
0 S0.000148181.1
Add Liquidity191167112025-02-09 15:41:0040 hrs ago1739115660IN
0xCB650F86...523453958
0 S0.00014931.1
Swap Exact Token...191165262025-02-09 15:39:5140 hrs ago1739115591IN
0xCB650F86...523453958
0 S0.000126341.1
Add Liquidity190907542025-02-09 13:08:2342 hrs ago1739106503IN
0xCB650F86...523453958
0 S0.000142431.1
Remove Liquidity190904282025-02-09 13:06:3142 hrs ago1739106391IN
0xCB650F86...523453958
0 S0.000053781.1
Remove Liquidity190904192025-02-09 13:06:2842 hrs ago1739106388IN
0xCB650F86...523453958
0 S0.000148181.1
Swap Exact Token...190900592025-02-09 13:04:2142 hrs ago1739106261IN
0xCB650F86...523453958
0 S0.000126361.1
Add Liquidity190897472025-02-09 13:02:3342 hrs ago1739106153IN
0xCB650F86...523453958
0 S0.000149331.1
Add Liquidity190790622025-02-09 12:01:1544 hrs ago1739102475IN
0xCB650F86...523453958
0 S0.000142461.1
Add Liquidity190789302025-02-09 12:00:3044 hrs ago1739102430IN
0xCB650F86...523453958
0 S0.000142431.1
Add Liquidity190553122025-02-09 9:44:0046 hrs ago1739094240IN
0xCB650F86...523453958
0 S0.000142431.1
Add Liquidity190511552025-02-09 9:20:0646 hrs ago1739092806IN
0xCB650F86...523453958
0 S0.000314281
Add Liquidity190488462025-02-09 9:06:5746 hrs ago1739092017IN
0xCB650F86...523453958
0 S0.000314291
Swap Exact Token...190479462025-02-09 9:01:4447 hrs ago1739091704IN
0xCB650F86...523453958
0 S0.00012291.1
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
195286012025-02-11 7:56:245 mins ago1739260584
0xCB650F86...523453958
0 S
195286012025-02-11 7:56:245 mins ago1739260584
0xCB650F86...523453958
0 S
195286012025-02-11 7:56:245 mins ago1739260584
0xCB650F86...523453958
0 S
195212372025-02-11 7:13:1249 mins ago1739257992
0xCB650F86...523453958
0 S
195212372025-02-11 7:13:1249 mins ago1739257992
0xCB650F86...523453958
0 S
195193382025-02-11 7:01:431 hr ago1739257303
0xCB650F86...523453958
0 S
195193382025-02-11 7:01:431 hr ago1739257303
0xCB650F86...523453958
0 S
195148892025-02-11 6:35:241 hr ago1739255724
0xCB650F86...523453958
0 S
195148892025-02-11 6:35:241 hr ago1739255724
0xCB650F86...523453958
0 S
195148892025-02-11 6:35:241 hr ago1739255724
0xCB650F86...523453958
0 S
195126832025-02-11 6:22:281 hr ago1739254948
0xCB650F86...523453958
0 S
195126832025-02-11 6:22:281 hr ago1739254948
0xCB650F86...523453958
0 S
195126832025-02-11 6:22:281 hr ago1739254948
0xCB650F86...523453958
0 S
195126832025-02-11 6:22:281 hr ago1739254948
0xCB650F86...523453958
0 S
195126832025-02-11 6:22:281 hr ago1739254948
0xCB650F86...523453958
0 S
195126222025-02-11 6:22:061 hr ago1739254926
0xCB650F86...523453958
0 S
195126222025-02-11 6:22:061 hr ago1739254926
0xCB650F86...523453958
0 S
195126222025-02-11 6:22:061 hr ago1739254926
0xCB650F86...523453958
0 S
195126222025-02-11 6:22:061 hr ago1739254926
0xCB650F86...523453958
0 S
195126222025-02-11 6:22:061 hr ago1739254926
0xCB650F86...523453958
0 S
195117292025-02-11 6:16:431 hr ago1739254603
0xCB650F86...523453958
0 S
195117292025-02-11 6:16:431 hr ago1739254603
0xCB650F86...523453958
0 S
195117292025-02-11 6:16:431 hr ago1739254603
0xCB650F86...523453958
0 S
195059912025-02-11 5:42:542 hrs ago1739252574
0xCB650F86...523453958
0 S
195059912025-02-11 5:42:542 hrs ago1739252574
0xCB650F86...523453958
0 S
View All Internal Transactions
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)

File 1 of 9 : SlsV1Router.sol
// 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);
    }
}

File 2 of 9 : ISlsV1Factory.sol
// 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);
}

File 3 of 9 : ISlsV1Pair.sol
// 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;
}

File 4 of 9 : SlsV1Library.sol
// 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;
    }
}

File 5 of 9 : ISLSErrors.sol
// 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);
}

File 6 of 9 : SlsV1Pair.sol
// 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)
        );
    }
}

File 7 of 9 : ERC20.sol
// 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);
    }
}

File 8 of 9 : Math.sol
// 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;
        }
    }
}

File 9 of 9 : UQ112x112.sol
// 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);
    }
}

Settings
{
  "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": {}
}

Contract ABI

[{"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"}]

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


Block Transaction Gas Used Reward
view all blocks produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.