false
true
0

Contract Address Details

0xd032365C138E7385bc50f6DF12fE5Ef8Eca8f0EC

Contract Name
FeeSplitter
Creator
0x51034d–782d8b at 0x1a5043–130693
Balance
112,298.703496395974601437 PLS ( )
Tokens
Fetching tokens...
Transactions
494 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
26134214
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
FeeSplitter




Optimization enabled
true
Compiler version
v0.8.17+commit.8df45f5f




Optimization runs
20000
EVM Version
default




Verified at
2023-10-20T00:10:09.300822Z

Constructor Arguments

0x000000000000000000000000bbc56bfdefb90e2f3e67e00e75bef0cd1ed2231e0000000000000000000000003123183dc942fd721899bf589d55baa39753628b00000000000000000000000098bf93ebf5c380c0e6ae8e192a7e2ae08edacc02000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27000000000000000000000000207e6b4529840a4fd518f73c68bc9c19b2a15944000000000000000000000000476559a5665f8f42402e42b04b0a4cfd6769b7b8

Arg [0] (address) : 0xbbc56bfdefb90e2f3e67e00e75bef0cd1ed2231e
Arg [1] (address) : 0x3123183dc942fd721899bf589d55baa39753628b
Arg [2] (address) : 0x98bf93ebf5c380c0e6ae8e192a7e2ae08edacc02
Arg [3] (address) : 0x165c3410fc91ef562c50559f7d2289febed552d9
Arg [4] (address) : 0xa1077a294dde1b09bb078844df40758a5d0f9a27
Arg [5] (address) : 0x207e6b4529840a4fd518f73c68bc9c19b2a15944
Arg [6] (address) : 0x476559a5665f8f42402e42b04b0a4cfd6769b7b8

              

Contract source code

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// File: contracts/feesplitter/FeeSplitter.sol


pragma solidity 0.8.17;


interface IFactory {
    function getPair(address tokenA, address tokenB) external view returns (address pair);
}

interface IPair {
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function token0() external view returns (address);
}

interface IWPLS {
    function withdraw(uint256 amount) external;
}

interface IERC20 {
    function approve(address spender, uint256 value) external returns (bool);
}

interface IMint {
    function totalSupply() external view returns (uint256);
    function burn(uint256 amount) external;
    function balanceOf(address account) external view returns (uint256);
}


interface IRouter {
    function factory() external pure returns (address);
    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] memory path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] memory path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);
}

/**
 * @title FeeSplitter Contract
 * @notice This contract distributes fees generated from token transactions
 * to three different addresses according to predefined percentages.
 */
contract FeeSplitter is ReentrancyGuard {
    address public vulcan; // "Mintra OA Address"

    address public mintStakingAddress;
    address public rootAddress;

    IMint private mintToken;
    IWPLS private wplsToken;
    
    IRouter private router1;
    IRouter private router2;
    uint256 private router1Fee = 9971; // 0.29%
    uint256 private router2Fee = 9971; // 0.29%

    address private factoryAddress1;
    address private factoryAddress2;

    uint256 public maxSlippageBasisPoints = 100; // This is 1% slippage
    
    uint256 public plsAmountForMintBuyAndBurn = 0;
    uint256 public lastTimeBuyAndBurnExecutedBlockNumber;
    address[] private pathBuyAndBurn = new address[](2);

    uint256 private constant THIRTY_THREE_POINT_THREE = 3330; // 33.3%
    uint256 public constant BOUNTY_REWARD_BASIS_POINTS = 10; // 0.1% 

    event BuyBackAndBurn(
        uint256 soldPlsAmount,
        uint256 boughtMintAmount,
        uint256 totalSupplyBefore,
        uint256 totalSupplyAfter,
        uint256 timestamp
    );

    modifier onlyVulcan() {
        require(msg.sender == vulcan, "Not vulcan");
        _;
    }

    constructor(
        address _mintStakingAddress,
        address _rootAddress,
        address _routerAddress1,
        address _routerAddress2,
        address _wplsTokenAddress,
        address _mintTokenAddress,
        address _vulcan
    ) {
        require (_mintStakingAddress != address(0), "_mintStakingAddress is zero");
        require(_rootAddress != address(0), "_rootAddress is zero");
        require(_routerAddress1 != address(0), "_routerAddress1 cannot be 0");
        require(_routerAddress2 != address(0), "_routerAddress2 cannot be 0");
        require(_wplsTokenAddress != address(0), "WPLS address cannot be 0");
        require(_mintTokenAddress != address(0), "Mint address cannot be 0");
        require(_vulcan != address(0), "Vulcan address cannot be 0");

        mintStakingAddress = _mintStakingAddress;
        rootAddress = _rootAddress;

        router1 = IRouter(_routerAddress1);
        router2 = IRouter(_routerAddress2);
        factoryAddress1 = router1.factory();
        factoryAddress2 = router2.factory();


        vulcan = _vulcan;

        wplsToken = IWPLS(_wplsTokenAddress);
        mintToken = IMint(_mintTokenAddress);
        
        pathBuyAndBurn[0] = _wplsTokenAddress;
        pathBuyAndBurn[1] = _mintTokenAddress;
    }

    /**
     * @dev Fallback function - accepts incoming PLS.
     */
    receive() external payable {   
    }

    /**
     * Process the tokens and distribute the rewards. MINT tokens are burned when buybackAndBurn is executed.
     * 
     * @param tokenAddresses[] 
     * @param amounts[] 
     */
    function flush(uint256 plsAmountToBuyAndBurnMintWith, bool buyAndBurnIsV1, address[] memory tokenAddresses, uint256[] memory amounts, bool[] memory isV1) 
        public nonReentrant  {
       // solhint-disable-next-line avoid-tx-origin
       require(msg.sender == tx.origin, "Origin must be a EOA");

       processErc20s(tokenAddresses, amounts, isV1);

       uint256 plsAmountToDistribute = address(this).balance - plsAmountForMintBuyAndBurn;
               
       // Distribute the rewards
       if (plsAmountToDistribute > 1e18) {
        (
            uint256 _stakingRewardsPls, // amount of tokens for staking rewards
            uint256 _buyBackAndBurnPls, // amount of tokens for buyback and burn
            uint256 _rootAddressPls, // amount of tokens for root address
            uint256 _bounty // amount of tokens for bounty
        ) = splitRewards(plsAmountToDistribute);

        plsAmountForMintBuyAndBurn += _buyBackAndBurnPls;

        require (plsAmountForMintBuyAndBurn >= plsAmountToBuyAndBurnMintWith, "MintBurn: PLS amount too high");

        // update rewards for the staking contract
        (bool successMintStaking, ) = payable(mintStakingAddress).call{value: _stakingRewardsPls}("");
        require(successMintStaking, "Sending to mintStaking failed");
        
        // transfer tokens to the root address
        (bool successRootAddress, ) = payable(rootAddress).call{value: _rootAddressPls}("");
        require(successRootAddress, "Sending to root address failed");

        // transfer tokens for the bounty
        (bool successBountyAddress, ) = payable(msg.sender).call{value: _bounty}("");
        require(successBountyAddress, "Sending to bounty address failed");

        // buyback and burn
        if (plsAmountForMintBuyAndBurn >= 1e17) {
            buybackAndBurn(plsAmountToBuyAndBurnMintWith, buyAndBurnIsV1);
        }
       }
    }

    /**
     * Iterate through all the erc20's. If it's WPLS, withdraw it. If it's MINT, burn it. If it's anything else, swap it for PLS.
     * 
     * @param tokenAddresses[] 
     * @param amounts[]
     * @param isRouter1Array[] 
     */
    function processErc20s(address[] memory tokenAddresses, uint256[] memory amounts, bool[] memory isRouter1Array) internal {
         address wplsTokenAddress = address(wplsToken);
         
         for (uint256 i = 0; i < tokenAddresses.length; i++) {
            uint256 amount = amounts[i];
            address tokenAddress = tokenAddresses[i];
            bool isRouter1 = isRouter1Array[i];

            if (tokenAddress == wplsTokenAddress) {
                // withdraw the PLS
                wplsToken.withdraw(amount);
            } else if (tokenAddress != address(mintToken)) { // Mint tokens are burned when buybackAndBurn is executed

                uint256 slippageBasisPoints = calculateSlippageErc20(tokenAddress, amount, isRouter1);

                require(
                    slippageBasisPoints <= maxSlippageBasisPoints, 
                    "Slippage too high"
                );
                
                address[] memory path = new address[](2);
                path[0] = tokenAddress;
                path[1] = wplsTokenAddress;
                
                // Execute the swap
                if (isRouter1) {
                    // Approve the router only the amount needed
                    IERC20(tokenAddress).approve(address(router1), amount);
                    
                    router1.swapExactTokensForETH(amount, 0, path, address(this), block.timestamp + 10);
                } else {
                    // Approve the router only the amount needed
                    IERC20(tokenAddress).approve(address(router2), amount);

                    router2.swapExactTokensForETH(amount, 0, path, address(this), block.timestamp + 10);
                }
            }
         }
    }

    /**
     * @notice Calculate total available PLS balance and split it into four parts,
     * stakingRewards, buybackAndBurn, rootAddress and bounty according to percentage
     * @return stakingRewards The amount of PLS for staking rewards
     * @return _buybackAndBurn The amount of PLS for buyback and burn
     * @return rootAddressPls The amount of PLS for rootAddress
     * @return bounty The amount of PLS for bounty
     */
    function splitRewards(uint256 availableBalance)
        internal
        pure
        returns (
            uint256 stakingRewards,
            uint256 _buybackAndBurn,
            uint256 rootAddressPls, 
            uint256 bounty
        )
    {
        if (availableBalance > 1e18) {
            bounty = ((availableBalance * BOUNTY_REWARD_BASIS_POINTS ) / 10000);
            stakingRewards = ((availableBalance * THIRTY_THREE_POINT_THREE ) / 10000);
            _buybackAndBurn = ((availableBalance * THIRTY_THREE_POINT_THREE ) / 10000);
            rootAddressPls = availableBalance - (bounty + stakingRewards + _buybackAndBurn);
        }

        return (stakingRewards, _buybackAndBurn, rootAddressPls, bounty);
    }

    /**
     * Calculate the slippage for a given amount of ERC20Tokens
     * 
     * @param erc20TokenAddress ERC20 Token Address
     * @param amountIn Amount of ERC20 Tokens
     * @param isRouter1 What router to use
     * @return slippageBasisPoints Slippage in basis points
     */
    function calculateSlippageErc20(address erc20TokenAddress, uint256 amountIn, bool isRouter1) public view 
        returns (uint256 slippageBasisPoints) {
        
        address factoryAddress;

        if (isRouter1) {
            factoryAddress = factoryAddress1;
        } else {
            factoryAddress = factoryAddress2;
        }

        IPair pair = IPair(IFactory(factoryAddress).getPair(erc20TokenAddress, address(wplsToken)));
 
        slippageBasisPoints = slippageCalculation(amountIn, pair, erc20TokenAddress, isRouter1);

        return slippageBasisPoints;
    }

    /**
     * Calculate the slippage for a given amount of PLS
     * 
     * @param inPls Amount of PLS in
     * @param isRouter1 What router to use
     * @return slippageBasisPoints Slippage in basis points
     */
    function calculateSlippageMintBuyAndBurn(uint256 inPls, bool isRouter1) public view 
        returns (uint256 slippageBasisPoints ) {

        address factoryAddress;
        address wplsTokenAddress = address(wplsToken);

        if (isRouter1) {
            factoryAddress = factoryAddress1;
        } else {
            factoryAddress = factoryAddress2;
        }

        IPair pair = IPair(IFactory(factoryAddress).getPair(address(mintToken), wplsTokenAddress));
        
        slippageBasisPoints = slippageCalculation(inPls, pair, wplsTokenAddress, isRouter1);

        return slippageBasisPoints;
    }

    /**
     * @dev Execute the buyback and burn
     * 
     * @param plsAmount Amount of PLS to buyback and burn
     * @param isRouter1 What router to use
     * @return amounts 
     */
    function buybackAndBurn(uint256 plsAmount, bool isRouter1) internal 
        returns (uint256[] memory amounts) {    

        // Do not allow the buyBackAndBurn function to be called more than once per block
        require(
            block.number != lastTimeBuyAndBurnExecutedBlockNumber,
            "MintBurn: Need to wait"
        );

        uint256 slippageBasisPoints = calculateSlippageMintBuyAndBurn(plsAmount, isRouter1);

        require(
            slippageBasisPoints <= maxSlippageBasisPoints, 
            "MintBurn: Slippage too high"
        );

        if (isRouter1) {
            amounts = router1.swapExactETHForTokens{
                value: plsAmount
            }(0, pathBuyAndBurn, address(this), block.timestamp + 10);
        } else {
            amounts = router2.swapExactETHForTokens{
                value: plsAmount
            }(0, pathBuyAndBurn, address(this), block.timestamp + 10);
        }

        // Adjust how much PLS is left to buy and burn
        plsAmountForMintBuyAndBurn = plsAmountForMintBuyAndBurn - plsAmount;

        uint256 mintBalance = mintToken.balanceOf(address(this));

        uint256 mintTotalSupplyBefore = mintToken.totalSupply();

        if (mintBalance > 0) {
            mintToken.burn(mintBalance);
        }

        uint256 mintTotalSupplyAfter = mintToken.totalSupply();

        // Update the last time executed block number
        lastTimeBuyAndBurnExecutedBlockNumber = block.number;

        emit BuyBackAndBurn(
            amounts[0],
            amounts[1],
            mintTotalSupplyBefore,
            mintTotalSupplyAfter,
            block.timestamp
        );

        return amounts;
    }

    /**
     * @dev Calculate the slippage for a given amount of tokens
     * 
     * @param amountIn Amount of tokens to swap 
     * @param pair Pair address
     * @param reserveInAddress Address of the reserve in
     * @param isRouter1 What router to use
     * @return slippageBasisPoints 
     */
    function slippageCalculation(uint256 amountIn, IPair pair, address reserveInAddress, bool isRouter1) internal view 
        returns (uint256 slippageBasisPoints ) {
        
        (uint256 reserve0, uint256 reserve1, ) = pair.getReserves();
        (uint256 reserveIn,) = reserveInAddress == pair.token0() ? (reserve0, reserve1) : (reserve1, reserve0);

        uint256 fee = isRouter1 ? router1Fee : router2Fee;

        uint256 amountToBuyWithMinusFee;

        amountToBuyWithMinusFee = (amountIn * fee) / 10000;

        slippageBasisPoints = (amountToBuyWithMinusFee * 10000) / reserveIn;
    
        return slippageBasisPoints;
    }

    /**
    * @dev Allow the changing of the max slippage bettween a bounds
    * @param _maxSlippageBasisPoints slippage value in basis points
    */
    function changeSlippage(uint256 _maxSlippageBasisPoints) external onlyVulcan {
        require(_maxSlippageBasisPoints >= 10, "MintBurn: Min Slippage .1%");
        require(_maxSlippageBasisPoints <= 1500, "MintBurn: Max Slippage 15%");

        maxSlippageBasisPoints = _maxSlippageBasisPoints;
    }

    /**
     * @dev Allow the changing of the router addresses
     * @param routerAddress1 Router one address
     * @param routerAddress2 Router two address
     */
     function changeRouterAddresses(address routerAddress1, address routerAddress2) external onlyVulcan {
        require(routerAddress1 != address(0), "Invalid address");
        require(routerAddress2 != address(0), "Invalid address");

        router1 = IRouter(routerAddress1);
        factoryAddress1 = router1.factory();

        router2 = IRouter(routerAddress2);
        factoryAddress2 = router2.factory();
     }

    /**
     * @dev Allow the changing of the router fees. 
     * If there is not fee for the given router pass in 1. This will only effect the slippage caculation insignificantly.
     * 
     * @param _router1Fee Router1 fee
     * @param _router2Fee Router2 fee
     */
     function changeRouterFees(uint256 _router1Fee, uint256 _router2Fee) external onlyVulcan {
        require(_router1Fee > 0, "_router1Fee Invalid");
        require(_router2Fee > 0, "_router2Fee Invalid");

        router1Fee = _router1Fee;
        router2Fee = _router2Fee;
     }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_mintStakingAddress","internalType":"address"},{"type":"address","name":"_rootAddress","internalType":"address"},{"type":"address","name":"_routerAddress1","internalType":"address"},{"type":"address","name":"_routerAddress2","internalType":"address"},{"type":"address","name":"_wplsTokenAddress","internalType":"address"},{"type":"address","name":"_mintTokenAddress","internalType":"address"},{"type":"address","name":"_vulcan","internalType":"address"}]},{"type":"event","name":"BuyBackAndBurn","inputs":[{"type":"uint256","name":"soldPlsAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"boughtMintAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalSupplyBefore","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalSupplyAfter","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"BOUNTY_REWARD_BASIS_POINTS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"slippageBasisPoints","internalType":"uint256"}],"name":"calculateSlippageErc20","inputs":[{"type":"address","name":"erc20TokenAddress","internalType":"address"},{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"bool","name":"isRouter1","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"slippageBasisPoints","internalType":"uint256"}],"name":"calculateSlippageMintBuyAndBurn","inputs":[{"type":"uint256","name":"inPls","internalType":"uint256"},{"type":"bool","name":"isRouter1","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeRouterAddresses","inputs":[{"type":"address","name":"routerAddress1","internalType":"address"},{"type":"address","name":"routerAddress2","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeRouterFees","inputs":[{"type":"uint256","name":"_router1Fee","internalType":"uint256"},{"type":"uint256","name":"_router2Fee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeSlippage","inputs":[{"type":"uint256","name":"_maxSlippageBasisPoints","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"flush","inputs":[{"type":"uint256","name":"plsAmountToBuyAndBurnMintWith","internalType":"uint256"},{"type":"bool","name":"buyAndBurnIsV1","internalType":"bool"},{"type":"address[]","name":"tokenAddresses","internalType":"address[]"},{"type":"uint256[]","name":"amounts","internalType":"uint256[]"},{"type":"bool[]","name":"isV1","internalType":"bool[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastTimeBuyAndBurnExecutedBlockNumber","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxSlippageBasisPoints","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"mintStakingAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"plsAmountForMintBuyAndBurn","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rootAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"vulcan","inputs":[]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

Verify & Publish
0x6126f360088190556009556064600c556000600d556002608081815260e060405290816020016020820280368337505081516200004492600f925060200190620004fa565b503480156200005257600080fd5b506040516200298438038062002984833981016040819052620000759162000598565b60016000556001600160a01b038716620000d65760405162461bcd60e51b815260206004820152601b60248201527f5f6d696e745374616b696e6741646472657373206973207a65726f000000000060448201526064015b60405180910390fd5b6001600160a01b0386166200012e5760405162461bcd60e51b815260206004820152601460248201527f5f726f6f7441646472657373206973207a65726f0000000000000000000000006044820152606401620000cd565b6001600160a01b038516620001865760405162461bcd60e51b815260206004820152601b60248201527f5f726f7574657241646472657373312063616e6e6f74206265203000000000006044820152606401620000cd565b6001600160a01b038416620001de5760405162461bcd60e51b815260206004820152601b60248201527f5f726f7574657241646472657373322063616e6e6f74206265203000000000006044820152606401620000cd565b6001600160a01b038316620002365760405162461bcd60e51b815260206004820152601860248201527f57504c5320616464726573732063616e6e6f74206265203000000000000000006044820152606401620000cd565b6001600160a01b0382166200028e5760405162461bcd60e51b815260206004820152601860248201527f4d696e7420616464726573732063616e6e6f74206265203000000000000000006044820152606401620000cd565b6001600160a01b038116620002e65760405162461bcd60e51b815260206004820152601a60248201527f56756c63616e20616464726573732063616e6e6f7420626520300000000000006044820152606401620000cd565b600280546001600160a01b03808a166001600160a01b0319928316179092556003805489841690831617905560068054888416908316811790915560078054938816939092169290921790556040805163c45a015560e01b8152905163c45a0155916004808201926020929091908290030181865afa1580156200036e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200039491906200062d565b600a80546001600160a01b0319166001600160a01b039283161790556007546040805163c45a015560e01b81529051919092169163c45a01559160048083019260209291908290030181865afa158015620003f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041991906200062d565b600b80546001600160a01b03199081166001600160a01b039384161790915560018054821684841617905560058054821686841617905560048054909116918416919091179055600f805484919060009062000479576200047962000652565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555081600f600181548110620004bf57620004bf62000652565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050505050505062000668565b82805482825590600052602060002090810192821562000552579160200282015b828111156200055257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200051b565b506200056092915062000564565b5090565b5b8082111562000560576000815560010162000565565b80516001600160a01b03811681146200059357600080fd5b919050565b600080600080600080600060e0888a031215620005b457600080fd5b620005bf886200057b565b9650620005cf602089016200057b565b9550620005df604089016200057b565b9450620005ef606089016200057b565b9350620005ff608089016200057b565b92506200060f60a089016200057b565b91506200061f60c089016200057b565b905092959891949750929550565b6000602082840312156200064057600080fd5b6200064b826200057b565b9392505050565b634e487b7160e01b600052603260045260246000fd5b61230c80620006786000396000f3fe6080604052600436106100d65760003560e01c8063a11e04661161007f578063bec872b011610059578063bec872b01461023a578063bf13d8051461025a578063d40c9d891461027a578063f810d0681461029a57600080fd5b8063a11e0466146101cb578063aaa2b8c8146101f8578063af6df0301461022557600080fd5b80636920c3cf116100b05780636920c3cf1461017357806371e76ec61461019557806380c53dfc146101b557600080fd5b8063065d02de146100e25780632969ca7e1461010b578063331f566e1461015d57600080fd5b366100dd57005b600080fd5b3480156100ee57600080fd5b506100f8600e5481565b6040519081526020015b60405180910390f35b34801561011757600080fd5b506001546101389073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610102565b34801561016957600080fd5b506100f8600c5481565b34801561017f57600080fd5b5061019361018e366004611d81565b6102ba565b005b3480156101a157600080fd5b506101936101b0366004611e86565b610674565b3480156101c157600080fd5b506100f8600d5481565b3480156101d757600080fd5b506002546101389073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020457600080fd5b506003546101389073ffffffffffffffffffffffffffffffffffffffff1681565b34801561023157600080fd5b506100f8600a81565b34801561024657600080fd5b50610193610255366004611ebf565b6109be565b34801561026657600080fd5b50610193610275366004611ed8565b610b1b565b34801561028657600080fd5b506100f8610295366004611efa565b610c7b565b3480156102a657600080fd5b506100f86102b5366004611f3c565b610d74565b6102c2610e90565b333214610330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4f726967696e206d757374206265206120454f4100000000000000000000000060448201526064015b60405180910390fd5b61033b838383610f03565b6000600d544761034b9190611f90565b9050670de0b6b3a76400008111156106625760008060008061036c85611461565b935093509350935082600d60008282546103869190611fa3565b9091555050600d548a11156103f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d696e744275726e3a20504c5320616d6f756e7420746f6f20686967680000006044820152606401610327565b60025460405160009173ffffffffffffffffffffffffffffffffffffffff169086908381818185875af1925050503d8060008114610451576040519150601f19603f3d011682016040523d82523d6000602084013e610456565b606091505b50509050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f53656e64696e6720746f206d696e745374616b696e67206661696c65640000006044820152606401610327565b60035460405160009173ffffffffffffffffffffffffffffffffffffffff169085908381818185875af1925050503d806000811461051b576040519150601f19603f3d011682016040523d82523d6000602084013e610520565b606091505b505090508061058b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53656e64696e6720746f20726f6f742061646472657373206661696c656400006044820152606401610327565b604051600090339085908381818185875af1925050503d80600081146105cd576040519150601f19603f3d011682016040523d82523d6000602084013e6105d2565b606091505b505090508061063d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53656e64696e6720746f20626f756e74792061646472657373206661696c65646044820152606401610327565b67016345785d8a0000600d541061065a576106588d8d6114f0565b505b505050505050505b5061066d6001600055565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b73ffffffffffffffffffffffffffffffffffffffff8216610772576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610327565b73ffffffffffffffffffffffffffffffffffffffff81166107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610327565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155604080517fc45a0155000000000000000000000000000000000000000000000000000000008152905163c45a0155916004808201926020929091908290030181865afa158015610886573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108aa9190611fb6565b600a805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600780549284169290911682179055604080517fc45a0155000000000000000000000000000000000000000000000000000000008152905163c45a0155916004808201926020929091908290030181865afa158015610951573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109759190611fb6565b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b600a811015610aaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e744275726e3a204d696e20536c697070616765202e31250000000000006044820152606401610327565b6105dc811115610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e744275726e3a204d617820536c697070616765203135250000000000006044820152606401610327565b600c55565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b60008211610c06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f726f757465723146656520496e76616c6964000000000000000000000000006044820152606401610327565b60008111610c70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f726f757465723246656520496e76616c6964000000000000000000000000006044820152606401610327565b600891909155600955565b6000808215610ca35750600a5473ffffffffffffffffffffffffffffffffffffffff16610cbe565b50600b5473ffffffffffffffffffffffffffffffffffffffff165b6005546040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152918216602482015260009183169063e6a4390590604401602060405180830381865afa158015610d38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5c9190611fb6565b9050610d6a85828887611a3f565b9695505050505050565b600554600090819073ffffffffffffffffffffffffffffffffffffffff168315610db857600a5473ffffffffffffffffffffffffffffffffffffffff169150610dd4565b600b5473ffffffffffffffffffffffffffffffffffffffff1691505b600480546040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182169281019290925282811660248301526000919084169063e6a4390590604401602060405180830381865afa158015610e52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e769190611fb6565b9050610e8486828488611a3f565b93505050505b92915050565b600260005403610efc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610327565b6002600055565b60055473ffffffffffffffffffffffffffffffffffffffff1660005b845181101561066d576000848281518110610f3c57610f3c611fda565b602002602001015190506000868381518110610f5a57610f5a611fda565b602002602001015190506000858481518110610f7857610f78611fda565b602002602001015190508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361103e576005546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b5050505061144b565b60045473ffffffffffffffffffffffffffffffffffffffff83811691161461144b57600061106d838584610c7b565b9050600c548111156110db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f536c69707061676520746f6f20686967680000000000000000000000000000006044820152606401610327565b604080516002808252606082018352600092602083019080368337019050509050838160008151811061111057611110611fda565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050868160018151811061115e5761115e611fda565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505082156112f5576006546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152602481018790529085169063095ea7b3906044016020604051808303816000875af1158015611217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123b9190612009565b5060065473ffffffffffffffffffffffffffffffffffffffff166318cbafe5866000843061126a42600a611fa3565b6040518663ffffffff1660e01b815260040161128a959493929190612026565b6000604051808303816000875af11580156112a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526112ef91908101906120b1565b50611448565b6007546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152602481018790529085169063095ea7b3906044016020604051808303816000875af115801561136e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113929190612009565b5060075473ffffffffffffffffffffffffffffffffffffffff166318cbafe586600084306113c142600a611fa3565b6040518663ffffffff1660e01b81526004016113e1959493929190612026565b6000604051808303816000875af1158015611400573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261144691908101906120b1565b505b50505b505050808061145990612142565b915050610f1f565b600080600080670de0b6b3a76400008511156114e957612710611485600a8761217a565b61148f9190612191565b90506127106114a0610d028761217a565b6114aa9190612191565b93506127106114bb610d028761217a565b6114c59190612191565b9250826114d28583611fa3565b6114dc9190611fa3565b6114e69086611f90565b91505b9193509193565b6060600e54430361155d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d696e744275726e3a204e65656420746f2077616974000000000000000000006044820152606401610327565b60006115698484610d74565b9050600c548111156115d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4d696e744275726e3a20536c69707061676520746f6f206869676800000000006044820152606401610327565b82156116975760065473ffffffffffffffffffffffffffffffffffffffff16637ff36ab5856000600f3061160c42600a611fa3565b6040518663ffffffff1660e01b815260040161162b94939291906121cc565b60006040518083038185885af1158015611649573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261169091908101906120b1565b915061174d565b60075473ffffffffffffffffffffffffffffffffffffffff16637ff36ab5856000600f306116c642600a611fa3565b6040518663ffffffff1660e01b81526004016116e594939291906121cc565b60006040518083038185885af1158015611703573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261174a91908101906120b1565b91505b83600d5461175b9190611f90565b600d55600480546040517f70a08231000000000000000000000000000000000000000000000000000000008152309281019290925260009173ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f69190612255565b90506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188b9190612255565b9050811561191657600480546040517f42966c6800000000000000000000000000000000000000000000000000000000815291820184905273ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b1580156118fd57600080fd5b505af1158015611911573d6000803e3d6000fd5b505050505b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a99190612255565b905043600e819055507f2ea8c072b627ef4c43903880f428548c0532eae74e4f1ab05ca4c59a1a4b5266856000815181106119e6576119e6611fda565b602002602001015186600181518110611a0157611a01611fda565b602090810291909101810151604080519384529183015281018490526060810183905242608082015260a00160405180910390a15050505092915050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611a8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab39190612291565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060008673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b499190611fb6565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614611b82578183611b85565b82825b509050600085611b9757600954611b9b565b6008545b90506000612710611bac838c61217a565b611bb69190612191565b905082611bc58261271061217a565b611bcf9190612191565b9a9950505050505050505050565b8015158114611beb57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611c6457611c64611bee565b604052919050565b600067ffffffffffffffff821115611c8657611c86611bee565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611beb57600080fd5b600082601f830112611cc357600080fd5b81356020611cd8611cd383611c6c565b611c1d565b82815260059290921b84018101918181019086841115611cf757600080fd5b8286015b84811015611d125780358352918301918301611cfb565b509695505050505050565b600082601f830112611d2e57600080fd5b81356020611d3e611cd383611c6c565b82815260059290921b84018101918181019086841115611d5d57600080fd5b8286015b84811015611d12578035611d7481611bdd565b8352918301918301611d61565b600080600080600060a08688031215611d9957600080fd5b85359450602080870135611dac81611bdd565b9450604087013567ffffffffffffffff80821115611dc957600080fd5b818901915089601f830112611ddd57600080fd5b8135611deb611cd382611c6c565b81815260059190911b8301840190848101908c831115611e0a57600080fd5b938501935b82851015611e31578435611e2281611c90565b82529385019390850190611e0f565b975050506060890135925080831115611e4957600080fd5b611e558a848b01611cb2565b94506080890135925080831115611e6b57600080fd5b5050611e7988828901611d1d565b9150509295509295909350565b60008060408385031215611e9957600080fd5b8235611ea481611c90565b91506020830135611eb481611c90565b809150509250929050565b600060208284031215611ed157600080fd5b5035919050565b60008060408385031215611eeb57600080fd5b50508035926020909101359150565b600080600060608486031215611f0f57600080fd5b8335611f1a81611c90565b9250602084013591506040840135611f3181611bdd565b809150509250925092565b60008060408385031215611f4f57600080fd5b823591506020830135611eb481611bdd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610e8a57610e8a611f61565b80820180821115610e8a57610e8a611f61565b600060208284031215611fc857600080fd5b8151611fd381611c90565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561201b57600080fd5b8151611fd381611bdd565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b8181101561208357845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101612051565b505073ffffffffffffffffffffffffffffffffffffffff969096166060850152505050608001529392505050565b600060208083850312156120c457600080fd5b825167ffffffffffffffff8111156120db57600080fd5b8301601f810185136120ec57600080fd5b80516120fa611cd382611c6c565b81815260059190911b8201830190838101908783111561211957600080fd5b928401925b828410156121375783518252928401929084019061211e565b979650505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361217357612173611f61565b5060010190565b8082028115828204841417610e8a57610e8a611f61565b6000826121c7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060808201868352602060808185015281875480845260a0860191508860005282600020935060005b8181101561222857845473ffffffffffffffffffffffffffffffffffffffff16835260019485019492840192016121f6565b505073ffffffffffffffffffffffffffffffffffffffff9690961660408501525050506060015292915050565b60006020828403121561226757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461228c57600080fd5b919050565b6000806000606084860312156122a657600080fd5b6122af8461226e565b92506122bd6020850161226e565b9150604084015163ffffffff81168114611f3157600080fdfea26469706673582212200b0afbf4c10f1b9202fb58aaa6dbfe3cad067d251d89fc1a4b47985fa97600fd64736f6c63430008110033000000000000000000000000bbc56bfdefb90e2f3e67e00e75bef0cd1ed2231e0000000000000000000000003123183dc942fd721899bf589d55baa39753628b00000000000000000000000098bf93ebf5c380c0e6ae8e192a7e2ae08edacc02000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27000000000000000000000000207e6b4529840a4fd518f73c68bc9c19b2a15944000000000000000000000000476559a5665f8f42402e42b04b0a4cfd6769b7b8

Deployed ByteCode

0x6080604052600436106100d65760003560e01c8063a11e04661161007f578063bec872b011610059578063bec872b01461023a578063bf13d8051461025a578063d40c9d891461027a578063f810d0681461029a57600080fd5b8063a11e0466146101cb578063aaa2b8c8146101f8578063af6df0301461022557600080fd5b80636920c3cf116100b05780636920c3cf1461017357806371e76ec61461019557806380c53dfc146101b557600080fd5b8063065d02de146100e25780632969ca7e1461010b578063331f566e1461015d57600080fd5b366100dd57005b600080fd5b3480156100ee57600080fd5b506100f8600e5481565b6040519081526020015b60405180910390f35b34801561011757600080fd5b506001546101389073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610102565b34801561016957600080fd5b506100f8600c5481565b34801561017f57600080fd5b5061019361018e366004611d81565b6102ba565b005b3480156101a157600080fd5b506101936101b0366004611e86565b610674565b3480156101c157600080fd5b506100f8600d5481565b3480156101d757600080fd5b506002546101389073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020457600080fd5b506003546101389073ffffffffffffffffffffffffffffffffffffffff1681565b34801561023157600080fd5b506100f8600a81565b34801561024657600080fd5b50610193610255366004611ebf565b6109be565b34801561026657600080fd5b50610193610275366004611ed8565b610b1b565b34801561028657600080fd5b506100f8610295366004611efa565b610c7b565b3480156102a657600080fd5b506100f86102b5366004611f3c565b610d74565b6102c2610e90565b333214610330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4f726967696e206d757374206265206120454f4100000000000000000000000060448201526064015b60405180910390fd5b61033b838383610f03565b6000600d544761034b9190611f90565b9050670de0b6b3a76400008111156106625760008060008061036c85611461565b935093509350935082600d60008282546103869190611fa3565b9091555050600d548a11156103f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d696e744275726e3a20504c5320616d6f756e7420746f6f20686967680000006044820152606401610327565b60025460405160009173ffffffffffffffffffffffffffffffffffffffff169086908381818185875af1925050503d8060008114610451576040519150601f19603f3d011682016040523d82523d6000602084013e610456565b606091505b50509050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f53656e64696e6720746f206d696e745374616b696e67206661696c65640000006044820152606401610327565b60035460405160009173ffffffffffffffffffffffffffffffffffffffff169085908381818185875af1925050503d806000811461051b576040519150601f19603f3d011682016040523d82523d6000602084013e610520565b606091505b505090508061058b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53656e64696e6720746f20726f6f742061646472657373206661696c656400006044820152606401610327565b604051600090339085908381818185875af1925050503d80600081146105cd576040519150601f19603f3d011682016040523d82523d6000602084013e6105d2565b606091505b505090508061063d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53656e64696e6720746f20626f756e74792061646472657373206661696c65646044820152606401610327565b67016345785d8a0000600d541061065a576106588d8d6114f0565b505b505050505050505b5061066d6001600055565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b73ffffffffffffffffffffffffffffffffffffffff8216610772576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610327565b73ffffffffffffffffffffffffffffffffffffffff81166107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610327565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155604080517fc45a0155000000000000000000000000000000000000000000000000000000008152905163c45a0155916004808201926020929091908290030181865afa158015610886573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108aa9190611fb6565b600a805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600780549284169290911682179055604080517fc45a0155000000000000000000000000000000000000000000000000000000008152905163c45a0155916004808201926020929091908290030181865afa158015610951573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109759190611fb6565b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b600a811015610aaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e744275726e3a204d696e20536c697070616765202e31250000000000006044820152606401610327565b6105dc811115610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e744275726e3a204d617820536c697070616765203135250000000000006044820152606401610327565b600c55565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b60008211610c06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f726f757465723146656520496e76616c6964000000000000000000000000006044820152606401610327565b60008111610c70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f726f757465723246656520496e76616c6964000000000000000000000000006044820152606401610327565b600891909155600955565b6000808215610ca35750600a5473ffffffffffffffffffffffffffffffffffffffff16610cbe565b50600b5473ffffffffffffffffffffffffffffffffffffffff165b6005546040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152918216602482015260009183169063e6a4390590604401602060405180830381865afa158015610d38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5c9190611fb6565b9050610d6a85828887611a3f565b9695505050505050565b600554600090819073ffffffffffffffffffffffffffffffffffffffff168315610db857600a5473ffffffffffffffffffffffffffffffffffffffff169150610dd4565b600b5473ffffffffffffffffffffffffffffffffffffffff1691505b600480546040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182169281019290925282811660248301526000919084169063e6a4390590604401602060405180830381865afa158015610e52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e769190611fb6565b9050610e8486828488611a3f565b93505050505b92915050565b600260005403610efc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610327565b6002600055565b60055473ffffffffffffffffffffffffffffffffffffffff1660005b845181101561066d576000848281518110610f3c57610f3c611fda565b602002602001015190506000868381518110610f5a57610f5a611fda565b602002602001015190506000858481518110610f7857610f78611fda565b602002602001015190508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361103e576005546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b5050505061144b565b60045473ffffffffffffffffffffffffffffffffffffffff83811691161461144b57600061106d838584610c7b565b9050600c548111156110db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f536c69707061676520746f6f20686967680000000000000000000000000000006044820152606401610327565b604080516002808252606082018352600092602083019080368337019050509050838160008151811061111057611110611fda565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050868160018151811061115e5761115e611fda565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505082156112f5576006546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152602481018790529085169063095ea7b3906044016020604051808303816000875af1158015611217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123b9190612009565b5060065473ffffffffffffffffffffffffffffffffffffffff166318cbafe5866000843061126a42600a611fa3565b6040518663ffffffff1660e01b815260040161128a959493929190612026565b6000604051808303816000875af11580156112a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526112ef91908101906120b1565b50611448565b6007546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152602481018790529085169063095ea7b3906044016020604051808303816000875af115801561136e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113929190612009565b5060075473ffffffffffffffffffffffffffffffffffffffff166318cbafe586600084306113c142600a611fa3565b6040518663ffffffff1660e01b81526004016113e1959493929190612026565b6000604051808303816000875af1158015611400573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261144691908101906120b1565b505b50505b505050808061145990612142565b915050610f1f565b600080600080670de0b6b3a76400008511156114e957612710611485600a8761217a565b61148f9190612191565b90506127106114a0610d028761217a565b6114aa9190612191565b93506127106114bb610d028761217a565b6114c59190612191565b9250826114d28583611fa3565b6114dc9190611fa3565b6114e69086611f90565b91505b9193509193565b6060600e54430361155d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d696e744275726e3a204e65656420746f2077616974000000000000000000006044820152606401610327565b60006115698484610d74565b9050600c548111156115d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4d696e744275726e3a20536c69707061676520746f6f206869676800000000006044820152606401610327565b82156116975760065473ffffffffffffffffffffffffffffffffffffffff16637ff36ab5856000600f3061160c42600a611fa3565b6040518663ffffffff1660e01b815260040161162b94939291906121cc565b60006040518083038185885af1158015611649573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261169091908101906120b1565b915061174d565b60075473ffffffffffffffffffffffffffffffffffffffff16637ff36ab5856000600f306116c642600a611fa3565b6040518663ffffffff1660e01b81526004016116e594939291906121cc565b60006040518083038185885af1158015611703573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261174a91908101906120b1565b91505b83600d5461175b9190611f90565b600d55600480546040517f70a08231000000000000000000000000000000000000000000000000000000008152309281019290925260009173ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f69190612255565b90506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188b9190612255565b9050811561191657600480546040517f42966c6800000000000000000000000000000000000000000000000000000000815291820184905273ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b1580156118fd57600080fd5b505af1158015611911573d6000803e3d6000fd5b505050505b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a99190612255565b905043600e819055507f2ea8c072b627ef4c43903880f428548c0532eae74e4f1ab05ca4c59a1a4b5266856000815181106119e6576119e6611fda565b602002602001015186600181518110611a0157611a01611fda565b602090810291909101810151604080519384529183015281018490526060810183905242608082015260a00160405180910390a15050505092915050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611a8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab39190612291565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060008673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b499190611fb6565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614611b82578183611b85565b82825b509050600085611b9757600954611b9b565b6008545b90506000612710611bac838c61217a565b611bb69190612191565b905082611bc58261271061217a565b611bcf9190612191565b9a9950505050505050505050565b8015158114611beb57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611c6457611c64611bee565b604052919050565b600067ffffffffffffffff821115611c8657611c86611bee565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611beb57600080fd5b600082601f830112611cc357600080fd5b81356020611cd8611cd383611c6c565b611c1d565b82815260059290921b84018101918181019086841115611cf757600080fd5b8286015b84811015611d125780358352918301918301611cfb565b509695505050505050565b600082601f830112611d2e57600080fd5b81356020611d3e611cd383611c6c565b82815260059290921b84018101918181019086841115611d5d57600080fd5b8286015b84811015611d12578035611d7481611bdd565b8352918301918301611d61565b600080600080600060a08688031215611d9957600080fd5b85359450602080870135611dac81611bdd565b9450604087013567ffffffffffffffff80821115611dc957600080fd5b818901915089601f830112611ddd57600080fd5b8135611deb611cd382611c6c565b81815260059190911b8301840190848101908c831115611e0a57600080fd5b938501935b82851015611e31578435611e2281611c90565b82529385019390850190611e0f565b975050506060890135925080831115611e4957600080fd5b611e558a848b01611cb2565b94506080890135925080831115611e6b57600080fd5b5050611e7988828901611d1d565b9150509295509295909350565b60008060408385031215611e9957600080fd5b8235611ea481611c90565b91506020830135611eb481611c90565b809150509250929050565b600060208284031215611ed157600080fd5b5035919050565b60008060408385031215611eeb57600080fd5b50508035926020909101359150565b600080600060608486031215611f0f57600080fd5b8335611f1a81611c90565b9250602084013591506040840135611f3181611bdd565b809150509250925092565b60008060408385031215611f4f57600080fd5b823591506020830135611eb481611bdd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610e8a57610e8a611f61565b80820180821115610e8a57610e8a611f61565b600060208284031215611fc857600080fd5b8151611fd381611c90565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561201b57600080fd5b8151611fd381611bdd565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b8181101561208357845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101612051565b505073ffffffffffffffffffffffffffffffffffffffff969096166060850152505050608001529392505050565b600060208083850312156120c457600080fd5b825167ffffffffffffffff8111156120db57600080fd5b8301601f810185136120ec57600080fd5b80516120fa611cd382611c6c565b81815260059190911b8201830190838101908783111561211957600080fd5b928401925b828410156121375783518252928401929084019061211e565b979650505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361217357612173611f61565b5060010190565b8082028115828204841417610e8a57610e8a611f61565b6000826121c7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060808201868352602060808185015281875480845260a0860191508860005282600020935060005b8181101561222857845473ffffffffffffffffffffffffffffffffffffffff16835260019485019492840192016121f6565b505073ffffffffffffffffffffffffffffffffffffffff9690961660408501525050506060015292915050565b60006020828403121561226757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461228c57600080fd5b919050565b6000806000606084860312156122a657600080fd5b6122af8461226e565b92506122bd6020850161226e565b9150604084015163ffffffff81168114611f3157600080fdfea26469706673582212200b0afbf4c10f1b9202fb58aaa6dbfe3cad067d251d89fc1a4b47985fa97600fd64736f6c63430008110033