Contract Address Details

0x8b85BA055269d6e14Cc5f88974Ea114aAcecF162

Contract Name
Collector
Creator
0xb4590b–f14953 at 0x29b314–3beab1
Balance
0 mADA
Tokens
Fetching tokens...
Transactions
5 Transactions
Transfers
3,078 Transfers
Gas Used
758,964
Last Balance Update
42966717
Contract name:
Collector




Optimization enabled
false
Compiler version
v0.6.12+commit.27d51765




EVM Version
default




Verified at
2022-11-01T12:17:22.352792Z

Constructor Arguments

0000000000000000000000002ef06a90b0e7ae3ae508e83ea6628a3987945460000000000000000000000000f0c73e6287867baa4f865a17ee711ec989c78ac0000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f9

Arg [0] (address) : 0x2ef06a90b0e7ae3ae508e83ea6628a3987945460
Arg [1] (address) : 0xf0c73e6287867baa4f865a17ee711ec989c78ac0
Arg [2] (address) : 0xae83571000af4499798d1e3b0fa0070eb3a3e3f9

              

Contract source code

// Sources flattened with hardhat v2.7.0 https://hardhat.org

// File contracts/libraries/SafeMath.sol

pragma solidity ^0.6.0;

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)

library SafeMath {
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x, 'ds-math-add-overflow');
    }

    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x, 'ds-math-sub-underflow');
    }

    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
    }
}


// File contracts/interfaces/IERC20.sol

pragma solidity >=0.6.0;

interface IERC20 {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view 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);
}


// File contracts/libraries/SafeERC20.sol

pragma solidity ^0.6.0;

library SafeERC20 {
    function safeSymbol(IERC20 token) internal view returns(string memory) {
        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x95d89b41));
        return success && data.length > 0 ? abi.decode(data, (string)) : "???";
    }

    function safeName(IERC20 token) internal view returns(string memory) {
        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x06fdde03));
        return success && data.length > 0 ? abi.decode(data, (string)) : "???";
    }

    function safeDecimals(IERC20 token) public view returns (uint8) {
        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x313ce567));
        return success && data.length == 32 ? abi.decode(data, (uint8)) : 18;
    }

    function safeTransfer(IERC20 token, address to, uint256 amount) internal {
        (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0xa9059cbb, to, amount));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "SafeERC20: Transfer failed");
    }

    function safeTransferFrom(IERC20 token, address from, uint256 amount) internal {
        (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0x23b872dd, from, address(this), amount));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "SafeERC20: TransferFrom failed");
    }
}


// File contracts/interfaces/IPair.sol

pragma solidity ^0.6.0;

interface IPair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}


// File contracts/interfaces/IFactory.sol

pragma solidity ^0.6.0;
interface IFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}


// File contracts/Ownable.sol

// Audit on 5-Jan-2021 by Keno and BoringCrypto

// P1 - P3: OK
pragma solidity ^0.6.0;

// Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol + Claimable.sol
// Edited by BoringCrypto

// T1 - T4: OK
contract OwnableData {
    // V1 - V5: OK
    address public owner;
    // V1 - V5: OK
    address public pendingOwner;
}

// T1 - T4: OK
contract Ownable is OwnableData {
    // E1: OK
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor () internal {
        owner = msg.sender;
        emit OwnershipTransferred(address(0), msg.sender);
    }

    // F1 - F9: OK
    // C1 - C21: OK
    function transferOwnership(address newOwner, bool direct, bool renounce) public onlyOwner {
        if (direct) {
            // Checks
            require(newOwner != address(0) || renounce, "Ownable: zero address");

            // Effects
            emit OwnershipTransferred(owner, newOwner);
            owner = newOwner;
        } else {
            // Effects
            pendingOwner = newOwner;
        }
    }

    // F1 - F9: OK
    // C1 - C21: OK
    function claimOwnership() public {
        address _pendingOwner = pendingOwner;

        // Checks
        require(msg.sender == _pendingOwner, "Ownable: caller != pending owner");

        // Effects
        emit OwnershipTransferred(owner, _pendingOwner);
        owner = _pendingOwner;
        pendingOwner = address(0);
    }

    // M1 - M5: OK
    // C1 - C21: OK
    modifier onlyOwner() {
        require(msg.sender == owner, "Ownable: caller is not the owner");
        _;
    }
}


// File contracts/Collector.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;




contract Collector is Ownable {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;


    IFactory public immutable factory;
    address public PToken;
    address public immutable wada;
    address public stakingContract;
    bool public locked; //lock liquidity inside the collector until the staking contract is deployed

    mapping(address => address) internal _bridges;

    event LogBridgeSet(address indexed token, address indexed bridge);
    event LogConvert(
        address indexed server,
        address indexed token0,
        address indexed token1,
        uint256 amount0,
        uint256 amount1,
        uint256 amountPToken
    );

    constructor(
        address _factory,
        address _PToken,
        address _wada
    ) public {
        factory = IFactory(_factory);
        PToken = _PToken;
        wada = _wada;
        locked = true;
    }

    function bridgeFor(address token) public view returns (address bridge) {
        bridge = _bridges[token];
        if (bridge == address(0)) {
            bridge = wada;
        }
    }

    function setBridge(address token, address bridge) external onlyOwner {
        // Checks
        require(
            token != PToken && token != wada && token != bridge,
            "Collector: Invalid bridge"
        );

        // Effects
        _bridges[token] = bridge;
        emit LogBridgeSet(token, bridge);
    }

    function setStakingContract(address _stakingContract) external onlyOwner {
        stakingContract = _stakingContract;
    }

    function setPToken(address _PToken) external onlyOwner {
        PToken = _PToken;
    }

    modifier onlyEOA() {
        // Try to make flash-loan exploit harder to do by only allowing externally owned addresses.
        require(msg.sender == tx.origin, "Collector: must use EOA");
        _;
    }

    modifier onlyWhenUnlocked() {
        require(locked == false, "Collector: liquidity is locked");
        _;
    }

    function setLock(bool _locked) external onlyOwner {
        locked = _locked;
    }

    function convert(address token0, address token1) external onlyEOA() onlyWhenUnlocked() onlyOwner {
        _convert(token0, token1);
    }

    function convertMultiple(
        address[] calldata token0,
        address[] calldata token1
    ) external onlyEOA() onlyWhenUnlocked() onlyOwner {
        require(token0.length == token1.length, "the length of the array is invalid");
        uint256 len = token0.length;
        for (uint256 i = 0; i < len; i++) {
            _convert(token0[i], token1[i]);
        }
    }

    function _convert(address token0, address token1) internal {
        IPair pair = IPair(factory.getPair(token0, token1));
        require(address(pair) != address(0), "Collector: Invalid pair");

        IERC20(address(pair)).safeTransfer(
            address(pair),
            pair.balanceOf(address(this))
        );

        (uint256 amount0, uint256 amount1) = pair.burn(address(this));
        if (token0 != pair.token0()) {
            (amount0, amount1) = (amount1, amount0);
        }
        emit LogConvert(
            msg.sender,
            token0,
            token1,
            amount0,
            amount1,
            _convertStep(token0, token1, amount0, amount1)
        );
    }

    function _convertStep(
        address token0,
        address token1,
        uint256 amount0,
        uint256 amount1
    ) internal returns (uint256 PTokenOut) {
        // Interactions
        if (token0 == token1) {
            uint256 amount = amount0.add(amount1);
            if (token0 == PToken) {
                IERC20(PToken).safeTransfer(stakingContract, amount);
                PTokenOut = amount;
            } else if (token0 == wada) {
                PTokenOut = _toPToken(wada, amount);
            } else {
                address bridge = bridgeFor(token0);
                amount = _swap(token0, bridge, amount, address(this));
                PTokenOut = _convertStep(bridge, bridge, amount, 0);
            }
        } else if (token0 == PToken) {
            IERC20(PToken).safeTransfer(stakingContract, amount0);
            PTokenOut = _toPToken(token1, amount1).add(amount0);
        } else if (token1 == PToken) {
            IERC20(PToken).safeTransfer(stakingContract, amount1);
            PTokenOut = _toPToken(token0, amount0).add(amount1);
        } else if (token0 == wada) {
            // eg. ADA - USDC
            PTokenOut = _toPToken(
                wada,
                _swap(token1, wada, amount1, address(this)).add(amount0)
            );
        } else if (token1 == wada) {
            // eg. USDT - ADA
            PTokenOut = _toPToken(
                wada,
                _swap(token0, wada, amount0, address(this)).add(amount1)
            );
        } else {
            // eg. MIC - USDT
            address bridge0 = bridgeFor(token0);
            address bridge1 = bridgeFor(token1);
            if (bridge0 == token1) {
                // eg. MIC - USDT - and bridgeFor(MIC) = USDT
                PTokenOut = _convertStep(
                    bridge0,
                    token1,
                    _swap(token0, bridge0, amount0, address(this)),
                    amount1
                );
            } else if (bridge1 == token0) {
                // eg. WBTC - DSD - and bridgeFor(DSD) = WBTC
                PTokenOut = _convertStep(
                    token0,
                    bridge1,
                    amount0,
                    _swap(token1, bridge1, amount1, address(this))
                );
            } else {
                PTokenOut = _convertStep(
                    bridge0,
                    bridge1, // eg. USDT - DSD - and bridgeFor(DSD) = WBTC
                    _swap(token0, bridge0, amount0, address(this)),
                    _swap(token1, bridge1, amount1, address(this))
                );
            }
        }
    }

    function _swap(
        address fromToken,
        address toToken,
        uint256 amountIn,
        address to
    ) internal returns (uint256 amountOut) {

        IPair pair = IPair(factory.getPair(fromToken, toToken));
        require(address(pair) != address(0), "Collector: Cannot convert");

        (uint256 reserve0, uint256 reserve1, ) = pair.getReserves();
        uint256 amountInWithFee = amountIn.mul(997);
        if (fromToken == pair.token0()) {
            amountOut =
                amountInWithFee.mul(reserve1) /
                reserve0.mul(1000).add(amountInWithFee);
            IERC20(fromToken).safeTransfer(address(pair), amountIn);
            pair.swap(0, amountOut, to, new bytes(0));
            // TODO: Add maximum slippage?
        } else {
            amountOut =
                amountInWithFee.mul(reserve0) /
                reserve1.mul(1000).add(amountInWithFee);
            IERC20(fromToken).safeTransfer(address(pair), amountIn);
            pair.swap(amountOut, 0, to, new bytes(0));
            // TODO: Add maximum slippage?
        }
    }

    function _toPToken(address token, uint256 amountIn)
        internal
        returns (uint256 amountOut)
    {
        amountOut = _swap(token, PToken, amountIn, stakingContract);
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_factory","internalType":"address"},{"type":"address","name":"_PToken","internalType":"address"},{"type":"address","name":"_wada","internalType":"address"}]},{"type":"event","name":"LogBridgeSet","inputs":[{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"address","name":"bridge","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"LogConvert","inputs":[{"type":"address","name":"server","internalType":"address","indexed":true},{"type":"address","name":"token0","internalType":"address","indexed":true},{"type":"address","name":"token1","internalType":"address","indexed":true},{"type":"uint256","name":"amount0","internalType":"uint256","indexed":false},{"type":"uint256","name":"amount1","internalType":"uint256","indexed":false},{"type":"uint256","name":"amountPToken","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"PToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"bridge","internalType":"address"}],"name":"bridgeFor","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"convert","inputs":[{"type":"address","name":"token0","internalType":"address"},{"type":"address","name":"token1","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"convertMultiple","inputs":[{"type":"address[]","name":"token0","internalType":"address[]"},{"type":"address[]","name":"token1","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IFactory"}],"name":"factory","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"locked","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBridge","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"address","name":"bridge","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLock","inputs":[{"type":"bool","name":"_locked","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPToken","inputs":[{"type":"address","name":"_PToken","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setStakingContract","inputs":[{"type":"address","name":"_stakingContract","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"stakingContract","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"},{"type":"bool","name":"direct","internalType":"bool"},{"type":"bool","name":"renounce","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"wada","inputs":[]}]
            

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101005760003560e01c80639dd373b911610097578063cf30901211610066578063cf309012146104c3578063e30c3978146104e3578063e552a11b14610517578063ee99205c1461054b57610100565b80639dd373b914610379578063a761a939146103bd578063bd1b820c1461042b578063c45a01551461048f57610100565b8063619d5194116100d3578063619d51941461026d5780638da5cb5b1461029d57806396bb4fae146102d15780639d22ae8c1461031557610100565b8063078dfbe714610105578063303e6aa4146101615780634e71e0c81461022f5780635aa8cbcd14610239575b600080fd5b61015f6004803603606081101561011b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080351515906020019092919080351515906020019092919050505061057f565b005b61022d6004803603604081101561017757600080fd5b810190808035906020019064010000000081111561019457600080fd5b8201836020820111156101a657600080fd5b803590602001918460208302840111640100000000831117156101c857600080fd5b9091929391929390803590602001906401000000008111156101e957600080fd5b8201836020820111156101fb57600080fd5b8035906020019184602083028401116401000000008311171561021d57600080fd5b90919293919293905050506107f7565b005b610237610ac2565b005b610241610c89565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61029b6004803603602081101561028357600080fd5b81019080803515159060200190929190505050610cad565b005b6102a5610d8b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610313600480360360208110156102e757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610daf565b005b6103776004803603604081101561032b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610eb4565b005b6103bb6004803603602081101561038f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506111a5565b005b6103ff600480360360208110156103d357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506112aa565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61048d6004803603604081101561044157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061136c565b005b610497611565565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104cb611589565b60405180821515815260200191505060405180910390f35b6104eb61159c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61051f6115c2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105536115e8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610640576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b81156107b057600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158061067f5750805b6106f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f4f776e61626c653a207a65726f2061646472657373000000000000000000000081525060200191505060405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506107f2565b82600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b505050565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610898576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f436f6c6c6563746f723a206d7573742075736520454f4100000000000000000081525060200191505060405180910390fd5b60001515600360149054906101000a900460ff16151514610921576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f436f6c6c6563746f723a206c6971756964697479206973206c6f636b6564000081525060200191505060405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b818190508484905014610a40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612a766022913960400191505060405180910390fd5b600084849050905060005b81811015610aba57610aad868683818110610a6257fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16858584818110610a8b57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1661160e565b8080600101915050610a4b565b505050505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b8a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c657220213d2070656e64696e67206f776e657281525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f981565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d6e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600360146101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e70576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f75576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561101f57507f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f973ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b801561105757508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6110c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f436f6c6c6563746f723a20496e76616c6964206272696467650000000000000081525060200191505060405180910390fd5b80600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f2e103aa707acc565f9a1547341914802b2bfe977fd79c595209f248ae4b0061360405160405180910390a35050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611367577f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f990505b919050565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461140d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f436f6c6c6563746f723a206d7573742075736520454f4100000000000000000081525060200191505060405180910390fd5b60001515600360149054906101000a900460ff16151514611496576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f436f6c6c6563746f723a206c6971756964697479206973206c6f636b6564000081525060200191505060405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611557576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611561828261160e565b5050565b7f0000000000000000000000002ef06a90b0e7ae3ae508e83ea6628a398794546081565b600360149054906101000a900460ff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60007f0000000000000000000000002ef06a90b0e7ae3ae508e83ea6628a398794546073ffffffffffffffffffffffffffffffffffffffff1663e6a4390584846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b1580156116b557600080fd5b505afa1580156116c9573d6000803e3d6000fd5b505050506040513d60208110156116df57600080fd5b81019080805190602001909291905050509050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611795576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f436f6c6c6563746f723a20496e76616c6964207061697200000000000000000081525060200191505060405180910390fd5b611861818273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561180057600080fd5b505afa158015611814573d6000803e3d6000fd5b505050506040513d602081101561182a57600080fd5b81019080805190602001909291905050508373ffffffffffffffffffffffffffffffffffffffff16611a719092919063ffffffff16565b6000808273ffffffffffffffffffffffffffffffffffffffff166389afcb44306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506040805180830381600087803b1580156118cc57600080fd5b505af11580156118e0573d6000803e3d6000fd5b505050506040513d60408110156118f657600080fd5b810190808051906020019092919080519060200190929190505050915091508273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561195b57600080fd5b505afa15801561196f573d6000803e3d6000fd5b505050506040513d602081101561198557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146119d357808280925081935050505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fd06b1d7ed79b664d17472c6f6997b929f1abe463ccccb4e5b6a0038f2f730c158585611a478b8b8a8a611c54565b60405180848152602001838152602001828152602001935050505060405180910390a45050505050565b600060608473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310611b345780518252602082019150602081019050602083039250611b11565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611b96576040519150601f19603f3d011682016040523d82523d6000602084013e611b9b565b606091505b5091509150818015611bdb5750600081511480611bda5750808060200190516020811015611bc857600080fd5b81019080805190602001909291905050505b5b611c4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f5361666545524332303a205472616e73666572206661696c656400000000000081525060200191505060405180910390fd5b5050505050565b60008373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415611e26576000611c9f838561226d90919063ffffffff16565b9050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415611d6e57611d66600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611a719092919063ffffffff16565b809150611e20565b7f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f973ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415611df357611dec7f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f9826122f0565b9150611e1f565b6000611dfe876112aa565b9050611e0c8782843061234a565b9150611e1b8182846000611c54565b9250505b5b50612265565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415611f0e57611eeb600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611a719092919063ffffffff16565b611f0783611ef986856122f0565b61226d90919063ffffffff16565b9050612264565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611ff657611fd3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611a719092919063ffffffff16565b611fef82611fe187866122f0565b61226d90919063ffffffff16565b9050612263565b7f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156120b8576120b17f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f96120ac8561209e887f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f9883061234a565b61226d90919063ffffffff16565b6122f0565b9050612262565b7f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f973ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561217a576121737f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f961216e84612160897f000000000000000000000000ae83571000af4499798d1e3b0fa0070eb3a3e3f9893061234a565b61226d90919063ffffffff16565b6122f0565b9050612261565b6000612185866112aa565b90506000612192866112aa565b90508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156121e6576121df82876121d98a868a3061234a565b87611c54565b925061225e565b8673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156122385761223187828761222c8a868a3061234a565b611c54565b925061225d565b61225a82826122498a868a3061234a565b6122558a868a3061234a565b611c54565b92505b5b50505b5b5b5b5b949350505050565b60008282840191508110156122ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f64732d6d6174682d6164642d6f766572666c6f7700000000000000000000000081525060200191505060405180910390fd5b92915050565b600061234283600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661234a565b905092915050565b6000807f0000000000000000000000002ef06a90b0e7ae3ae508e83ea6628a398794546073ffffffffffffffffffffffffffffffffffffffff1663e6a4390587876040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b1580156123f257600080fd5b505afa158015612406573d6000803e3d6000fd5b505050506040513d602081101561241c57600080fd5b81019080805190602001909291905050509050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156124d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f436f6c6c6563746f723a2043616e6e6f7420636f6e766572740000000000000081525060200191505060405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561251b57600080fd5b505afa15801561252f573d6000803e3d6000fd5b505050506040513d606081101561254557600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060006125a66103e5886129e090919063ffffffff16565b90508373ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156125ee57600080fd5b505afa158015612602573d6000803e3d6000fd5b505050506040513d602081101561261857600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16141561281a57612683816126756103e8866129e090919063ffffffff16565b61226d90919063ffffffff16565b61269683836129e090919063ffffffff16565b8161269d57fe5b0494506126cb84888b73ffffffffffffffffffffffffffffffffffffffff16611a719092919063ffffffff16565b8373ffffffffffffffffffffffffffffffffffffffff1663022c0d9f60008789600067ffffffffffffffff8111801561270357600080fd5b506040519080825280601f01601f1916602001820160405280156127365781602001600182028036833780820191505090505b506040518563ffffffff1660e01b8152600401808581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156127ae578082015181840152602081019050612793565b50505050905090810190601f1680156127db5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156127fd57600080fd5b505af1158015612811573d6000803e3d6000fd5b505050506129d4565b612841816128336103e8856129e090919063ffffffff16565b61226d90919063ffffffff16565b61285484836129e090919063ffffffff16565b8161285b57fe5b04945061288984888b73ffffffffffffffffffffffffffffffffffffffff16611a719092919063ffffffff16565b8373ffffffffffffffffffffffffffffffffffffffff1663022c0d9f86600089600067ffffffffffffffff811180156128c157600080fd5b506040519080825280601f01601f1916602001820160405280156128f45781602001600182028036833780820191505090505b506040518563ffffffff1660e01b8152600401808581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561296c578082015181840152602081019050612951565b50505050905090810190601f1680156129995780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156129bb57600080fd5b505af11580156129cf573d6000803e3d6000fd5b505050505b50505050949350505050565b6000808214806129fd57508282838502925082816129fa57fe5b04145b612a6f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f64732d6d6174682d6d756c2d6f766572666c6f7700000000000000000000000081525060200191505060405180910390fd5b9291505056fe746865206c656e677468206f662074686520617272617920697320696e76616c6964a264697066735822122054bfbe2719476aa7d153613e012eb66d1299af0f7a7daf3fdcdacbb482b73c6164736f6c634300060c0033