Token DiversiFi_Dividend_Tracker

 

Overview ERC-20

Price
$0.00 @ 0.000000 FTM
Fully Diluted Market Cap
Total Supply:
5,222,628.285256 DiversiFi_Dividend_Tracker

Holders:
430 addresses

Transfers:
-

Contract:
0x3a57c1184026c8a7c1901f9cfcfdbe90bd118efc0x3a57c1184026C8A7C1901f9CFcFDbe90BD118eFc

Decimals:
9

Social Profiles:
Not Available, Update ?

Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DiversiFiDividendTracker

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-01-19
*/

/**
 *Submitted for verification at FtmScan.com on 2021-12-01
*/

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

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

interface IUniswapV2Pair {
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event Transfer(address indexed from, address indexed to, uint256 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 (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 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 (uint256);

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

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

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function kLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to)
        external
        returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(address, address) external;
}

interface IUniswapV2Factory {
    event PairCreated(
        address indexed token0,
        address indexed token1,
        address pair,
        uint256
    );

    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(uint256) external view returns (address pair);

    function allPairsLength() external view returns (uint256);

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

    function setFeeTo(address) external;

    function setFeeToSetter(address) external;
}

library IterableMapping {
    // Iterable mapping from address to uint;
    struct Map {
        address[] keys;
        mapping(address => uint256) values;
        mapping(address => uint256) indexOf;
        mapping(address => bool) inserted;
    }

    function get(Map storage map, address key) internal view returns (uint256) {
        return map.values[key];
    }

    function getIndexOfKey(Map storage map, address key)
        internal
        view
        returns (int256)
    {
        if (!map.inserted[key]) {
            return -1;
        }
        return int256(map.indexOf[key]);
    }

    function getKeyAtIndex(Map storage map, uint256 index)
        internal
        view
        returns (address)
    {
        return map.keys[index];
    }

    function size(Map storage map) internal view returns (uint256) {
        return map.keys.length;
    }

    function set(
        Map storage map,
        address key,
        uint256 val
    ) internal {
        if (map.inserted[key]) {
            map.values[key] = val;
        } else {
            map.inserted[key] = true;
            map.values[key] = val;
            map.indexOf[key] = map.keys.length;
            map.keys.push(key);
        }
    }

    function remove(Map storage map, address key) internal {
        if (!map.inserted[key]) {
            return;
        }

        delete map.inserted[key];
        delete map.values[key];

        uint256 index = map.indexOf[key];
        uint256 lastIndex = map.keys.length - 1;
        address lastKey = map.keys[lastIndex];

        map.indexOf[lastKey] = index;
        delete map.indexOf[key];

        map.keys[index] = lastKey;
        map.keys.pop();
    }
}

interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount)
        external
        returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

contract ERC20 is Context, IERC20, IERC20Metadata {
    using SafeMath for uint256;

    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account)
        public
        view
        virtual
        override
        returns (uint256)
    {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount)
        public
        virtual
        override
        returns (bool)
    {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender)
        public
        view
        virtual
        override
        returns (uint256)
    {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount)
        public
        virtual
        override
        returns (bool)
    {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(
            sender,
            _msgSender(),
            _allowances[sender][_msgSender()].sub(
                amount,
                "ERC20: transfer amount exceeds allowance"
            )
        );
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue)
        public
        virtual
        returns (bool)
    {
        _approve(
            _msgSender(),
            spender,
            _allowances[_msgSender()][spender].add(addedValue)
        );
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue)
        public
        virtual
        returns (bool)
    {
        _approve(
            _msgSender(),
            spender,
            _allowances[_msgSender()][spender].sub(
                subtractedValue,
                "ERC20: decreased allowance below zero"
            )
        );
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(
            amount,
            "ERC20: transfer amount exceeds balance"
        );
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(
            amount,
            "ERC20: burn amount exceeds balance"
        );
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

interface DividendPayingTokenOptionalInterface {
    /// @notice View the amount of dividend in wei that an address can withdraw.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` can withdraw.
    function withdrawableDividendOf(address _owner)
        external
        view
        returns (uint256);

    /// @notice View the amount of dividend in wei that an address has withdrawn.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` has withdrawn.
    function withdrawnDividendOf(address _owner)
        external
        view
        returns (uint256);

    /// @notice View the amount of dividend in wei that an address has earned in total.
    /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` has earned in total.
    function accumulativeDividendOf(address _owner)
        external
        view
        returns (uint256);
}

interface DividendPayingTokenInterface {
    /// @notice View the amount of dividend in wei that an address can withdraw.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` can withdraw.
    function dividendOf(address _owner) external view returns (uint256);

    /// @notice Distributes ether to token holders as dividends.
    /// @dev SHOULD distribute the paid ether to token holders as dividends.
    ///  SHOULD NOT directly transfer ether to token holders in this function.
    ///  MUST emit a `DividendsDistributed` event when the amount of distributed ether is greater than 0.
    function distributeDividends() external payable;

    /// @notice Withdraws the ether distributed to the sender.
    /// @dev SHOULD transfer `dividendOf(msg.sender)` wei to `msg.sender`, and `dividendOf(msg.sender)` SHOULD be 0 after the transfer.
    ///  MUST emit a `DividendWithdrawn` event if the amount of ether transferred is greater than 0.
    function withdrawDividend() external;

    /// @dev This event MUST emit when ether is distributed to token holders.
    /// @param from The address which sends ether to this contract.
    /// @param weiAmount The amount of distributed ether in wei.
    event DividendsDistributed(address indexed from, uint256 weiAmount);

    /// @dev This event MUST emit when an address withdraws their dividend.
    /// @param to The address which withdraws ether from this contract.
    /// @param weiAmount The amount of withdrawn ether in wei.
    event DividendWithdrawn(address indexed to, uint256 weiAmount);
}

library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(_owner == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(
            newOwner != address(0),
            "Ownable: new owner is the zero address"
        );
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

library SafeMathInt {
    int256 private constant MIN_INT256 = int256(1) << 255;
    int256 private constant MAX_INT256 = ~(int256(1) << 255);

    /**
     * @dev Multiplies two int256 variables and fails on overflow.
     */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a * b;

        // Detect overflow when multiplying MIN_INT256 with -1
        require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
        require((b == 0) || (c / b == a));
        return c;
    }

    /**
     * @dev Division of two int256 variables and fails on overflow.
     */
    function div(int256 a, int256 b) internal pure returns (int256) {
        // Prevent overflow when dividing MIN_INT256 by -1
        require(b != -1 || a != MIN_INT256);

        // Solidity already throws when dividing by 0.
        return a / b;
    }

    /**
     * @dev Subtracts two int256 variables and fails on overflow.
     */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a));
        return c;
    }

    /**
     * @dev Adds two int256 variables and fails on overflow.
     */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a));
        return c;
    }

    /**
     * @dev Converts to absolute value, and fails on overflow.
     */
    function abs(int256 a) internal pure returns (int256) {
        require(a != MIN_INT256);
        return a < 0 ? -a : a;
    }

    function toUint256Safe(int256 a) internal pure returns (uint256) {
        require(a >= 0);
        return uint256(a);
    }
}

library SafeMathUint {
    function toInt256Safe(uint256 a) internal pure returns (int256) {
        int256 b = int256(a);
        require(b >= 0);
        return b;
    }
}

interface IUniswapV2Router01 {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

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

    function swapETHForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) external pure returns (uint256 amountB);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountOut);

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountIn);

    function getAmountsOut(uint256 amountIn, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);

    function getAmountsIn(uint256 amountOut, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);
}

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
}

contract DividendPayingToken is
    ERC20,
    DividendPayingTokenInterface,
    DividendPayingTokenOptionalInterface
{
    using SafeMath for uint256;
    using SafeMathUint for uint256;
    using SafeMathInt for int256;

    // With `magnitude`, we can properly distribute dividends even if the amount of received ether is small.
    // For more discussion about choosing the value of `magnitude`,
    //  see https://github.com/ethereum/EIPs/issues/1726#issuecomment-472352728
    uint256 internal constant magnitude = 2**128;

    uint256 internal magnifiedDividendPerShare;

    // About dividendCorrection:
    // If the token balance of a `_user` is never changed, the dividend of `_user` can be computed with:
    //   `dividendOf(_user) = dividendPerShare * balanceOf(_user)`.
    // When `balanceOf(_user)` is changed (via minting/burning/transferring tokens),
    //   `dividendOf(_user)` should not be changed,
    //   but the computed value of `dividendPerShare * balanceOf(_user)` is changed.
    // To keep the `dividendOf(_user)` unchanged, we add a correction term:
    //   `dividendOf(_user) = dividendPerShare * balanceOf(_user) + dividendCorrectionOf(_user)`,
    //   where `dividendCorrectionOf(_user)` is updated whenever `balanceOf(_user)` is changed:
    //   `dividendCorrectionOf(_user) = dividendPerShare * (old balanceOf(_user)) - (new balanceOf(_user))`.
    // So now `dividendOf(_user)` returns the same value before and after `balanceOf(_user)` is changed.
    mapping(address => int256) internal magnifiedDividendCorrections;
    mapping(address => uint256) internal withdrawnDividends;

    uint256 public totalDividendsDistributed;

    constructor(string memory _name, string memory _symbol)
        ERC20(_name, _symbol)
    {}

    /// @dev Distributes dividends whenever ether is paid to this contract.
    receive() external payable {
        distributeDividends();
    }

    /// @notice Distributes ether to token holders as dividends.
    /// @dev It reverts if the total supply of tokens is 0.
    /// It emits the `DividendsDistributed` event if the amount of received ether is greater than 0.
    /// About undistributed ether:
    ///   In each distribution, there is a small amount of ether not distributed,
    ///     the magnified amount of which is
    ///     `(msg.value * magnitude) % totalSupply()`.
    ///   With a well-chosen `magnitude`, the amount of undistributed ether
    ///     (de-magnified) in a distribution can be less than 1 wei.
    ///   We can actually keep track of the undistributed ether in a distribution
    ///     and try to distribute it in the next distribution,
    ///     but keeping track of such data on-chain costs much more than
    ///     the saved ether, so we don't do that.
    function distributeDividends() public payable override {
        require(totalSupply() > 0);

        if (msg.value > 0) {
            magnifiedDividendPerShare = magnifiedDividendPerShare.add(
                (msg.value).mul(magnitude) / totalSupply()
            );
            emit DividendsDistributed(msg.sender, msg.value);

            totalDividendsDistributed = totalDividendsDistributed.add(
                msg.value
            );
        }
    }

    /// @notice Withdraws the ether distributed to the sender.
    /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
    function withdrawDividend() public virtual override {
        _withdrawDividendOfUser(payable(msg.sender));
    }

    /// @notice Withdraws the ether distributed to the sender.
    /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
    function _withdrawDividendOfUser(address payable user)
        internal
        virtual
        returns (uint256)
    {
        uint256 _withdrawableDividend = withdrawableDividendOf(user);
        if (_withdrawableDividend > 0) {
            withdrawnDividends[user] = withdrawnDividends[user].add(
                _withdrawableDividend
            );
            emit DividendWithdrawn(user, _withdrawableDividend);
            (bool success, ) = user.call{
                value: _withdrawableDividend,
                gas: 3000
            }("");

            if (!success) {
                withdrawnDividends[user] = withdrawnDividends[user].sub(
                    _withdrawableDividend
                );
                return 0;
            }

            return _withdrawableDividend;
        }

        return 0;
    }

    /// @notice View the amount of dividend in wei that an address can withdraw.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` can withdraw.
    function dividendOf(address _owner) public view override returns (uint256) {
        return withdrawableDividendOf(_owner);
    }

    /// @notice View the amount of dividend in wei that an address can withdraw.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` can withdraw.
    function withdrawableDividendOf(address _owner)
        public
        view
        override
        returns (uint256)
    {
        return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
    }

    /// @notice View the amount of dividend in wei that an address has withdrawn.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` has withdrawn.
    function withdrawnDividendOf(address _owner)
        public
        view
        override
        returns (uint256)
    {
        return withdrawnDividends[_owner];
    }

    /// @notice View the amount of dividend in wei that an address has earned in total.
    /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
    /// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` has earned in total.
    function accumulativeDividendOf(address _owner)
        public
        view
        override
        returns (uint256)
    {
        return
            magnifiedDividendPerShare
                .mul(balanceOf(_owner))
                .toInt256Safe()
                .add(magnifiedDividendCorrections[_owner])
                .toUint256Safe() / magnitude;
    }

    /// @dev Internal function that transfer tokens from one address to another.
    /// Update magnifiedDividendCorrections to keep dividends unchanged.
    /// @param from The address to transfer from.
    /// @param to The address to transfer to.
    /// @param value The amount to be transferred.
    function _transfer(
        address from,
        address to,
        uint256 value
    ) internal virtual override {
        require(false);

        int256 _magCorrection = magnifiedDividendPerShare
            .mul(value)
            .toInt256Safe();
        magnifiedDividendCorrections[from] = magnifiedDividendCorrections[from]
            .add(_magCorrection);
        magnifiedDividendCorrections[to] = magnifiedDividendCorrections[to].sub(
            _magCorrection
        );
    }

    /// @dev Internal function that mints tokens to an account.
    /// Update magnifiedDividendCorrections to keep dividends unchanged.
    /// @param account The account that will receive the created tokens.
    /// @param value The amount that will be created.
    function _mint(address account, uint256 value) internal override {
        super._mint(account, value);

        magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
            account
        ].sub((magnifiedDividendPerShare.mul(value)).toInt256Safe());
    }

    /// @dev Internal function that burns an amount of the token of a given account.
    /// Update magnifiedDividendCorrections to keep dividends unchanged.
    /// @param account The account whose tokens will be burnt.
    /// @param value The amount that will be burnt.
    function _burn(address account, uint256 value) internal override {
        super._burn(account, value);

        magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
            account
        ].add((magnifiedDividendPerShare.mul(value)).toInt256Safe());
    }

    function _setBalance(address account, uint256 newBalance) internal {
        uint256 currentBalance = balanceOf(account);

        if (newBalance > currentBalance) {
            uint256 mintAmount = newBalance.sub(currentBalance);
            _mint(account, mintAmount);
        } else if (newBalance < currentBalance) {
            uint256 burnAmount = currentBalance.sub(newBalance);
            _burn(account, burnAmount);
        }
    }
}

contract DiversiFi is ERC20, Ownable {
    using SafeMath for uint256;

    IUniswapV2Router02 public uniswapV2Router;

    address public uniswapV2Pair;

    bool private swapping;
    bool private stakingEnabled = false;
    bool public tradingEnabled = false;
    // Saturday, January 15, 2022 00:00:00 GMT
    uint public immutable forceStartTradingAt = 1642233600;
    uint256 public sellAmount = 0;
    uint256 public buyAmount = 0;
    uint256 private totalSellFees;
    uint256 private totalBuyFees;

    DiversiFiDividendTracker public dividendTracker;

    address public liquidityWallet;

    address payable public operations1Address =
        payable(0xb2055632af7521E16c57e2DBD943eC0C5e78e078);
    address payable public operations2Address =
        payable(0x92e5cbb95E1831e732CC26E8Fe81431a73FA3d5e);

    uint256 public maxSellTransactionAmount = 0;
    uint256 public swapTokensAtAmount = 250000 * (10**9);

    uint256 public operationsFees = 4;
    uint256 public liquidityFee = 1;
    uint256 public FTMRewardsBuyFee = 5;
    uint256 public FTMRewardsSellFee = 5;
    bool public swapAndLiquifyEnabled = true;

    // use by default 300,000 gas to process auto-claiming dividends
    uint256 public gasForProcessing = 300000;

    // exlcude from fees and max transaction amount
    mapping(address => bool) private _isExcludedFromFees;

    // store addresses that a automatic market maker pairs. Any transfer *to* these addresses
    // could be subject to a maximum transfer amount
    mapping(address => bool) public automatedMarketMakerPairs;

    mapping(address => uint256) public stakingBonus;
    mapping(address => uint256) public stakingUntilDate;
    mapping(uint256 => uint256) public stakingAmounts;

    mapping(address => bool) private canTransferBeforeTradingIsEnabled;

    event EnableAccountStaking(address indexed account, uint256 duration);
    event UpdateStakingAmounts(uint256 duration, uint256 amount);

    event EnableSwapAndLiquify(bool enabled);
    event EnableStaking(bool enabled);

    event SetPreSaleWallet(address wallet);

    event UpdateDividendTracker(
        address indexed newAddress,
        address indexed oldAddress
    );

    event UpdateUniswapV2Router(
        address indexed newAddress,
        address indexed oldAddress
    );

    event TradingEnabled();

    event UpdateFees(
        uint256 operations,
        uint256 liquidity,
        uint256 FTMRewardsBuy,
        uint256 FTMRewardsSell
    );

    event ExcludeFromFees(address indexed account, bool isExcluded);
    event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);

    event LiquidityWalletUpdated(
        address indexed newLiquidityWallet,
        address indexed oldLiquidityWallet
    );

    event GasForProcessingUpdated(
        uint256 indexed newValue,
        uint256 indexed oldValue
    );

    event SwapAndLiquify(
        uint256 tokensSwapped,
        uint256 ethReceived,
        uint256 tokensIntoLiqudity
    );

    event SendDividends(uint256 amount, uint256 opAmount, bool success);

    event ProcessedDividendTracker(
        uint256 iterations,
        uint256 claims,
        uint256 lastProcessedIndex,
        bool indexed automatic,
        uint256 gas,
        address indexed processor
    );

    event UpdatePayoutToken(address account, address token);
    event UpdateAllowTokens(address token, bool allow);

    constructor() ERC20("DiversiFi", "DFi") {
        dividendTracker = new DiversiFiDividendTracker(payable(this));

        liquidityWallet = owner();

        uniswapV2Router = IUniswapV2Router02(
            0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506
            
        );

        // Create a uniswap pair for this new token
        uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(
                address(this),
                uniswapV2Router.WETH()
            );

        _setAutomatedMarketMakerPair(uniswapV2Pair, true);

        // exclude from receiving dividends
        dividendTracker.excludeFromDividends(address(dividendTracker));
        dividendTracker.excludeFromDividends(address(this));
        dividendTracker.excludeFromDividends(
            0x000000000000000000000000000000000000dEaD
        );
        dividendTracker.excludedFromDividends(address(0));
        dividendTracker.excludeFromDividends(owner());
        dividendTracker.excludeFromDividends(address(uniswapV2Router));

        // exclude from paying fees or having max transaction amount
        _isExcludedFromFees[liquidityWallet] = true;
        _isExcludedFromFees[address(this)] = true;
        _isExcludedFromFees[owner()] = true;
        _isExcludedFromFees[address(dividendTracker)] = true;

        totalSellFees = FTMRewardsSellFee.add(liquidityFee).add(operationsFees);
        totalBuyFees = FTMRewardsBuyFee.add(liquidityFee).add(operationsFees);

        canTransferBeforeTradingIsEnabled[owner()] = true;
        /*
            _mint is an internal function in ERC20.sol that is only called here,
            and CANNOT be called ever again
        */

        _mint(owner(), 10000000 * (10**9));
    }

    function decimals() public view virtual override returns (uint8) {
        return 9;
    }

    receive() external payable {}

    function updateStakingAmounts(uint256 duration, uint256 bonus)
        public
        onlyOwner
    {
        require(stakingAmounts[duration] != bonus);
        require(bonus <= 500, "Staking bonus can't exceed 500%");

        stakingAmounts[duration] = bonus;
        emit UpdateStakingAmounts(duration, bonus);
    }

    function enableTrading() external onlyOwner {
        require(!tradingEnabled);

        tradingEnabled = true;
        emit TradingEnabled();
    }

    function setPresaleWallet(address wallet) external onlyOwner {
        canTransferBeforeTradingIsEnabled[wallet] = true;
        _isExcludedFromFees[wallet] = true;
        dividendTracker.excludeFromDividends(wallet);

        emit SetPreSaleWallet(wallet);
    }

    function enableStaking(bool enable) public onlyOwner {
        require(stakingEnabled != enable);
        stakingEnabled = enable;

        emit EnableStaking(enable);
    }

    function stake(uint256 duration) public {
        require(stakingEnabled, "Staking is not enabled");
        require(stakingAmounts[duration] != 0, "Invalid staking duration");
        require(
            stakingUntilDate[_msgSender()] < block.timestamp.add(duration),
            "already staked for a longer duration"
        );

        stakingBonus[_msgSender()] = stakingAmounts[duration];
        stakingUntilDate[_msgSender()] = block.timestamp.add(duration);

        dividendTracker.setBalance(
            _msgSender(),
            getStakingBalance(_msgSender())
        );

        emit EnableAccountStaking(_msgSender(), duration);
    }

    function updateMaxAmount(uint256 newNum) public onlyOwner {
        require(maxSellTransactionAmount != newNum);
        // 0 means disabled
        require(
            maxSellTransactionAmount == 0 ||
                maxSellTransactionAmount >= 1000 * (10**9),
            "max sell amount must either be disabled or greater than 1 thousand"
        );
        maxSellTransactionAmount = newNum * (10**9);
    }

    function updateSwapTokensAtAmount(uint256 newNum) public onlyOwner {
        require(swapTokensAtAmount != newNum);
        require(
                swapTokensAtAmount >= 50000 * (10**9),
            "Swap Token Amount must be greater than 50 thousand"
        );
        swapTokensAtAmount = newNum * (10**9);
    }
    
    function updateDividendTracker(address newAddress) public onlyOwner {
        require(newAddress != address(dividendTracker));

        DiversiFiDividendTracker newDividendTracker = DiversiFiDividendTracker(
            payable(newAddress)
        );

        require(newDividendTracker.owner() == address(this));

        newDividendTracker.excludeFromDividends(address(newDividendTracker));
        newDividendTracker.excludeFromDividends(address(this));
        newDividendTracker.excludeFromDividends(owner());
        newDividendTracker.excludeFromDividends(address(uniswapV2Router));

        emit UpdateDividendTracker(newAddress, address(dividendTracker));

        dividendTracker = newDividendTracker;
    }

    function updateOperations1Address(address payable newAddress)
        public
        onlyOwner
    {
        operations1Address = newAddress;
    }

    function updateOperations2Address(address payable newAddress)
        public
        onlyOwner
    {
        operations2Address = newAddress;
    }

    function updateUniswapV2Router(address newAddress) public onlyOwner {
        require(newAddress != address(uniswapV2Router));
        emit UpdateUniswapV2Router(newAddress, address(uniswapV2Router));
        uniswapV2Router = IUniswapV2Router02(newAddress);
        dividendTracker.updateUniswapV2Router(newAddress);
    }

    function excludeFromFees(address account, bool excluded) public onlyOwner {
        require(_isExcludedFromFees[account] != excluded);
        _isExcludedFromFees[account] = excluded;

        emit ExcludeFromFees(account, excluded);
    }

    function enableSwapAndLiquify(bool enabled) public onlyOwner {
        require(swapAndLiquifyEnabled != enabled);
        swapAndLiquifyEnabled = enabled;

        emit EnableSwapAndLiquify(enabled);
    }

    function setAutomatedMarketMakerPair(address pair, bool value)
        public
        onlyOwner
    {
        require(pair != uniswapV2Pair);

        _setAutomatedMarketMakerPair(pair, value);
    }

    function setAllowCustomTokens(bool allow) public onlyOwner {
        dividendTracker.setAllowCustomTokens(allow);
    }

    function setAllowAutoReinvest(bool allow) public onlyOwner {
        dividendTracker.setAllowAutoReinvest(allow);
    }

    function _setAutomatedMarketMakerPair(address pair, bool value) private {
        automatedMarketMakerPairs[pair] = value;

        if (value) {
            dividendTracker.excludeFromDividends(pair);
        }

        emit SetAutomatedMarketMakerPair(pair, value);
    }

    function updateLiquidityWallet(address newLiquidityWallet)
        public
        onlyOwner
    {
        excludeFromFees(newLiquidityWallet, true);
        emit LiquidityWalletUpdated(newLiquidityWallet, liquidityWallet);
        liquidityWallet = newLiquidityWallet;
    }

    function updateGasForProcessing(uint256 newValue) public onlyOwner {
        require(newValue >= 200000 && newValue <= 600000);
        emit GasForProcessingUpdated(newValue, gasForProcessing);
        gasForProcessing = newValue;
    }

    function updateFees(
        uint256 operations,
        uint256 liquidity,
        uint256 FTMRewardsBuy,
        uint256 FTMRewardsSell
    ) public onlyOwner {
        require(operations <= 20, "operation fees can't exceed 20%");
        require(liquidity <= 20, "liquidity fees can't exceed 20%");
        require(
            FTMRewardsBuy >= 1 && FTMRewardsBuy <= 50,
            "FTM reward fees must be between 1 and 50"
        );
        require(
            FTMRewardsSell >= 1 && FTMRewardsSell <= 50,
            "FTM reward fees must be between 1 and 50"
        );

        operationsFees = operations;
        liquidityFee = liquidity;
        FTMRewardsBuyFee = FTMRewardsBuy;
        FTMRewardsSellFee = FTMRewardsSell;

        totalSellFees = FTMRewardsSellFee.add(liquidityFee).add(operationsFees);
        totalBuyFees = FTMRewardsBuyFee.add(liquidityFee).add(operationsFees);

        emit UpdateFees(operations, liquidity, FTMRewardsBuy, FTMRewardsSell);
    }

    function getStakingInfo(address account)
        external
        view
        returns (uint256, uint256)
    {
        return (stakingUntilDate[account], stakingBonus[account]);
    }

    function getTotalDividendsDistributed() external view returns (uint256) {
        return dividendTracker.totalDividendsDistributed();
    }

    function isExcludedFromFees(address account) public view returns (bool) {
        return _isExcludedFromFees[account];
    }

    function withdrawableDividendOf(address account)
        public
        view
        returns (uint256)
    {
        return dividendTracker.withdrawableDividendOf(account);
    }

    function dividendTokenBalanceOf(address account)
        public
        view
        returns (uint256)
    {
        return dividendTracker.balanceOf(account);
    }

    function getAccountDividendsInfo(address account)
        external
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256
        )
    {
        return dividendTracker.getAccount(account);
    }

    function getAccountDividendsInfoAtIndex(uint256 index)
        external
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256
        )
    {
        return dividendTracker.getAccountAtIndex(index);
    }

    function processDividendTracker(uint256 gas) external {
        (
            uint256 iterations,
            uint256 claims,
            uint256 lastProcessedIndex
        ) = dividendTracker.process(gas);
        emit ProcessedDividendTracker(
            iterations,
            claims,
            lastProcessedIndex,
            false,
            gas,
            tx.origin
        );
    }

    function claim() external {
        dividendTracker.processAccount(payable(msg.sender), false);
    }

    function getLastProcessedIndex() external view returns (uint256) {
        return dividendTracker.getLastProcessedIndex();
    }

    function getNumberOfDividendTokenHolders() external view returns (uint256) {
        return dividendTracker.getNumberOfTokenHolders();
    }

    function setAutoClaim(bool value) external {
        dividendTracker.setAutoClaim(msg.sender, value);
    }

    function setReinvest(bool value) external {
        dividendTracker.setReinvest(msg.sender, value);
    }

    function setDividendsPaused(bool value) external onlyOwner {
        dividendTracker.setDividendsPaused(value);
    }

    function isExcludedFromAutoClaim(address account)
        external
        view
        returns (bool)
    {
        return dividendTracker.isExcludedFromAutoClaim(account);
    }

    function isReinvest(address account) external view returns (bool) {
        return dividendTracker.isReinvest(account);
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(
            tradingEnabled || canTransferBeforeTradingIsEnabled[from] || block.timestamp >= forceStartTradingAt,
            "Trading has not yet been enabled"
        );

        if (amount == 0) {
            super._transfer(from, to, 0);
            return;
        } else if (
            !swapping && !_isExcludedFromFees[from] && !_isExcludedFromFees[to]
        ) {
            bool isSelling = automatedMarketMakerPairs[to];

            if (!automatedMarketMakerPairs[from] && stakingEnabled) {
                require(
                    stakingUntilDate[from] <= block.timestamp,
                    "Tokens are staked and locked!"
                );
                if (stakingUntilDate[from] != 0) {
                    stakingUntilDate[from] = 0;
                    stakingBonus[from] = 0;
                }
            }

            uint256 FTMRewardsFee;

            if (isSelling) {
                FTMRewardsFee = FTMRewardsSellFee;
            } else {
                FTMRewardsFee = FTMRewardsBuyFee;
            }

            uint256 totalFees = FTMRewardsFee.add(liquidityFee).add(operationsFees);

            if (
                maxSellTransactionAmount != 0 &&
                isSelling && // sells only by detecting transfer to automated market maker pair
                from != address(uniswapV2Router) //router -> pair is removing liquidity which shouldn't have max
            ) {
                require(
                    amount <= maxSellTransactionAmount,
                    "maxSellTransactionAmount."
                );
            }

            uint256 contractTokenBalance = balanceOf(address(this));

            bool canSwap = contractTokenBalance >= swapTokensAtAmount;

            if (canSwap && !automatedMarketMakerPairs[from]) {
                swapping = true;

                if (swapAndLiquifyEnabled) {
                    uint256 totalBuySell = buyAmount.add(sellAmount);
                    uint256 swapAmountBought = contractTokenBalance
                        .mul(buyAmount)
                        .div(totalBuySell);
                    uint256 swapAmountSold = contractTokenBalance
                        .mul(sellAmount)
                        .div(totalBuySell);

                    uint256 swapBuyTokens = swapAmountBought
                        .mul(liquidityFee)
                        .div(totalBuyFees);

                    uint256 swapSellTokens = swapAmountSold
                        .mul(liquidityFee)
                        .div(totalSellFees);

                    uint256 swapTokens = swapSellTokens.add(swapBuyTokens);

                    swapAndLiquify(swapTokens);
                }

                uint256 remainingBalance = balanceOf(address(this));

                swapAndSendDividends(remainingBalance);

                buyAmount = 0;
                sellAmount = 0;

                swapping = false;
            }

            uint256 fees = amount.mul(totalFees).div(100);

            amount = amount.sub(fees);

            if (isSelling) {
                sellAmount = sellAmount.add(fees);
            } else {
                buyAmount = buyAmount.add(fees);
            }

            super._transfer(from, address(this), fees);

            uint256 gas = gasForProcessing;

            try dividendTracker.process(gas) returns (
                uint256 iterations,
                uint256 claims,
                uint256 lastProcessedIndex
            ) {
                emit ProcessedDividendTracker(
                    iterations,
                    claims,
                    lastProcessedIndex,
                    true,
                    gas,
                    tx.origin
                );
            } catch {}
        }

        super._transfer(from, to, amount);

        dividendTracker.setBalance(from, getStakingBalance(from));
        dividendTracker.setBalance(to, getStakingBalance(to));
    }

    function getStakingBalance(address account) private view returns (uint256) {
        return
            stakingEnabled
                ? balanceOf(account).mul(stakingBonus[account].add(100)).div(
                    100
                )
                : balanceOf(account);
    }

    function swapAndLiquify(uint256 tokens) private {
        // split the contract balance into halves
        uint256 half = tokens.div(2);
        uint256 otherHalf = tokens.sub(half);

        // capture the contract's current ETH balance.
        // this is so that we can capture exactly the amount of ETH that the
        // swap creates, and not make the liquidity event include any ETH that
        // has been manually sent to the contract
        uint256 initialBalance = address(this).balance;

        // swap tokens for ETH
        swapTokensForEth(half); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered

        // how much ETH did we just swap into?
        uint256 newBalance = address(this).balance.sub(initialBalance);

        // add liquidity to uniswap
        addLiquidity(otherHalf, newBalance);

        emit SwapAndLiquify(half, newBalance, otherHalf);
    }

    function swapTokensForEth(uint256 tokenAmount) private {
        // generate the uniswap pair path of token -> weth
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();

        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // make the swap
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
    }

    function updatePayoutToken(address token) public {
        require(balanceOf(msg.sender) > 0);
        require(token != address(this));

        dividendTracker.updatePayoutToken(msg.sender, token);
        emit UpdatePayoutToken(msg.sender, token);
    }

    function getPayoutToken(address account) public view returns (address) {
        return dividendTracker.getPayoutToken(account);
    }

    function updateAllowTokens(address token, bool allow) public onlyOwner {
        require(token != address(this));

        dividendTracker.updateAllowTokens(token, allow);
        emit UpdateAllowTokens(token, allow);
    }

    function getAllowTokens(address token) public view returns (bool) {
        return dividendTracker.getAllowTokens(token);
    }

    function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        // approve token transfer to cover all possible scenarios
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // add the liquidity
        uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            liquidityWallet,
            block.timestamp
        );
    }

    function forceSwapAndSendDividends(uint256 tokens) public onlyOwner {
        uint256 totalAmount = buyAmount.add(sellAmount);
        uint256 fromBuy = tokens.mul(buyAmount).div(totalAmount);
        uint256 fromSell = tokens.mul(sellAmount).div(totalAmount);

        swapAndSendDividends(tokens);

        buyAmount = buyAmount.sub(fromBuy);
        sellAmount = sellAmount.sub(fromSell);
    }

    function swapAndSendDividends(uint256 tokens) private {
        swapTokensForEth(tokens);
        uint256 totalAmount = buyAmount.add(sellAmount);

        uint256 dividendsFromBuy = address(this)
            .balance
            .mul(buyAmount)
            .div(totalAmount)
            .mul(FTMRewardsBuyFee)
            .div(FTMRewardsBuyFee.add(operationsFees));

        uint256 dividendsFromSell = address(this)
            .balance
            .mul(sellAmount)
            .div(totalAmount)
            .mul(FTMRewardsSellFee)
            .div(FTMRewardsSellFee.add(operationsFees));

        uint256 dividends = dividendsFromBuy.add(dividendsFromSell);

        (bool success, ) = address(dividendTracker).call{value: dividends}("");

        uint256 theRest = address(this).balance;
        uint256 half = theRest.div(2);
        uint256 otherHalf = theRest - half;
        (bool successOp1, ) = address(operations1Address).call{value: half}("");

        (bool successOp2, ) = address(operations2Address).call{
            value: otherHalf
        }("");

        emit SendDividends(
            dividends,
            theRest,
            success && successOp1 && successOp2
        );
    }
}

contract DiversiFiDividendTracker is DividendPayingToken, Ownable {
    using SafeMath for uint256;
    using SafeMathInt for int256;
    using IterableMapping for IterableMapping.Map;

    IterableMapping.Map private tokenHoldersMap;
    uint256 public lastProcessedIndex;

    mapping(address => bool) public excludedFromDividends;
    mapping(address => bool) public excludedFromAutoClaim;
    mapping(address => bool) public autoReinvest;
    mapping(address => address) public payoutToken;
    mapping(address => bool) public allowTokens;
    bool public allowCustomTokens;
    bool public allowAutoReinvest;
    bool public dividendsPaused = false;

    IUniswapV2Router02 public uniswapV2Router;

    DiversiFi public diversiFi;

    mapping(address => uint256) public lastClaimTimes;

    uint256 public immutable minimumTokenBalanceForAutoDividends;
    uint256 public immutable minimumTokenBalanceForDividends;

    event ExcludeFromDividends(address indexed account);
    event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue);
    event DividendReinvested(
        address indexed acount,
        uint256 value,
        bool indexed automatic
    );
    event Claim(
        address indexed account,
        uint256 amount,
        bool indexed automatic
    );
    event DividendsPaused(bool paused);
    event SetAllowCustomTokens(bool allow);
    event SetAllowAutoReinvest(bool allow);

    constructor(address payable mainContract)
        DividendPayingToken(
            "DiversiFi_Dividend_Tracker",
            "DiversiFi_Dividend_Tracker"
        )
    {
        diversiFi = DiversiFi(mainContract);
        minimumTokenBalanceForAutoDividends = 1000 * (10**9);
        minimumTokenBalanceForDividends = 100 * (10**9);

        uniswapV2Router = IUniswapV2Router02(
            0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506 
        );
        allowCustomTokens = true;
        allowAutoReinvest = true;
    }

    function decimals() public view virtual override returns (uint8) {
        return 9;
    }

    function _transfer(
        address,
        address,
        uint256
    ) internal pure override {
        require(false, "DiversiFi_Dividend_Tracker: No transfers allowed");
    }

    function withdrawDividend() public pure override {
        require(
            false,
            "DiversiFi_Dividend_Tracker: withdrawDividend disabled. Use the 'claim' function on the main DiversiFi contract."
        );
    }

    function isExcludedFromAutoClaim(address account)
        external
        view
        onlyOwner
        returns (bool)
    {
        return excludedFromAutoClaim[account];
    }

    function isReinvest(address account)
        external
        view
        onlyOwner
        returns (bool)
    {
        return autoReinvest[account];
    }

    function setAllowCustomTokens(bool allow) external onlyOwner {
        require(allowCustomTokens != allow);
        allowCustomTokens = allow;
        emit SetAllowCustomTokens(allow);
    }

    function setAllowAutoReinvest(bool allow) external onlyOwner {
        require(allowAutoReinvest != allow);
        allowAutoReinvest = allow;
        emit SetAllowAutoReinvest(allow);
    }

    function excludeFromDividends(address account) external onlyOwner {
        require(!excludedFromDividends[account]);
        excludedFromDividends[account] = true;

        _setBalance(account, 0);
        tokenHoldersMap.remove(account);

        emit ExcludeFromDividends(account);
    }

    function setAutoClaim(address account, bool value) external onlyOwner {
        excludedFromAutoClaim[account] = value;
    }

    function setReinvest(address account, bool value) external onlyOwner {
        autoReinvest[account] = value;
    }

    function setDividendsPaused(bool value) external onlyOwner {
        require(dividendsPaused != value);
        dividendsPaused = value;
        emit DividendsPaused(value);
    }

    function getLastProcessedIndex() external view returns (uint256) {
        return lastProcessedIndex;
    }

    function getNumberOfTokenHolders() external view returns (uint256) {
        return tokenHoldersMap.keys.length;
    }

    function getAccount(address _account)
        public
        view
        returns (
            address account,
            int256 index,
            int256 iterationsUntilProcessed,
            uint256 withdrawableDividends,
            uint256 totalDividends,
            uint256 lastClaimTime
        )
    {
        account = _account;

        index = tokenHoldersMap.getIndexOfKey(account);

        iterationsUntilProcessed = -1;

        if (index >= 0) {
            if (uint256(index) > lastProcessedIndex) {
                iterationsUntilProcessed = index.sub(
                    int256(lastProcessedIndex)
                );
            } else {
                uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length >
                    lastProcessedIndex
                    ? tokenHoldersMap.keys.length.sub(lastProcessedIndex)
                    : 0;

                iterationsUntilProcessed = index.add(
                    int256(processesUntilEndOfArray)
                );
            }
        }

        withdrawableDividends = withdrawableDividendOf(account);
        totalDividends = accumulativeDividendOf(account);

        lastClaimTime = lastClaimTimes[account];
    }

    function getAccountAtIndex(uint256 index)
        public
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256
        )
    {
        if (index >= tokenHoldersMap.size()) {
            return (
                0x0000000000000000000000000000000000000000,
                -1,
                -1,
                0,
                0,
                0
            );
        }

        address account = tokenHoldersMap.getKeyAtIndex(index);

        return getAccount(account);
    }

    function setBalance(address account, uint256 newBalance)
        external
        onlyOwner
    {
        if (excludedFromDividends[account]) {
            return;
        }

        if (newBalance < minimumTokenBalanceForDividends) {
            tokenHoldersMap.remove(account);
            _setBalance(account, 0);

            return;
        }

        _setBalance(account, newBalance);

        if (newBalance >= minimumTokenBalanceForAutoDividends) {
            tokenHoldersMap.set(account, newBalance);
        } else {
            tokenHoldersMap.remove(account);
        }
    }

    function process(uint256 gas)
        public
        returns (
            uint256,
            uint256,
            uint256
        )
    {
        uint256 numberOfTokenHolders = tokenHoldersMap.keys.length;

        if (numberOfTokenHolders == 0 || dividendsPaused) {
            return (0, 0, lastProcessedIndex);
        }

        uint256 _lastProcessedIndex = lastProcessedIndex;

        uint256 gasUsed = 0;

        uint256 gasLeft = gasleft();

        uint256 iterations = 0;
        uint256 claims = 0;

        while (gasUsed < gas && iterations < numberOfTokenHolders) {
            _lastProcessedIndex++;

            if (_lastProcessedIndex >= numberOfTokenHolders) {
                _lastProcessedIndex = 0;
            }

            address account = tokenHoldersMap.keys[_lastProcessedIndex];

            if (!excludedFromAutoClaim[account]) {
                if (processAccount(payable(account), true)) {
                    claims++;
                }
            }

            iterations++;

            uint256 newGasLeft = gasleft();

            if (gasLeft > newGasLeft) {
                gasUsed = gasUsed.add(gasLeft.sub(newGasLeft));
            }

            gasLeft = newGasLeft;
        }

        lastProcessedIndex = _lastProcessedIndex;

        return (iterations, claims, lastProcessedIndex);
    }

    function processAccount(address payable account, bool automatic)
        public
        onlyOwner
        returns (bool)
    {
        if (dividendsPaused) {
            return false;
        }

        bool reinvest = autoReinvest[account];

        if (automatic && reinvest && !allowAutoReinvest) {
            return false;
        }

        uint256 amount = reinvest
            ? _reinvestDividendOfUser(account)
            : _withdrawDividendOfUser(account);

        if (amount > 0) {
            lastClaimTimes[account] = block.timestamp;
            if (reinvest) {
                emit DividendReinvested(account, amount, automatic);
            } else {
                emit Claim(account, amount, automatic);
            }
            return true;
        }

        return false;
    }

    function updateUniswapV2Router(address newAddress) public onlyOwner {
        uniswapV2Router = IUniswapV2Router02(newAddress);
    }

    function updatePayoutToken(address account, address token)
        public
        onlyOwner
    {
        require(
            allowTokens[token] || token == address(0),
            "Token not in allow list"
        );
        payoutToken[account] = token;
    }

    function getPayoutToken(address account) public view returns (address) {
        return payoutToken[account];
    }

    function updateAllowTokens(address token, bool allow) public onlyOwner {
        allowTokens[token] = allow;
    }

    function getAllowTokens(address token) public view returns (bool) {
        return allowTokens[token];
    }

    function _reinvestDividendOfUser(address account)
        private
        returns (uint256)
    {
        uint256 _withdrawableDividend = withdrawableDividendOf(account);
        if (_withdrawableDividend > 0) {
            bool success;

            withdrawnDividends[account] = withdrawnDividends[account].add(
                _withdrawableDividend
            );

            address[] memory path = new address[](2);
            path[0] = uniswapV2Router.WETH();
            path[1] = address(diversiFi);

            uint256 prevBalance = diversiFi.balanceOf(address(this));

            // make the swap
            try
                uniswapV2Router
                    .swapExactETHForTokensSupportingFeeOnTransferTokens{
                    value: _withdrawableDividend
                }(
                    0, // accept any amount of Tokens
                    path,
                    address(this),
                    block.timestamp
                )
            {
                uint256 received = diversiFi.balanceOf(address(this)).sub(
                    prevBalance
                );
                if (received > 0) {
                    success = true;
                    diversiFi.transfer(account, received);
                } else {
                    success = false;
                }
            } catch {
                success = false;
            }

            if (!success) {
                withdrawnDividends[account] = withdrawnDividends[account].sub(
                    _withdrawableDividend
                );
                return 0;
            }

            return _withdrawableDividend;
        }

        return 0;
    }

    function _withdrawDividendOfUser(address payable user)
        internal
        override
        returns (uint256)
    {
        uint256 _withdrawableDividend = withdrawableDividendOf(user);
        if (_withdrawableDividend > 0) {
            withdrawnDividends[user] = withdrawnDividends[user].add(
                _withdrawableDividend
            );

            address tokenAddress = payoutToken[user];
            bool success;

            // if no tokenAddress assume ftm payout
            if (
                !allowCustomTokens ||
                tokenAddress == address(0) ||
                !allowTokens[tokenAddress]
            ) {
                (success, ) = user.call{
                    value: _withdrawableDividend,
                    gas: 3000
                }("");
            } else {
                //investor wants to be payed out in a custom token
                address[] memory path = new address[](2);
                path[0] = uniswapV2Router.WETH();
                path[1] = tokenAddress;

                try
                    uniswapV2Router
                        .swapExactETHForTokensSupportingFeeOnTransferTokens{
                        value: _withdrawableDividend
                    }(
                        0, // accept any amount of Tokens
                        path,
                        user,
                        block.timestamp
                    )
                {
                    success = true;
                } catch {
                    success = false;
                }
            }

            if (!success) {
                withdrawnDividends[user] = withdrawnDividends[user].sub(
                    _withdrawableDividend
                );
                return 0;
            } else {
                emit DividendWithdrawn(user, _withdrawableDividend);
            }

            return _withdrawableDividend;
        }

        return 0;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address payable","name":"mainContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"bool","name":"automatic","type":"bool"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newValue","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"oldValue","type":"uint256"}],"name":"ClaimWaitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"acount","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":true,"internalType":"bool","name":"automatic","type":"bool"}],"name":"DividendReinvested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"weiAmount","type":"uint256"}],"name":"DividendWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"weiAmount","type":"uint256"}],"name":"DividendsDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"DividendsPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"ExcludeFromDividends","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"allow","type":"bool"}],"name":"SetAllowAutoReinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"allow","type":"bool"}],"name":"SetAllowCustomTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"accumulativeDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowAutoReinvest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowCustomTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"autoReinvest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributeDividends","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"diversiFi","outputs":[{"internalType":"contract DiversiFi","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"dividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dividendsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeFromDividends","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"excludedFromAutoClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"excludedFromDividends","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccount","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"int256","name":"index","type":"int256"},{"internalType":"int256","name":"iterationsUntilProcessed","type":"int256"},{"internalType":"uint256","name":"withdrawableDividends","type":"uint256"},{"internalType":"uint256","name":"totalDividends","type":"uint256"},{"internalType":"uint256","name":"lastClaimTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getAccountAtIndex","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getAllowTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastProcessedIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumberOfTokenHolders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getPayoutToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromAutoClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isReinvest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastClaimTimes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastProcessedIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumTokenBalanceForAutoDividends","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumTokenBalanceForDividends","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"payoutToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gas","type":"uint256"}],"name":"process","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"},{"internalType":"bool","name":"automatic","type":"bool"}],"name":"processAccount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"allow","type":"bool"}],"name":"setAllowAutoReinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"allow","type":"bool"}],"name":"setAllowCustomTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setAutoClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"setBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setDividendsPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setReinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDividendsDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"allow","type":"bool"}],"name":"updateAllowTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"updatePayoutToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"updateUniswapV2Router","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawDividend","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"withdrawableDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"withdrawnDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c06040526014805462ff0000191690553480156200001d57600080fd5b506040516200348638038062003486833981016040819052620000409162000224565b604080518082018252601a8082527f4469766572736946695f4469766964656e645f547261636b6572000000000000602080840182815285518087019096529285528401528151919291839183916200009c916003916200017e565b508051620000b29060049060208401906200017e565b50505050506000620000c96200017a60201b60201c565b600980546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350601580546001600160a01b0319166001600160a01b039290921691909117905564e8d4a5100060805264174876e80060a0526014805462ff0001600160b81b031916761b02da8cb0d097eb8d57a175b88c7d8b4799750600010117905562000291565b3390565b8280546200018c9062000254565b90600052602060002090601f016020900481019282620001b05760008555620001fb565b82601f10620001cb57805160ff1916838001178555620001fb565b82800160010185558215620001fb579182015b82811115620001fb578251825591602001919060010190620001de565b50620002099291506200020d565b5090565b5b808211156200020957600081556001016200020e565b60006020828403121562000236578081fd5b81516001600160a01b03811681146200024d578182fd5b9392505050565b600181811c908216806200026957607f821691505b602082108114156200028b57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a0516131c1620002c560003960008181610a1101526117cc0152600081816108c7015261181801526131c16000f3fe6080604052600436106103645760003560e01c806370a08231116101c6578063a9059cbb116100f7578063dd62ed3e11610095578063f2fde38b1161006f578063f2fde38b14610ae7578063f7dd53a914610b07578063fbcbc0f114610b27578063ffb2c47914610b4757600080fd5b8063dd62ed3e14610a6c578063e30443bc14610ab2578063e7841ec014610ad257600080fd5b8063ba079d49116100d1578063ba079d49146109bf578063bc4c4b37146109df578063be10b614146109ff578063c32c293d14610a3357600080fd5b8063a9059cbb14610949578063aafd847a14610969578063b22f8a041461099f57600080fd5b806395d89b4111610164578063a1363cda1161013e578063a1363cda146108b5578063a4234069146108e9578063a457c2d714610909578063a8b9d2401461092957600080fd5b806395d89b41146108665780639c3372ea1461087b5780639eec101e1461089b57600080fd5b806385a6b3ae116101a057806385a6b3ae146107f25780638bc1d639146108085780638da5cb5b1461082857806391b89fba1461084657600080fd5b806370a082311461077157806370d3c747146107a7578063715018a6146107dd57600080fd5b80633599bb17116102a05780635183d6fd1161023e57806365b8dbc01161021857806365b8dbc0146106ec5780636a4740021461070c5780636b69163b146107215780636d48467b1461075157600080fd5b80635183d6fd1461063c5780635344b50b146106935780635b72c18c146106b357600080fd5b8063418089041161027a578063418089041461059d5780634e5ee1c0146105bc5780634e7b827f146105ec5780635123425b1461061c57600080fd5b80633599bb171461053d578063395093511461055d57806340ffdd801461057d57600080fd5b80631d4ff89a1161030d57806327ce0147116102e757806327ce0147146104cb5780633009a609146104eb578063313ce5671461050157806331e79db01461051d57600080fd5b80631d4ff89a1461044e578063226cfa3d1461047e57806323b872dd146104ab57600080fd5b806309bbedde1161033e57806309bbedde146103db5780631694505e146103fa57806318160ddd1461043957600080fd5b806303c833021461037857806306fdde0314610380578063095ea7b3146103ab57600080fd5b3661037357610371610b82565b005b600080fd5b610371610b82565b34801561038c57600080fd5b50610395610c22565b6040516103a29190612ef9565b60405180910390f35b3480156103b757600080fd5b506103cb6103c6366004612dee565b610cb4565b60405190151581526020016103a2565b3480156103e757600080fd5b50600a545b6040519081526020016103a2565b34801561040657600080fd5b5060145461042190630100000090046001600160a01b031681565b6040516001600160a01b0390911681526020016103a2565b34801561044557600080fd5b506002546103ec565b34801561045a57600080fd5b506103cb610469366004612cff565b60116020526000908152604090205460ff1681565b34801561048a57600080fd5b506103ec610499366004612cff565b60166020526000908152604090205481565b3480156104b757600080fd5b506103cb6104c6366004612d9c565b610ccb565b3480156104d757600080fd5b506103ec6104e6366004612cff565b610d34565b3480156104f757600080fd5b506103ec600e5481565b34801561050d57600080fd5b50604051600981526020016103a2565b34801561052957600080fd5b50610371610538366004612cff565b610d9d565b34801561054957600080fd5b50610371610558366004612e19565b610e80565b34801561056957600080fd5b506103cb610578366004612dee565b610f3b565b34801561058957600080fd5b50610371610598366004612e19565b610f71565b3480156105a957600080fd5b506014546103cb90610100900460ff1681565b3480156105c857600080fd5b506103cb6105d7366004612cff565b60136020526000908152604090205460ff1681565b3480156105f857600080fd5b506103cb610607366004612cff565b600f6020526000908152604090205460ff1681565b34801561062857600080fd5b50610371610637366004612ddc565b61101e565b34801561064857600080fd5b5061065c610657366004612e51565b611091565b604080516001600160a01b0390971687526020870195909552938501929092526060840152608083015260a082015260c0016103a2565b34801561069f57600080fd5b50601554610421906001600160a01b031681565b3480156106bf57600080fd5b506103cb6106ce366004612cff565b6001600160a01b031660009081526013602052604090205460ff1690565b3480156106f857600080fd5b50610371610707366004612cff565b6110f1565b34801561071857600080fd5b5061037161117a565b34801561072d57600080fd5b506103cb61073c366004612cff565b60106020526000908152604090205460ff1681565b34801561075d57600080fd5b506103cb61076c366004612cff565b611234565b34801561077d57600080fd5b506103ec61078c366004612cff565b6001600160a01b031660009081526020819052604090205490565b3480156107b357600080fd5b506104216107c2366004612cff565b6012602052600090815260409020546001600160a01b031681565b3480156107e957600080fd5b5061037161129e565b3480156107fe57600080fd5b506103ec60085481565b34801561081457600080fd5b50610371610823366004612ddc565b611330565b34801561083457600080fd5b506009546001600160a01b0316610421565b34801561085257600080fd5b506103ec610861366004612cff565b6113a3565b34801561087257600080fd5b506103956113ae565b34801561088757600080fd5b50610371610896366004612e19565b6113bd565b3480156108a757600080fd5b506014546103cb9060ff1681565b3480156108c157600080fd5b506103ec7f000000000000000000000000000000000000000000000000000000000000000081565b3480156108f557600080fd5b506014546103cb9062010000900460ff1681565b34801561091557600080fd5b506103cb610924366004612dee565b61145c565b34801561093557600080fd5b506103ec610944366004612cff565b6114ab565b34801561095557600080fd5b506103cb610964366004612dee565b6114d7565b34801561097557600080fd5b506103ec610984366004612cff565b6001600160a01b031660009081526007602052604090205490565b3480156109ab57600080fd5b506103716109ba366004612ddc565b6114e4565b3480156109cb57600080fd5b506103cb6109da366004612cff565b611557565b3480156109eb57600080fd5b506103cb6109fa366004612d37565b6115c1565b348015610a0b57600080fd5b506103ec7f000000000000000000000000000000000000000000000000000000000000000081565b348015610a3f57600080fd5b50610421610a4e366004612cff565b6001600160a01b039081166000908152601260205260409020541690565b348015610a7857600080fd5b506103ec610a87366004612d6f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b348015610abe57600080fd5b50610371610acd366004612dee565b61175d565b348015610ade57600080fd5b50600e546103ec565b348015610af357600080fd5b50610371610b02366004612cff565b611854565b348015610b1357600080fd5b50610371610b22366004612d6f565b611974565b348015610b3357600080fd5b5061065c610b42366004612cff565b611a64565b348015610b5357600080fd5b50610b67610b62366004612e51565b611b13565b604080519384526020840192909252908201526060016103a2565b6000610b8d60025490565b11610b9757600080fd5b3415610c2057610bd7610ba960025490565b610bc434700100000000000000000000000000000000611c46565b610bce9190612fbc565b60055490611ce8565b60055560405134815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a2600854610c1c9034611ce8565b6008555b565b606060038054610c319061306a565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5d9061306a565b8015610caa5780601f10610c7f57610100808354040283529160200191610caa565b820191906000526020600020905b815481529060010190602001808311610c8d57829003601f168201915b5050505050905090565b6000610cc1338484611d47565b5060015b92915050565b6000610cd8848484611e9f565b610d2a8433610d258560405180606001604052806028815260200161311f602891396001600160a01b038a1660009081526001602090815260408083203384529091529020549190611f12565b611d47565b5060019392505050565b6001600160a01b0381166000908152600660209081526040808320549183905282205460055470010000000000000000000000000000000092610d9392610d8e92610d8891610d839190611c46565b611f4c565b90611f5c565b611f9a565b610cc59190612fbc565b6009546001600160a01b03163314610dea5760405162461bcd60e51b8152602060048201819052602482015260008051602061314783398151915260448201526064015b60405180910390fd5b6001600160a01b0381166000908152600f602052604090205460ff1615610e1057600080fd5b6001600160a01b0381166000908152600f60205260408120805460ff19166001179055610e3e908290611fad565b610e49600a8261200c565b6040516001600160a01b038216907fa878b31040b2e6d0a9a3d3361209db3908ba62014b0dca52adbaee451d128b2590600090a250565b6009546001600160a01b03163314610ec85760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b60145460ff620100009091041615158115151415610ee557600080fd5b60148054821515620100000262ff0000199091161790556040517f3da2593f2c4724acfbd754045321e852cad26f3974834b1890045530f89c21b390610f3090831515815260200190565b60405180910390a150565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610cc1918590610d259086611ce8565b6009546001600160a01b03163314610fb95760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b60145460ff6101009091041615158115151415610fd557600080fd5b601480548215156101000261ff00199091161790556040517fc138a28750b971696f46ea59731c471ef1e08e4015404afdb139fd2e87dca1bb90610f3090831515815260200190565b6009546001600160a01b031633146110665760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b03919091166000908152601360205260409020805460ff1916911515919091179055565b6000806000806000806110a3600a5490565b87106110c25750600094506000199350839250849150819050806110e8565b60006110cf600a89612171565b90506110da81611a64565b965096509650965096509650505b91939550919395565b6009546001600160a01b031633146111395760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b601480546001600160a01b039092166301000000027fffffffffffffffffff0000000000000000000000000000000000000000ffffff909216919091179055565b60405162461bcd60e51b815260206004820152606f60248201527f4469766572736946695f4469766964656e645f547261636b65723a207769746860448201527f647261774469766964656e642064697361626c65642e2055736520746865202760648201527f636c61696d272066756e6374696f6e206f6e20746865206d61696e204469766560848201527f727369466920636f6e74726163742e000000000000000000000000000000000060a482015260c401610de1565b6009546000906001600160a01b0316331461127f5760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b506001600160a01b031660009081526010602052604090205460ff1690565b6009546001600160a01b031633146112e65760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6009546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600980546001600160a01b0319169055565b6009546001600160a01b031633146113785760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b03919091166000908152601060205260409020805460ff1916911515919091179055565b6000610cc5826114ab565b606060048054610c319061306a565b6009546001600160a01b031633146114055760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b60145460ff161515811515141561141b57600080fd5b6014805460ff19168215159081179091556040519081527f8d34c313963017194ed726d050e868657d0e2d2c6748d13e358cd4b89d4ee7c890602001610f30565b6000610cc13384610d2585604051806060016040528060258152602001613167602591393360009081526001602090815260408083206001600160a01b038d1684529091529020549190611f12565b6001600160a01b038116600090815260076020526040812054610cc5906114d184610d34565b906121b2565b6000610cc1338484611e9f565b6009546001600160a01b0316331461152c5760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b03919091166000908152601160205260409020805460ff1916911515919091179055565b6009546000906001600160a01b031633146115a25760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b506001600160a01b031660009081526011602052604090205460ff1690565b6009546000906001600160a01b0316331461160c5760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b60145462010000900460ff161561162557506000610cc5565b6001600160a01b03831660009081526011602052604090205460ff1682801561164b5750805b801561165f5750601454610100900460ff16155b1561166e576000915050610cc5565b6000816116835761167e856121f4565b61168c565b61168c85612532565b90508015611752576001600160a01b0385166000908152601660205260409020429055811561170057831515856001600160a01b03167ffbd928dd3806a2bdf802f3a28a2cc55205f95dbcd2c3ed313abfca278366f80c836040516116f391815260200190565b60405180910390a3611747565b831515856001600160a01b03167fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf0928360405161173e91815260200190565b60405180910390a35b600192505050610cc5565b506000949350505050565b6009546001600160a01b031633146117a55760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b0382166000908152600f602052604090205460ff16156117ca575050565b7f000000000000000000000000000000000000000000000000000000000000000081101561180c576117fd600a8361200c565b611808826000611fad565b5050565b6118168282611fad565b7f0000000000000000000000000000000000000000000000000000000000000000811061184957611808600a8383612927565b611808600a8361200c565b6009546001600160a01b0316331461189c5760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b0381166119185760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610de1565b6009546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600980546001600160a01b0319166001600160a01b0392909216919091179055565b6009546001600160a01b031633146119bc5760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b03811660009081526013602052604090205460ff16806119ea57506001600160a01b038116155b611a365760405162461bcd60e51b815260206004820152601760248201527f546f6b656e206e6f7420696e20616c6c6f77206c6973740000000000000000006044820152606401610de1565b6001600160a01b03918216600090815260126020526040902080546001600160a01b03191691909216179055565b80600080808080611a76600a876129d0565b9450600019935060008512611ad857600e54851115611aa457600e54611a9d908690612a1b565b9350611ad8565b600e54600a5460009110611ab9576000611ac8565b600e54600a54611ac8916121b2565b9050611ad48682611f5c565b9450505b611ae1866114ab565b9250611aec86610d34565b6001600160a01b038716600090815260166020526040902054969895975093959294915050565b600a5460009081908190801580611b32575060145462010000900460ff165b15611b48575050600e5460009250829150611c3f565b600e546000805a90506000805b8984108015611b6357508582105b15611c2e5784611b72816130a5565b955050858510611b8157600094505b6000600a6000018681548110611ba757634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b0316808352601090915260409091205490915060ff16611bf457611be18160016115c1565b15611bf45781611bf0816130a5565b9250505b82611bfe816130a5565b93505060005a905080851115611c2557611c22611c1b86836121b2565b8790611ce8565b95505b9350611b559050565b600e85905590975095509193505050505b9193909250565b600082611c5557506000610cc5565b6000611c618385612fdc565b905082611c6e8583612fbc565b14611ce15760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60448201527f77000000000000000000000000000000000000000000000000000000000000006064820152608401610de1565b9392505050565b600080611cf58385612fa4565b905083811015611ce15760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610de1565b6001600160a01b038316611dc25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610de1565b6001600160a01b038216611e3e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610de1565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60405162461bcd60e51b815260206004820152603060248201527f4469766572736946695f4469766964656e645f547261636b65723a204e6f207460448201527f72616e736665727320616c6c6f776564000000000000000000000000000000006064820152608401610de1565b505050565b60008184841115611f365760405162461bcd60e51b8152600401610de19190612ef9565b506000611f438486613053565b95945050505050565b60008181811215610cc557600080fd5b600080611f698385612f4c565b905060008312158015611f7c5750838112155b80611f915750600083128015611f9157508381125b611ce157600080fd5b600080821215611fa957600080fd5b5090565b6001600160a01b03821660009081526020819052604090205480821115611fec576000611fda83836121b2565b9050611fe68482612a58565b50505050565b80821015611f0d57600061200082846121b2565b9050611fe68482612abc565b6001600160a01b038116600090815260038301602052604090205460ff16612032575050565b6001600160a01b03811660009081526003830160209081526040808320805460ff191690556001808601835281842084905560028601909252822054845490929161207c91613053565b905060008460000182815481106120a357634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b0390811680845260028901909252604080842087905590871683528220919091558554909150819086908590811061210057634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055845485908061214857634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b600082600001828154811061219657634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03169392505050565b6000611ce183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611f12565b600080612200836114ab565b90508015612529576001600160a01b03831660009081526007602052604090205461222b9082611ce8565b6001600160a01b0380851660009081526007602090815260408083209490945560129052918220546014549116919060ff16158061227057506001600160a01b038216155b8061229457506001600160a01b03821660009081526013602052604090205460ff16155b156122f7576040516001600160a01b03861690610bb89085906000818181858888f193505050503d80600081146122e7576040519150601f19603f3d011682016040523d82523d6000602084013e6122ec565b606091505b50508091505061248f565b604080516002808252606082018352600092602083019080368337019050509050601460039054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b15801561236657600080fd5b505afa15801561237a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239e9190612d1b565b816000815181106123bf57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b031681525050828160018151811061240157634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201015260145460405163b6f9de9560e01b815263010000009091049091169063b6f9de959086906124509060009086908c904290600401612ec4565b6000604051808303818588803b15801561246957600080fd5b505af19350505050801561247b575060015b612488576000915061248d565b600191505b505b806124dd576001600160a01b0385166000908152600760205260409020546124b790846121b2565b6001600160a01b0390951660009081526007602052604081209590955550929392505050565b846001600160a01b03167fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d8460405161251891815260200190565b60405180910390a250909392505050565b50600092915050565b60008061253e836114ab565b90508015612529576001600160a01b0383166000908152600760205260408120546125699083611ce8565b6001600160a01b0385166000908152600760205260408082209290925581516002808252606082019093529091816020016020820280368337019050509050601460039054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b1580156125f657600080fd5b505afa15801561260a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262e9190612d1b565b8160008151811061264f57634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201015260155482519116908290600190811061268e57634e487b7160e01b600052603260045260246000fd5b6001600160a01b0392831660209182029290920101526015546040516370a0823160e01b815230600482015260009291909116906370a082319060240160206040518083038186803b1580156126e357600080fd5b505afa1580156126f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271b9190612e69565b60145460405163b6f9de9560e01b8152919250630100000090046001600160a01b03169063b6f9de9590869061275c90600090879030904290600401612ec4565b6000604051808303818588803b15801561277557600080fd5b505af193505050508015612787575060015b61279457600092506128ce565b6015546040516370a0823160e01b81523060048201526000916128169184916001600160a01b0316906370a082319060240160206040518083038186803b1580156127de57600080fd5b505afa1580156127f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d19190612e69565b905080156128c7576015546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015260248201849052600196509091169063a9059cbb90604401602060405180830381600087803b15801561288957600080fd5b505af115801561289d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c19190612e35565b506128cc565b600093505b505b8261291d576001600160a01b0386166000908152600760205260409020546128f690856121b2565b6001600160a01b039096166000908152600760205260408120969096555093949350505050565b5091949350505050565b6001600160a01b038216600090815260038401602052604090205460ff161561296c576001600160a01b03821660009081526001840160205260409020819055505050565b6001600160a01b03821660008181526003850160209081526040808320805460ff19166001908117909155878101835281842086905587546002890184529184208290558101875586835291200180546001600160a01b0319169091179055505050565b6001600160a01b038116600090815260038301602052604081205460ff166129fb5750600019610cc5565b506001600160a01b03166000908152600291909101602052604090205490565b600080612a288385612ffb565b905060008312158015612a3b5750838113155b80611f915750600083128015611f915750838113611ce157600080fd5b612a628282612b00565b612a9c612a7d610d8383600554611c4690919063ffffffff16565b6001600160a01b03841660009081526006602052604090205490612a1b565b6001600160a01b0390921660009081526006602052604090209190915550565b612ac68282612bdf565b612a9c612ae1610d8383600554611c4690919063ffffffff16565b6001600160a01b03841660009081526006602052604090205490611f5c565b6001600160a01b038216612b565760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610de1565b600254612b639082611ce8565b6002556001600160a01b038216600090815260208190526040902054612b899082611ce8565b6001600160a01b038316600081815260208181526040808320949094559251848152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a35050565b6001600160a01b038216612c5b5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610de1565b612c98816040518060600160405280602281526020016130fd602291396001600160a01b0385166000908152602081905260409020549190611f12565b6001600160a01b038316600090815260208190526040902055600254612cbe90826121b2565b6002556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612bd3565b600060208284031215612d10578081fd5b8135611ce1816130d6565b600060208284031215612d2c578081fd5b8151611ce1816130d6565b60008060408385031215612d49578081fd5b8235612d54816130d6565b91506020830135612d64816130ee565b809150509250929050565b60008060408385031215612d81578182fd5b8235612d8c816130d6565b91506020830135612d64816130d6565b600080600060608486031215612db0578081fd5b8335612dbb816130d6565b92506020840135612dcb816130d6565b929592945050506040919091013590565b60008060408385031215612d49578182fd5b60008060408385031215612e00578182fd5b8235612e0b816130d6565b946020939093013593505050565b600060208284031215612e2a578081fd5b8135611ce1816130ee565b600060208284031215612e46578081fd5b8151611ce1816130ee565b600060208284031215612e62578081fd5b5035919050565b600060208284031215612e7a578081fd5b5051919050565b6000815180845260208085019450808401835b83811015612eb95781516001600160a01b031687529582019590820190600101612e94565b509495945050505050565b848152608060208201526000612edd6080830186612e81565b6001600160a01b03949094166040830152506060015292915050565b6000602080835283518082850152825b81811015612f2557858101830151858201604001528201612f09565b81811115612f365783604083870101525b50601f01601f1916929092016040019392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615612f8657612f866130c0565b82600160ff1b038412811615612f9e57612f9e6130c0565b50500190565b60008219821115612fb757612fb76130c0565b500190565b600082612fd757634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612ff657612ff66130c0565b500290565b600080831283600160ff1b01831281151615613019576130196130c0565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561304d5761304d6130c0565b50500390565b600082821015613065576130656130c0565b500390565b600181811c9082168061307e57607f821691505b6020821081141561309f57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156130b9576130b96130c0565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146130eb57600080fd5b50565b80151581146130eb57600080fdfe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657245524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122058a930dca684adcddf0226e4202f7551f9505675bf8d4b2b37f47f043ae4559164736f6c63430008040033000000000000000000000000323b05c10029ae66b46baf0604739331edb4808f

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000323b05c10029ae66b46baf0604739331edb4808f

-----Decoded View---------------
Arg [0] : mainContract (address): 0x323b05c10029ae66b46baf0604739331edb4808f

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000323b05c10029ae66b46baf0604739331edb4808f


Deployed ByteCode Sourcemap

69343:13579:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38051:21;:19;:21::i;:::-;69343:13579;;;;;38957:471;;;:::i;9949:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;12257:210;;;;;;;;;;-1:-1:-1;12257:210:0;;;;;:::i;:::-;;:::i;:::-;;;5442:14:1;;5435:22;5417:41;;5405:2;5390:18;12257:210:0;5372:92:1;73538:120:0;;;;;;;;;;-1:-1:-1;73623:15:0;:27;73538:120;;;12248:25:1;;;12236:2;12221:18;73538:120:0;12203:76:1;70020:41:0;;;;;;;;;;-1:-1:-1;70020:41:0;;;;;;;-1:-1:-1;;;;;70020:41:0;;;;;;-1:-1:-1;;;;;4323:55:1;;;;4305:74;;4293:2;4278:18;70020:41:0;4260:125:1;11069:108:0;;;;;;;;;;-1:-1:-1;11157:12:0;;11069:108;;69750:44;;;;;;;;;;-1:-1:-1;69750:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;70105:49;;;;;;;;;;-1:-1:-1;70105:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;12949:454;;;;;;;;;;-1:-1:-1;12949:454:0;;;;;:::i;:::-;;:::i;42385:372::-;;;;;;;;;;-1:-1:-1;42385:372:0;;;;;:::i;:::-;;:::i;69588:33::-;;;;;;;;;;;;;;;;71356:92;;;;;;;;;;-1:-1:-1;71356:92:0;;71439:1;12750:36:1;;12738:2;12723:18;71356:92:0;12705:87:1;72664:298:0;;;;;;;;;;-1:-1:-1;72664:298:0;;;;;:::i;:::-;;:::i;73230:183::-;;;;;;;;;;-1:-1:-1;73230:183:0;;;;;:::i;:::-;;:::i;13812:300::-;;;;;;;;;;-1:-1:-1;13812:300:0;;;;;:::i;:::-;;:::i;72462:194::-;;;;;;;;;;-1:-1:-1;72462:194:0;;;;;:::i;:::-;;:::i;69940:29::-;;;;;;;;;;-1:-1:-1;69940:29:0;;;;;;;;;;;69854:43;;;;;;;;;;-1:-1:-1;69854:43:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;69630:53;;;;;;;;;;-1:-1:-1;69630:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;78943:116;;;;;;;;;;-1:-1:-1;78943:116:0;;;;;:::i;:::-;;:::i;74923:609::-;;;;;;;;;;-1:-1:-1;74923:609:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4691:55:1;;;;4673:74;;4778:2;4763:18;;4756:34;;;;4806:18;;;4799:34;;;;4864:2;4849:18;;4842:34;4907:3;4892:19;;4885:35;-1:-1:-1;4936:19:1;;4929:35;4660:3;4645:19;74923:609:0;4627:343:1;70070:26:0;;;;;;;;;;-1:-1:-1;70070:26:0;;;;-1:-1:-1;;;;;70070:26:0;;;79067:110;;;;;;;;;;-1:-1:-1;79067:110:0;;;;;:::i;:::-;-1:-1:-1;;;;;79151:18:0;79127:4;79151:18;;;:11;:18;;;;;;;;;79067:110;78396:135;;;;;;;;;;-1:-1:-1;78396:135:0;;;;;:::i;:::-;;:::i;71652:234::-;;;;;;;;;;;;;:::i;69690:53::-;;;;;;;;;;-1:-1:-1;69690:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;71894:186;;;;;;;;;;-1:-1:-1;71894:186:0;;;;;:::i;:::-;;:::i;11240:177::-;;;;;;;;;;-1:-1:-1;11240:177:0;;;;;:::i;:::-;-1:-1:-1;;;;;11391:18:0;11359:7;11391:18;;;;;;;;;;;;11240:177;69801:46;;;;;;;;;;-1:-1:-1;69801:46:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;69801:46:0;;;27898:148;;;;;;;;;;;;;:::i;37785:40::-;;;;;;;;;;;;;;;;72970:127;;;;;;;;;;-1:-1:-1;72970:127:0;;;;;:::i;:::-;;:::i;27256:79::-;;;;;;;;;;-1:-1:-1;27321:6:0;;-1:-1:-1;;;;;27321:6:0;27256:79;;40970:131;;;;;;;;;;-1:-1:-1;40970:131:0;;;;;:::i;:::-;;:::i;10168:104::-;;;;;;;;;;;;;:::i;72260:194::-;;;;;;;;;;-1:-1:-1;72260:194:0;;;;;:::i;:::-;;:::i;69904:29::-;;;;;;;;;;-1:-1:-1;69904:29:0;;;;;;;;70163:60;;;;;;;;;;;;;;;69976:35;;;;;;;;;;-1:-1:-1;69976:35:0;;;;;;;;;;;14615:400;;;;;;;;;;-1:-1:-1;14615:400:0;;;;;:::i;:::-;;:::i;41320:216::-;;;;;;;;;;-1:-1:-1;41320:216:0;;;;;:::i;:::-;;:::i;11630:::-;;;;;;;;;;-1:-1:-1;11630:216:0;;;;;:::i;:::-;;:::i;41757:177::-;;;;;;;;;;-1:-1:-1;41757:177:0;;;;;:::i;:::-;-1:-1:-1;;;;;41900:26:0;41868:7;41900:26;;;:18;:26;;;;;;;41757:177;73105:117;;;;;;;;;;-1:-1:-1;73105:117:0;;;;;:::i;:::-;;:::i;72088:164::-;;;;;;;;;;-1:-1:-1;72088:164:0;;;;;:::i;:::-;;:::i;77557:831::-;;;;;;;;;;-1:-1:-1;77557:831:0;;;;;:::i;:::-;;:::i;70230:56::-;;;;;;;;;;;;;;;78818:117;;;;;;;;;;-1:-1:-1;78818:117:0;;;;;:::i;:::-;-1:-1:-1;;;;;78907:20:0;;;78880:7;78907:20;;;:11;:20;;;;;;;;78818:117;11909:201;;;;;;;;;;-1:-1:-1;11909:201:0;;;;;:::i;:::-;-1:-1:-1;;;;;12075:18:0;;;12043:7;12075:18;;;-1:-1:-1;12075:18:0;;;;;;;;:27;;;;;;;;;;;;;11909:201;75540:610;;;;;;;;;;-1:-1:-1;75540:610:0;;;;;:::i;:::-;;:::i;73421:109::-;;;;;;;;;;-1:-1:-1;73504:18:0;;73421:109;;28201:281;;;;;;;;;;-1:-1:-1;28201:281:0;;;;;:::i;:::-;;:::i;78539:271::-;;;;;;;;;;-1:-1:-1;78539:271:0;;;;;:::i;:::-;;:::i;73666:1249::-;;;;;;;;;;-1:-1:-1;73666:1249:0;;;;;:::i;:::-;;:::i;76158:1391::-;;;;;;;;;;-1:-1:-1;76158:1391:0;;;;;:::i;:::-;;:::i;:::-;;;;12486:25:1;;;12542:2;12527:18;;12520:34;;;;12570:18;;;12563:34;12474:2;12459:18;76158:1391:0;12441:162:1;38957:471:0;39047:1;39031:13;11157:12;;;11069:108;39031:13;:17;39023:26;;;;;;39066:9;:13;39062:359;;39124:105;39201:13;11157:12;;;11069:108;39201:13;39172:26;39173:9;36661:6;39172:15;:26::i;:::-;:42;;;;:::i;:::-;39124:25;;;:29;:105::i;:::-;39096:25;:133;39249:43;;39282:9;12248:25:1;;39270:10:0;;39249:43;;12236:2:1;12221:18;39249:43:0;;;;;;;39337:25;;:72;;39385:9;39337:29;:72::i;:::-;39309:25;:100;39062:359;38957:471::o;9949:100::-;10003:13;10036:5;10029:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9949:100;:::o;12257:210::-;12376:4;12398:39;243:10;12421:7;12430:6;12398:8;:39::i;:::-;-1:-1:-1;12455:4:0;12257:210;;;;;:::o;12949:454::-;13089:4;13106:36;13116:6;13124:9;13135:6;13106:9;:36::i;:::-;13153:220;13176:6;243:10;13224:138;13280:6;13224:138;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;13224:19:0;;;;;;-1:-1:-1;13224:19:0;;;;;;;;243:10;13224:33;;;;;;;;;;:37;:138::i;:::-;13153:8;:220::i;:::-;-1:-1:-1;13391:4:0;12949:454;;;;;:::o;42385:372::-;-1:-1:-1;;;;;42666:36:0;;42499:7;42666:36;;;:28;:36;;;;;;;;;11391:18;;;;;;;42544:25;;36661:6;;42544:193;;:159;;:99;;:66;;:25;:47;:66::i;:::-;:97;:99::i;:::-;:121;;:159::i;:::-;:191;:193::i;:::-;:205;;;;:::i;72664:298::-;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;;;;;;;;;-1:-1:-1;;;;;72750:30:0;::::1;;::::0;;;:21:::1;:30;::::0;;;;;::::1;;72749:31;72741:40;;;::::0;::::1;;-1:-1:-1::0;;;;;72792:30:0;::::1;;::::0;;;:21:::1;:30;::::0;;;;:37;;-1:-1:-1;;72792:37:0::1;-1:-1:-1::0;72792:37:0::1;::::0;;72842:23:::1;::::0;72792:30;;72842:11:::1;:23::i;:::-;72876:31;:15;72899:7:::0;72876:22:::1;:31::i;:::-;72925:29;::::0;-1:-1:-1;;;;;72925:29:0;::::1;::::0;::::1;::::0;;;::::1;72664:298:::0;:::o;73230:183::-;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;73308:15:::1;::::0;::::1;::::0;;;::::1;;:24;;::::0;::::1;;;;73300:33;;;::::0;::::1;;73344:15;:23:::0;;-1:-1:-1;;73344:23:0::1;::::0;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;73383:22:::1;::::0;5417:41:1;;;73383:22:0::1;::::0;5405:2:1;5390:18;73383:22:0::1;;;;;;;;73230:183:::0;:::o;13812:300::-;243:10;13927:4;14021:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;14021:34:0;;;;;;;;;;13927:4;;13949:133;;14021:34;;:50;;14060:10;14021:38;:50::i;72462:194::-;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;72542:17:::1;::::0;::::1;;::::0;;::::1;;:26;;::::0;::::1;;;;72534:35;;;::::0;::::1;;72580:17;:25:::0;;-1:-1:-1;;72580:25:0::1;;::::0;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;72621:27:::1;::::0;5417:41:1;;;72621:27:0::1;::::0;5405:2:1;5390:18;72621:27:0::1;5372:92:1::0;78943:116:0;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;-1:-1:-1;;;;;79025:18:0;;;::::1;;::::0;;;:11:::1;:18;::::0;;;;:26;;-1:-1:-1;;79025:26:0::1;::::0;::::1;;::::0;;;::::1;::::0;;78943:116::o;74923:609::-;75027:7;75049:6;75070;75091:7;75113;75135;75183:22;:15;5068;;4987:104;75183:22;75174:5;:31;75170:249;;-1:-1:-1;75248:42:0;;-1:-1:-1;;;;;;;;75248:42:0;;-1:-1:-1;75248:42:0;;-1:-1:-1;75248:42:0;75222:185;;75170:249;75431:15;75449:36;:15;75479:5;75449:29;:36::i;:::-;75431:54;;75505:19;75516:7;75505:10;:19::i;:::-;75498:26;;;;;;;;;;;;;74923:609;;;;;;;;:::o;78396:135::-;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;78475:15:::1;:48:::0;;-1:-1:-1;;;;;78475:48:0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;78396:135::o;71652:234::-;71712:166;;-1:-1:-1;;;71712:166:0;;9813:2:1;71712:166:0;;;9795:21:1;9852:3;9832:18;;;9825:31;9892:34;9872:18;;;9865:62;9963:34;9943:18;;;9936:62;10035:34;10014:19;;;10007:63;10107:17;10086:19;;;10079:46;10142:19;;71712:166:0;9785:382:1;71894:186:0;27468:6;;72013:4;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;-1:-1:-1;;;;;;72042:30:0::1;;::::0;;;:21:::1;:30;::::0;;;;;::::1;;::::0;71894:186::o;27898:148::-;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;27989:6:::1;::::0;27968:40:::1;::::0;28005:1:::1;::::0;-1:-1:-1;;;;;27989:6:0::1;::::0;27968:40:::1;::::0;28005:1;;27968:40:::1;28019:6;:19:::0;;-1:-1:-1;;;;;;28019:19:0::1;::::0;;27898:148::o;72970:127::-;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;-1:-1:-1;;;;;73051:30:0;;;::::1;;::::0;;;:21:::1;:30;::::0;;;;:38;;-1:-1:-1;;73051:38:0::1;::::0;::::1;;::::0;;;::::1;::::0;;72970:127::o;40970:131::-;41036:7;41063:30;41086:6;41063:22;:30::i;10168:104::-;10224:13;10257:7;10250:14;;;;;:::i;72260:194::-;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;72340:17:::1;::::0;::::1;;:26;;::::0;::::1;;;;72332:35;;;::::0;::::1;;72378:17;:25:::0;;-1:-1:-1;;72378:25:0::1;::::0;::::1;;::::0;;::::1;::::0;;;72419:27:::1;::::0;5417:41:1;;;72419:27:0::1;::::0;5405:2:1;5390:18;72419:27:0::1;5372:92:1::0;14615:400:0;14735:4;14757:228;243:10;14807:7;14829:145;14886:15;14829:145;;;;;;;;;;;;;;;;;243:10;14829:25;;;;:11;:25;;;;;;;;-1:-1:-1;;;;;14829:34:0;;;;;;;;;;;;:38;:145::i;41320:216::-;-1:-1:-1;;;;;41501:26:0;;41434:7;41501:26;;;:18;:26;;;;;;41466:62;;:30;41501:26;41466:22;:30::i;:::-;:34;;:62::i;11630:216::-;11752:4;11774:42;243:10;11798:9;11809:6;11774:9;:42::i;73105:117::-;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;-1:-1:-1;;;;;73185:21:0;;;::::1;;::::0;;;:12:::1;:21;::::0;;;;:29;;-1:-1:-1;;73185:29:0::1;::::0;::::1;;::::0;;;::::1;::::0;;73105:117::o;72088:164::-;27468:6;;72194:4;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;-1:-1:-1;;;;;;72223:21:0::1;;::::0;;;:12:::1;:21;::::0;;;;;::::1;;::::0;72088:164::o;77557:831::-;27468:6;;77675:4;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;77701:15:::1;::::0;;;::::1;;;77697:60;;;-1:-1:-1::0;77740:5:0::1;77733:12;;77697:60;-1:-1:-1::0;;;;;77785:21:0;::::1;77769:13;77785:21:::0;;;:12:::1;:21;::::0;;;;;::::1;;77823:9:::0;:21;::::1;;;;77836:8;77823:21;:43;;;;-1:-1:-1::0;77849:17:0::1;::::0;::::1;::::0;::::1;;;77848:18;77823:43;77819:88;;;77890:5;77883:12;;;;;77819:88;77919:14;77936:8;:104;;78008:32;78032:7;78008:23;:32::i;:::-;77936:104;;;77960:32;77984:7;77960:23;:32::i;:::-;77919:121:::0;-1:-1:-1;78057:10:0;;78053:303:::1;;-1:-1:-1::0;;;;;78084:23:0;::::1;;::::0;;;:14:::1;:23;::::0;;;;78110:15:::1;78084:41:::0;;78140:179;::::1;;;78178:46;::::0;12248:25:1;;;78178:46:0;::::1;;::::0;-1:-1:-1;;;;;78178:46:0;::::1;::::0;::::1;::::0;12236:2:1;12221:18;78178:46:0::1;;;;;;;78140:179;;;78270:33;::::0;12248:25:1;;;78270:33:0;::::1;;::::0;-1:-1:-1;;;;;78270:33:0;::::1;::::0;::::1;::::0;12236:2:1;12221:18;78270:33:0::1;;;;;;;78140:179;78340:4;78333:11;;;;;;78053:303;-1:-1:-1::0;78375:5:0::1;::::0;77557:831;-1:-1:-1;;;;77557:831:0:o;75540:610::-;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;-1:-1:-1;;;;;75654:30:0;::::1;;::::0;;;:21:::1;:30;::::0;;;;;::::1;;75650:69;;;75540:610:::0;;:::o;75650:69::-:1;75748:31;75735:10;:44;75731:169;;;75796:31;:15;75819:7:::0;75796:22:::1;:31::i;:::-;75842:23;75854:7;75863:1;75842:11;:23::i;:::-;75540:610:::0;;:::o;75731:169::-:1;75912:32;75924:7;75933:10;75912:11;:32::i;:::-;75975:35;75961:10;:49;75957:186;;76027:40;:15;76047:7:::0;76056:10;76027:19:::1;:40::i;75957:186::-;76100:31;:15;76123:7:::0;76100:22:::1;:31::i;28201:281::-:0;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;-1:-1:-1;;;;;28304:22:0;::::1;28282:110;;;::::0;-1:-1:-1;;;28282:110:0;;8647:2:1;28282:110:0::1;::::0;::::1;8629:21:1::0;8686:2;8666:18;;;8659:30;8725:34;8705:18;;;8698:62;8796:8;8776:18;;;8769:36;8822:19;;28282:110:0::1;8619:228:1::0;28282:110:0::1;28429:6;::::0;28408:38:::1;::::0;-1:-1:-1;;;;;28408:38:0;;::::1;::::0;28429:6:::1;::::0;28408:38:::1;::::0;28429:6:::1;::::0;28408:38:::1;28457:6;:17:::0;;-1:-1:-1;;;;;;28457:17:0::1;-1:-1:-1::0;;;;;28457:17:0;;;::::1;::::0;;;::::1;::::0;;28201:281::o;78539:271::-;27468:6;;-1:-1:-1;;;;;27468:6:0;243:10;27468:22;27460:67;;;;-1:-1:-1;;;27460:67:0;;10776:2:1;27460:67:0;;;10758:21:1;;;10795:18;;;10788:30;-1:-1:-1;;;;;;;;;;;10834:18:1;;;10827:62;10906:18;;27460:67:0;10748:182:1;27460:67:0;-1:-1:-1;;;;;78671:18:0;::::1;;::::0;;;:11:::1;:18;::::0;;;;;::::1;;::::0;:41:::1;;-1:-1:-1::0;;;;;;78693:19:0;::::1;::::0;78671:41:::1;78649:114;;;::::0;-1:-1:-1;;;78649:114:0;;8295:2:1;78649:114:0::1;::::0;::::1;8277:21:1::0;8334:2;8314:18;;;8307:30;8373:25;8353:18;;;8346:53;8416:18;;78649:114:0::1;8267:173:1::0;78649:114:0::1;-1:-1:-1::0;;;;;78774:20:0;;::::1;;::::0;;;:11:::1;:20;::::0;;;;:28;;-1:-1:-1;;;;;;78774:28:0::1;::::0;;;::::1;;::::0;;78539:271::o;73666:1249::-;74009:8;73766:15;;;;;74038:38;:15;74009:8;74038:29;:38::i;:::-;74030:46;-1:-1:-1;;;;;;74135:10:0;;74131:598;;74183:18;;74174:5;74166:35;74162:556;;;74288:18;;74249:77;;:5;;:9;:77::i;:::-;74222:104;;74162:556;;;74453:18;;74402:15;:27;74367:32;;-1:-1:-1;74402:169:0;;74570:1;74402:169;;;74527:18;;74495:15;:27;:51;;:31;:51::i;:::-;74367:204;-1:-1:-1;74619:83:0;:5;74367:204;74619:9;:83::i;:::-;74592:110;;74162:556;;74765:31;74788:7;74765:22;:31::i;:::-;74741:55;;74824:31;74847:7;74824:22;:31::i;:::-;-1:-1:-1;;;;;74884:23:0;;;;;;:14;:23;;;;;;;;73666:1249;;-1:-1:-1;73666:1249:0;;;;74899:7;-1:-1:-1;;73666:1249:0:o;76158:1391::-;76346:15;:27;76236:7;;;;;;76390:25;;;:44;;-1:-1:-1;76419:15:0;;;;;;;76390:44;76386:110;;;-1:-1:-1;;76465:18:0;;76459:1;;-1:-1:-1;76459:1:0;;-1:-1:-1;76451:33:0;;76386:110;76538:18;;76508:27;;76619:9;76601:27;;76641:18;76674:14;76705:724;76722:3;76712:7;:13;:50;;;;;76742:20;76729:10;:33;76712:50;76705:724;;;76779:21;;;;:::i;:::-;;;;76844:20;76821:19;:43;76817:107;;76907:1;76885:23;;76817:107;76940:15;76958;:20;;76979:19;76958:41;;;;;;-1:-1:-1;;;76958:41:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;76958:41:0;77021:30;;;:21;:30;;;;;;;;76958:41;;-1:-1:-1;77021:30:0;;77016:166;;77076:38;77099:7;77109:4;77076:14;:38::i;:::-;77072:95;;;77139:8;;;;:::i;:::-;;;;77072:95;77198:12;;;;:::i;:::-;;;;77227:18;77248:9;77227:30;;77288:10;77278:7;:20;77274:107;;;77329:36;77341:23;:7;77353:10;77341:11;:23::i;:::-;77329:7;;:11;:36::i;:::-;77319:46;;77274:107;77407:10;-1:-1:-1;76705:724:0;;-1:-1:-1;76705:724:0;;77441:18;:40;;;77502:10;;-1:-1:-1;77514:6:0;-1:-1:-1;77462:19:0;;-1:-1:-1;;;;76158:1391:0;;;;;;:::o;23566:471::-;23624:7;23869:6;23865:47;;-1:-1:-1;23899:1:0;23892:8;;23865:47;23924:9;23936:5;23940:1;23936;:5;:::i;:::-;23924:17;-1:-1:-1;23969:1:0;23960:5;23964:1;23924:17;23960:5;:::i;:::-;:10;23952:56;;;;-1:-1:-1;;;23952:56:0;;10374:2:1;23952:56:0;;;10356:21:1;10413:2;10393:18;;;10386:30;10452:34;10432:18;;;10425:62;10523:3;10503:18;;;10496:31;10544:19;;23952:56:0;10346:223:1;23952:56:0;24028:1;23566:471;-1:-1:-1;;;23566:471:0:o;22178:181::-;22236:7;;22268:5;22272:1;22268;:5;:::i;:::-;22256:17;;22297:1;22292;:6;;22284:46;;;;-1:-1:-1;;;22284:46:0;;9457:2:1;22284:46:0;;;9439:21:1;9496:2;9476:18;;;9469:30;9535:29;9515:18;;;9508:57;9582:18;;22284:46:0;9429:177:1;18006:380:0;-1:-1:-1;;;;;18142:19:0;;18134:68;;;;-1:-1:-1;;;18134:68:0;;11539:2:1;18134:68:0;;;11521:21:1;11578:2;11558:18;;;11551:30;11617:34;11597:18;;;11590:62;11688:6;11668:18;;;11661:34;11712:19;;18134:68:0;11511:226:1;18134:68:0;-1:-1:-1;;;;;18221:21:0;;18213:68;;;;-1:-1:-1;;;18213:68:0;;9054:2:1;18213:68:0;;;9036:21:1;9093:2;9073:18;;;9066:30;9132:34;9112:18;;;9105:62;9203:4;9183:18;;;9176:32;9225:19;;18213:68:0;9026:224:1;18213:68:0;-1:-1:-1;;;;;18294:18:0;;;;;;;-1:-1:-1;18294:18:0;;;;;;;;:27;;;;;;;;;;;;;:36;;;18346:32;;12248:25:1;;;18346:32:0;;;;;;;;;;;;18006:380;;;:::o;71456:188::-;71570:66;;-1:-1:-1;;;71570:66:0;;7878:2:1;71570:66:0;;;7860:21:1;7917:2;7897:18;;;7890:30;7956:34;7936:18;;;7929:62;8027:18;8007;;;8000:46;8063:19;;71570:66:0;7850:238:1;71570:66:0;71456:188;;;:::o;23081:226::-;23201:7;23237:12;23229:6;;;;23221:29;;;;-1:-1:-1;;;23221:29:0;;;;;;;;:::i;:::-;-1:-1:-1;23261:9:0;23273:5;23277:1;23273;:5;:::i;:::-;23261:17;23081:226;-1:-1:-1;;;;;23081:226:0:o;30306:148::-;30362:6;30399:1;30420:6;;;;30412:15;;;;;29741:176;29797:6;;29827:5;29831:1;29827;:5;:::i;:::-;29816:16;;29857:1;29852;:6;;:16;;;;;29867:1;29862;:6;;29852:16;29851:38;;;;29878:1;29874;:5;:14;;;;;29887:1;29883;:5;29874:14;29843:47;;;;;30144:127;30200:7;30233:1;30228;:6;;30220:15;;;;;;-1:-1:-1;30261:1:0;30144:127::o;44715:451::-;-1:-1:-1;;;;;11391:18:0;;44793:22;11391:18;;;;;;;;;;;44853:27;;;44849:310;;;44897:18;44918:30;:10;44933:14;44918;:30::i;:::-;44897:51;;44963:26;44969:7;44978:10;44963:5;:26::i;:::-;44849:310;71456:188;;;:::o;44849:310::-;45024:14;45011:10;:27;45007:152;;;45055:18;45076:30;:14;45095:10;45076:18;:30::i;:::-;45055:51;;45121:26;45127:7;45136:10;45121:5;:26::i;5470:481::-;-1:-1:-1;;;;;5541:17:0;;;;;;:12;;;:17;;;;;;;;5536:57;;5470:481;;:::o;5536:57::-;-1:-1:-1;;;;;5612:17:0;;;;;;:12;;;:17;;;;;;;;5605:24;;-1:-1:-1;;5605:24:0;;;-1:-1:-1;5647:10:0;;;:15;;;;;5640:22;;;5691:11;;;:16;;;;;;5738:15;;5691:16;;5612:17;5738:19;;;:::i;:::-;5718:39;;5768:15;5786:3;:8;;5795:9;5786:19;;;;;;-1:-1:-1;;;5786:19:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;5786:19:0;;;5818:20;;;:11;;;:20;;;;;;;:28;;;5864:16;;;;;;;5857:23;;;;5893:15;;5786:19;;-1:-1:-1;5786:19:0;;5818:11;;:28;;5893:15;;;;-1:-1:-1;;;5893:15:0;;;;;;;;;;;;;;;;;;:25;;-1:-1:-1;;;;;;5893:25:0;-1:-1:-1;;;;;5893:25:0;;;;;;;;;;5929:14;;;;;;;-1:-1:-1;;;5929:14:0;;;;;;;;;;;;;;;;-1:-1:-1;;5929:14:0;;;;;;;-1:-1:-1;;;;;;5929:14:0;;;;;;-1:-1:-1;;;;;5470:481:0:o;4819:160::-;4924:7;4956:3;:8;;4965:5;4956:15;;;;;;-1:-1:-1;;;4956:15:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;4956:15:0;;;-1:-1:-1;;;4819:160:0:o;22642:136::-;22700:7;22727:43;22731:1;22734;22727:43;;;;;;;;;;;;;;;;;:3;:43::i;80922:1997::-;81031:7;81056:29;81088:28;81111:4;81088:22;:28::i;:::-;81056:60;-1:-1:-1;81131:25:0;;81127:1764;;-1:-1:-1;;;;;81200:24:0;;;;;;:18;:24;;;;;;:83;;81247:21;81200:28;:83::i;:::-;-1:-1:-1;;;;;81173:24:0;;;;;;;:18;:24;;;;;;;;:110;;;;81323:11;:17;;;;;;81460;;81323;;;81173:24;81460:17;;81459:18;;:65;;-1:-1:-1;;;;;;81498:26:0;;;81459:65;:112;;;-1:-1:-1;;;;;;81546:25:0;;;;;;:11;:25;;;;;;;;81545:26;81459:112;81437:1096;;;81620:115;;-1:-1:-1;;;;;81620:9:0;;;81708:4;;81659:21;;81620:115;;;;81659:21;81620:9;81708:4;81620:115;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81606:129;;;;;81437:1096;;;81868:16;;;81882:1;81868:16;;;;;;;;81844:21;;81868:16;;;;;;;;-1:-1:-1;;81913:15:0;;:22;;;-1:-1:-1;;;81913:22:0;;;;81844:40;;-1:-1:-1;81913:15:0;;;;-1:-1:-1;;;;;81913:15:0;;:20;;-1:-1:-1;81913:22:0;;;;;;;;;;;;;;:15;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81903:4;81908:1;81903:7;;;;;;-1:-1:-1;;;81903:7:0;;;;;;;;;-1:-1:-1;;;;;81903:32:0;;;:7;;;;;;;;;;;:32;81954:7;;81964:12;;81954:4;;-1:-1:-1;;81954:7:0;;;;-1:-1:-1;;;81954:7:0;;;;;;;;;-1:-1:-1;;;;;81954:22:0;;;:7;;;;;;;;;:22;82022:15;;:356;;-1:-1:-1;;;82022:356:0;;:15;;;;;;;;-1:-1:-1;;82148:21:0;;82022:356;;82219:1;;82278:4;;82309;;82340:15;;82022:356;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81997:521;;82493:5;82483:15;;81997:521;;;82429:4;82419:14;;81997:521;81437:1096;;82554:7;82549:286;;-1:-1:-1;;;;;82609:24:0;;;;;;:18;:24;;;;;;:91;;82660:21;82609:28;:91::i;:::-;-1:-1:-1;;;;;82582:24:0;;;;;;;;:18;:24;;;;;:118;;;;-1:-1:-1;82582:24:0;;;-1:-1:-1;;;80922:1997:0:o;82549:286::-;82773:46;;12248:25:1;;;-1:-1:-1;;;;;82773:46:0;;;;;12236:2:1;12221:18;82773:46:0;;;;;;;-1:-1:-1;82858:21:0;;80922:1997;-1:-1:-1;;;80922:1997:0:o;81127:1764::-;-1:-1:-1;82910:1:0;;80922:1997;-1:-1:-1;;80922:1997:0:o;79185:1729::-;79270:7;79295:29;79327:31;79350:7;79327:22;:31::i;:::-;79295:63;-1:-1:-1;79373:25:0;;79369:1517;;-1:-1:-1;;;;;79474:27:0;;79415:12;79474:27;;;:18;:27;;;;;;:86;;79524:21;79474:31;:86::i;:::-;-1:-1:-1;;;;;79444:27:0;;;;;;:18;:27;;;;;;;;:116;;;;79601:16;;79615:1;79601:16;;;;;;;;79444:27;;79601:16;;79615:1;79601:16;;;79444:27;79601:16;;;-1:-1:-1;;79642:15:0;;:22;;;-1:-1:-1;;;79642:22:0;;;;79577:40;;-1:-1:-1;79642:15:0;;;;-1:-1:-1;;;;;79642:15:0;;:20;;-1:-1:-1;79642:22:0;;;;;;;;;;;;;;:15;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79632:4;79637:1;79632:7;;;;;;-1:-1:-1;;;79632:7:0;;;;;;;;;-1:-1:-1;;;;;79632:32:0;;;:7;;;;;;;;;:32;79697:9;;79679:7;;79697:9;;;79679:7;;-1:-1:-1;;79679:7:0;;;;-1:-1:-1;;;79679:7:0;;;;;;;;;-1:-1:-1;;;;;79679:28:0;;;:7;;;;;;;;;:28;79746:9;;:34;;-1:-1:-1;;;79746:34:0;;79774:4;79746:34;;;4305:74:1;79724:19:0;;79746:9;;;;;:19;;4278:18:1;;79746:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79848:15;;:333;;-1:-1:-1;;;79848:333:0;;79724:56;;-1:-1:-1;79848:15:0;;;-1:-1:-1;;;;;79848:15:0;;-1:-1:-1;;79966:21:0;;79848:333;;80029:1;;80084:4;;80119;;80147:15;;79848:333;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79827:787;;80593:5;80583:15;;79827:787;;;80233:9;;:34;;-1:-1:-1;;;80233:34:0;;80261:4;80233:34;;;4305:74:1;80214:16:0;;80233:91;;80294:11;;-1:-1:-1;;;;;80233:9:0;;:19;;4278:18:1;;80233:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:91::-;80214:110;-1:-1:-1;80347:12:0;;80343:199;;80421:9;;:37;;;;;-1:-1:-1;;;;;5167:55:1;;;80421:37:0;;;5149:74:1;5239:18;;;5232:34;;;80394:4:0;;-1:-1:-1;80421:9:0;;;;:18;;5122::1;;80421:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;80343:199;;;80517:5;80507:15;;80343:199;80195:362;79827:787;80635:7;80630:200;;-1:-1:-1;;;;;80693:27:0;;;;;;:18;:27;;;;;;:94;;80747:21;80693:31;:94::i;:::-;-1:-1:-1;;;;;80663:27:0;;;;;;;;:18;:27;;;;;:124;;;;-1:-1:-1;80663:27:0;;;-1:-1:-1;;;;79185:1729:0:o;80630:200::-;-1:-1:-1;80853:21:0;;79185:1729;-1:-1:-1;;;;79185:1729:0:o;5099:363::-;-1:-1:-1;;;;;5213:17:0;;;;;;:12;;;:17;;;;;;;;5209:246;;;-1:-1:-1;;;;;5247:15:0;;;;;;;;-1:-1:-1;5247:10:0;;;;:15;;;;;;:21;71456:188::o;5209:246::-;-1:-1:-1;;;;;5301:17:0;;;;;;;;:12;;;:17;;;;;;;;:24;;-1:-1:-1;;5301:24:0;-1:-1:-1;5301:24:0;;;;;;5340:10;;;:15;;;;;:21;;;;5395:15;;5376:11;;;:16;;;;;:34;;;5425:18;;;;;;;;;;;;;;;-1:-1:-1;;;;;;5425:18:0;;;;;;5099:363::o;4575:236::-;-1:-1:-1;;;;;4707:17:0;;4678:6;4707:17;;;:12;;;:17;;;;;;;;4702:60;;-1:-1:-1;;;4741:9:0;;4702:60;-1:-1:-1;;;;;;4786:16:0;;;;;:11;;;;;:16;;;;;;;4575:236::o;29477:176::-;29533:6;;29563:5;29567:1;29563;:5;:::i;:::-;29552:16;;29593:1;29588;:6;;:16;;;;;29603:1;29598;:6;;29588:16;29587:38;;;;29614:1;29610;:5;:14;;;;;29623:1;29619;:5;29579:47;;;;;43854:284;43930:27;43942:7;43951:5;43930:11;:27::i;:::-;44010:120;44076:53;44077:36;44107:5;44077:25;;:29;;:36;;;;:::i;44076:53::-;-1:-1:-1;;;;;44010:61:0;;;;;;:28;:61;;;;;;;:65;:120::i;:::-;-1:-1:-1;;;;;43970:37:0;;;;;;;;:28;:37;;;;;:160;;;;-1:-1:-1;43854:284:0:o;44423:::-;44499:27;44511:7;44520:5;44499:11;:27::i;:::-;44579:120;44645:53;44646:36;44676:5;44646:25;;:29;;:36;;;;:::i;44645:53::-;-1:-1:-1;;;;;44579:61:0;;;;;;:28;:61;;;;;;;:65;:120::i;16402:378::-;-1:-1:-1;;;;;16486:21:0;;16478:65;;;;-1:-1:-1;;;16478:65:0;;11944:2:1;16478:65:0;;;11926:21:1;11983:2;11963:18;;;11956:30;12022:33;12002:18;;;11995:61;12073:18;;16478:65:0;11916:181:1;16478:65:0;16633:12;;:24;;16650:6;16633:16;:24::i;:::-;16618:12;:39;-1:-1:-1;;;;;16689:18:0;;:9;:18;;;;;;;;;;;:30;;16712:6;16689:22;:30::i;:::-;-1:-1:-1;;;;;16668:18:0;;:9;:18;;;;;;;;;;;:51;;;;16735:37;;12248:25:1;;;16668:18:0;;:9;;16735:37;;12221:18:1;16735:37:0;;;;;;;;16402:378;;:::o;17113:455::-;-1:-1:-1;;;;;17197:21:0;;17189:67;;;;-1:-1:-1;;;17189:67:0;;11137:2:1;17189:67:0;;;11119:21:1;11176:2;11156:18;;;11149:30;11215:34;11195:18;;;11188:62;11286:3;11266:18;;;11259:31;11307:19;;17189:67:0;11109:223:1;17189:67:0;17352:105;17389:6;17352:105;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;17352:18:0;;:9;:18;;;;;;;;;;;;;:22;:105::i;:::-;-1:-1:-1;;;;;17331:18:0;;:9;:18;;;;;;;;;;:126;17483:12;;:24;;17500:6;17483:16;:24::i;:::-;17468:12;:39;17523:37;;12248:25:1;;;17549:1:0;;-1:-1:-1;;;;;17523:37:0;;;;;12236:2:1;12221:18;17523:37:0;12203:76:1;14:257;73:6;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:31;235:5;210:31;:::i;276:261::-;346:6;399:2;387:9;378:7;374:23;370:32;367:2;;;420:6;412;405:22;367:2;457:9;451:16;476:31;501:5;476:31;:::i;542:400::-;615:6;623;676:2;664:9;655:7;651:23;647:32;644:2;;;697:6;689;682:22;644:2;741:9;728:23;760:31;785:5;760:31;:::i;:::-;810:5;-1:-1:-1;867:2:1;852:18;;839:32;880:30;839:32;880:30;:::i;:::-;929:7;919:17;;;634:308;;;;;:::o;947:398::-;1015:6;1023;1076:2;1064:9;1055:7;1051:23;1047:32;1044:2;;;1097:6;1089;1082:22;1044:2;1141:9;1128:23;1160:31;1185:5;1160:31;:::i;:::-;1210:5;-1:-1:-1;1267:2:1;1252:18;;1239:32;1280:33;1239:32;1280:33;:::i;1350:466::-;1427:6;1435;1443;1496:2;1484:9;1475:7;1471:23;1467:32;1464:2;;;1517:6;1509;1502:22;1464:2;1561:9;1548:23;1580:31;1605:5;1580:31;:::i;:::-;1630:5;-1:-1:-1;1687:2:1;1672:18;;1659:32;1700:33;1659:32;1700:33;:::i;:::-;1454:362;;1752:7;;-1:-1:-1;;;1806:2:1;1791:18;;;;1778:32;;1454:362::o;1821:392::-;1886:6;1894;1947:2;1935:9;1926:7;1922:23;1918:32;1915:2;;;1968:6;1960;1953:22;2218:325;2286:6;2294;2347:2;2335:9;2326:7;2322:23;2318:32;2315:2;;;2368:6;2360;2353:22;2315:2;2412:9;2399:23;2431:31;2456:5;2431:31;:::i;:::-;2481:5;2533:2;2518:18;;;;2505:32;;-1:-1:-1;;;2305:238:1:o;2548:251::-;2604:6;2657:2;2645:9;2636:7;2632:23;2628:32;2625:2;;;2678:6;2670;2663:22;2625:2;2722:9;2709:23;2741:28;2763:5;2741:28;:::i;2804:255::-;2871:6;2924:2;2912:9;2903:7;2899:23;2895:32;2892:2;;;2945:6;2937;2930:22;2892:2;2982:9;2976:16;3001:28;3023:5;3001:28;:::i;3064:190::-;3123:6;3176:2;3164:9;3155:7;3151:23;3147:32;3144:2;;;3197:6;3189;3182:22;3144:2;-1:-1:-1;3225:23:1;;3134:120;-1:-1:-1;3134:120:1:o;3259:194::-;3329:6;3382:2;3370:9;3361:7;3357:23;3353:32;3350:2;;;3403:6;3395;3388:22;3350:2;-1:-1:-1;3431:16:1;;3340:113;-1:-1:-1;3340:113:1:o;3458:486::-;3511:3;3549:5;3543:12;3576:6;3571:3;3564:19;3602:4;3631:2;3626:3;3622:12;3615:19;;3668:2;3661:5;3657:14;3689:3;3701:218;3715:6;3712:1;3709:13;3701:218;;;3780:13;;-1:-1:-1;;;;;3776:62:1;3764:75;;3859:12;;;;3894:15;;;;-1:-1:-1;3730:9:1;3701:218;;;-1:-1:-1;3935:3:1;;3519:425;-1:-1:-1;;;;;3519:425:1:o;5984:541::-;6263:6;6252:9;6245:25;6306:3;6301:2;6290:9;6286:18;6279:31;6226:4;6327:57;6379:3;6368:9;6364:19;6356:6;6327:57;:::i;:::-;-1:-1:-1;;;;;6420:55:1;;;;6415:2;6400:18;;6393:83;-1:-1:-1;6507:2:1;6492:18;6485:34;6420:55;6319:65;-1:-1:-1;;6235:290:1:o;7068:603::-;7180:4;7209:2;7238;7227:9;7220:21;7270:6;7264:13;7313:6;7308:2;7297:9;7293:18;7286:34;7338:4;7351:140;7365:6;7362:1;7359:13;7351:140;;;7460:14;;;7456:23;;7450:30;7426:17;;;7445:2;7422:26;7415:66;7380:10;;7351:140;;;7509:6;7506:1;7503:13;7500:2;;;7579:4;7574:2;7565:6;7554:9;7550:22;7546:31;7539:45;7500:2;-1:-1:-1;7655:2:1;7634:15;-1:-1:-1;;7630:29:1;7615:45;;;;7662:2;7611:54;;7189:482;-1:-1:-1;;;7189:482:1:o;12797:369::-;12836:3;12871;12868:1;12864:11;12982:1;12914:66;12910:74;12907:1;12903:82;12898:2;12891:10;12887:99;12884:2;;;12989:18;;:::i;:::-;-1:-1:-1;;;13036:74:1;;;13029:82;;13021:91;;13018:2;;;13115:18;;:::i;:::-;-1:-1:-1;;13151:9:1;;12844:322::o;13171:128::-;13211:3;13242:1;13238:6;13235:1;13232:13;13229:2;;;13248:18;;:::i;:::-;-1:-1:-1;13284:9:1;;13219:80::o;13304:274::-;13344:1;13370;13360:2;;-1:-1:-1;13395:88:1;;13506:4;13503:1;13496:15;13534:4;13402:1;13524:15;13360:2;-1:-1:-1;13563:9:1;;13350:228::o;13583:168::-;13623:7;13689:1;13685;13681:6;13677:14;13674:1;13671:21;13666:1;13659:9;13652:17;13648:45;13645:2;;;13696:18;;:::i;:::-;-1:-1:-1;13736:9:1;;13635:116::o;13756:372::-;13795:4;13824:12;;;13852:10;;-1:-1:-1;;;13871:74:1;;13864:82;;13848:99;13845:2;;;13950:18;;:::i;:::-;14069:1;14001:66;13997:74;13994:1;13990:82;13986:2;13982:91;13979:2;;;14076:18;;:::i;:::-;-1:-1:-1;;14113:9:1;;13804:324::o;14133:125::-;14173:4;14201:1;14198;14195:8;14192:2;;;14206:18;;:::i;:::-;-1:-1:-1;14243:9:1;;14182:76::o;14263:437::-;14342:1;14338:12;;;;14385;;;14406:2;;14460:4;14452:6;14448:17;14438:27;;14406:2;14513;14505:6;14502:14;14482:18;14479:38;14476:2;;;-1:-1:-1;;;14547:1:1;14540:88;14651:4;14648:1;14641:15;14679:4;14676:1;14669:15;14476:2;;14318:382;;;:::o;14705:135::-;14744:3;-1:-1:-1;;14765:17:1;;14762:2;;;14785:18;;:::i;:::-;-1:-1:-1;14832:1:1;14821:13;;14752:88::o;14845:184::-;-1:-1:-1;;;14894:1:1;14887:88;14994:4;14991:1;14984:15;15018:4;15015:1;15008:15;15034:154;-1:-1:-1;;;;;15109:54:1;;15099:65;;15089:2;;15178:1;15175;15168:12;15089:2;15079:109;:::o;15193:118::-;15279:5;15272:13;15265:21;15258:5;15255:32;15245:2;;15301:1;15298;15291:12

Swarm Source

ipfs://58a930dca684adcddf0226e4202f7551f9505675bf8d4b2b37f47f043ae45591
Loading