Token UTU Trust Token

 

Overview ERC-20

Price
$0.00 @ 0.000000 MATIC
Fully Diluted Market Cap
Total Supply:
62,160,660 UTT

Holders:
6,106 addresses

Transfers:
-

Contract:
0xba6de5f4a98d2aebb289d1136194d05ee24c426f0xbA6de5f4a98d2AEbb289d1136194D05Ee24C426f

Decimals:
0

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:
UTT

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 20 : UTT.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";
import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";

contract UTT is ERC20Burnable, ERC20Pausable, Ownable, ChainlinkClient {
    using Chainlink for Chainlink.Request;

    /**
     * The `socialConnections` mapping is storing the connected socialIds
     * as so: address => socialTypeId => socialUserIdHash
     */
    mapping (address => mapping (uint256 => bytes32) ) socialConnections;

    /**
     * The `socialConnectionReward` variable is the amount of tokens to be minted
     * as a reward for connecting/verifying with a social platform user id.
     */
    uint256 public socialConnectionReward = 10000;


    // Reward parameters:

    /** New stake offset (see whitepaper) */
    uint256 public O_n = 1;

    /** Discounting component for the new stake (see whitepaper) */
    uint256 public D_n = 30;

    /** Discounting component for the stake of first-level previous endorsers (see whitepaper) */
    uint256 public D_lvl1 = 2;

    /** Discounting component for the stake of second-level previous endorsers (see whitepaper) */
    uint256 public D_lvl2 = 20; //

    /** Discounting component for other previous endorsers' total stake (see whitepaper) */
    uint256 public D_o = 5000;

    // Keeping track of stakes on endorsements:

    /** A map targetAddress => endorserAddress => stake mapping all endorser's stakes by their endorsement target */
    mapping (address => mapping(address => uint256)) public previousEndorserStakes;

    /** A map targetAddress => stake with the total stake by target */
    mapping (address => uint) public totalStake;

    // Oracle related:

    /**
     * Chainlinkg orcale request data structure
     */
    struct OracleRequest {
        address from;
        address target;
        uint256 amount;
        string transactionId;
    }

    /** Sent oracle requests by id  */
    mapping (bytes32 => OracleRequest) private oracleRequests;

    /** Address of the Chainlink oracle operator contract */
    address private oracle;

    /** Id for oracle jobs from this contract */
    bytes32 private jobId;

    /** LINK fee to be paid to the oracle operator contract for each request */
    uint256 private fee;

    /** Contract migration flag; when migrating any further endorsements or social connections are disabled. */
    bool public isMigrating;


    // Events for connecting social media accounts/other user ids.

    /** Social media account was connected */
    event AddConnection(address indexed _user, uint indexed _connectedTypeId, bytes32 indexed _connectedUserIdHash);

    /** Social media account was disconnected */
    event RemoveConnection(address indexed _user, uint indexed _connectedTypeId, bytes32 indexed _connectedUserIdHash);


    // Events for endorsements.

    /** A new endorsement was made */
    event Endorse(address indexed _from, address indexed _to, uint _value, string _transactionId);

    /** A first-level previous endorser was rewarded */
    event RewardPreviousEndorserLevel1(address endorser, uint256 reward);

    /** A second-level previous endorser was rewarded */
    event RewardPreviousEndorserLevel2(address endorser, uint256 reward);

    /**
     * Constructs new UTU Trust Token contract.
     * See also {ERC20-constructor}.
     * @param _mintAmount amount of UTT minted to the deploying address; only used in testing.
     * @param _oracle Chainlink oracle operator contract address
     * @param _jobId Id for oracle jobs from this contract
     * @param _fee Initial value for the LINK fee
     * @param _link LINK token address
     */
    constructor(
        uint256 _mintAmount,
        address _oracle,
        string memory _jobId,
        uint256 _fee,
        address _link
    )
        ERC20("UTU Trust Token", "UTT")
    {
        _mint(msg.sender, _mintAmount);
        setChainlinkToken(_link);
        oracle = _oracle;
        jobId = stringToBytes32(_jobId);
        fee = _fee;
    }

    /**
     * Requires that the contract is not migrating.
     */
    modifier notMigrating() {
        require(!isMigrating, "Contract is migrating");
        _;
    }

    /**
     * Pauses all token transfers.
     *
     * See {ERC20Pausable} and {Pausable-_pause}.
     *
     */
    function pause()
        public
        virtual
        onlyOwner
    {
        _pause();
    }

    /**
     * Unpauses all token transfers.
     *
     * See {ERC20Pausable} and {Pausable-_unpause}.
     *
     */
    function unpause()
        public
        virtual
        onlyOwner
    {
        _unpause();
    }

    /**
     * Returns 0 decimals (since we don't need decimals for this particular use case).
     */
    function decimals() public view virtual override returns (uint8) {
        return 0;
    }

    // Governance functions for setting the reward and penalty parameters

    /** Sets the O_n reward formula parameter */
    function setO_n(uint256 val) public onlyOwner {
        O_n = val;
    }

    /** Sets the D_n reward formula parameter */
    function setD_n(uint256 val) public onlyOwner {
        D_n = val;
    }

    /** Sets the D_lvl1 reward formula parameter */
    function setD_lvl1(uint256 val) public onlyOwner {
        D_lvl1 = val;
    }

    /** Sets the D_lvl2 reward formula parameter */
    function setD_lvl2(uint256 val) public onlyOwner {
        D_lvl2 = val;
    }

    /** Sets the D_o reward formula parameter */
    function setD_o(uint256 val) public onlyOwner {
        D_o = val;
    }


    /** Sets the LINK fee to be paid for each request */
    function setFee(uint256 _fee) public onlyOwner {
        fee = _fee;
    }

    /**
     * @dev Computes the reward to be given to previousEndorser for a new endorsement of s_n on the given target and the
     * previous endorser level-dependent discount D_lvl_p. It assumes that the new endorsement s_n has not yet been
     * added to the totalStake map.
     * See whitepaper.
     * @param target the endorsed entity (address is just used as an id here)
     * @param previousEndorser address of the previous endorser for whom the reward shall be computed
     * @param D_lvl_p Discounting factor for the level of the previous endorser (i.e. value of D_lvl1 or D_lvl2)
     * @param s_n stake for the new endorsement
     * @return The reward in UTT that shall be minted to previousEndorser
     */
    function computeReward(
        address target,
        address previousEndorser,
        uint256 D_lvl_p,
        uint256 s_n
    )
    private
    view
    returns (uint256)
    {
        uint256 s_p = previousEndorserStakes[target][previousEndorser];
        uint256 s_o = totalStake[target] - s_p;

        return
            (s_p *  (s_n + O_n) * D_o)
            /
            (D_lvl_p * (s_n + D_n) * (D_o + s_o));
    }


    /**
     * @dev Called from fulfillEndorse, which is called by the oracle operator contract when the oracle has retrieved
     * previous endorsers from the UTU Trust API. It computes the rewards for each previous endorser according to their
     * levels, and adds the new stake to the totalStake and previousEndorserStakes maps.
     * @param from new endorser's address
     * @param target the endorsed entity (address is just used as an id here)
     * @param amount the stake for the new endorsement
     * @param transactionId an id representing the "business transaction" for which the endorsement was made; this is
              _not_ necessarily an Ethereum transaction id.
     * @param endorsersLevel1 list of first-level previous endorser addresses.
     * @param endorsersLevel2 list of second-level previous endorser addresses.
     * Invokes `super._transfer()`.
     */
    function _endorse(
        address from,
        address target,
        uint256 amount,
        string memory transactionId,
        address[] memory endorsersLevel1,
        address[] memory endorsersLevel2
    )
        internal
    {
        //reward first-level previous endorsers
        for(uint8 i=0; i < endorsersLevel1.length; i++){
            uint256 endorserReward = computeReward(target, endorsersLevel1[i], D_lvl1, amount);

            // mint rewarded tokens to endorser
            super._mint(address(endorsersLevel1[i]), endorserReward);
            emit RewardPreviousEndorserLevel1(endorsersLevel1[i], endorserReward);
        }

        //reward first-level previous endorsers
        for(uint8 i=0; i < endorsersLevel2.length; i++){
            uint256 endorserReward = computeReward(target, endorsersLevel2[i], D_lvl2, amount);

            // mint rewarded tokens to endorser
            super._mint(endorsersLevel2[i], endorserReward);
            emit RewardPreviousEndorserLevel2(endorsersLevel2[i], endorserReward);
        }

        totalStake[target] += amount;
        previousEndorserStakes[target][from] += amount;

        emit Endorse(from, target, amount, transactionId);
    }

    /**
     * @notice Creates a new staked endorsement, where the caller is the endorser. Previous endorsers, retrieved
     *         from the UTU Trust API via an oracle, will be rewarded according to the reward formula from the
     *         whitepaper.
     * @dev This creates an oracle request. The actual endorsement, staking and rewarding is done on its fulfillment.
     * @param target the endorsed entity (address is just used as an id here)
     * @param amount the stake for the new endorsement
     * @param transactionId an id representing the "business transaction" for which the endorsement was made; this is
     *        _not_ necessarily an Ethereum transaction id.
     */
    function endorse(address target, uint256 amount, string memory transactionId) notMigrating external {
        require(msg.sender == tx.origin, "should be an user");

        uint256 fromBalance = balanceOf(msg.sender);
        require(fromBalance >= amount, "UTT: endorse amount exceeds balance");

        Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfillEndorse.selector);
        request.add("targetAddress", addressToString(target));
        request.add("sourceAddress", addressToString(msg.sender));
        request.add("transactionId", transactionId);
        bytes32 requestId = sendOperatorRequestTo(oracle, request, fee);
        oracleRequests[requestId] = OracleRequest({ from: msg.sender, target: target, amount: amount, transactionId: transactionId });
    }

    /**
     * @dev Called back from the oracle operator contract when the oracle request was fulfilled, with the retrieved
     *      values.
     * @param _requestId oracle request id as it was stored in oracleRequests
     * @param endorsersLevel1 list of first-level previous endorser addresses
     * @param endorsersLevel2 list of second-level previous endorser addresses
     */
    function fulfillEndorse(
        bytes32 _requestId,
        address[] calldata endorsersLevel1,
        address[] calldata endorsersLevel2
    )
        external
        recordChainlinkFulfillment(_requestId)
    {
        OracleRequest memory r = oracleRequests[_requestId];
        require(r.target != address(0), "unknown endorsment");
        _burn(r.from, r.amount);
        _endorse(r.from, r.target, r.amount, r.transactionId, endorsersLevel1, endorsersLevel2);
    }

    /**
     * @dev Called by UTU's social media connector when the user connects a supported social media account, and rewards
     *      them for it with a configured amount of UTT. It's callable only by owner to prevent calls for which the
     *      connector hasn't verified that the connection was really made, and to prevent repeated dis/-reconnects
     *      (this might be solved differently in the future).
     * @param user the connecting user's address
     * @param connectedTypeId id of the social media platform; we allow a user to connect a particular platform only
     *        once.
     * @param connectedUserIdHash hash of the user account id or name; this value is hashed to preserve the user's
     *        privacy.
     */
    function addConnection(
        address user,
        uint256 connectedTypeId,
        bytes32 connectedUserIdHash
    )
        public
        notMigrating
        onlyOwner
    {
        // only add connection if not previously added
        if (socialConnections[user][connectedTypeId] == 0) {
            socialConnections[user][connectedTypeId] = connectedUserIdHash;

            // mint reward
            super._mint(user, socialConnectionReward);

            emit AddConnection(user, connectedTypeId, connectedUserIdHash);
        }
    }

    /**
     * @dev Called by UTU's social media connector when the user removes a connection to a social media account. It's
     *      callable only by owner to prevent repeated dis/-reconnects (this might be solved differently in the future).
     * @param user the connecting user's address
     * @param connectedTypeId id of the social media platform
     */
    function removeConnection(
        address user,
        uint256 connectedTypeId
    )
        public
        notMigrating
        onlyOwner
    {
        // only remove connection if currently connected
        if (socialConnections[user][connectedTypeId] != 0) {
            socialConnections[user][connectedTypeId] = 0;

            emit RemoveConnection(user, connectedTypeId, 0);
        }
    }

    /**
     * Sets the amount of UTT to be rewarded for (new) social media connections
     * @param amount of UTT to be rewarded for (new) social media connections
     */
    function setSocialConnectionReward(
        uint256 amount
    )
        public
        onlyOwner
    {
        socialConnectionReward = amount;
    }

    /**
     * @dev just calls super._beforeTokenTransfer()
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    )
        internal
        override(ERC20, ERC20Pausable)
    {
        super._beforeTokenTransfer(from, to, amount);
    }

    /**
     * Always reverts on external calls on transfer, since UTT is not transferable.
     */
    function transfer(address recipient, uint256 amount) public pure override returns (bool) {
      revert('Not allowed.');
    }


    /**
     * * Always reverts on external calls on approve, since UTT is not transferable.
     */
    function approve(address spender, uint256 amount) public pure override returns (bool) {
      revert('Not allowed.');
    }

    /**
     * @dev Converts an address to a string "0x..." representation.
     * @param x an address
     * @return string representation of the address
     */
    function addressToString(address x) internal pure returns (string memory) {
        bytes memory s = new bytes(40);
        for (uint i = 0; i < 20; i++) {
            bytes1 b = bytes1(uint8(uint(uint160(x)) / (2**(8*(19 - i)))));
            bytes1 hi = bytes1(uint8(b) / 16);
            bytes1 lo = bytes1(uint8(b) - 16 * uint8(hi));
            s[2*i] = char(hi);
            s[2*i+1] = char(lo);
        }
        return string(abi.encodePacked("0x", string(s)));
    }

    /**
     * @dev Converts a byte value to its readable char value.@param
     * @param b byte value
     * @return c the value as a readable char
     */
    function char(bytes1 b) internal pure returns (bytes1 c) {
        if (uint8(b) < 10) return bytes1(uint8(b) + 0x30);
        else return bytes1(uint8(b) + 0x57);
    }

    /**
     * @dev Converts a string to a bytes32 representation
     * @param source a string
     * @return result a bytes32
     */
    function stringToBytes32(string memory source) public pure returns (bytes32 result) {
        bytes memory tempEmptyStringTest = bytes(source);
        if (tempEmptyStringTest.length == 0) {
            return 0x0;
        }
        assembly {
            result := mload(add(source, 32))
        }
    }

    /**
     * Toggles the migration flag. While migrating, no new endorsements or social media (dis)connections can be made.
     * @dev Endorsements can still be fulfilled; thus the actual migration process should not be started until
     *      all pending fulfillments are done.
	 */
    function toggleMigrationFlag() public onlyOwner {
        isMigrating = !isMigrating;
    }
}

File 2 of 20 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract 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() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual 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 {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 3 of 20 : ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    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);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        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] + 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) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This 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);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(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 += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(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);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(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 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 {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

File 4 of 20 : ERC20Burnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../ERC20.sol";
import "../../../utils/Context.sol";

/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        uint256 currentAllowance = allowance(account, _msgSender());
        require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
        unchecked {
            _approve(account, _msgSender(), currentAllowance - amount);
        }
        _burn(account, amount);
    }
}

File 5 of 20 : ERC20Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../ERC20.sol";
import "../../../security/Pausable.sol";

/**
 * @dev ERC20 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC20Pausable is ERC20, Pausable {
    /**
     * @dev See {ERC20-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

        require(!paused(), "ERC20Pausable: token transfer while paused");
    }
}

File 6 of 20 : ChainlinkClient.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./Chainlink.sol";
import "./interfaces/ENSInterface.sol";
import "./interfaces/LinkTokenInterface.sol";
import "./interfaces/ChainlinkRequestInterface.sol";
import "./interfaces/OperatorInterface.sol";
import "./interfaces/PointerInterface.sol";
import {ENSResolver as ENSResolver_Chainlink} from "./vendor/ENSResolver.sol";

/**
 * @title The ChainlinkClient contract
 * @notice Contract writers can inherit this contract in order to create requests for the
 * Chainlink network
 */
abstract contract ChainlinkClient {
  using Chainlink for Chainlink.Request;

  uint256 internal constant LINK_DIVISIBILITY = 10**18;
  uint256 private constant AMOUNT_OVERRIDE = 0;
  address private constant SENDER_OVERRIDE = address(0);
  uint256 private constant ORACLE_ARGS_VERSION = 1;
  uint256 private constant OPERATOR_ARGS_VERSION = 2;
  bytes32 private constant ENS_TOKEN_SUBNAME = keccak256("link");
  bytes32 private constant ENS_ORACLE_SUBNAME = keccak256("oracle");
  address private constant LINK_TOKEN_POINTER = 0xC89bD4E1632D3A43CB03AAAd5262cbe4038Bc571;

  ENSInterface private s_ens;
  bytes32 private s_ensNode;
  LinkTokenInterface private s_link;
  OperatorInterface private s_oracle;
  uint256 private s_requestCount = 1;
  mapping(bytes32 => address) private s_pendingRequests;

  event ChainlinkRequested(bytes32 indexed id);
  event ChainlinkFulfilled(bytes32 indexed id);
  event ChainlinkCancelled(bytes32 indexed id);

  /**
   * @notice Creates a request that can hold additional parameters
   * @param specId The Job Specification ID that the request will be created for
   * @param callbackAddr address to operate the callback on
   * @param callbackFunctionSignature function signature to use for the callback
   * @return A Chainlink Request struct in memory
   */
  function buildChainlinkRequest(
    bytes32 specId,
    address callbackAddr,
    bytes4 callbackFunctionSignature
  ) internal pure returns (Chainlink.Request memory) {
    Chainlink.Request memory req;
    return req.initialize(specId, callbackAddr, callbackFunctionSignature);
  }

  /**
   * @notice Creates a request that can hold additional parameters
   * @param specId The Job Specification ID that the request will be created for
   * @param callbackFunctionSignature function signature to use for the callback
   * @return A Chainlink Request struct in memory
   */
  function buildOperatorRequest(bytes32 specId, bytes4 callbackFunctionSignature)
    internal
    view
    returns (Chainlink.Request memory)
  {
    Chainlink.Request memory req;
    return req.initialize(specId, address(this), callbackFunctionSignature);
  }

  /**
   * @notice Creates a Chainlink request to the stored oracle address
   * @dev Calls `chainlinkRequestTo` with the stored oracle address
   * @param req The initialized Chainlink Request
   * @param payment The amount of LINK to send for the request
   * @return requestId The request ID
   */
  function sendChainlinkRequest(Chainlink.Request memory req, uint256 payment) internal returns (bytes32) {
    return sendChainlinkRequestTo(address(s_oracle), req, payment);
  }

  /**
   * @notice Creates a Chainlink request to the specified oracle address
   * @dev Generates and stores a request ID, increments the local nonce, and uses `transferAndCall` to
   * send LINK which creates a request on the target oracle contract.
   * Emits ChainlinkRequested event.
   * @param oracleAddress The address of the oracle for the request
   * @param req The initialized Chainlink Request
   * @param payment The amount of LINK to send for the request
   * @return requestId The request ID
   */
  function sendChainlinkRequestTo(
    address oracleAddress,
    Chainlink.Request memory req,
    uint256 payment
  ) internal returns (bytes32 requestId) {
    uint256 nonce = s_requestCount;
    s_requestCount = nonce + 1;
    bytes memory encodedRequest = abi.encodeWithSelector(
      ChainlinkRequestInterface.oracleRequest.selector,
      SENDER_OVERRIDE, // Sender value - overridden by onTokenTransfer by the requesting contract's address
      AMOUNT_OVERRIDE, // Amount value - overridden by onTokenTransfer by the actual amount of LINK sent
      req.id,
      address(this),
      req.callbackFunctionId,
      nonce,
      ORACLE_ARGS_VERSION,
      req.buf.buf
    );
    return _rawRequest(oracleAddress, nonce, payment, encodedRequest);
  }

  /**
   * @notice Creates a Chainlink request to the stored oracle address
   * @dev This function supports multi-word response
   * @dev Calls `sendOperatorRequestTo` with the stored oracle address
   * @param req The initialized Chainlink Request
   * @param payment The amount of LINK to send for the request
   * @return requestId The request ID
   */
  function sendOperatorRequest(Chainlink.Request memory req, uint256 payment) internal returns (bytes32) {
    return sendOperatorRequestTo(address(s_oracle), req, payment);
  }

  /**
   * @notice Creates a Chainlink request to the specified oracle address
   * @dev This function supports multi-word response
   * @dev Generates and stores a request ID, increments the local nonce, and uses `transferAndCall` to
   * send LINK which creates a request on the target oracle contract.
   * Emits ChainlinkRequested event.
   * @param oracleAddress The address of the oracle for the request
   * @param req The initialized Chainlink Request
   * @param payment The amount of LINK to send for the request
   * @return requestId The request ID
   */
  function sendOperatorRequestTo(
    address oracleAddress,
    Chainlink.Request memory req,
    uint256 payment
  ) internal returns (bytes32 requestId) {
    uint256 nonce = s_requestCount;
    s_requestCount = nonce + 1;
    bytes memory encodedRequest = abi.encodeWithSelector(
      OperatorInterface.operatorRequest.selector,
      SENDER_OVERRIDE, // Sender value - overridden by onTokenTransfer by the requesting contract's address
      AMOUNT_OVERRIDE, // Amount value - overridden by onTokenTransfer by the actual amount of LINK sent
      req.id,
      req.callbackFunctionId,
      nonce,
      OPERATOR_ARGS_VERSION,
      req.buf.buf
    );
    return _rawRequest(oracleAddress, nonce, payment, encodedRequest);
  }

  /**
   * @notice Make a request to an oracle
   * @param oracleAddress The address of the oracle for the request
   * @param nonce used to generate the request ID
   * @param payment The amount of LINK to send for the request
   * @param encodedRequest data encoded for request type specific format
   * @return requestId The request ID
   */
  function _rawRequest(
    address oracleAddress,
    uint256 nonce,
    uint256 payment,
    bytes memory encodedRequest
  ) private returns (bytes32 requestId) {
    requestId = keccak256(abi.encodePacked(this, nonce));
    s_pendingRequests[requestId] = oracleAddress;
    emit ChainlinkRequested(requestId);
    require(s_link.transferAndCall(oracleAddress, payment, encodedRequest), "unable to transferAndCall to oracle");
  }

  /**
   * @notice Allows a request to be cancelled if it has not been fulfilled
   * @dev Requires keeping track of the expiration value emitted from the oracle contract.
   * Deletes the request from the `pendingRequests` mapping.
   * Emits ChainlinkCancelled event.
   * @param requestId The request ID
   * @param payment The amount of LINK sent for the request
   * @param callbackFunc The callback function specified for the request
   * @param expiration The time of the expiration for the request
   */
  function cancelChainlinkRequest(
    bytes32 requestId,
    uint256 payment,
    bytes4 callbackFunc,
    uint256 expiration
  ) internal {
    OperatorInterface requested = OperatorInterface(s_pendingRequests[requestId]);
    delete s_pendingRequests[requestId];
    emit ChainlinkCancelled(requestId);
    requested.cancelOracleRequest(requestId, payment, callbackFunc, expiration);
  }

  /**
   * @notice the next request count to be used in generating a nonce
   * @dev starts at 1 in order to ensure consistent gas cost
   * @return returns the next request count to be used in a nonce
   */
  function getNextRequestCount() internal view returns (uint256) {
    return s_requestCount;
  }

  /**
   * @notice Sets the stored oracle address
   * @param oracleAddress The address of the oracle contract
   */
  function setChainlinkOracle(address oracleAddress) internal {
    s_oracle = OperatorInterface(oracleAddress);
  }

  /**
   * @notice Sets the LINK token address
   * @param linkAddress The address of the LINK token contract
   */
  function setChainlinkToken(address linkAddress) internal {
    s_link = LinkTokenInterface(linkAddress);
  }

  /**
   * @notice Sets the Chainlink token address for the public
   * network as given by the Pointer contract
   */
  function setPublicChainlinkToken() internal {
    setChainlinkToken(PointerInterface(LINK_TOKEN_POINTER).getAddress());
  }

  /**
   * @notice Retrieves the stored address of the LINK token
   * @return The address of the LINK token
   */
  function chainlinkTokenAddress() internal view returns (address) {
    return address(s_link);
  }

  /**
   * @notice Retrieves the stored address of the oracle contract
   * @return The address of the oracle contract
   */
  function chainlinkOracleAddress() internal view returns (address) {
    return address(s_oracle);
  }

  /**
   * @notice Allows for a request which was created on another contract to be fulfilled
   * on this contract
   * @param oracleAddress The address of the oracle contract that will fulfill the request
   * @param requestId The request ID used for the response
   */
  function addChainlinkExternalRequest(address oracleAddress, bytes32 requestId) internal notPendingRequest(requestId) {
    s_pendingRequests[requestId] = oracleAddress;
  }

  /**
   * @notice Sets the stored oracle and LINK token contracts with the addresses resolved by ENS
   * @dev Accounts for subnodes having different resolvers
   * @param ensAddress The address of the ENS contract
   * @param node The ENS node hash
   */
  function useChainlinkWithENS(address ensAddress, bytes32 node) internal {
    s_ens = ENSInterface(ensAddress);
    s_ensNode = node;
    bytes32 linkSubnode = keccak256(abi.encodePacked(s_ensNode, ENS_TOKEN_SUBNAME));
    ENSResolver_Chainlink resolver = ENSResolver_Chainlink(s_ens.resolver(linkSubnode));
    setChainlinkToken(resolver.addr(linkSubnode));
    updateChainlinkOracleWithENS();
  }

  /**
   * @notice Sets the stored oracle contract with the address resolved by ENS
   * @dev This may be called on its own as long as `useChainlinkWithENS` has been called previously
   */
  function updateChainlinkOracleWithENS() internal {
    bytes32 oracleSubnode = keccak256(abi.encodePacked(s_ensNode, ENS_ORACLE_SUBNAME));
    ENSResolver_Chainlink resolver = ENSResolver_Chainlink(s_ens.resolver(oracleSubnode));
    setChainlinkOracle(resolver.addr(oracleSubnode));
  }

  /**
   * @notice Ensures that the fulfillment is valid for this contract
   * @dev Use if the contract developer prefers methods instead of modifiers for validation
   * @param requestId The request ID for fulfillment
   */
  function validateChainlinkCallback(bytes32 requestId)
    internal
    recordChainlinkFulfillment(requestId)
  // solhint-disable-next-line no-empty-blocks
  {

  }

  /**
   * @dev Reverts if the sender is not the oracle of the request.
   * Emits ChainlinkFulfilled event.
   * @param requestId The request ID for fulfillment
   */
  modifier recordChainlinkFulfillment(bytes32 requestId) {
    require(msg.sender == s_pendingRequests[requestId], "Source must be the oracle of the request");
    delete s_pendingRequests[requestId];
    emit ChainlinkFulfilled(requestId);
    _;
  }

  /**
   * @dev Reverts if the request is already pending
   * @param requestId The request ID for fulfillment
   */
  modifier notPendingRequest(bytes32 requestId) {
    require(s_pendingRequests[requestId] == address(0), "Request is already pending");
    _;
  }
}

File 7 of 20 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 8 of 20 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
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);
}

File 9 of 20 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
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);
}

File 10 of 20 : Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 11 of 20 : Chainlink.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {CBORChainlink} from "./vendor/CBORChainlink.sol";
import {BufferChainlink} from "./vendor/BufferChainlink.sol";

/**
 * @title Library for common Chainlink functions
 * @dev Uses imported CBOR library for encoding to buffer
 */
library Chainlink {
  uint256 internal constant defaultBufferSize = 256; // solhint-disable-line const-name-snakecase

  using CBORChainlink for BufferChainlink.buffer;

  struct Request {
    bytes32 id;
    address callbackAddress;
    bytes4 callbackFunctionId;
    uint256 nonce;
    BufferChainlink.buffer buf;
  }

  /**
   * @notice Initializes a Chainlink request
   * @dev Sets the ID, callback address, and callback function signature on the request
   * @param self The uninitialized request
   * @param jobId The Job Specification ID
   * @param callbackAddr The callback address
   * @param callbackFunc The callback function signature
   * @return The initialized request
   */
  function initialize(
    Request memory self,
    bytes32 jobId,
    address callbackAddr,
    bytes4 callbackFunc
  ) internal pure returns (Chainlink.Request memory) {
    BufferChainlink.init(self.buf, defaultBufferSize);
    self.id = jobId;
    self.callbackAddress = callbackAddr;
    self.callbackFunctionId = callbackFunc;
    return self;
  }

  /**
   * @notice Sets the data for the buffer without encoding CBOR on-chain
   * @dev CBOR can be closed with curly-brackets {} or they can be left off
   * @param self The initialized request
   * @param data The CBOR data
   */
  function setBuffer(Request memory self, bytes memory data) internal pure {
    BufferChainlink.init(self.buf, data.length);
    BufferChainlink.append(self.buf, data);
  }

  /**
   * @notice Adds a string value to the request with a given key name
   * @param self The initialized request
   * @param key The name of the key
   * @param value The string value to add
   */
  function add(
    Request memory self,
    string memory key,
    string memory value
  ) internal pure {
    self.buf.encodeString(key);
    self.buf.encodeString(value);
  }

  /**
   * @notice Adds a bytes value to the request with a given key name
   * @param self The initialized request
   * @param key The name of the key
   * @param value The bytes value to add
   */
  function addBytes(
    Request memory self,
    string memory key,
    bytes memory value
  ) internal pure {
    self.buf.encodeString(key);
    self.buf.encodeBytes(value);
  }

  /**
   * @notice Adds a int256 value to the request with a given key name
   * @param self The initialized request
   * @param key The name of the key
   * @param value The int256 value to add
   */
  function addInt(
    Request memory self,
    string memory key,
    int256 value
  ) internal pure {
    self.buf.encodeString(key);
    self.buf.encodeInt(value);
  }

  /**
   * @notice Adds a uint256 value to the request with a given key name
   * @param self The initialized request
   * @param key The name of the key
   * @param value The uint256 value to add
   */
  function addUint(
    Request memory self,
    string memory key,
    uint256 value
  ) internal pure {
    self.buf.encodeString(key);
    self.buf.encodeUInt(value);
  }

  /**
   * @notice Adds an array of strings to the request with a given key name
   * @param self The initialized request
   * @param key The name of the key
   * @param values The array of string values to add
   */
  function addStringArray(
    Request memory self,
    string memory key,
    string[] memory values
  ) internal pure {
    self.buf.encodeString(key);
    self.buf.startArray();
    for (uint256 i = 0; i < values.length; i++) {
      self.buf.encodeString(values[i]);
    }
    self.buf.endSequence();
  }
}

File 12 of 20 : ENSInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ENSInterface {
  // Logged when the owner of a node assigns a new owner to a subnode.
  event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);

  // Logged when the owner of a node transfers ownership to a new account.
  event Transfer(bytes32 indexed node, address owner);

  // Logged when the resolver for a node changes.
  event NewResolver(bytes32 indexed node, address resolver);

  // Logged when the TTL of a node changes
  event NewTTL(bytes32 indexed node, uint64 ttl);

  function setSubnodeOwner(
    bytes32 node,
    bytes32 label,
    address owner
  ) external;

  function setResolver(bytes32 node, address resolver) external;

  function setOwner(bytes32 node, address owner) external;

  function setTTL(bytes32 node, uint64 ttl) external;

  function owner(bytes32 node) external view returns (address);

  function resolver(bytes32 node) external view returns (address);

  function ttl(bytes32 node) external view returns (uint64);
}

File 13 of 20 : LinkTokenInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface LinkTokenInterface {
  function allowance(address owner, address spender) external view returns (uint256 remaining);

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

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

  function decimals() external view returns (uint8 decimalPlaces);

  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);

  function increaseApproval(address spender, uint256 subtractedValue) external;

  function name() external view returns (string memory tokenName);

  function symbol() external view returns (string memory tokenSymbol);

  function totalSupply() external view returns (uint256 totalTokensIssued);

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

  function transferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  ) external returns (bool success);

  function transferFrom(
    address from,
    address to,
    uint256 value
  ) external returns (bool success);
}

File 14 of 20 : ChainlinkRequestInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ChainlinkRequestInterface {
  function oracleRequest(
    address sender,
    uint256 requestPrice,
    bytes32 serviceAgreementID,
    address callbackAddress,
    bytes4 callbackFunctionId,
    uint256 nonce,
    uint256 dataVersion,
    bytes calldata data
  ) external;

  function cancelOracleRequest(
    bytes32 requestId,
    uint256 payment,
    bytes4 callbackFunctionId,
    uint256 expiration
  ) external;
}

File 15 of 20 : OperatorInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./OracleInterface.sol";
import "./ChainlinkRequestInterface.sol";

interface OperatorInterface is OracleInterface, ChainlinkRequestInterface {
  function operatorRequest(
    address sender,
    uint256 payment,
    bytes32 specId,
    bytes4 callbackFunctionId,
    uint256 nonce,
    uint256 dataVersion,
    bytes calldata data
  ) external;

  function fulfillOracleRequest2(
    bytes32 requestId,
    uint256 payment,
    address callbackAddress,
    bytes4 callbackFunctionId,
    uint256 expiration,
    bytes calldata data
  ) external returns (bool);

  function ownerTransferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  ) external returns (bool success);

  function distributeFunds(address payable[] calldata receivers, uint256[] calldata amounts) external payable;

  function getAuthorizedSenders() external returns (address[] memory);

  function setAuthorizedSenders(address[] calldata senders) external;

  function getForwarder() external returns (address);
}

File 16 of 20 : PointerInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface PointerInterface {
  function getAddress() external view returns (address);
}

File 17 of 20 : ENSResolver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

abstract contract ENSResolver {
  function addr(bytes32 node) public view virtual returns (address);
}

File 18 of 20 : CBORChainlink.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.19;

import {BufferChainlink} from "./BufferChainlink.sol";

library CBORChainlink {
  using BufferChainlink for BufferChainlink.buffer;

  uint8 private constant MAJOR_TYPE_INT = 0;
  uint8 private constant MAJOR_TYPE_NEGATIVE_INT = 1;
  uint8 private constant MAJOR_TYPE_BYTES = 2;
  uint8 private constant MAJOR_TYPE_STRING = 3;
  uint8 private constant MAJOR_TYPE_ARRAY = 4;
  uint8 private constant MAJOR_TYPE_MAP = 5;
  uint8 private constant MAJOR_TYPE_TAG = 6;
  uint8 private constant MAJOR_TYPE_CONTENT_FREE = 7;

  uint8 private constant TAG_TYPE_BIGNUM = 2;
  uint8 private constant TAG_TYPE_NEGATIVE_BIGNUM = 3;

  function encodeFixedNumeric(BufferChainlink.buffer memory buf, uint8 major, uint64 value) private pure {
    if(value <= 23) {
      buf.appendUint8(uint8((major << 5) | value));
    } else if (value <= 0xFF) {
      buf.appendUint8(uint8((major << 5) | 24));
      buf.appendInt(value, 1);
    } else if (value <= 0xFFFF) {
      buf.appendUint8(uint8((major << 5) | 25));
      buf.appendInt(value, 2);
    } else if (value <= 0xFFFFFFFF) {
      buf.appendUint8(uint8((major << 5) | 26));
      buf.appendInt(value, 4);
    } else {
      buf.appendUint8(uint8((major << 5) | 27));
      buf.appendInt(value, 8);
    }
  }

  function encodeIndefiniteLengthType(BufferChainlink.buffer memory buf, uint8 major) private pure {
    buf.appendUint8(uint8((major << 5) | 31));
  }

  function encodeUInt(BufferChainlink.buffer memory buf, uint value) internal pure {
    if(value > 0xFFFFFFFFFFFFFFFF) {
      encodeBigNum(buf, value);
    } else {
      encodeFixedNumeric(buf, MAJOR_TYPE_INT, uint64(value));
    }
  }

  function encodeInt(BufferChainlink.buffer memory buf, int value) internal pure {
    if(value < -0x10000000000000000) {
      encodeSignedBigNum(buf, value);
    } else if(value > 0xFFFFFFFFFFFFFFFF) {
      encodeBigNum(buf, uint(value));
    } else if(value >= 0) {
      encodeFixedNumeric(buf, MAJOR_TYPE_INT, uint64(uint256(value)));
    } else {
      encodeFixedNumeric(buf, MAJOR_TYPE_NEGATIVE_INT, uint64(uint256(-1 - value)));
    }
  }

  function encodeBytes(BufferChainlink.buffer memory buf, bytes memory value) internal pure {
    encodeFixedNumeric(buf, MAJOR_TYPE_BYTES, uint64(value.length));
    buf.append(value);
  }

  function encodeBigNum(BufferChainlink.buffer memory buf, uint value) internal pure {
    buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_BIGNUM));
    encodeBytes(buf, abi.encode(value));
  }

  function encodeSignedBigNum(BufferChainlink.buffer memory buf, int input) internal pure {
    buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_NEGATIVE_BIGNUM));
    encodeBytes(buf, abi.encode(uint256(-1 - input)));
  }

  function encodeString(BufferChainlink.buffer memory buf, string memory value) internal pure {
    encodeFixedNumeric(buf, MAJOR_TYPE_STRING, uint64(bytes(value).length));
    buf.append(bytes(value));
  }

  function startArray(BufferChainlink.buffer memory buf) internal pure {
    encodeIndefiniteLengthType(buf, MAJOR_TYPE_ARRAY);
  }

  function startMap(BufferChainlink.buffer memory buf) internal pure {
    encodeIndefiniteLengthType(buf, MAJOR_TYPE_MAP);
  }

  function endSequence(BufferChainlink.buffer memory buf) internal pure {
    encodeIndefiniteLengthType(buf, MAJOR_TYPE_CONTENT_FREE);
  }
}

File 19 of 20 : BufferChainlink.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @dev A library for working with mutable byte buffers in Solidity.
 *
 * Byte buffers are mutable and expandable, and provide a variety of primitives
 * for writing to them. At any time you can fetch a bytes object containing the
 * current contents of the buffer. The bytes object should not be stored between
 * operations, as it may change due to resizing of the buffer.
 */
library BufferChainlink {
  /**
   * @dev Represents a mutable buffer. Buffers have a current value (buf) and
   *      a capacity. The capacity may be longer than the current value, in
   *      which case it can be extended without the need to allocate more memory.
   */
  struct buffer {
    bytes buf;
    uint256 capacity;
  }

  /**
   * @dev Initializes a buffer with an initial capacity.
   * @param buf The buffer to initialize.
   * @param capacity The number of bytes of space to allocate the buffer.
   * @return The buffer, for chaining.
   */
  function init(buffer memory buf, uint256 capacity) internal pure returns (buffer memory) {
    if (capacity % 32 != 0) {
      capacity += 32 - (capacity % 32);
    }
    // Allocate space for the buffer data
    buf.capacity = capacity;
    assembly {
      let ptr := mload(0x40)
      mstore(buf, ptr)
      mstore(ptr, 0)
      mstore(0x40, add(32, add(ptr, capacity)))
    }
    return buf;
  }

  /**
   * @dev Initializes a new buffer from an existing bytes object.
   *      Changes to the buffer may mutate the original value.
   * @param b The bytes object to initialize the buffer with.
   * @return A new buffer.
   */
  function fromBytes(bytes memory b) internal pure returns (buffer memory) {
    buffer memory buf;
    buf.buf = b;
    buf.capacity = b.length;
    return buf;
  }

  function resize(buffer memory buf, uint256 capacity) private pure {
    bytes memory oldbuf = buf.buf;
    init(buf, capacity);
    append(buf, oldbuf);
  }

  function max(uint256 a, uint256 b) private pure returns (uint256) {
    if (a > b) {
      return a;
    }
    return b;
  }

  /**
   * @dev Sets buffer length to 0.
   * @param buf The buffer to truncate.
   * @return The original buffer, for chaining..
   */
  function truncate(buffer memory buf) internal pure returns (buffer memory) {
    assembly {
      let bufptr := mload(buf)
      mstore(bufptr, 0)
    }
    return buf;
  }

  /**
   * @dev Writes a byte string to a buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param off The start offset to write to.
   * @param data The data to append.
   * @param len The number of bytes to copy.
   * @return The original buffer, for chaining.
   */
  function write(
    buffer memory buf,
    uint256 off,
    bytes memory data,
    uint256 len
  ) internal pure returns (buffer memory) {
    require(len <= data.length);

    if (off + len > buf.capacity) {
      resize(buf, max(buf.capacity, len + off) * 2);
    }

    uint256 dest;
    uint256 src;
    assembly {
      // Memory address of the buffer data
      let bufptr := mload(buf)
      // Length of existing buffer data
      let buflen := mload(bufptr)
      // Start address = buffer address + offset + sizeof(buffer length)
      dest := add(add(bufptr, 32), off)
      // Update buffer length if we're extending it
      if gt(add(len, off), buflen) {
        mstore(bufptr, add(len, off))
      }
      src := add(data, 32)
    }

    // Copy word-length chunks while possible
    for (; len >= 32; len -= 32) {
      assembly {
        mstore(dest, mload(src))
      }
      dest += 32;
      src += 32;
    }

    // Copy remaining bytes
    unchecked {
      uint256 mask = (256**(32 - len)) - 1;
      assembly {
        let srcpart := and(mload(src), not(mask))
        let destpart := and(mload(dest), mask)
        mstore(dest, or(destpart, srcpart))
      }
    }

    return buf;
  }

  /**
   * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @param len The number of bytes to copy.
   * @return The original buffer, for chaining.
   */
  function append(
    buffer memory buf,
    bytes memory data,
    uint256 len
  ) internal pure returns (buffer memory) {
    return write(buf, buf.buf.length, data, len);
  }

  /**
   * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @return The original buffer, for chaining.
   */
  function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
    return write(buf, buf.buf.length, data, data.length);
  }

  /**
   * @dev Writes a byte to the buffer. Resizes if doing so would exceed the
   *      capacity of the buffer.
   * @param buf The buffer to append to.
   * @param off The offset to write the byte at.
   * @param data The data to append.
   * @return The original buffer, for chaining.
   */
  function writeUint8(
    buffer memory buf,
    uint256 off,
    uint8 data
  ) internal pure returns (buffer memory) {
    if (off >= buf.capacity) {
      resize(buf, buf.capacity * 2);
    }

    assembly {
      // Memory address of the buffer data
      let bufptr := mload(buf)
      // Length of existing buffer data
      let buflen := mload(bufptr)
      // Address = buffer address + sizeof(buffer length) + off
      let dest := add(add(bufptr, off), 32)
      mstore8(dest, data)
      // Update buffer length if we extended it
      if eq(off, buflen) {
        mstore(bufptr, add(buflen, 1))
      }
    }
    return buf;
  }

  /**
   * @dev Appends a byte to the buffer. Resizes if doing so would exceed the
   *      capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @return The original buffer, for chaining.
   */
  function appendUint8(buffer memory buf, uint8 data) internal pure returns (buffer memory) {
    return writeUint8(buf, buf.buf.length, data);
  }

  /**
   * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would
   *      exceed the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param off The offset to write at.
   * @param data The data to append.
   * @param len The number of bytes to write (left-aligned).
   * @return The original buffer, for chaining.
   */
  function write(
    buffer memory buf,
    uint256 off,
    bytes32 data,
    uint256 len
  ) private pure returns (buffer memory) {
    if (len + off > buf.capacity) {
      resize(buf, (len + off) * 2);
    }

    unchecked {
      uint256 mask = (256**len) - 1;
      // Right-align data
      data = data >> (8 * (32 - len));
      assembly {
        // Memory address of the buffer data
        let bufptr := mload(buf)
        // Address = buffer address + sizeof(buffer length) + off + len
        let dest := add(add(bufptr, off), len)
        mstore(dest, or(and(mload(dest), not(mask)), data))
        // Update buffer length if we extended it
        if gt(add(off, len), mload(bufptr)) {
          mstore(bufptr, add(off, len))
        }
      }
    }
    return buf;
  }

  /**
   * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the
   *      capacity of the buffer.
   * @param buf The buffer to append to.
   * @param off The offset to write at.
   * @param data The data to append.
   * @return The original buffer, for chaining.
   */
  function writeBytes20(
    buffer memory buf,
    uint256 off,
    bytes20 data
  ) internal pure returns (buffer memory) {
    return write(buf, off, bytes32(data), 20);
  }

  /**
   * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @return The original buffer, for chhaining.
   */
  function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
    return write(buf, buf.buf.length, bytes32(data), 20);
  }

  /**
   * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @return The original buffer, for chaining.
   */
  function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
    return write(buf, buf.buf.length, data, 32);
  }

  /**
   * @dev Writes an integer to the buffer. Resizes if doing so would exceed
   *      the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param off The offset to write at.
   * @param data The data to append.
   * @param len The number of bytes to write (right-aligned).
   * @return The original buffer, for chaining.
   */
  function writeInt(
    buffer memory buf,
    uint256 off,
    uint256 data,
    uint256 len
  ) private pure returns (buffer memory) {
    if (len + off > buf.capacity) {
      resize(buf, (len + off) * 2);
    }

    uint256 mask = (256**len) - 1;
    assembly {
      // Memory address of the buffer data
      let bufptr := mload(buf)
      // Address = buffer address + off + sizeof(buffer length) + len
      let dest := add(add(bufptr, off), len)
      mstore(dest, or(and(mload(dest), not(mask)), data))
      // Update buffer length if we extended it
      if gt(add(off, len), mload(bufptr)) {
        mstore(bufptr, add(off, len))
      }
    }
    return buf;
  }

  /**
   * @dev Appends a byte to the end of the buffer. Resizes if doing so would
   * exceed the capacity of the buffer.
   * @param buf The buffer to append to.
   * @param data The data to append.
   * @return The original buffer.
   */
  function appendInt(
    buffer memory buf,
    uint256 data,
    uint256 len
  ) internal pure returns (buffer memory) {
    return writeInt(buf, buf.buf.length, data, len);
  }
}

File 20 of 20 : OracleInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface OracleInterface {
  function fulfillOracleRequest(
    bytes32 requestId,
    uint256 payment,
    address callbackAddress,
    bytes4 callbackFunctionId,
    uint256 expiration,
    bytes32 data
  ) external returns (bool);

  function isAuthorizedSender(address node) external view returns (bool);

  function withdraw(address recipient, uint256 amount) external;

  function withdrawable() external view returns (uint256);
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"string","name":"_jobId","type":"string"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_link","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"uint256","name":"_connectedTypeId","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"_connectedUserIdHash","type":"bytes32"}],"name":"AddConnection","type":"event"},{"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":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkRequested","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"},{"indexed":false,"internalType":"string","name":"_transactionId","type":"string"}],"name":"Endorse","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":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"uint256","name":"_connectedTypeId","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"_connectedUserIdHash","type":"bytes32"}],"name":"RemoveConnection","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"endorser","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPreviousEndorserLevel1","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"endorser","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPreviousEndorserLevel2","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"D_lvl1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"D_lvl2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"D_n","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"D_o","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"O_n","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"connectedTypeId","type":"uint256"},{"internalType":"bytes32","name":"connectedUserIdHash","type":"bytes32"}],"name":"addConnection","outputs":[],"stateMutability":"nonpayable","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":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"transactionId","type":"string"}],"name":"endorse","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"address[]","name":"endorsersLevel1","type":"address[]"},{"internalType":"address[]","name":"endorsersLevel2","type":"address[]"}],"name":"fulfillEndorse","outputs":[],"stateMutability":"nonpayable","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":[],"name":"isMigrating","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"previousEndorserStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"connectedTypeId","type":"uint256"}],"name":"removeConnection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setD_lvl1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setD_lvl2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setD_n","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setD_o","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setO_n","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setSocialConnectionReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"socialConnectionReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"source","type":"string"}],"name":"stringToBytes32","outputs":[{"internalType":"bytes32","name":"result","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleMigrationFlag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalStake","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":"pure","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":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526001600a55612710600d556001600e55601e600f55600260105560146011556113886012553480156200003657600080fd5b5060405162005f7e38038062005f7e83398181016040528101906200005c919062000685565b6040518060400160405280600f81526020017f55545520547275737420546f6b656e00000000000000000000000000000000008152506040518060400160405280600381526020017f55545400000000000000000000000000000000000000000000000000000000008152508160039080519060200190620000e092919062000529565b508060049080519060200190620000f992919062000529565b5050506000600560006101000a81548160ff021916908315150217905550620001376200012b620001c460201b60201c565b620001cc60201b60201c565b6200014933866200029260201b60201c565b6200015a816200040b60201b60201c565b83601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001ac836200044f60201b60201c565b60178190555081601881905550505050505062000af7565b600033905090565b6000600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000305576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002fc906200078b565b60405180910390fd5b62000319600083836200047b60201b60201c565b80600260008282546200032d91906200085c565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546200038491906200085c565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051620003eb9190620007cf565b60405180910390a362000407600083836200049860201b60201c565b5050565b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000808290506000815114156200046d576000801b91505062000476565b60208301519150505b919050565b620004938383836200049d60201b62001f681760201c565b505050565b505050565b620004b58383836200050d60201b62001fc01760201c565b620004c56200051260201b60201c565b1562000508576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004ff90620007ad565b60405180910390fd5b505050565b505050565b6000600560009054906101000a900460ff16905090565b82805462000537906200092d565b90600052602060002090601f0160209004810192826200055b5760008555620005a7565b82601f106200057657805160ff1916838001178555620005a7565b82800160010185558215620005a7579182015b82811115620005a657825182559160200191906001019062000589565b5b509050620005b69190620005ba565b5090565b5b80821115620005d5576000816000905550600101620005bb565b5090565b6000620005f0620005ea8462000815565b620007ec565b9050828152602081018484840111156200060f576200060e62000a2b565b5b6200061c848285620008f7565b509392505050565b600081519050620006358162000ac3565b92915050565b600082601f83011262000653576200065262000a26565b5b815162000665848260208601620005d9565b91505092915050565b6000815190506200067f8162000add565b92915050565b600080600080600060a08688031215620006a457620006a362000a35565b5b6000620006b4888289016200066e565b9550506020620006c78882890162000624565b945050604086015167ffffffffffffffff811115620006eb57620006ea62000a30565b5b620006f9888289016200063b565b93505060606200070c888289016200066e565b92505060806200071f8882890162000624565b9150509295509295909350565b60006200073b601f836200084b565b9150620007488262000a4b565b602082019050919050565b600062000762602a836200084b565b91506200076f8262000a74565b604082019050919050565b6200078581620008ed565b82525050565b60006020820190508181036000830152620007a6816200072c565b9050919050565b60006020820190508181036000830152620007c88162000753565b9050919050565b6000602082019050620007e660008301846200077a565b92915050565b6000620007f86200080b565b905062000806828262000963565b919050565b6000604051905090565b600067ffffffffffffffff821115620008335762000832620009f7565b5b6200083e8262000a3a565b9050602081019050919050565b600082825260208201905092915050565b60006200086982620008ed565b91506200087683620008ed565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115620008ae57620008ad62000999565b5b828201905092915050565b6000620008c682620008cd565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b8381101562000917578082015181840152602081019050620008fa565b8381111562000927576000848401525b50505050565b600060028204905060018216806200094657607f821691505b602082108114156200095d576200095c620009c8565b5b50919050565b6200096e8262000a3a565b810181811067ffffffffffffffff8211171562000990576200098f620009f7565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b7f45524332305061757361626c653a20746f6b656e207472616e7366657220776860008201527f696c652070617573656400000000000000000000000000000000000000000000602082015250565b62000ace81620008b9565b811462000ada57600080fd5b50565b62000ae881620008ed565b811462000af457600080fd5b50565b6154778062000b076000396000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c80638456cb5911610146578063b5a5767c116100c3578063dd62ed3e11610087578063dd62ed3e146106ae578063f05e777d146106de578063f1af4829146106fc578063f2fde38b14610718578063fa01fc2114610734578063fd7dd0571461075257610253565b8063b5a5767c1461061e578063c5c58b891461063a578063ce97554414610656578063cfb5192814610660578063d51d81271461069057610253565b80639e24bc371161010a5780639e24bc3714610542578063a457c2d71461055e578063a9059cbb1461058e578063b273fc9a146105be578063b36cc8e7146105ee57610253565b80638456cb59146104c45780638b5f09c1146104ce5780638c5b133f146104ea5780638da5cb5b1461050657806395d89b411461052457610253565b806339509351116101d457806360f556991161019857806360f556991461043457806369fe0e2d1461045257806370a082311461046e578063715018a61461049e57806379cc6790146104a857610253565b806339509351146103a45780633f4ba83a146103d457806342966c68146103de5780634349138e146103fa5780635c975abb1461041657610253565b80631a147def1161021b5780631a147def146102fe57806323b872dd1461031c5780632652c4931461034c578063313ce5671461036a57806337e75f6d1461038857610253565b806306fdde031461025857806307cd206e14610276578063095ea7b3146102945780631168c24c146102c457806318160ddd146102e0575b600080fd5b61026061076e565b60405161026d9190614309565b60405180910390f35b61027e610800565b60405161028b919061460b565b60405180910390f35b6102ae60048036038101906102a99190613ae0565b610806565b6040516102bb91906142d3565b60405180910390f35b6102de60048036038101906102d99190613ced565b610843565b005b6102e86108c9565b6040516102f5919061460b565b60405180910390f35b6103066108d3565b604051610313919061460b565b60405180910390f35b61033660048036038101906103319190613a8d565b6108d9565b60405161034391906142d3565b60405180910390f35b6103546109d1565b604051610361919061460b565b60405180910390f35b6103726109d7565b60405161037f9190614656565b60405180910390f35b6103a2600480360381019061039d9190613b20565b6109dc565b005b6103be60048036038101906103b99190613ae0565b610baf565b6040516103cb91906142d3565b60405180910390f35b6103dc610c5b565b005b6103f860048036038101906103f39190613ced565b610ce1565b005b610414600480360381019061040f9190613c0f565b610cf5565b005b61041e611093565b60405161042b91906142d3565b60405180910390f35b61043c6110aa565b604051610449919061460b565b60405180910390f35b61046c60048036038101906104679190613ced565b6110b0565b005b61048860048036038101906104839190613a20565b611136565b604051610495919061460b565b60405180910390f35b6104a661117e565b005b6104c260048036038101906104bd9190613ae0565b611206565b005b6104cc611281565b005b6104e860048036038101906104e39190613ced565b611307565b005b61050460048036038101906104ff9190613ced565b61138d565b005b61050e611413565b60405161051b91906141db565b60405180910390f35b61052c61143d565b6040516105399190614309565b60405180910390f35b61055c60048036038101906105579190613ced565b6114cf565b005b61057860048036038101906105739190613ae0565b611555565b60405161058591906142d3565b60405180910390f35b6105a860048036038101906105a39190613ae0565b611640565b6040516105b591906142d3565b60405180910390f35b6105d860048036038101906105d39190613a20565b61167d565b6040516105e5919061460b565b60405180910390f35b61060860048036038101906106039190613a4d565b611695565b604051610615919061460b565b60405180910390f35b61063860048036038101906106339190613ced565b6116ba565b005b610654600480360381019061064f9190613ae0565b611740565b005b61065e61190b565b005b61067a60048036038101906106759190613ca4565b6119b3565b60405161068791906142ee565b60405180910390f35b6106986119dd565b6040516106a5919061460b565b60405180910390f35b6106c860048036038101906106c39190613a4d565b6119e3565b6040516106d5919061460b565b60405180910390f35b6106e6611a6a565b6040516106f391906142d3565b60405180910390f35b61071660048036038101906107119190613b73565b611a7d565b005b610732600480360381019061072d9190613a20565b611de4565b005b61073c611edc565b604051610749919061460b565b60405180910390f35b61076c60048036038101906107679190613ced565b611ee2565b005b60606003805461077d90614b6a565b80601f01602080910402602001604051908101604052809291908181526020018280546107a990614b6a565b80156107f65780601f106107cb576101008083540402835291602001916107f6565b820191906000526020600020905b8154815290600101906020018083116107d957829003601f168201915b5050505050905090565b60115481565b60006040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083a9061436b565b60405180910390fd5b61084b611fc5565b73ffffffffffffffffffffffffffffffffffffffff16610869611413565b73ffffffffffffffffffffffffffffffffffffffff16146108bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b6906144eb565b60405180910390fd5b8060118190555050565b6000600254905090565b600e5481565b60006108e6848484611fcd565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610931611fc5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828110156109b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a8906144cb565b60405180910390fd5b6109c5856109bd611fc5565b85840361224e565b60019150509392505050565b600f5481565b600090565b601960009054906101000a900460ff1615610a2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a239061446b565b60405180910390fd5b610a34611fc5565b73ffffffffffffffffffffffffffffffffffffffff16610a52611413565b73ffffffffffffffffffffffffffffffffffffffff1614610aa8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9f906144eb565b60405180910390fd5b6000801b600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020541415610baa5780600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550610b6483600d54612419565b80828473ffffffffffffffffffffffffffffffffffffffff167fa47d864ce75457dd6fd6ea2212dfd39907f59d0a81f7c8abfe743e7f910cfa3260405160405180910390a45b505050565b6000610c51610bbc611fc5565b848460016000610bca611fc5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c4c919061470a565b61224e565b6001905092915050565b610c63611fc5565b73ffffffffffffffffffffffffffffffffffffffff16610c81611413565b73ffffffffffffffffffffffffffffffffffffffff1614610cd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cce906144eb565b60405180910390fd5b610cdf612579565b565b610cf2610cec611fc5565b8261261b565b50565b84600b600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8e9061458b565b60405180910390fd5b600b600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055807f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a60405160405180910390a26000601560008881526020019081526020016000206040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160028201548152602001600382018054610ee090614b6a565b80601f0160208091040260200160405190810160405280929190818152602001828054610f0c90614b6a565b8015610f595780601f10610f2e57610100808354040283529160200191610f59565b820191906000526020600020905b815481529060010190602001808311610f3c57829003601f168201915b5050505050815250509050600073ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff161415610fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fcf9061440b565b60405180910390fd5b610fea8160000151826040015161261b565b61108a81600001518260200151836040015184606001518a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050898980806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050506127f2565b50505050505050565b6000600560009054906101000a900460ff16905090565b60105481565b6110b8611fc5565b73ffffffffffffffffffffffffffffffffffffffff166110d6611413565b73ffffffffffffffffffffffffffffffffffffffff161461112c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611123906144eb565b60405180910390fd5b8060188190555050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611186611fc5565b73ffffffffffffffffffffffffffffffffffffffff166111a4611413565b73ffffffffffffffffffffffffffffffffffffffff16146111fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f1906144eb565b60405180910390fd5b6112046000612aea565b565b600061121983611214611fc5565b6119e3565b90508181101561125e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112559061450b565b60405180910390fd5b6112728361126a611fc5565b84840361224e565b61127c838361261b565b505050565b611289611fc5565b73ffffffffffffffffffffffffffffffffffffffff166112a7611413565b73ffffffffffffffffffffffffffffffffffffffff16146112fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112f4906144eb565b60405180910390fd5b611305612bb0565b565b61130f611fc5565b73ffffffffffffffffffffffffffffffffffffffff1661132d611413565b73ffffffffffffffffffffffffffffffffffffffff1614611383576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137a906144eb565b60405180910390fd5b80600f8190555050565b611395611fc5565b73ffffffffffffffffffffffffffffffffffffffff166113b3611413565b73ffffffffffffffffffffffffffffffffffffffff1614611409576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611400906144eb565b60405180910390fd5b8060108190555050565b6000600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606004805461144c90614b6a565b80601f016020809104026020016040519081016040528092919081815260200182805461147890614b6a565b80156114c55780601f1061149a576101008083540402835291602001916114c5565b820191906000526020600020905b8154815290600101906020018083116114a857829003601f168201915b5050505050905090565b6114d7611fc5565b73ffffffffffffffffffffffffffffffffffffffff166114f5611413565b73ffffffffffffffffffffffffffffffffffffffff161461154b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611542906144eb565b60405180910390fd5b8060128190555050565b60008060016000611564611fc5565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015611621576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611618906145ab565b60405180910390fd5b61163561162c611fc5565b8585840361224e565b600191505092915050565b60006040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116749061436b565b60405180910390fd5b60146020528060005260406000206000915090505481565b6013602052816000526040600020602052806000526040600020600091509150505481565b6116c2611fc5565b73ffffffffffffffffffffffffffffffffffffffff166116e0611413565b73ffffffffffffffffffffffffffffffffffffffff1614611736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172d906144eb565b60405180910390fd5b80600d8190555050565b601960009054906101000a900460ff1615611790576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117879061446b565b60405180910390fd5b611798611fc5565b73ffffffffffffffffffffffffffffffffffffffff166117b6611413565b73ffffffffffffffffffffffffffffffffffffffff161461180c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611803906144eb565b60405180910390fd5b6000801b600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000205414611907576000801b600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055506000801b818373ffffffffffffffffffffffffffffffffffffffff167f633cace5793d041e54c2c70b3b27c6f59d15fd4ec6dd309f906a31369d42c34260405160405180910390a45b5050565b611913611fc5565b73ffffffffffffffffffffffffffffffffffffffff16611931611413565b73ffffffffffffffffffffffffffffffffffffffff1614611987576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161197e906144eb565b60405180910390fd5b601960009054906101000a900460ff1615601960006101000a81548160ff021916908315150217905550565b6000808290506000815114156119cf576000801b9150506119d8565b60208301519150505b919050565b60125481565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b601960009054906101000a900460ff1681565b601960009054906101000a900460ff1615611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061446b565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b32906143ab565b60405180910390fd5b6000611b4633611136565b905082811015611b8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b829061448b565b60405180910390fd5b6000611ba160175430634349138e60e01b612c53565b9050611bf56040518060400160405280600d81526020017f7461726765744164647265737300000000000000000000000000000000000000815250611be587612c84565b83612e669092919063ffffffff16565b611c476040518060400160405280600d81526020017f736f757263654164647265737300000000000000000000000000000000000000815250611c3733612c84565b83612e669092919063ffffffff16565b611c916040518060400160405280600d81526020017f7472616e73616374696f6e4964000000000000000000000000000000000000008152508483612e669092919063ffffffff16565b6000611cc2601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683601854612e99565b905060405180608001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff168152602001868152602001858152506015600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550604082015181600201556060820151816003019080519060200190611dd89291906137dc565b50905050505050505050565b611dec611fc5565b73ffffffffffffffffffffffffffffffffffffffff16611e0a611413565b73ffffffffffffffffffffffffffffffffffffffff1614611e60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e57906144eb565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ed0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec7906143cb565b60405180910390fd5b611ed981612aea565b50565b600d5481565b611eea611fc5565b73ffffffffffffffffffffffffffffffffffffffff16611f08611413565b73ffffffffffffffffffffffffffffffffffffffff1614611f5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f55906144eb565b60405180910390fd5b80600e8190555050565b611f73838383611fc0565b611f7b611093565b15611fbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb2906145eb565b60405180910390fd5b505050565b505050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561203d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120349061454b565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156120ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a49061432b565b60405180910390fd5b6120b8838383612f63565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561213e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121359061444b565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546121d1919061470a565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612235919061460b565b60405180910390a3612248848484612f73565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156122be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b59061456b565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561232e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612325906143eb565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161240c919061460b565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612489576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612480906145cb565b60405180910390fd5b61249560008383612f63565b80600260008282546124a7919061470a565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546124fc919061470a565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612561919061460b565b60405180910390a361257560008383612f73565b5050565b612581611093565b6125c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125b79061434b565b60405180910390fd5b6000600560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa612604611fc5565b60405161261191906141db565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561268b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126829061452b565b60405180910390fd5b61269782600083612f63565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561271d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127149061438b565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816002600082825461277491906149ff565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516127d9919061460b565b60405180910390a36127ed83600084612f73565b505050565b60005b82518160ff1610156128c157600061282e87858460ff168151811061281d5761281c614d2c565b5b602002602001015160105489612f78565b9050612857848360ff168151811061284957612848614d2c565b5b602002602001015182612419565b7fd10a84a6af20735b834fa7634e3c2f819fc7108ea4498c21dc1a853eeadb02da848360ff168151811061288e5761288d614d2c565b5b6020026020010151826040516128a59291906141f6565b60405180910390a15080806128b990614c16565b9150506127f5565b5060005b81518160ff1610156129915760006128fe87848460ff16815181106128ed576128ec614d2c565b5b602002602001015160115489612f78565b9050612927838360ff168151811061291957612918614d2c565b5b602002602001015182612419565b7f215c1a1edf8a8bef237b56242f6856daff6ec173a64970dd07fa5c8852aebe47838360ff168151811061295e5761295d614d2c565b5b6020026020010151826040516129759291906141f6565b60405180910390a150808061298990614c16565b9150506128c5565b5083601460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546129e1919061470a565b9250508190555083601360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a74919061470a565b925050819055508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f28f6e4bebd410ff24835163f718e2ba8c267a2ba3b1bdc05c5bd100907356fa78686604051612ada929190614626565b60405180910390a3505050505050565b6000600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612bb8611093565b15612bf8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bef906144ab565b60405180910390fd5b6001600560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612c3c611fc5565b604051612c4991906141db565b60405180910390a1565b612c5b613862565b612c63613862565b612c7a858585846130b6909392919063ffffffff16565b9150509392505050565b60606000602867ffffffffffffffff811115612ca357612ca2614d5b565b5b6040519080825280601f01601f191660200182016040528015612cd55781602001600182028036833780820191505090505b50905060005b6014811015612e3d576000816013612cf391906149ff565b6008612cff919061496a565b6002612d0b919061484c565b8573ffffffffffffffffffffffffffffffffffffffff16612d2c9190614797565b60f81b9050600060108260f81c612d4391906147c8565b60f81b905060008160f81c6010612d5a91906149c4565b8360f81c612d689190614a33565b60f81b9050612d7682613166565b85856002612d84919061496a565b81518110612d9557612d94614d2c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612dcd81613166565b856001866002612ddd919061496a565b612de7919061470a565b81518110612df857612df7614d2c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505050508080612e3590614bcd565b915050612cdb565b5080604051602001612e4f91906141b9565b604051602081830303815290604052915050919050565b612e7d8284608001516131ac90919063ffffffff16565b612e948184608001516131ac90919063ffffffff16565b505050565b600080600a549050600181612eae919061470a565b600a819055506000633c6d41b960e01b600080876000015188604001518660028b6080015160000151604051602401612eed979695949392919061421f565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050612f58868386846131d1565b925050509392505050565b612f6e838383611f68565b505050565b505050565b600080601360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600081601460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461304791906149ff565b905080601254613057919061470a565b600f5485613065919061470a565b86613070919061496a565b61307a919061496a565b601254600e548661308b919061470a565b84613096919061496a565b6130a0919061496a565b6130aa9190614797565b92505050949350505050565b6130be613862565b6130ce8560800151610100613375565b508385600001818152505082856020019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508185604001907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050849050949350505050565b6000600a8260f81c60ff1610156131915760308260f81c6131879190614760565b60f81b90506131a7565b60578260f81c6131a19190614760565b60f81b90505b919050565b6131b982600383516133df565b6131cc818361356490919063ffffffff16565b505050565b600030846040516020016131e692919061418d565b60405160208183030381529060405280519060200120905084600b600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550807fb5e6e01e79f91267dc17b4e6314d5d4d03593d2ceee0fbb452b750bd70ea5af960405160405180910390a2600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634000aea08685856040518463ffffffff1660e01b81526004016132dc93929190614295565b602060405180830381600087803b1580156132f657600080fd5b505af115801561330a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332e9190613be2565b61336d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133649061442b565b60405180910390fd5b949350505050565b61337d6138cf565b600060208361338c9190614c6e565b146133b85760208261339e9190614c6e565b60206133aa91906149ff565b826133b5919061470a565b91505b81836020018181525050604051808452600081528281016020016040525082905092915050565b60178167ffffffffffffffff1611613416576134108160058460ff16901b60ff16178461358690919063ffffffff16565b5061355f565b60ff8167ffffffffffffffff161161346c57613445601860058460ff16901b178461358690919063ffffffff16565b506134668167ffffffffffffffff166001856135a69092919063ffffffff16565b5061355e565b61ffff8167ffffffffffffffff16116134c35761349c601960058460ff16901b178461358690919063ffffffff16565b506134bd8167ffffffffffffffff166002856135a69092919063ffffffff16565b5061355d565b63ffffffff8167ffffffffffffffff161161351c576134f5601a60058460ff16901b178461358690919063ffffffff16565b506135168167ffffffffffffffff166004856135a69092919063ffffffff16565b5061355c565b613539601b60058460ff16901b178461358690919063ffffffff16565b5061355a8167ffffffffffffffff166008856135a69092919063ffffffff16565b505b5b5b5b505050565b61356c6138cf565b61357e838460000151518485516135c8565b905092915050565b61358e6138cf565b61359e83846000015151846136b7565b905092915050565b6135ae6138cf565b6135bf84856000015151858561370e565b90509392505050565b6135d06138cf565b82518211156135de57600080fd5b846020015182856135ef919061470a565b1115613624576136238560026136148860200151888761360f919061470a565b61379c565b61361e919061496a565b6137b8565b5b6000808651805187602083010193508088870111156136435787860182525b60208701925050505b6020841061368a5780518252602082613665919061470a565b9150602081613674919061470a565b905060208461368391906149ff565b935061364c565b60006001856020036101000a03905080198251168184511681811785525050508692505050949350505050565b6136bf6138cf565b836020015183106136e5576136e484600286602001516136df919061496a565b6137b8565b5b8351805160208583010184815381861415613701576001820183525b5050508390509392505050565b6137166138cf565b84602001518483613727919061470a565b111561374f5761374e856002868561373f919061470a565b613749919061496a565b6137b8565b5b6000600183610100613761919061484c565b61376b91906149ff565b9050855183868201018583198251161781528151858801111561378e5784870182525b505085915050949350505050565b6000818311156137ae578290506137b2565b8190505b92915050565b6000826000015190506137cb8383613375565b506137d68382613564565b50505050565b8280546137e890614b6a565b90600052602060002090601f01602090048101928261380a5760008555613851565b82601f1061382357805160ff1916838001178555613851565b82800160010185558215613851579182015b82811115613850578251825591602001919060010190613835565b5b50905061385e91906138e9565b5090565b6040518060a0016040528060008019168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001600081526020016138c96138cf565b81525090565b604051806040016040528060608152602001600081525090565b5b808211156139025760008160009055506001016138ea565b5090565b600061391961391484614696565b614671565b90508281526020810184848401111561393557613934614d99565b5b613940848285614b28565b509392505050565b600081359050613957816153e5565b92915050565b60008083601f84011261397357613972614d8f565b5b8235905067ffffffffffffffff8111156139905761398f614d8a565b5b6020830191508360208202830111156139ac576139ab614d94565b5b9250929050565b6000815190506139c2816153fc565b92915050565b6000813590506139d781615413565b92915050565b600082601f8301126139f2576139f1614d8f565b5b8135613a02848260208601613906565b91505092915050565b600081359050613a1a8161542a565b92915050565b600060208284031215613a3657613a35614da3565b5b6000613a4484828501613948565b91505092915050565b60008060408385031215613a6457613a63614da3565b5b6000613a7285828601613948565b9250506020613a8385828601613948565b9150509250929050565b600080600060608486031215613aa657613aa5614da3565b5b6000613ab486828701613948565b9350506020613ac586828701613948565b9250506040613ad686828701613a0b565b9150509250925092565b60008060408385031215613af757613af6614da3565b5b6000613b0585828601613948565b9250506020613b1685828601613a0b565b9150509250929050565b600080600060608486031215613b3957613b38614da3565b5b6000613b4786828701613948565b9350506020613b5886828701613a0b565b9250506040613b69868287016139c8565b9150509250925092565b600080600060608486031215613b8c57613b8b614da3565b5b6000613b9a86828701613948565b9350506020613bab86828701613a0b565b925050604084013567ffffffffffffffff811115613bcc57613bcb614d9e565b5b613bd8868287016139dd565b9150509250925092565b600060208284031215613bf857613bf7614da3565b5b6000613c06848285016139b3565b91505092915050565b600080600080600060608688031215613c2b57613c2a614da3565b5b6000613c39888289016139c8565b955050602086013567ffffffffffffffff811115613c5a57613c59614d9e565b5b613c668882890161395d565b9450945050604086013567ffffffffffffffff811115613c8957613c88614d9e565b5b613c958882890161395d565b92509250509295509295909350565b600060208284031215613cba57613cb9614da3565b5b600082013567ffffffffffffffff811115613cd857613cd7614d9e565b5b613ce4848285016139dd565b91505092915050565b600060208284031215613d0357613d02614da3565b5b6000613d1184828501613a0b565b91505092915050565b613d2381614a67565b82525050565b613d3281614a79565b82525050565b613d4181614a85565b82525050565b613d5081614a8f565b82525050565b6000613d61826146c7565b613d6b81856146dd565b9350613d7b818560208601614b37565b613d8481614da8565b840191505092915050565b613da0613d9b82614af2565b614c40565b82525050565b6000613db1826146d2565b613dbb81856146ee565b9350613dcb818560208601614b37565b613dd481614da8565b840191505092915050565b6000613dea826146d2565b613df481856146ff565b9350613e04818560208601614b37565b80840191505092915050565b6000613e1d6023836146ee565b9150613e2882614dd3565b604082019050919050565b6000613e406014836146ee565b9150613e4b82614e22565b602082019050919050565b6000613e63600c836146ee565b9150613e6e82614e4b565b602082019050919050565b6000613e866022836146ee565b9150613e9182614e74565b604082019050919050565b6000613ea96011836146ee565b9150613eb482614ec3565b602082019050919050565b6000613ecc6026836146ee565b9150613ed782614eec565b604082019050919050565b6000613eef6022836146ee565b9150613efa82614f3b565b604082019050919050565b6000613f126012836146ee565b9150613f1d82614f8a565b602082019050919050565b6000613f356002836146ff565b9150613f4082614fb3565b600282019050919050565b6000613f586023836146ee565b9150613f6382614fdc565b604082019050919050565b6000613f7b6026836146ee565b9150613f868261502b565b604082019050919050565b6000613f9e6015836146ee565b9150613fa98261507a565b602082019050919050565b6000613fc16023836146ee565b9150613fcc826150a3565b604082019050919050565b6000613fe46010836146ee565b9150613fef826150f2565b602082019050919050565b60006140076028836146ee565b91506140128261511b565b604082019050919050565b600061402a6020836146ee565b91506140358261516a565b602082019050919050565b600061404d6024836146ee565b915061405882615193565b604082019050919050565b60006140706021836146ee565b915061407b826151e2565b604082019050919050565b60006140936025836146ee565b915061409e82615231565b604082019050919050565b60006140b66024836146ee565b91506140c182615280565b604082019050919050565b60006140d96028836146ee565b91506140e4826152cf565b604082019050919050565b60006140fc6025836146ee565b91506141078261531e565b604082019050919050565b600061411f601f836146ee565b915061412a8261536d565b602082019050919050565b6000614142602a836146ee565b915061414d82615396565b604082019050919050565b61416181614adb565b82525050565b61417861417382614adb565b614c64565b82525050565b61418781614ae5565b82525050565b60006141998285613d8f565b6014820191506141a98284614167565b6020820191508190509392505050565b60006141c482613f28565b91506141d08284613ddf565b915081905092915050565b60006020820190506141f06000830184613d1a565b92915050565b600060408201905061420b6000830185613d1a565b6142186020830184614158565b9392505050565b600060e082019050614234600083018a613d1a565b6142416020830189614158565b61424e6040830188613d38565b61425b6060830187613d47565b6142686080830186614158565b61427560a0830185614158565b81810360c08301526142878184613d56565b905098975050505050505050565b60006060820190506142aa6000830186613d1a565b6142b76020830185614158565b81810360408301526142c98184613d56565b9050949350505050565b60006020820190506142e86000830184613d29565b92915050565b60006020820190506143036000830184613d38565b92915050565b600060208201905081810360008301526143238184613da6565b905092915050565b6000602082019050818103600083015261434481613e10565b9050919050565b6000602082019050818103600083015261436481613e33565b9050919050565b6000602082019050818103600083015261438481613e56565b9050919050565b600060208201905081810360008301526143a481613e79565b9050919050565b600060208201905081810360008301526143c481613e9c565b9050919050565b600060208201905081810360008301526143e481613ebf565b9050919050565b6000602082019050818103600083015261440481613ee2565b9050919050565b6000602082019050818103600083015261442481613f05565b9050919050565b6000602082019050818103600083015261444481613f4b565b9050919050565b6000602082019050818103600083015261446481613f6e565b9050919050565b6000602082019050818103600083015261448481613f91565b9050919050565b600060208201905081810360008301526144a481613fb4565b9050919050565b600060208201905081810360008301526144c481613fd7565b9050919050565b600060208201905081810360008301526144e481613ffa565b9050919050565b600060208201905081810360008301526145048161401d565b9050919050565b6000602082019050818103600083015261452481614040565b9050919050565b6000602082019050818103600083015261454481614063565b9050919050565b6000602082019050818103600083015261456481614086565b9050919050565b60006020820190508181036000830152614584816140a9565b9050919050565b600060208201905081810360008301526145a4816140cc565b9050919050565b600060208201905081810360008301526145c4816140ef565b9050919050565b600060208201905081810360008301526145e481614112565b9050919050565b6000602082019050818103600083015261460481614135565b9050919050565b60006020820190506146206000830184614158565b92915050565b600060408201905061463b6000830185614158565b818103602083015261464d8184613da6565b90509392505050565b600060208201905061466b600083018461417e565b92915050565b600061467b61468c565b90506146878282614b9c565b919050565b6000604051905090565b600067ffffffffffffffff8211156146b1576146b0614d5b565b5b6146ba82614da8565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600061471582614adb565b915061472083614adb565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561475557614754614c9f565b5b828201905092915050565b600061476b82614ae5565b915061477683614ae5565b92508260ff0382111561478c5761478b614c9f565b5b828201905092915050565b60006147a282614adb565b91506147ad83614adb565b9250826147bd576147bc614cce565b5b828204905092915050565b60006147d382614ae5565b91506147de83614ae5565b9250826147ee576147ed614cce565b5b828204905092915050565b6000808291508390505b60018511156148435780860481111561481f5761481e614c9f565b5b600185161561482e5780820291505b808102905061483c85614dc6565b9450614803565b94509492505050565b600061485782614adb565b915061486283614adb565b925061488f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484614897565b905092915050565b6000826148a75760019050614963565b816148b55760009050614963565b81600181146148cb57600281146148d557614904565b6001915050614963565b60ff8411156148e7576148e6614c9f565b5b8360020a9150848211156148fe576148fd614c9f565b5b50614963565b5060208310610133831016604e8410600b84101617156149395782820a90508381111561493457614933614c9f565b5b614963565b61494684848460016147f9565b9250905081840481111561495d5761495c614c9f565b5b81810290505b9392505050565b600061497582614adb565b915061498083614adb565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156149b9576149b8614c9f565b5b828202905092915050565b60006149cf82614ae5565b91506149da83614ae5565b92508160ff04831182151516156149f4576149f3614c9f565b5b828202905092915050565b6000614a0a82614adb565b9150614a1583614adb565b925082821015614a2857614a27614c9f565b5b828203905092915050565b6000614a3e82614ae5565b9150614a4983614ae5565b925082821015614a5c57614a5b614c9f565b5b828203905092915050565b6000614a7282614abb565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000614afd82614b04565b9050919050565b6000614b0f82614b16565b9050919050565b6000614b2182614abb565b9050919050565b82818337600083830152505050565b60005b83811015614b55578082015181840152602081019050614b3a565b83811115614b64576000848401525b50505050565b60006002820490506001821680614b8257607f821691505b60208210811415614b9657614b95614cfd565b5b50919050565b614ba582614da8565b810181811067ffffffffffffffff82111715614bc457614bc3614d5b565b5b80604052505050565b6000614bd882614adb565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614c0b57614c0a614c9f565b5b600182019050919050565b6000614c2182614ae5565b915060ff821415614c3557614c34614c9f565b5b600182019050919050565b6000614c4b82614c52565b9050919050565b6000614c5d82614db9565b9050919050565b6000819050919050565b6000614c7982614adb565b9150614c8483614adb565b925082614c9457614c93614cce565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b60008160011c9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f4e6f7420616c6c6f7765642e0000000000000000000000000000000000000000600082015250565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b7f73686f756c6420626520616e2075736572000000000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f756e6b6e6f776e20656e646f72736d656e740000000000000000000000000000600082015250565b7f3078000000000000000000000000000000000000000000000000000000000000600082015250565b7f756e61626c6520746f207472616e73666572416e6443616c6c20746f206f726160008201527f636c650000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f436f6e7472616374206973206d6967726174696e670000000000000000000000600082015250565b7f5554543a20656e646f72736520616d6f756e7420657863656564732062616c6160008201527f6e63650000000000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f7760008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f536f75726365206d75737420626520746865206f7261636c65206f662074686560008201527f2072657175657374000000000000000000000000000000000000000000000000602082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b7f45524332305061757361626c653a20746f6b656e207472616e7366657220776860008201527f696c652070617573656400000000000000000000000000000000000000000000602082015250565b6153ee81614a67565b81146153f957600080fd5b50565b61540581614a79565b811461541057600080fd5b50565b61541c81614a85565b811461542757600080fd5b50565b61543381614adb565b811461543e57600080fd5b5056fea2646970667358221220ba777900f57b1fd7aa880d7cb507e8421374c5f8eb565fa563962f7033b51a5464736f6c63430008070033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073ac0b4ba4fc1c42b8dffa39f3e4e0e95eb9b8fd00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f100000000000000000000000000000000000000000000000000000000000000203065656337653164643064323437366361316138373264666236363333663438

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

000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073ac0b4ba4fc1c42b8dffa39f3e4e0e95eb9b8fd00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f100000000000000000000000000000000000000000000000000000000000000203065656337653164643064323437366361316138373264666236363333663438

-----Decoded View---------------
Arg [0] : _mintAmount (uint256): 0
Arg [1] : _oracle (address): 0x73ac0b4ba4fc1c42b8dffa39f3e4e0e95eb9b8fd
Arg [2] : _jobId (string): 0eec7e1dd0d2476ca1a872dfb6633f48
Arg [3] : _fee (uint256): 100000000000000
Arg [4] : _link (address): 0xb0897686c545045afc77cf20ec7a532e3120e0f1

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 00000000000000000000000073ac0b4ba4fc1c42b8dffa39f3e4e0e95eb9b8fd
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [3] : 00000000000000000000000000000000000000000000000000005af3107a4000
Arg [4] : 000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [6] : 3065656337653164643064323437366361316138373264666236363333663438


Loading