FTM Price: $0.519245 (+0.35%)
 

Overview

Max Total Supply

304.392386391029270161 BAMM

Holders

3

Total Transfers

-

Market

Price

$0.00 @ 0.000000 FTM

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
BAMM

Compiler Version
v0.6.11+commit.5ef660b1

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, BSD-3-Clause license

Contract Source Code (Solidity)

/**
 *Submitted for verification at ftmscan.com on 2022-01-05
*/

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

// File contracts/Dependencies/SafeMath.sol

// SPDX-License-Identifier: MIT

pragma solidity 0.6.11;

/**
 * Based on OpenZeppelin's SafeMath:
 * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol
 *
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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


// File contracts/B.Protocol/TokenAdapter.sol



pragma solidity 0.6.11;

contract TokenAdapter {
    using SafeMath for uint256;

    string constant public name = "B.AMM";
    string constant public symbol = "BAMM";
    uint8 constant public decimals = 18;

    uint public totalSupply;

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);

    // balanceOf for each account
    mapping(address => uint256) public balanceOf;
 
    // Owner of account approves the transfer of an amount to another account
    mapping(address => mapping (address => uint256)) public allowance;
 
    // Transfer the balance from owner's account to another account
    function transfer(address to, uint tokens) public returns (bool success) {
        balanceOf[msg.sender] = balanceOf[msg.sender].sub(tokens);
        balanceOf[to] = balanceOf[to].add(tokens);
        emit Transfer(msg.sender, to, tokens);
        return true;
    }
 
    // Send `tokens` amount of tokens from address `from` to address `to`
    // The transferFrom method is used for a withdraw workflow, allowing contracts to send
    // tokens on your behalf, for example to "deposit" to a contract address and/or to charge
    // fees in sub-currencies; the command should fail unless the _from account has
    // deliberately authorized the sender of the message via some mechanism; we propose
    // these standardized APIs for approval:
    function transferFrom(address from, address to, uint tokens) public returns (bool success) {
        balanceOf[from] = balanceOf[from].sub(tokens);
        if(allowance[from][msg.sender] != type(uint256).max) {
            allowance[from][msg.sender] = allowance[from][msg.sender].sub(tokens);
        }
        balanceOf[to] = balanceOf[to].add(tokens);
        emit Transfer(from, to, tokens);
        return true;
    }
 
    // Allow `spender` to withdraw from your account, multiple times, up to the `tokens` amount.
    // If this function is called again it overwrites the current allowance with _value.
    function approve(address spender, uint tokens) public returns (bool success) {
        allowance[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        return true;
    }

    function mint(address to, uint tokens) internal {
        balanceOf[to] = balanceOf[to].add(tokens);
        totalSupply = totalSupply.add(tokens);

        emit Transfer(address(0), to, tokens);
    }

    function burn(address owner, uint tokens) internal {
        balanceOf[owner] = balanceOf[owner].sub(tokens);
        totalSupply = totalSupply.sub(tokens);

        emit Transfer(owner, address(0), tokens);        
    }
}


// File contracts/B.Protocol/PriceFormula.sol



pragma solidity 0.6.11;

contract PriceFormula {
    using SafeMath for uint256;

    function getSumFixedPoint(uint x, uint y, uint A) public pure returns(uint) {
        if(x == 0 && y == 0) return 0;

        uint sum = x.add(y);

        for(uint i = 0 ; i < 255 ; i++) {
            uint dP = sum;
            dP = dP.mul(sum) / (x.mul(2)).add(1);
            dP = dP.mul(sum) / (y.mul(2)).add(1);

            uint prevSum = sum;

            uint n = (A.mul(2).mul(x.add(y)).add(dP.mul(2))).mul(sum);
            uint d = (A.mul(2).sub(1).mul(sum));
            sum = n / d.add(dP.mul(3));

            if(sum <= prevSum.add(1) && prevSum <= sum.add(1)) break;
        }

        return sum;
    }

    function getReturn(uint xQty, uint xBalance, uint yBalance, uint A) public pure returns(uint) {
        uint sum = getSumFixedPoint(xBalance, yBalance, A);

        uint c = sum.mul(sum) / (xQty.add(xBalance)).mul(2);
        c = c.mul(sum) / A.mul(4);
        uint b = (xQty.add(xBalance)).add(sum / A.mul(2));
        uint yPrev = 0;
        uint y = sum;

        for(uint i = 0 ; i < 255 ; i++) {
            yPrev = y;
            uint n = (y.mul(y)).add(c);
            uint d = y.mul(2).add(b).sub(sum); 
            y = n / d;

            if(y <= yPrev.add(1) && yPrev <= y.add(1)) break;
        }

        return yBalance.sub(y).sub(1);
    }
}


// File contracts/Interfaces/IPriceFeed.sol



pragma solidity 0.6.11;

interface IPriceFeed {

    // --- Events ---
    event LastGoodPriceUpdated(uint _lastGoodPrice);
   
    // --- Function ---
    function fetchPrice() external returns (uint);
}


// File contracts/Dependencies/Ownable.sol



pragma solidity 0.6.11;

/**
 * Based on OpenZeppelin's Ownable contract:
 * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.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.
 *
 * 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.
 */
contract Ownable {
    address private _owner;

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

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

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

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

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _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);
    }
        
    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     *
     * NOTE: This function is not safe, as it doesn’t check owner is calling it.
     * Make sure you check it before calling it.
     */
    function _renounceOwnership() internal {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }
}


// File contracts/Dependencies/AggregatorV3Interface.sol


// Code from https://github.com/smartcontractkit/chainlink/blob/master/evm-contracts/src/v0.6/interfaces/AggregatorV3Interface.sol

pragma solidity 0.6.11;

interface AggregatorV3Interface {

  function decimals() external view returns (uint8);
  function description() external view returns (string memory);
  function version() external view returns (uint256);

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

  function latestRoundData()
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
}


// File @openzeppelin/contracts/utils/[email protected]



pragma solidity ^0.6.0;

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

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

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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


// File @openzeppelin/contracts/token/ERC20/[email protected]



pragma solidity ^0.6.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 @openzeppelin/contracts/math/[email protected]



pragma solidity ^0.6.0;


// File @openzeppelin/contracts/utils/[email protected]



pragma solidity ^0.6.2;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return _functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        return _functionCallWithValue(target, data, value, errorMessage);
    }

    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


// File @openzeppelin/contracts/token/ERC20/[email protected]



pragma solidity ^0.6.0;



/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}


// File @openzeppelin/contracts/GSN/[email protected]



pragma solidity ^0.6.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 GSN 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 payable) {
        return msg.sender;
    }

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


// File @openzeppelin/contracts/token/ERC20/[email protected]



pragma solidity ^0.6.0;




/**
 * @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 guidelines: functions revert instead
 * of 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 {
    using SafeMath for uint256;
    using Address for address;

    mapping (address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;
        _decimals = 18;
    }

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

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view 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 {_setupDecimals} is
     * called.
     *
     * 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 returns (uint8) {
        return _decimals;
    }

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(sender, recipient, amount);

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

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

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

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

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

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

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

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

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

    /**
     * @dev Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal {
        _decimals = decimals_;
    }

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


// File contracts/B.Protocol/BAMM.sol



pragma solidity 0.6.11;









interface ICToken {
    function redeem(uint redeemTokens) external returns (uint);
    function balanceOf(address a) external view returns (uint);
    function liquidateBorrow(address borrower, uint amount, address collateral) external returns (uint);
    function underlying() external view returns(IERC20);
}

contract BAMM is TokenAdapter, PriceFormula, Ownable, ReentrancyGuard {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    IERC20 public immutable LUSD;
    uint public immutable lusdDecimals;
    IERC20[] public collaterals; // IMPORTANT - collateral != LUSD
    mapping(address => AggregatorV3Interface) public priceAggregators;
    mapping(address => uint) public collateralDecimals;
    mapping(address => bool) public cTokens;
    ICToken public immutable cBorrow;

    address payable public immutable feePool;
    uint public constant MAX_FEE = 100; // 1%
    uint public constant MAX_CALLER_FEE = 100; // 1%
    uint public fee = 0; // fee in bps
    uint public callerFee = 0; // fee in bps
    uint public A = 20;
    uint public constant MIN_A = 20;
    uint public constant MAX_A = 200;    

    uint public immutable maxDiscount; // max discount in bips

    uint constant public PRECISION = 1e18;

    event ParamsSet(uint A, uint fee, uint callerFee);
    event UserDeposit(address indexed user, uint lusdAmount, uint numShares);
    event UserWithdraw(address indexed user, uint lusdAmount, uint numShares);
    event RebalanceSwap(address indexed user, uint lusdAmount, IERC20 token, uint tokenAmount, uint timestamp);

    constructor(
        address _LUSD,
        address _cBorrow,
        uint _maxDiscount,
        address payable _feePool)
        public
    {
        LUSD = IERC20(_LUSD);
        lusdDecimals = ERC20(_LUSD).decimals();
        cBorrow = ICToken(_cBorrow);

        feePool = _feePool;
        maxDiscount = _maxDiscount;

        IERC20(_LUSD).safeApprove(address(_cBorrow), uint(-1));

        require(ERC20(_LUSD).decimals() <= 18, "unsupported decimals");
    }

    function setParams(uint _A, uint _fee, uint _callerFee) external onlyOwner {
        require(_fee <= MAX_FEE, "setParams: fee is too big");
        require(_callerFee <= MAX_CALLER_FEE, "setParams: caller fee is too big");        
        require(_A >= MIN_A, "setParams: A too small");
        require(_A <= MAX_A, "setParams: A too big");

        fee = _fee;
        callerFee = _callerFee;
        A = _A;

        emit ParamsSet(_A, _fee, _callerFee);
    }

    function addCollateral(ICToken ctoken, AggregatorV3Interface feed) external onlyOwner {
        IERC20 token = ctoken.underlying();

        // validations
        require(token != LUSD, "addCollateral: LUSD cannot be collateral");
        require(feed != AggregatorV3Interface(0x0), "addCollateral: invalid feed");
        require(! cTokens[address(ctoken)], "addCollateral: collateral listed");
        require(priceAggregators[address(token)] == AggregatorV3Interface(0x0), "addCollateral: underlying already added");

        // add the token
        collaterals.push(token);
        priceAggregators[address(token)] = feed;
        collateralDecimals[address(token)] = ERC20(address(token)).decimals();
        cTokens[address(ctoken)] = true;        
    }

    function removeCollateral(ICToken ctoken) external onlyOwner {
        IERC20 token = ctoken.underlying();

        for(uint i = 0 ; i < collaterals.length ; i++) {
            if(collaterals[i] == token) {
                collaterals[i] = collaterals[collaterals.length - 1];
                collaterals.pop();
                priceAggregators[address(token)] = AggregatorV3Interface(0x0);
                cTokens[address(ctoken)] = false;
                break;
            }
        }
    }

    function fetchPrice(IERC20 token) public view returns(uint) {
        AggregatorV3Interface priceAggregator = priceAggregators[address(token)];
        if(priceAggregator == AggregatorV3Interface(address(0x0))) return 0;

        uint chainlinkDecimals;
        uint chainlinkLatestAnswer;
        uint chainlinkTimestamp;

        // First, try to get current decimal precision:
        try priceAggregator.decimals() returns (uint8 decimals) {
            // If call to Chainlink succeeds, record the current decimal precision
            chainlinkDecimals = decimals;
        } catch {
            // If call to Chainlink aggregator reverts, return a zero response with success = false
            return 0;
        }

        // Secondly, try to get latest price data:
        try priceAggregator.latestRoundData() returns
        (
            uint80 /* roundId */,
            int256 answer,
            uint256 /* startedAt */,
            uint256 timestamp,
            uint80 /* answeredInRound */
        )
        {
            // If call to Chainlink succeeds, return the response and success = true
            chainlinkLatestAnswer = uint(answer);
            chainlinkTimestamp = timestamp;
        } catch {
            // If call to Chainlink aggregator reverts, return a zero response with success = false
            return 0;
        }

        if(chainlinkTimestamp + 1 hours < now) return 0; // price is down

        int chainlinkDecimalFactor = int(chainlinkDecimals + collateralDecimals[address(token)]) - int(lusdDecimals);
        if(chainlinkDecimalFactor >= 0) {
            return chainlinkLatestAnswer.mul(PRECISION) / (10 ** uint(chainlinkDecimalFactor));
        }
        else {
            return chainlinkLatestAnswer.mul(PRECISION) * (10 ** uint(-1 * chainlinkDecimalFactor));
        }
    }

    function getCollateralValue() public view returns(bool succ, uint value) {
        value = 0;
        succ = true;

        for(uint i = 0 ; i < collaterals.length ; i++) {
            IERC20 token = collaterals[i];
            uint bal = token.balanceOf(address(this));
            if(bal > 0) {
                uint price = fetchPrice(token);
                if(price == 0) {
                    succ = false;
                    break;
                }

                value = value.add(bal.mul(price) / PRECISION);                
            }
        }
    }


    function deposit(uint lusdAmount) external nonReentrant {        
        // update share
        uint lusdValue = LUSD.balanceOf(address(this));
        (bool succ, uint colValue) = getCollateralValue();

        require(succ, "deposit: chainlink is down");

        uint totalValue = lusdValue.add(colValue);

        // this is in theory not reachable. if it is, better halt deposits
        // the condition is equivalent to: (totalValue = 0) ==> (totalSupply = 0)
        require(totalValue > 0 || totalSupply == 0, "deposit: system is rekt");

        uint newShare = PRECISION;
        if(totalSupply > 0) newShare = totalSupply.mul(lusdAmount) / totalValue;

        // deposit
        LUSD.safeTransferFrom(msg.sender, address(this), lusdAmount);

        // update LP token
        mint(msg.sender, newShare);

        emit UserDeposit(msg.sender, lusdAmount, newShare);        
    }

    function withdraw(uint numShares) external nonReentrant {
        uint supplyBefore = totalSupply; // this is to save gas

        uint lusdBal = LUSD.balanceOf(address(this));
        uint lusdAmount = lusdBal.mul(numShares).div(supplyBefore);

        uint[] memory collateralAmounts = new uint[](collaterals.length);
        IERC20[] memory collateralTypes = collaterals;

        for(uint i = 0 ; i < collateralTypes.length ; i++) {
            uint bal = collateralTypes[i].balanceOf(address(this));
            collateralAmounts[i] = bal.mul(numShares).div(supplyBefore);
        }

        // update LP token
        burn(msg.sender, numShares);

        // send lusd and collateral leftovers
        if(lusdAmount > 0) LUSD.safeTransfer(msg.sender, lusdAmount);
        for(uint i = 0 ; i < collateralTypes.length ; i++) {
            if(collateralAmounts[i] > 0 ) collateralTypes[i].safeTransfer(msg.sender, collateralAmounts[i]);
        }

        emit UserWithdraw(msg.sender, lusdAmount, numShares);            
    }

    function addBps(uint n, int bps) internal pure returns(uint) {
        require(bps <= 10000, "reduceBps: bps exceeds max");
        require(bps >= -10000, "reduceBps: bps exceeds min");

        return n.mul(uint(10000 + bps)) / 10000;
    }

    function getSwapAmount(uint lusdQty, IERC20 token) public view returns(uint tokenAmount) {
        uint lusdBalance = LUSD.balanceOf(address(this));
        uint tokenBalance  = token.balanceOf(address(this));

        (bool succ, uint collateralValue) = getCollateralValue();
        if(! succ) return 0; // chainlink is down

        uint token2usdPrice = fetchPrice(token);
        if(token2usdPrice == 0) return 0; // chainlink is down

        uint maxReturn = addBps(lusdQty.mul(PRECISION) / token2usdPrice, int(maxDiscount));

        uint xQty = lusdQty;
        uint xBalance = lusdBalance;
        uint yBalance = lusdBalance.add(collateralValue.mul(2));
        
        uint usdReturn = getReturn(xQty, xBalance, yBalance, A);
        uint basicTokenReturn = usdReturn.mul(PRECISION) / token2usdPrice;

        if(tokenBalance < basicTokenReturn) basicTokenReturn = tokenBalance; // cannot give more than balance 
        if(maxReturn < basicTokenReturn) basicTokenReturn = maxReturn;

        tokenAmount = basicTokenReturn;
    }

    // get token in return to LUSD
    function swap(uint lusdAmount, IERC20 returnToken, uint minReturn, address payable dest) public nonReentrant returns(uint) {
        require(returnToken != LUSD, "swap: unsupported");

        uint returnAmount = getSwapAmount(lusdAmount, returnToken);

        require(returnAmount >= minReturn, "swap: low return");

        LUSD.safeTransferFrom(msg.sender, address(this), lusdAmount);

        uint feeAmount = addBps(lusdAmount, int(fee)).sub(lusdAmount);
        if(feeAmount > 0) LUSD.safeTransfer(feePool, feeAmount);

        returnToken.safeTransfer(dest, returnAmount);

        emit RebalanceSwap(msg.sender, lusdAmount, returnToken, returnAmount, now);

        return returnAmount;
    }

    receive() external payable {}

    function canLiquidate(
        ICToken cTokenBorrowed,
        ICToken cTokenCollateral,
        uint repayAmount
    )
        external
        view
        returns(bool)
    {
        if(cTokenBorrowed != cBorrow) return false;
        if((! cTokens[address(cTokenCollateral)]) && (cTokenCollateral != cTokenBorrowed)) return false;

        return repayAmount <= LUSD.balanceOf(address(this));
    }

    // callable by anyone
    function liquidateBorrow(address borrower, uint amount, ICToken collateral) external nonReentrant returns (uint) {
        require(cTokens[address(collateral)] || collateral == cBorrow, "liquidateBorrow: invalid collateral");

        IERC20 colToken = IERC20(collateral.underlying());

        uint tokenBalBefore = colToken.balanceOf(address(this));
        require(cBorrow.liquidateBorrow(borrower, amount, address(collateral)) == 0, "liquidateBorrow: liquidation failed");
        require(collateral.redeem(collateral.balanceOf(address(this))) == 0, "liquidateBorrow: collateral redeem failed");       
        uint tokenBalAfter = colToken.balanceOf(address(this));

        uint deltaToken = tokenBalAfter.sub(tokenBalBefore);
        if(collateral == cBorrow) deltaToken = amount;

        uint feeAmount = addBps(deltaToken, int(callerFee)).sub(deltaToken);
        if(feeAmount > 0 ) colToken.safeTransfer(msg.sender, feeAmount);
    }    
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_LUSD","type":"address"},{"internalType":"address","name":"_cBorrow","type":"address"},{"internalType":"uint256","name":"_maxDiscount","type":"uint256"},{"internalType":"address payable","name":"_feePool","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenOwner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"Approval","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":"uint256","name":"A","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"callerFee","type":"uint256"}],"name":"ParamsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"lusdAmount","type":"uint256"},{"indexed":false,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RebalanceSwap","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":"tokens","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"lusdAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"numShares","type":"uint256"}],"name":"UserDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"lusdAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"numShares","type":"uint256"}],"name":"UserWithdraw","type":"event"},{"inputs":[],"name":"A","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LUSD","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_A","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_CALLER_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_A","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ICToken","name":"ctoken","type":"address"},{"internalType":"contract AggregatorV3Interface","name":"feed","type":"address"}],"name":"addCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cBorrow","outputs":[{"internalType":"contract ICToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"cTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callerFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ICToken","name":"cTokenBorrowed","type":"address"},{"internalType":"contract ICToken","name":"cTokenCollateral","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"}],"name":"canLiquidate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"collateralDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"collaterals","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lusdAmount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feePool","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"fetchPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCollateralValue","outputs":[{"internalType":"bool","name":"succ","type":"bool"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"xQty","type":"uint256"},{"internalType":"uint256","name":"xBalance","type":"uint256"},{"internalType":"uint256","name":"yBalance","type":"uint256"},{"internalType":"uint256","name":"A","type":"uint256"}],"name":"getReturn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"A","type":"uint256"}],"name":"getSumFixedPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"lusdQty","type":"uint256"},{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"getSwapAmount","outputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"contract ICToken","name":"collateral","type":"address"}],"name":"liquidateBorrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lusdDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"priceAggregators","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ICToken","name":"ctoken","type":"address"}],"name":"removeCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_A","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"uint256","name":"_callerFee","type":"uint256"}],"name":"setParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"lusdAmount","type":"uint256"},{"internalType":"contract IERC20","name":"returnToken","type":"address"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"address payable","name":"dest","type":"address"}],"name":"swap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numShares","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

61012060405260006009556000600a556014600b553480156200002157600080fd5b5060405162003d3538038062003d35833981810160405260808110156200004757600080fd5b5080516020820151604080840151606090940151600380546001600160a01b031916339081179091559151939492939091906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600160049081556001600160601b0319606086901b166080526040805163313ce56760e01b815290516001600160a01b0387169263313ce56792808201926020929091829003018186803b158015620000f957600080fd5b505afa1580156200010e573d6000803e3d6000fd5b505050506040513d60208110156200012557600080fd5b505160ff1660a052606083811b6001600160601b031990811660c0529082901b1660e052610100829052620001736001600160a01b038516846000196200023e602090811b62002bc917901c565b6012846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015620001af57600080fd5b505afa158015620001c4573d6000803e3d6000fd5b505050506040513d6020811015620001db57600080fd5b505160ff16111562000234576040805162461bcd60e51b815260206004820152601460248201527f756e737570706f7274656420646563696d616c73000000000000000000000000604482015290519081900360640190fd5b5050505062000607565b801580620002c8575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b1580156200029857600080fd5b505afa158015620002ad573d6000803e3d6000fd5b505050506040513d6020811015620002c457600080fd5b5051155b620003055760405162461bcd60e51b815260040180806020018281038252603681526020018062003cff6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091526200035d9185916200036216565b505050565b6060620003be826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200041e60201b62002cdc179092919060201c565b8051909150156200035d57808060200190516020811015620003df57600080fd5b50516200035d5760405162461bcd60e51b815260040180806020018281038252602a81526020018062003cd5602a913960400191505060405180910390fd5b60606200043884846000856001600160e01b036200044016565b949350505050565b606062000456856001600160e01b036200060116565b620004a8576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310620004e95780518252601f199092019160209182019101620004c8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146200054d576040519150601f19603f3d011682016040523d82523d6000602084013e62000552565b606091505b5091509150811562000568579150620004389050565b805115620005795780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620005c5578181015183820152602001620005ab565b50505050905090810190601f168015620005f35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b3b151590565b60805160601c60a05160c05160601c60e05160601c61010051613630620006a5600039806112445280611bcf5250806119095280611dbf5250806110a852806114ed528061276452806128e65280612b4852508061187e5280611bf3525080610d725280610fad52806110ef528061159452806119985280611b4e5280611c6c5280611d485280611d9d528061201f528061248052506136306000f3fe6080604052600436106102555760003560e01c8063aaf5eb6811610139578063c6783af1116100b6578063e29e4fbc1161007a578063e29e4fbc146108a4578063f1ae3c7f146108da578063f2fde38b1461090d578063f446c1d014610940578063f5e3c46214610955578063f6a23320146107435761025c565b8063c6783af1146107d1578063c99d3a061461080c578063cf59d5631461083f578063dd62ed3e14610854578063ddca3f431461088f5761025c565b8063b8b89e1b116100fd578063b8b89e1b14610719578063bb9956841461072e578063bc063e1a14610743578063bfd4799614610758578063c047e563146107a15761025c565b8063aaf5eb681461065f578063ace1798e14610674578063ae2e933b146106a7578063b4fb1279146106bc578063b6b55f25146106ef5761025c565b80634bb4695d116101d257806385ad3f811161019657806385ad3f81146105715780638c0b09d0146105b45780638da5cb5b146105e75780638f32d59b146105fc57806395d89b4114610611578063a9059cbb146106265761025c565b80634bb4695d146104a5578063571a0ccf146104ba5780635a0ce676146104f35780636e9fe6701461052957806370a082311461053e5761025c565b806324c1173b1161021957806324c1173b146103de5780632e1a7d4d14610424578063313ce5671461045057806334d441d01461047b57806339698415146104905761025c565b8063068d59111461026157806306fdde03146102af578063095ea7b31461033957806318160ddd1461038657806323b872dd1461039b5761025c565b3661025c57005b600080fd5b34801561026d57600080fd5b5061029d6004803603608081101561028457600080fd5b5080359060208101359060408101359060600135610998565b60408051918252519081900360200190f35b3480156102bb57600080fd5b506102c4610b19565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102fe5781810151838201526020016102e6565b50505050905090810190601f16801561032b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561034557600080fd5b506103726004803603604081101561035c57600080fd5b506001600160a01b038135169060200135610b3a565b604080519115158252519081900360200190f35b34801561039257600080fd5b5061029d610ba1565b3480156103a757600080fd5b50610372600480360360608110156103be57600080fd5b506001600160a01b03813581169160208101359091169060400135610ba7565b3480156103ea57600080fd5b506104086004803603602081101561040157600080fd5b5035610cd7565b604080516001600160a01b039092168252519081900360200190f35b34801561043057600080fd5b5061044e6004803603602081101561044757600080fd5b5035610cfe565b005b34801561045c57600080fd5b50610465611096565b6040805160ff9092168252519081900360200190f35b34801561048757600080fd5b5061029d61109b565b34801561049c57600080fd5b5061029d6110a1565b3480156104b157600080fd5b506104086110a6565b3480156104c657600080fd5b5061029d600480360360408110156104dd57600080fd5b50803590602001356001600160a01b03166110ca565b3480156104ff57600080fd5b5061044e6004803603606081101561051657600080fd5b50803590602081013590604001356112ef565b34801561053557600080fd5b5061029d6114d2565b34801561054a57600080fd5b5061029d6004803603602081101561056157600080fd5b50356001600160a01b03166114d7565b34801561057d57600080fd5b506103726004803603606081101561059457600080fd5b506001600160a01b038135811691602081013590911690604001356114e9565b3480156105c057600080fd5b50610372600480360360208110156105d757600080fd5b50356001600160a01b0316611611565b3480156105f357600080fd5b50610408611626565b34801561060857600080fd5b50610372611635565b34801561061d57600080fd5b506102c4611646565b34801561063257600080fd5b506103726004803603604081101561064957600080fd5b506001600160a01b038135169060200135611666565b34801561066b57600080fd5b5061029d611704565b34801561068057600080fd5b5061029d6004803603602081101561069757600080fd5b50356001600160a01b0316611710565b3480156106b357600080fd5b50610408611907565b3480156106c857600080fd5b50610408600480360360208110156106df57600080fd5b50356001600160a01b031661192b565b3480156106fb57600080fd5b5061044e6004803603602081101561071257600080fd5b5035611946565b34801561072557600080fd5b5061029d611bcd565b34801561073a57600080fd5b5061029d611bf1565b34801561074f57600080fd5b5061029d611c15565b34801561076457600080fd5b5061029d6004803603608081101561077b57600080fd5b508035906001600160a01b03602082013581169160408101359160609091013516611c1a565b3480156107ad57600080fd5b506107b6611e64565b60408051921515835260208301919091528051918290030190f35b3480156107dd57600080fd5b5061044e600480360360408110156107f457600080fd5b506001600160a01b0381358116916020013516611f6d565b34801561081857600080fd5b5061044e6004803603602081101561082f57600080fd5b50356001600160a01b03166122b3565b34801561084b57600080fd5b5061040861247e565b34801561086057600080fd5b5061029d6004803603604081101561087757600080fd5b506001600160a01b03813581169160200135166124a2565b34801561089b57600080fd5b5061029d6124bf565b3480156108b057600080fd5b5061029d600480360360608110156108c757600080fd5b50803590602081013590604001356124c5565b3480156108e657600080fd5b5061029d600480360360208110156108fd57600080fd5b50356001600160a01b0316612643565b34801561091957600080fd5b5061044e6004803603602081101561093057600080fd5b50356001600160a01b0316612655565b34801561094c57600080fd5b5061029d6126ed565b34801561096157600080fd5b5061029d6004803603606081101561097857600080fd5b506001600160a01b038135811691602081013591604090910135166126f3565b6000806109a68585856124c5565b905060006109cb60026109bf898963ffffffff612ceb16565b9063ffffffff612d4516565b6109db838063ffffffff612d4516565b816109e257fe5b0490506109f684600463ffffffff612d4516565b610a06828463ffffffff612d4516565b81610a0d57fe5b0490506000610a4b610a2686600263ffffffff612d4516565b8481610a2e57fe5b04610a3f8a8a63ffffffff612ceb16565b9063ffffffff612ceb16565b9050600083815b60ff811015610af35790915081906000610a7686610a3f858063ffffffff612d4516565b90506000610a9f88610a9388610a3f88600263ffffffff612d4516565b9063ffffffff612d9e16565b9050808281610aaa57fe5b049350610abe85600163ffffffff612ceb16565b8411158015610add5750610ad984600163ffffffff612ceb16565b8511155b15610ae9575050610af3565b5050600101610a52565b50610b096001610a938a8463ffffffff612d9e16565b955050505050505b949350505050565b60405180604001604052806005815260200164422e414d4d60d81b81525081565b3360008181526002602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60005481565b6001600160a01b038316600090815260016020526040812054610bd0908363ffffffff612d9e16565b6001600160a01b038516600090815260016020908152604080832093909355600281528282203383529052205460001914610c5e576001600160a01b0384166000908152600260209081526040808320338452909152902054610c39908363ffffffff612d9e16565b6001600160a01b03851660009081526002602090815260408083203384529091529020555b6001600160a01b038316600090815260016020526040902054610c87908363ffffffff612ceb16565b6001600160a01b03808516600081815260016020908152604091829020949094558051868152905191939288169260008051602061353183398151915292918290030190a35060015b9392505050565b60058181548110610ce457fe5b6000918252602090912001546001600160a01b0316905081565b60026004541415610d44576040805162461bcd60e51b815260206004820152601f6024820152600080516020613436833981519152604482015290519081900360640190fd5b6002600490815560008054604080516370a0823160e01b815230948101949094525190926001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a0823191602480820192602092909190829003018186803b158015610db957600080fd5b505afa158015610dcd573d6000803e3d6000fd5b505050506040513d6020811015610de357600080fd5b505190506000610e0983610dfd848763ffffffff612d4516565b9063ffffffff612de016565b60055490915060609067ffffffffffffffff81118015610e2857600080fd5b50604051908082528060200260200182016040528015610e52578160200160208202803683370190505b50905060606005805480602002602001604051908101604052809291908181526020018280548015610ead57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e8f575b50939450600093505050505b8151811015610f8f576000828281518110610ed057fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610f2d57600080fd5b505afa158015610f41573d6000803e3d6000fd5b505050506040513d6020811015610f5757600080fd5b50519050610f6f87610dfd838b63ffffffff612d4516565b848381518110610f7b57fe5b602090810291909101015250600101610eb9565b50610f9a3387612e22565b8215610fda57610fda6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016338563ffffffff612eae16565b60005b815181101561104e576000838281518110610ff457fe5b60200260200101511115611046576110463384838151811061101257fe5b602002602001015184848151811061102657fe5b60200260200101516001600160a01b0316612eae9092919063ffffffff16565b600101610fdd565b506040805184815260208101889052815133927fd2263e970e3552b8e14c013f4d6af030894ef3ae6f025607042368db047a4418928290030190a25050600160045550505050565b601281565b600a5481565b60c881565b7f000000000000000000000000000000000000000000000000000000000000000081565b604080516370a0823160e01b8152306004820152905160009182916001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b15801561113557600080fd5b505afa158015611149573d6000803e3d6000fd5b505050506040513d602081101561115f57600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038616916370a08231916024808301926020929190829003018186803b1580156111ad57600080fd5b505afa1580156111c1573d6000803e3d6000fd5b505050506040513d60208110156111d757600080fd5b505190506000806111e6611e64565b91509150816111fc576000945050505050610b9b565b600061120787611710565b90508061121c57600095505050505050610b9b565b60006112688261123a8b670de0b6b3a764000063ffffffff612d4516565b8161124157fe5b047f0000000000000000000000000000000000000000000000000000000000000000612f00565b90508886600061128f61128287600263ffffffff612d4516565b8a9063ffffffff612ceb16565b905060006112a1848484600b54610998565b90506000866112be83670de0b6b3a764000063ffffffff612d4516565b816112c557fe5b049050808a10156112d35750885b808610156112de5750845b9d9c50505050505050505050505050565b6112f7611635565b611336576040805162461bcd60e51b815260206004820181905260248201526000805160206134ee833981519152604482015290519081900360640190fd5b606482111561138c576040805162461bcd60e51b815260206004820152601960248201527f736574506172616d733a2066656520697320746f6f2062696700000000000000604482015290519081900360640190fd5b60648111156113e2576040805162461bcd60e51b815260206004820181905260248201527f736574506172616d733a2063616c6c65722066656520697320746f6f20626967604482015290519081900360640190fd5b6014831015611431576040805162461bcd60e51b81526020600482015260166024820152751cd95d14185c985b5cce8810481d1bdbc81cdb585b1b60521b604482015290519081900360640190fd5b60c883111561147e576040805162461bcd60e51b8152602060048201526014602482015273736574506172616d733a204120746f6f2062696760601b604482015290519081900360640190fd5b6009829055600a819055600b839055604080518481526020810184905280820183905290517fee5d147c6dd8b96e80762594bab87a5a80c4c7ec653bdb804933445386340b019181900360600190a1505050565b601481565b60016020526000908152604090205481565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b03161461152c57506000610cd0565b6001600160a01b03831660009081526008602052604090205460ff161580156115675750836001600160a01b0316836001600160a01b031614155b1561157457506000610cd0565b604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b1580156115da57600080fd5b505afa1580156115ee573d6000803e3d6000fd5b505050506040513d602081101561160457600080fd5b5051909111159392505050565b60086020526000908152604090205460ff1681565b6003546001600160a01b031690565b6003546001600160a01b0316331490565b6040518060400160405280600481526020016342414d4d60e01b81525081565b33600090815260016020526040812054611686908363ffffffff612d9e16565b33600090815260016020526040808220929092556001600160a01b038516815220546116b8908363ffffffff612ceb16565b6001600160a01b0384166000818152600160209081526040918290209390935580518581529051919233926000805160206135318339815191529281900390910190a350600192915050565b670de0b6b3a764000081565b6001600160a01b038082166000908152600660205260408120549091168061173c576000915050611902565b6000806000836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561177a57600080fd5b505afa92505050801561179f57506040513d602081101561179a57600080fd5b505160015b6117b0576000945050505050611902565b60ff169250836001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156117ee57600080fd5b505afa92505050801561183057506040513d60a081101561180e57600080fd5b5080516020820151604083015160608401516080909401519293919290919060015b611841576000945050505050611902565b5091945090925050504281610e10011015611863576000945050505050611902565b6001600160a01b0386166000908152600760205260408120547f0000000000000000000000000000000000000000000000000000000000000000908501039081126118d957600a81900a6118c584670de0b6b3a764000063ffffffff612d4516565b816118cc57fe5b0495505050505050611902565b6000819003600a0a6118f984670de0b6b3a764000063ffffffff612d4516565b02955050505050505b919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6006602052600090815260409020546001600160a01b031681565b6002600454141561198c576040805162461bcd60e51b815260206004820152601f6024820152600080516020613436833981519152604482015290519081900360640190fd5b600260048190555060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611a0c57600080fd5b505afa158015611a20573d6000803e3d6000fd5b505050506040513d6020811015611a3657600080fd5b50519050600080611a45611e64565b9150915081611a9b576040805162461bcd60e51b815260206004820152601a60248201527f6465706f7369743a20636861696e6c696e6b20697320646f776e000000000000604482015290519081900360640190fd5b6000611aad848363ffffffff612ceb16565b90506000811180611abe5750600054155b611b0f576040805162461bcd60e51b815260206004820152601760248201527f6465706f7369743a2073797374656d2069732072656b74000000000000000000604482015290519081900360640190fd5b600054670de0b6b3a76400009015611b41576000548290611b36908863ffffffff612d4516565b81611b3d57fe5b0490505b611b7c6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308963ffffffff612fd516565b611b863382613035565b6040805187815260208101839052815133927f2f1a7fda57b5fd5cb62770aebd7fc9a8a0a834c5ff558eb7562f85f2b28c4375928290030190a25050600160045550505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b606481565b600060026004541415611c62576040805162461bcd60e51b815260206004820152601f6024820152600080516020613436833981519152604482015290519081900360640190fd5b60026004819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b03161415611ce5576040805162461bcd60e51b81526020600482015260116024820152701cddd85c0e881d5b9cdd5c1c1bdc9d1959607a1b604482015290519081900360640190fd5b6000611cf186866110ca565b905083811015611d3b576040805162461bcd60e51b815260206004820152601060248201526f39bbb0b81d103637bb903932ba3ab93760811b604482015290519081900360640190fd5b611d766001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308963ffffffff612fd516565b6000611d8887610a9389600954612f00565b90508015611dea57611dea6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000008363ffffffff612eae16565b611e046001600160a01b038716858463ffffffff612eae16565b604080518881526001600160a01b0388166020820152808201849052426060820152905133917fdc1d56f2d3b21db336b15d1c62c7d5f5c70b66b7a6630a1aebbb6ee05fa733b9919081900360800190a250600160045595945050505050565b60016000805b600554811015611f6857600060058281548110611e8357fe5b6000918252602080832090910154604080516370a0823160e01b815230600482015290516001600160a01b03909216945084926370a0823192602480840193829003018186803b158015611ed657600080fd5b505afa158015611eea573d6000803e3d6000fd5b505050506040513d6020811015611f0057600080fd5b505190508015611f5e576000611f1583611710565b905080611f285760009550505050611f68565b611f5a670de0b6b3a7640000611f44848463ffffffff612d4516565b81611f4b57fe5b8791900463ffffffff612ceb16565b9450505b5050600101611e6a565b509091565b611f75611635565b611fb4576040805162461bcd60e51b815260206004820181905260248201526000805160206134ee833981519152604482015290519081900360640190fd5b6000826001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b158015611fef57600080fd5b505afa158015612003573d6000803e3d6000fd5b505050506040513d602081101561201957600080fd5b505190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811690821614156120895760405162461bcd60e51b81526004018080602001828103825260288152602001806134c66028913960400191505060405180910390fd5b6001600160a01b0382166120e4576040805162461bcd60e51b815260206004820152601b60248201527f616464436f6c6c61746572616c3a20696e76616c696420666565640000000000604482015290519081900360640190fd5b6001600160a01b03831660009081526008602052604090205460ff1615612152576040805162461bcd60e51b815260206004820181905260248201527f616464436f6c6c61746572616c3a20636f6c6c61746572616c206c6973746564604482015290519081900360640190fd5b6001600160a01b0381811660009081526006602052604090205416156121a95760405162461bcd60e51b81526004018080602001828103825260278152602001806135516027913960400191505060405180910390fd5b60058054600181019091557f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b038084166001600160a01b0319928316811790935560008381526006602090815260409182902080549388169390941692909217909255815163313ce56760e01b8152915163313ce567926004808201939291829003018186803b15801561224657600080fd5b505afa15801561225a573d6000803e3d6000fd5b505050506040513d602081101561227057600080fd5b50516001600160a01b03918216600090815260076020908152604080832060ff909416909355949092168252600890935291909120805460ff1916600117905550565b6122bb611635565b6122fa576040805162461bcd60e51b815260206004820181905260248201526000805160206134ee833981519152604482015290519081900360640190fd5b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561233557600080fd5b505afa158015612349573d6000803e3d6000fd5b505050506040513d602081101561235f57600080fd5b5051905060005b60055481101561247957816001600160a01b03166005828154811061238757fe5b6000918252602090912001546001600160a01b03161415612471576005805460001981019081106123b457fe5b600091825260209091200154600580546001600160a01b0390921691839081106123da57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600580548061241357fe5b60008281526020808220830160001990810180546001600160a01b031990811690915593019093556001600160a01b03858116825260068452604080832080549094169093558616815260089092529020805460ff19169055612479565b600101612366565b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600260209081526000928352604080842090915290825290205481565b60095481565b6000831580156124d3575082155b156124e057506000610cd0565b60006124f2858563ffffffff612ceb16565b905060005b60ff81101561263a57816125176001610a3f89600263ffffffff612d4516565b612527828563ffffffff612d4516565b8161252e57fe5b0490506125476001610a3f88600263ffffffff612d4516565b612557828563ffffffff612d4516565b8161255e57fe5b0490508260006125a0826109bf61257c86600263ffffffff612d4516565b610a3f61258f8e8e63ffffffff612ceb16565b6109bf8d600263ffffffff612d4516565b905060006125be866109bf6001610a938c600263ffffffff612d4516565b90506125e16125d485600363ffffffff612d4516565b829063ffffffff612ceb16565b82816125e957fe5b0495506125fd83600163ffffffff612ceb16565b861115801561261c575061261886600163ffffffff612ceb16565b8311155b1561262a575050505061263a565b5050600190920191506124f79050565b50949350505050565b60076020526000908152604090205481565b61265d611635565b61269c576040805162461bcd60e51b815260206004820181905260248201526000805160206134ee833981519152604482015290519081900360640190fd5b6001600160a01b0381166126e15760405162461bcd60e51b81526004018080602001828103825260268152602001806134566026913960400191505060405180910390fd5b6126ea816130c2565b50565b600b5481565b60006002600454141561273b576040805162461bcd60e51b815260206004820152601f6024820152600080516020613436833981519152604482015290519081900360640190fd5b60026004556001600160a01b03821660009081526008602052604090205460ff168061279857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316145b6127d35760405162461bcd60e51b815260040180806020018281038252602381526020018061350e6023913960400191505060405180910390fd5b6000826001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561280e57600080fd5b505afa158015612822573d6000803e3d6000fd5b505050506040513d602081101561283857600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561288657600080fd5b505afa15801561289a573d6000803e3d6000fd5b505050506040513d60208110156128b057600080fd5b505160408051637af1e23160e11b81526001600160a01b03898116600483015260248201899052878116604483015291519293507f00000000000000000000000000000000000000000000000000000000000000009091169163f5e3c462916064808201926020929091908290030181600087803b15801561293157600080fd5b505af1158015612945573d6000803e3d6000fd5b505050506040513d602081101561295b57600080fd5b5051156129995760405162461bcd60e51b81526004018080602001828103825260238152602001806135786023913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516001600160a01b0386169163db006a759183916370a08231916024808301926020929190829003018186803b1580156129e757600080fd5b505afa1580156129fb573d6000803e3d6000fd5b505050506040513d6020811015612a1157600080fd5b5051604080516001600160e01b031960e085901b16815260048101929092525160248083019260209291908290030181600087803b158015612a5257600080fd5b505af1158015612a66573d6000803e3d6000fd5b505050506040513d6020811015612a7c57600080fd5b505115612aba5760405162461bcd60e51b815260040180806020018281038252602981526020018061347c6029913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516000916001600160a01b038516916370a0823191602480820192602092909190829003018186803b158015612b0457600080fd5b505afa158015612b18573d6000803e3d6000fd5b505050506040513d6020811015612b2e57600080fd5b505190506000612b44828463ffffffff612d9e16565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b03161415612b835750855b6000612b9582610a9384600a54612f00565b90508015612bb757612bb76001600160a01b038616338363ffffffff612eae16565b50506001600455509195945050505050565b801580612c4f575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015612c2157600080fd5b505afa158015612c35573d6000803e3d6000fd5b505050506040513d6020811015612c4b57600080fd5b5051155b612c8a5760405162461bcd60e51b81526004018080602001828103825260368152602001806135c56036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612479908490613114565b6060610b1184846000856131c5565b600082820183811015610cd0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082612d5457506000610b9b565b82820282848281612d6157fe5b0414610cd05760405162461bcd60e51b81526004018080602001828103825260218152602001806134a56021913960400191505060405180910390fd5b6000610cd083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613370565b6000610cd083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506133ca565b6001600160a01b038216600090815260016020526040902054612e4b908263ffffffff612d9e16565b6001600160a01b03831660009081526001602052604081209190915554612e78908263ffffffff612d9e16565b60009081556040805183815290516001600160a01b03851691600080516020613531833981519152919081900360200190a35050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612479908490613114565b6000612710821315612f59576040805162461bcd60e51b815260206004820152601a60248201527f7265647563654270733a206270732065786365656473206d6178000000000000604482015290519081900360640190fd5b61270f19821215612fb1576040805162461bcd60e51b815260206004820152601a60248201527f7265647563654270733a206270732065786365656473206d696e000000000000604482015290519081900360640190fd5b612710612fc68484830163ffffffff612d4516565b81612fcd57fe5b049392505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261302f908590613114565b50505050565b6001600160a01b03821660009081526001602052604090205461305e908263ffffffff612ceb16565b6001600160a01b0383166000908152600160205260408120919091555461308b908263ffffffff612ceb16565b60009081556040805183815290516001600160a01b0385169291600080516020613531833981519152919081900360200190a35050565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6060613169826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612cdc9092919063ffffffff16565b8051909150156124795780806020019051602081101561318857600080fd5b50516124795760405162461bcd60e51b815260040180806020018281038252602a81526020018061359b602a913960400191505060405180910390fd5b60606131d08561342f565b613221576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106132605780518252601f199092019160209182019101613241565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146132c2576040519150601f19603f3d011682016040523d82523d6000602084013e6132c7565b606091505b509150915081156132db579150610b119050565b8051156132eb5780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561333557818101518382015260200161331d565b50505050905090810190601f1680156133625780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b600081848411156133c25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561333557818101518382015260200161331d565b505050900390565b600081836134195760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561333557818101518382015260200161331d565b50600083858161342557fe5b0495945050505050565b3b15159056fe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573736c6971756964617465426f72726f773a20636f6c6c61746572616c2072656465656d206661696c6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77616464436f6c6c61746572616c3a204c5553442063616e6e6f7420626520636f6c6c61746572616c4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726c6971756964617465426f72726f773a20696e76616c696420636f6c6c61746572616cddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef616464436f6c6c61746572616c3a20756e6465726c79696e6720616c72656164792061646465646c6971756964617465426f72726f773a206c69717569646174696f6e206661696c65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a26469706673582212206590f3a0fe0d286e91fd7e2e7b9c63c88e70564e9a5e19d06948d6bcf4e4638e64736f6c634300060b00335361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b75000000000000000000000000243e33aa7f6787154a8e59d3c27a66db3f8818ee00000000000000000000000000000000000000000000000000000000000001900000000000000000000000008f95c99d8f2d03729c1300e59fc38299d831a7f7

Deployed Bytecode

0x6080604052600436106102555760003560e01c8063aaf5eb6811610139578063c6783af1116100b6578063e29e4fbc1161007a578063e29e4fbc146108a4578063f1ae3c7f146108da578063f2fde38b1461090d578063f446c1d014610940578063f5e3c46214610955578063f6a23320146107435761025c565b8063c6783af1146107d1578063c99d3a061461080c578063cf59d5631461083f578063dd62ed3e14610854578063ddca3f431461088f5761025c565b8063b8b89e1b116100fd578063b8b89e1b14610719578063bb9956841461072e578063bc063e1a14610743578063bfd4799614610758578063c047e563146107a15761025c565b8063aaf5eb681461065f578063ace1798e14610674578063ae2e933b146106a7578063b4fb1279146106bc578063b6b55f25146106ef5761025c565b80634bb4695d116101d257806385ad3f811161019657806385ad3f81146105715780638c0b09d0146105b45780638da5cb5b146105e75780638f32d59b146105fc57806395d89b4114610611578063a9059cbb146106265761025c565b80634bb4695d146104a5578063571a0ccf146104ba5780635a0ce676146104f35780636e9fe6701461052957806370a082311461053e5761025c565b806324c1173b1161021957806324c1173b146103de5780632e1a7d4d14610424578063313ce5671461045057806334d441d01461047b57806339698415146104905761025c565b8063068d59111461026157806306fdde03146102af578063095ea7b31461033957806318160ddd1461038657806323b872dd1461039b5761025c565b3661025c57005b600080fd5b34801561026d57600080fd5b5061029d6004803603608081101561028457600080fd5b5080359060208101359060408101359060600135610998565b60408051918252519081900360200190f35b3480156102bb57600080fd5b506102c4610b19565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102fe5781810151838201526020016102e6565b50505050905090810190601f16801561032b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561034557600080fd5b506103726004803603604081101561035c57600080fd5b506001600160a01b038135169060200135610b3a565b604080519115158252519081900360200190f35b34801561039257600080fd5b5061029d610ba1565b3480156103a757600080fd5b50610372600480360360608110156103be57600080fd5b506001600160a01b03813581169160208101359091169060400135610ba7565b3480156103ea57600080fd5b506104086004803603602081101561040157600080fd5b5035610cd7565b604080516001600160a01b039092168252519081900360200190f35b34801561043057600080fd5b5061044e6004803603602081101561044757600080fd5b5035610cfe565b005b34801561045c57600080fd5b50610465611096565b6040805160ff9092168252519081900360200190f35b34801561048757600080fd5b5061029d61109b565b34801561049c57600080fd5b5061029d6110a1565b3480156104b157600080fd5b506104086110a6565b3480156104c657600080fd5b5061029d600480360360408110156104dd57600080fd5b50803590602001356001600160a01b03166110ca565b3480156104ff57600080fd5b5061044e6004803603606081101561051657600080fd5b50803590602081013590604001356112ef565b34801561053557600080fd5b5061029d6114d2565b34801561054a57600080fd5b5061029d6004803603602081101561056157600080fd5b50356001600160a01b03166114d7565b34801561057d57600080fd5b506103726004803603606081101561059457600080fd5b506001600160a01b038135811691602081013590911690604001356114e9565b3480156105c057600080fd5b50610372600480360360208110156105d757600080fd5b50356001600160a01b0316611611565b3480156105f357600080fd5b50610408611626565b34801561060857600080fd5b50610372611635565b34801561061d57600080fd5b506102c4611646565b34801561063257600080fd5b506103726004803603604081101561064957600080fd5b506001600160a01b038135169060200135611666565b34801561066b57600080fd5b5061029d611704565b34801561068057600080fd5b5061029d6004803603602081101561069757600080fd5b50356001600160a01b0316611710565b3480156106b357600080fd5b50610408611907565b3480156106c857600080fd5b50610408600480360360208110156106df57600080fd5b50356001600160a01b031661192b565b3480156106fb57600080fd5b5061044e6004803603602081101561071257600080fd5b5035611946565b34801561072557600080fd5b5061029d611bcd565b34801561073a57600080fd5b5061029d611bf1565b34801561074f57600080fd5b5061029d611c15565b34801561076457600080fd5b5061029d6004803603608081101561077b57600080fd5b508035906001600160a01b03602082013581169160408101359160609091013516611c1a565b3480156107ad57600080fd5b506107b6611e64565b60408051921515835260208301919091528051918290030190f35b3480156107dd57600080fd5b5061044e600480360360408110156107f457600080fd5b506001600160a01b0381358116916020013516611f6d565b34801561081857600080fd5b5061044e6004803603602081101561082f57600080fd5b50356001600160a01b03166122b3565b34801561084b57600080fd5b5061040861247e565b34801561086057600080fd5b5061029d6004803603604081101561087757600080fd5b506001600160a01b03813581169160200135166124a2565b34801561089b57600080fd5b5061029d6124bf565b3480156108b057600080fd5b5061029d600480360360608110156108c757600080fd5b50803590602081013590604001356124c5565b3480156108e657600080fd5b5061029d600480360360208110156108fd57600080fd5b50356001600160a01b0316612643565b34801561091957600080fd5b5061044e6004803603602081101561093057600080fd5b50356001600160a01b0316612655565b34801561094c57600080fd5b5061029d6126ed565b34801561096157600080fd5b5061029d6004803603606081101561097857600080fd5b506001600160a01b038135811691602081013591604090910135166126f3565b6000806109a68585856124c5565b905060006109cb60026109bf898963ffffffff612ceb16565b9063ffffffff612d4516565b6109db838063ffffffff612d4516565b816109e257fe5b0490506109f684600463ffffffff612d4516565b610a06828463ffffffff612d4516565b81610a0d57fe5b0490506000610a4b610a2686600263ffffffff612d4516565b8481610a2e57fe5b04610a3f8a8a63ffffffff612ceb16565b9063ffffffff612ceb16565b9050600083815b60ff811015610af35790915081906000610a7686610a3f858063ffffffff612d4516565b90506000610a9f88610a9388610a3f88600263ffffffff612d4516565b9063ffffffff612d9e16565b9050808281610aaa57fe5b049350610abe85600163ffffffff612ceb16565b8411158015610add5750610ad984600163ffffffff612ceb16565b8511155b15610ae9575050610af3565b5050600101610a52565b50610b096001610a938a8463ffffffff612d9e16565b955050505050505b949350505050565b60405180604001604052806005815260200164422e414d4d60d81b81525081565b3360008181526002602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60005481565b6001600160a01b038316600090815260016020526040812054610bd0908363ffffffff612d9e16565b6001600160a01b038516600090815260016020908152604080832093909355600281528282203383529052205460001914610c5e576001600160a01b0384166000908152600260209081526040808320338452909152902054610c39908363ffffffff612d9e16565b6001600160a01b03851660009081526002602090815260408083203384529091529020555b6001600160a01b038316600090815260016020526040902054610c87908363ffffffff612ceb16565b6001600160a01b03808516600081815260016020908152604091829020949094558051868152905191939288169260008051602061353183398151915292918290030190a35060015b9392505050565b60058181548110610ce457fe5b6000918252602090912001546001600160a01b0316905081565b60026004541415610d44576040805162461bcd60e51b815260206004820152601f6024820152600080516020613436833981519152604482015290519081900360640190fd5b6002600490815560008054604080516370a0823160e01b815230948101949094525190926001600160a01b037f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b7516916370a0823191602480820192602092909190829003018186803b158015610db957600080fd5b505afa158015610dcd573d6000803e3d6000fd5b505050506040513d6020811015610de357600080fd5b505190506000610e0983610dfd848763ffffffff612d4516565b9063ffffffff612de016565b60055490915060609067ffffffffffffffff81118015610e2857600080fd5b50604051908082528060200260200182016040528015610e52578160200160208202803683370190505b50905060606005805480602002602001604051908101604052809291908181526020018280548015610ead57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e8f575b50939450600093505050505b8151811015610f8f576000828281518110610ed057fe5b60200260200101516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610f2d57600080fd5b505afa158015610f41573d6000803e3d6000fd5b505050506040513d6020811015610f5757600080fd5b50519050610f6f87610dfd838b63ffffffff612d4516565b848381518110610f7b57fe5b602090810291909101015250600101610eb9565b50610f9a3387612e22565b8215610fda57610fda6001600160a01b037f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b7516338563ffffffff612eae16565b60005b815181101561104e576000838281518110610ff457fe5b60200260200101511115611046576110463384838151811061101257fe5b602002602001015184848151811061102657fe5b60200260200101516001600160a01b0316612eae9092919063ffffffff16565b600101610fdd565b506040805184815260208101889052815133927fd2263e970e3552b8e14c013f4d6af030894ef3ae6f025607042368db047a4418928290030190a25050600160045550505050565b601281565b600a5481565b60c881565b7f000000000000000000000000243e33aa7f6787154a8e59d3c27a66db3f8818ee81565b604080516370a0823160e01b8152306004820152905160009182916001600160a01b037f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b7516916370a08231916024808301926020929190829003018186803b15801561113557600080fd5b505afa158015611149573d6000803e3d6000fd5b505050506040513d602081101561115f57600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038616916370a08231916024808301926020929190829003018186803b1580156111ad57600080fd5b505afa1580156111c1573d6000803e3d6000fd5b505050506040513d60208110156111d757600080fd5b505190506000806111e6611e64565b91509150816111fc576000945050505050610b9b565b600061120787611710565b90508061121c57600095505050505050610b9b565b60006112688261123a8b670de0b6b3a764000063ffffffff612d4516565b8161124157fe5b047f0000000000000000000000000000000000000000000000000000000000000190612f00565b90508886600061128f61128287600263ffffffff612d4516565b8a9063ffffffff612ceb16565b905060006112a1848484600b54610998565b90506000866112be83670de0b6b3a764000063ffffffff612d4516565b816112c557fe5b049050808a10156112d35750885b808610156112de5750845b9d9c50505050505050505050505050565b6112f7611635565b611336576040805162461bcd60e51b815260206004820181905260248201526000805160206134ee833981519152604482015290519081900360640190fd5b606482111561138c576040805162461bcd60e51b815260206004820152601960248201527f736574506172616d733a2066656520697320746f6f2062696700000000000000604482015290519081900360640190fd5b60648111156113e2576040805162461bcd60e51b815260206004820181905260248201527f736574506172616d733a2063616c6c65722066656520697320746f6f20626967604482015290519081900360640190fd5b6014831015611431576040805162461bcd60e51b81526020600482015260166024820152751cd95d14185c985b5cce8810481d1bdbc81cdb585b1b60521b604482015290519081900360640190fd5b60c883111561147e576040805162461bcd60e51b8152602060048201526014602482015273736574506172616d733a204120746f6f2062696760601b604482015290519081900360640190fd5b6009829055600a819055600b839055604080518481526020810184905280820183905290517fee5d147c6dd8b96e80762594bab87a5a80c4c7ec653bdb804933445386340b019181900360600190a1505050565b601481565b60016020526000908152604090205481565b60007f000000000000000000000000243e33aa7f6787154a8e59d3c27a66db3f8818ee6001600160a01b0316846001600160a01b03161461152c57506000610cd0565b6001600160a01b03831660009081526008602052604090205460ff161580156115675750836001600160a01b0316836001600160a01b031614155b1561157457506000610cd0565b604080516370a0823160e01b815230600482015290516001600160a01b037f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b7516916370a08231916024808301926020929190829003018186803b1580156115da57600080fd5b505afa1580156115ee573d6000803e3d6000fd5b505050506040513d602081101561160457600080fd5b5051909111159392505050565b60086020526000908152604090205460ff1681565b6003546001600160a01b031690565b6003546001600160a01b0316331490565b6040518060400160405280600481526020016342414d4d60e01b81525081565b33600090815260016020526040812054611686908363ffffffff612d9e16565b33600090815260016020526040808220929092556001600160a01b038516815220546116b8908363ffffffff612ceb16565b6001600160a01b0384166000818152600160209081526040918290209390935580518581529051919233926000805160206135318339815191529281900390910190a350600192915050565b670de0b6b3a764000081565b6001600160a01b038082166000908152600660205260408120549091168061173c576000915050611902565b6000806000836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561177a57600080fd5b505afa92505050801561179f57506040513d602081101561179a57600080fd5b505160015b6117b0576000945050505050611902565b60ff169250836001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156117ee57600080fd5b505afa92505050801561183057506040513d60a081101561180e57600080fd5b5080516020820151604083015160608401516080909401519293919290919060015b611841576000945050505050611902565b5091945090925050504281610e10011015611863576000945050505050611902565b6001600160a01b0386166000908152600760205260408120547f0000000000000000000000000000000000000000000000000000000000000006908501039081126118d957600a81900a6118c584670de0b6b3a764000063ffffffff612d4516565b816118cc57fe5b0495505050505050611902565b6000819003600a0a6118f984670de0b6b3a764000063ffffffff612d4516565b02955050505050505b919050565b7f0000000000000000000000008f95c99d8f2d03729c1300e59fc38299d831a7f781565b6006602052600090815260409020546001600160a01b031681565b6002600454141561198c576040805162461bcd60e51b815260206004820152601f6024820152600080516020613436833981519152604482015290519081900360640190fd5b600260048190555060007f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b756001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611a0c57600080fd5b505afa158015611a20573d6000803e3d6000fd5b505050506040513d6020811015611a3657600080fd5b50519050600080611a45611e64565b9150915081611a9b576040805162461bcd60e51b815260206004820152601a60248201527f6465706f7369743a20636861696e6c696e6b20697320646f776e000000000000604482015290519081900360640190fd5b6000611aad848363ffffffff612ceb16565b90506000811180611abe5750600054155b611b0f576040805162461bcd60e51b815260206004820152601760248201527f6465706f7369743a2073797374656d2069732072656b74000000000000000000604482015290519081900360640190fd5b600054670de0b6b3a76400009015611b41576000548290611b36908863ffffffff612d4516565b81611b3d57fe5b0490505b611b7c6001600160a01b037f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b751633308963ffffffff612fd516565b611b863382613035565b6040805187815260208101839052815133927f2f1a7fda57b5fd5cb62770aebd7fc9a8a0a834c5ff558eb7562f85f2b28c4375928290030190a25050600160045550505050565b7f000000000000000000000000000000000000000000000000000000000000019081565b7f000000000000000000000000000000000000000000000000000000000000000681565b606481565b600060026004541415611c62576040805162461bcd60e51b815260206004820152601f6024820152600080516020613436833981519152604482015290519081900360640190fd5b60026004819055507f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b756001600160a01b0316846001600160a01b03161415611ce5576040805162461bcd60e51b81526020600482015260116024820152701cddd85c0e881d5b9cdd5c1c1bdc9d1959607a1b604482015290519081900360640190fd5b6000611cf186866110ca565b905083811015611d3b576040805162461bcd60e51b815260206004820152601060248201526f39bbb0b81d103637bb903932ba3ab93760811b604482015290519081900360640190fd5b611d766001600160a01b037f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b751633308963ffffffff612fd516565b6000611d8887610a9389600954612f00565b90508015611dea57611dea6001600160a01b037f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b75167f0000000000000000000000008f95c99d8f2d03729c1300e59fc38299d831a7f78363ffffffff612eae16565b611e046001600160a01b038716858463ffffffff612eae16565b604080518881526001600160a01b0388166020820152808201849052426060820152905133917fdc1d56f2d3b21db336b15d1c62c7d5f5c70b66b7a6630a1aebbb6ee05fa733b9919081900360800190a250600160045595945050505050565b60016000805b600554811015611f6857600060058281548110611e8357fe5b6000918252602080832090910154604080516370a0823160e01b815230600482015290516001600160a01b03909216945084926370a0823192602480840193829003018186803b158015611ed657600080fd5b505afa158015611eea573d6000803e3d6000fd5b505050506040513d6020811015611f0057600080fd5b505190508015611f5e576000611f1583611710565b905080611f285760009550505050611f68565b611f5a670de0b6b3a7640000611f44848463ffffffff612d4516565b81611f4b57fe5b8791900463ffffffff612ceb16565b9450505b5050600101611e6a565b509091565b611f75611635565b611fb4576040805162461bcd60e51b815260206004820181905260248201526000805160206134ee833981519152604482015290519081900360640190fd5b6000826001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b158015611fef57600080fd5b505afa158015612003573d6000803e3d6000fd5b505050506040513d602081101561201957600080fd5b505190507f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b756001600160a01b0390811690821614156120895760405162461bcd60e51b81526004018080602001828103825260288152602001806134c66028913960400191505060405180910390fd5b6001600160a01b0382166120e4576040805162461bcd60e51b815260206004820152601b60248201527f616464436f6c6c61746572616c3a20696e76616c696420666565640000000000604482015290519081900360640190fd5b6001600160a01b03831660009081526008602052604090205460ff1615612152576040805162461bcd60e51b815260206004820181905260248201527f616464436f6c6c61746572616c3a20636f6c6c61746572616c206c6973746564604482015290519081900360640190fd5b6001600160a01b0381811660009081526006602052604090205416156121a95760405162461bcd60e51b81526004018080602001828103825260278152602001806135516027913960400191505060405180910390fd5b60058054600181019091557f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b038084166001600160a01b0319928316811790935560008381526006602090815260409182902080549388169390941692909217909255815163313ce56760e01b8152915163313ce567926004808201939291829003018186803b15801561224657600080fd5b505afa15801561225a573d6000803e3d6000fd5b505050506040513d602081101561227057600080fd5b50516001600160a01b03918216600090815260076020908152604080832060ff909416909355949092168252600890935291909120805460ff1916600117905550565b6122bb611635565b6122fa576040805162461bcd60e51b815260206004820181905260248201526000805160206134ee833981519152604482015290519081900360640190fd5b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561233557600080fd5b505afa158015612349573d6000803e3d6000fd5b505050506040513d602081101561235f57600080fd5b5051905060005b60055481101561247957816001600160a01b03166005828154811061238757fe5b6000918252602090912001546001600160a01b03161415612471576005805460001981019081106123b457fe5b600091825260209091200154600580546001600160a01b0390921691839081106123da57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600580548061241357fe5b60008281526020808220830160001990810180546001600160a01b031990811690915593019093556001600160a01b03858116825260068452604080832080549094169093558616815260089092529020805460ff19169055612479565b600101612366565b505050565b7f00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b7581565b600260209081526000928352604080842090915290825290205481565b60095481565b6000831580156124d3575082155b156124e057506000610cd0565b60006124f2858563ffffffff612ceb16565b905060005b60ff81101561263a57816125176001610a3f89600263ffffffff612d4516565b612527828563ffffffff612d4516565b8161252e57fe5b0490506125476001610a3f88600263ffffffff612d4516565b612557828563ffffffff612d4516565b8161255e57fe5b0490508260006125a0826109bf61257c86600263ffffffff612d4516565b610a3f61258f8e8e63ffffffff612ceb16565b6109bf8d600263ffffffff612d4516565b905060006125be866109bf6001610a938c600263ffffffff612d4516565b90506125e16125d485600363ffffffff612d4516565b829063ffffffff612ceb16565b82816125e957fe5b0495506125fd83600163ffffffff612ceb16565b861115801561261c575061261886600163ffffffff612ceb16565b8311155b1561262a575050505061263a565b5050600190920191506124f79050565b50949350505050565b60076020526000908152604090205481565b61265d611635565b61269c576040805162461bcd60e51b815260206004820181905260248201526000805160206134ee833981519152604482015290519081900360640190fd5b6001600160a01b0381166126e15760405162461bcd60e51b81526004018080602001828103825260268152602001806134566026913960400191505060405180910390fd5b6126ea816130c2565b50565b600b5481565b60006002600454141561273b576040805162461bcd60e51b815260206004820152601f6024820152600080516020613436833981519152604482015290519081900360640190fd5b60026004556001600160a01b03821660009081526008602052604090205460ff168061279857507f000000000000000000000000243e33aa7f6787154a8e59d3c27a66db3f8818ee6001600160a01b0316826001600160a01b0316145b6127d35760405162461bcd60e51b815260040180806020018281038252602381526020018061350e6023913960400191505060405180910390fd5b6000826001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561280e57600080fd5b505afa158015612822573d6000803e3d6000fd5b505050506040513d602081101561283857600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561288657600080fd5b505afa15801561289a573d6000803e3d6000fd5b505050506040513d60208110156128b057600080fd5b505160408051637af1e23160e11b81526001600160a01b03898116600483015260248201899052878116604483015291519293507f000000000000000000000000243e33aa7f6787154a8e59d3c27a66db3f8818ee9091169163f5e3c462916064808201926020929091908290030181600087803b15801561293157600080fd5b505af1158015612945573d6000803e3d6000fd5b505050506040513d602081101561295b57600080fd5b5051156129995760405162461bcd60e51b81526004018080602001828103825260238152602001806135786023913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516001600160a01b0386169163db006a759183916370a08231916024808301926020929190829003018186803b1580156129e757600080fd5b505afa1580156129fb573d6000803e3d6000fd5b505050506040513d6020811015612a1157600080fd5b5051604080516001600160e01b031960e085901b16815260048101929092525160248083019260209291908290030181600087803b158015612a5257600080fd5b505af1158015612a66573d6000803e3d6000fd5b505050506040513d6020811015612a7c57600080fd5b505115612aba5760405162461bcd60e51b815260040180806020018281038252602981526020018061347c6029913960400191505060405180910390fd5b604080516370a0823160e01b815230600482015290516000916001600160a01b038516916370a0823191602480820192602092909190829003018186803b158015612b0457600080fd5b505afa158015612b18573d6000803e3d6000fd5b505050506040513d6020811015612b2e57600080fd5b505190506000612b44828463ffffffff612d9e16565b90507f000000000000000000000000243e33aa7f6787154a8e59d3c27a66db3f8818ee6001600160a01b0316866001600160a01b03161415612b835750855b6000612b9582610a9384600a54612f00565b90508015612bb757612bb76001600160a01b038616338363ffffffff612eae16565b50506001600455509195945050505050565b801580612c4f575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015612c2157600080fd5b505afa158015612c35573d6000803e3d6000fd5b505050506040513d6020811015612c4b57600080fd5b5051155b612c8a5760405162461bcd60e51b81526004018080602001828103825260368152602001806135c56036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612479908490613114565b6060610b1184846000856131c5565b600082820183811015610cd0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082612d5457506000610b9b565b82820282848281612d6157fe5b0414610cd05760405162461bcd60e51b81526004018080602001828103825260218152602001806134a56021913960400191505060405180910390fd5b6000610cd083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613370565b6000610cd083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506133ca565b6001600160a01b038216600090815260016020526040902054612e4b908263ffffffff612d9e16565b6001600160a01b03831660009081526001602052604081209190915554612e78908263ffffffff612d9e16565b60009081556040805183815290516001600160a01b03851691600080516020613531833981519152919081900360200190a35050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612479908490613114565b6000612710821315612f59576040805162461bcd60e51b815260206004820152601a60248201527f7265647563654270733a206270732065786365656473206d6178000000000000604482015290519081900360640190fd5b61270f19821215612fb1576040805162461bcd60e51b815260206004820152601a60248201527f7265647563654270733a206270732065786365656473206d696e000000000000604482015290519081900360640190fd5b612710612fc68484830163ffffffff612d4516565b81612fcd57fe5b049392505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261302f908590613114565b50505050565b6001600160a01b03821660009081526001602052604090205461305e908263ffffffff612ceb16565b6001600160a01b0383166000908152600160205260408120919091555461308b908263ffffffff612ceb16565b60009081556040805183815290516001600160a01b0385169291600080516020613531833981519152919081900360200190a35050565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6060613169826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612cdc9092919063ffffffff16565b8051909150156124795780806020019051602081101561318857600080fd5b50516124795760405162461bcd60e51b815260040180806020018281038252602a81526020018061359b602a913960400191505060405180910390fd5b60606131d08561342f565b613221576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106132605780518252601f199092019160209182019101613241565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146132c2576040519150601f19603f3d011682016040523d82523d6000602084013e6132c7565b606091505b509150915081156132db579150610b119050565b8051156132eb5780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561333557818101518382015260200161331d565b50505050905090810190601f1680156133625780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b600081848411156133c25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561333557818101518382015260200161331d565b505050900390565b600081836134195760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561333557818101518382015260200161331d565b50600083858161342557fe5b0495945050505050565b3b15159056fe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573736c6971756964617465426f72726f773a20636f6c6c61746572616c2072656465656d206661696c6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77616464436f6c6c61746572616c3a204c5553442063616e6e6f7420626520636f6c6c61746572616c4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726c6971756964617465426f72726f773a20696e76616c696420636f6c6c61746572616cddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef616464436f6c6c61746572616c3a20756e6465726c79696e6720616c72656164792061646465646c6971756964617465426f72726f773a206c69717569646174696f6e206661696c65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a26469706673582212206590f3a0fe0d286e91fd7e2e7b9c63c88e70564e9a5e19d06948d6bcf4e4638e64736f6c634300060b0033

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

00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b75000000000000000000000000243e33aa7f6787154a8e59d3c27a66db3f8818ee00000000000000000000000000000000000000000000000000000000000001900000000000000000000000008f95c99d8f2d03729c1300e59fc38299d831a7f7

-----Decoded View---------------
Arg [0] : _LUSD (address): 0x04068DA6C83AFCFA0e13ba15A6696662335D5B75
Arg [1] : _cBorrow (address): 0x243E33aa7f6787154a8E59d3C27a66db3F8818ee
Arg [2] : _maxDiscount (uint256): 400
Arg [3] : _feePool (address): 0x8F95C99D8f2D03729C1300E59fc38299D831a7F7

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b75
Arg [1] : 000000000000000000000000243e33aa7f6787154a8e59d3c27a66db3f8818ee
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000190
Arg [3] : 0000000000000000000000008f95c99d8f2d03729c1300e59fc38299d831a7f7


Deployed Bytecode Sourcemap

41695:11563:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9377:672;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9377:672:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;5889:37;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7920:210;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;7920:210:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;6022:23;;;;;;;;;;;;;:::i;7293:430::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;7293:430:0;;;;;;;;;;;;;;;;;:::i;41916:27::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41916:27:0;;:::i;:::-;;;;-1:-1:-1;;;;;41916:27:0;;;;;;;;;;;;;;48653:1054;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48653:1054:0;;:::i;:::-;;5978:35;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;42388:25;;;;;;;;;;;;;:::i;42497:32::-;;;;;;;;;;;;;:::i;42159:::-;;;;;;;;;;;;;:::i;49969:1066::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49969:1066:0;;;;;;-1:-1:-1;;;;;49969:1066:0;;:::i;43476:473::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43476:473:0;;;;;;;;;;;;:::i;42459:31::-;;;;;;;;;;;;;:::i;6254:44::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6254:44:0;-1:-1:-1;;;;;6254:44:0;;:::i;51842:415::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;51842:415:0;;;;;;;;;;;;;;;;;:::i;42113:39::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42113:39:0;-1:-1:-1;;;;;42113:39:0;;:::i;11374:79::-;;;;;;;;;;;;;:::i;11740:92::-;;;;;;;;;;;;;:::i;5933:38::-;;;;;;;;;;;;;:::i;6531:271::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;6531:271:0;;;;;;;;:::i;42608:37::-;;;;;;;;;;;;;:::i;45254:1873::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45254:1873:0;-1:-1:-1;;;;;45254:1873:0;;:::i;42200:40::-;;;;;;;;;;;;;:::i;41984:65::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41984:65:0;-1:-1:-1;;;;;41984:65:0;;:::i;47728:917::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47728:917:0;;:::i;42542:33::-;;;;;;;;;;;;;:::i;41875:34::-;;;;;;;;;;;;;:::i;42247:::-;;;;;;;;;;;;;:::i;51079:718::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51079:718:0;;;-1:-1:-1;;;;;51079:718:0;;;;;;;;;;;;;;;;;;;:::i;47135:583::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;43957:776;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;43957:776:0;;;;;;;;;;:::i;44741:505::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44741:505:0;-1:-1:-1;;;;;44741:505:0;;:::i;41840:28::-;;;;;;;;;;;;;:::i;6387:65::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;6387:65:0;;;;;;;;;;:::i;42348:19::-;;;;;;;;;;;;;:::i;8731:638::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8731:638:0;;;;;;;;;;;;:::i;42056:50::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42056:50:0;-1:-1:-1;;;;;42056:50:0;;:::i;11840:192::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11840:192:0;-1:-1:-1;;;;;11840:192:0;;:::i;42434:18::-;;;;;;;;;;;;;:::i;52292:959::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;52292:959:0;;;;;;;;;;;;;;;;;:::i;9377:672::-;9465:4;9482:8;9493:39;9510:8;9520;9530:1;9493:16;:39::i;:::-;9482:50;-1:-1:-1;9545:6:0;9569:27;9594:1;9570:18;:4;9579:8;9570:18;:8;:18;:::i;:::-;9569:24;:27;:24;:27;:::i;:::-;9554:12;9562:3;;9554:12;:7;:12;:::i;:::-;:42;;;;;;;-1:-1:-1;9624:8:0;:1;9630;9624:8;:5;:8;:::i;:::-;9611:10;:1;9617:3;9611:10;:5;:10;:::i;:::-;:21;;;;;;;-1:-1:-1;9643:6:0;9652:40;9683:8;:1;9689;9683:8;:5;:8;:::i;:::-;9677:3;:14;;;;;;9653:18;:4;9662:8;9653:18;:8;:18;:::i;:::-;9652:24;:40;:24;:40;:::i;:::-;9643:49;-1:-1:-1;9703:10:0;9737:3;9703:10;9753:247;9774:3;9770:1;:7;9753:247;;;9808:1;;-1:-1:-1;9808:1:0;;9824:6;9833:17;9848:1;9834:8;9808:1;;9834:8;:5;:8;:::i;9833:17::-;9824:26;-1:-1:-1;9865:6:0;9874:24;9894:3;9874:15;9887:1;9874:8;:1;9880;9874:8;:5;:8;:::i;:15::-;:19;:24;:19;:24;:::i;:::-;9865:33;;9922:1;9918;:5;;;;;;;-1:-1:-1;9948:12:0;:5;9958:1;9948:12;:9;:12;:::i;:::-;9943:1;:17;;:38;;;;-1:-1:-1;9973:8:0;:1;9979;9973:8;:5;:8;:::i;:::-;9964:5;:17;;9943:38;9940:48;;;9983:5;;;;9940:48;-1:-1:-1;;9780:3:0;;9753:247;;;-1:-1:-1;10019:22:0;10039:1;10019:15;:8;10032:1;10019:15;:12;:15;:::i;:22::-;10012:29;;;;;;;9377:672;;;;;;;:::o;5889:37::-;;;;;;;;;;;;;;-1:-1:-1;;;5889:37:0;;;;:::o;7920:210::-;8018:10;7983:12;8008:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;8008:30:0;;;;;;;;;;;:39;;;8063:37;;;;;;;7983:12;;8008:30;;8018:10;;8063:37;;;;;;;;-1:-1:-1;8118:4:0;7920:210;;;;;:::o;6022:23::-;;;;:::o;7293:430::-;-1:-1:-1;;;;;7413:15:0;;7370:12;7413:15;;;:9;:15;;;;;;:27;;7433:6;7413:27;:19;:27;:::i;:::-;-1:-1:-1;;;;;7395:15:0;;;;;;:9;:15;;;;;;;;:45;;;;7454:9;:15;;;;;7470:10;7454:27;;;;;;-1:-1:-1;;7454:48:0;7451:149;;-1:-1:-1;;;;;7549:15:0;;;;;;:9;:15;;;;;;;;7565:10;7549:27;;;;;;;;:39;;7581:6;7549:39;:31;:39;:::i;:::-;-1:-1:-1;;;;;7519:15:0;;;;;;:9;:15;;;;;;;;7535:10;7519:27;;;;;;;:69;7451:149;-1:-1:-1;;;;;7626:13:0;;;;;;:9;:13;;;;;;:25;;7644:6;7626:25;:17;:25;:::i;:::-;-1:-1:-1;;;;;7610:13:0;;;;;;;:9;:13;;;;;;;;;:41;;;;7667:26;;;;;;;7610:13;;7667:26;;;;-1:-1:-1;;;;;;;;;;;7667:26:0;;;;;;;;-1:-1:-1;7711:4:0;7293:430;;;;;;:::o;41916:27::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41916:27:0;;-1:-1:-1;41916:27:0;:::o;48653:1054::-;15635:1;16241:7;;:19;;16233:63;;;;;-1:-1:-1;;;16233:63:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;16233:63:0;;;;;;;;;;;;;;;15635:1;16374:7;:18;;;48720:17:::1;48740:11:::0;;48802:29:::1;::::0;;-1:-1:-1;;;48802:29:0;;48825:4:::1;48802:29:::0;;::::1;::::0;;;;;48740:11;;-1:-1:-1;;;;;48802:4:0::1;:14;::::0;::::1;::::0;:29;;;;;::::1;::::0;;;;;;;;;:14;:29;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;48802:29:0;;-1:-1:-1;48842:15:0::1;48860:40;48887:12:::0;48860:22:::1;48802:29:::0;48872:9;48860:22:::1;:11;:22;:::i;:::-;:26:::0;:40:::1;:26;:40;:::i;:::-;48958:11;:18:::0;48842:58;;-1:-1:-1;48913:31:0::1;::::0;48947:30:::1;::::0;::::1;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;48947:30:0::1;;48913:64;;48988:31;49022:11;48988:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;48988:45:0::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;-1:-1:-1::0;48988:45:0;;-1:-1:-1;49050:6:0::1;::::0;-1:-1:-1;;;;49046:206:0::1;49067:15;:22;49063:1;:26;49046:206;;;49112:8;49123:15;49139:1;49123:18;;;;;;;;;;;;;;-1:-1:-1::0;;;;;49123:28:0::1;;49160:4;49123:43;;;;;;;;;;;;;-1:-1:-1::0;;;;;49123:43:0::1;-1:-1:-1::0;;;;;49123:43:0::1;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;49123:43:0;;-1:-1:-1;49204:36:0::1;49227:12:::0;49204:18:::1;49123:43:::0;49212:9;49204:18:::1;:7;:18;:::i;:36::-;49181:17;49199:1;49181:20;;;;;;;;;::::0;;::::1;::::0;;;;;:59;-1:-1:-1;49092:3:0::1;;49046:206;;;;49292:27;49297:10;49309:9;49292:4;:27::i;:::-;49382:14:::0;;49379:60:::1;;49398:41;-1:-1:-1::0;;;;;49398:4:0::1;:17;49416:10;49428::::0;49398:41:::1;:17;:41;:::i;:::-;49454:6;49450:173;49471:15;:22;49467:1;:26;49450:173;;;49542:1;49519:17;49537:1;49519:20;;;;;;;;;;;;;;:24;49516:95;;;49546:65;49578:10;49590:17;49608:1;49590:20;;;;;;;;;;;;;;49546:15;49562:1;49546:18;;;;;;;;;;;;;;-1:-1:-1::0;;;;;49546:31:0::1;;;:65;;;;;:::i;:::-;49496:3;;49450:173;;;-1:-1:-1::0;49640:47:0::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;49653:10:::1;::::0;49640:47:::1;::::0;;;;;;::::1;-1:-1:-1::0;;15591:1:0;16553:7;:22;-1:-1:-1;;;;48653:1054:0:o;5978:35::-;6011:2;5978:35;:::o;42388:25::-;;;;:::o;42497:32::-;42526:3;42497:32;:::o;42159:::-;;;:::o;49969:1066::-;50088:29;;;-1:-1:-1;;;50088:29:0;;50111:4;50088:29;;;;;;50040:16;;;;-1:-1:-1;;;;;50088:4:0;:14;;;;:29;;;;;;;;;;;;;;:14;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50088:29:0;50149:30;;;-1:-1:-1;;;50149:30:0;;50173:4;50149:30;;;;;;50088:29;;-1:-1:-1;50128:17:0;;-1:-1:-1;;;;;50149:15:0;;;;;:30;;;;;50088:29;;50149:30;;;;;;;:15;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50149:30:0;;-1:-1:-1;50193:9:0;;50228:20;:18;:20::i;:::-;50192:56;;;;50264:4;50259:19;;50277:1;50270:8;;;;;;;;50259:19;50312;50334:17;50345:5;50334:10;:17::i;:::-;50312:39;-1:-1:-1;50365:19:0;50362:32;;50393:1;50386:8;;;;;;;;;50362:32;50428:14;50445:65;50477:14;50452:22;:7;42641:4;50452:22;:11;:22;:::i;:::-;:39;;;;;;50497:11;50445:6;:65::i;:::-;50428:82;-1:-1:-1;50535:7:0;50569:11;50523:9;50607:39;50623:22;:15;50643:1;50623:22;:19;:22;:::i;:::-;50607:11;;:39;:15;:39;:::i;:::-;50591:55;;50667:14;50684:38;50694:4;50700:8;50710;50720:1;;50684:9;:38::i;:::-;50667:55;-1:-1:-1;50733:21:0;50784:14;50757:24;50667:55;42641:4;50757:24;:13;:24;:::i;:::-;:41;;;;;;50733:65;;50829:16;50814:12;:31;50811:67;;;-1:-1:-1;50866:12:0;50811:67;50938:16;50926:9;:28;50923:61;;;-1:-1:-1;50975:9:0;50923:61;51011:16;49969:1066;-1:-1:-1;;;;;;;;;;;;;49969:1066:0:o;43476:473::-;11586:9;:7;:9::i;:::-;11578:54;;;;;-1:-1:-1;;;11578:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;11578:54:0;;;;;;;;;;;;;;;42278:3:::1;43570:4;:15;;43562:53;;;::::0;;-1:-1:-1;;;43562:53:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;42332:3;43634:10;:28;;43626:73;;;::::0;;-1:-1:-1;;;43626:73:0;;::::1;;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;42488:2;43726;:11;;43718:46;;;::::0;;-1:-1:-1;;;43718:46:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;43718:46:0;;;;;;;;;;;;;::::1;;42526:3;43783:2;:11;;43775:44;;;::::0;;-1:-1:-1;;;43775:44:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;43775:44:0;;;;;;;;;;;;;::::1;;43832:3;:10:::0;;;43853:9:::1;:22:::0;;;43886:1:::1;:6:::0;;;43910:31:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;::::1;::::0;;;;;;;::::1;43476:473:::0;;;:::o;42459:31::-;42488:2;42459:31;:::o;6254:44::-;;;;;;;;;;;;;:::o;51842:415::-;52015:4;52058:7;-1:-1:-1;;;;;52040:25:0;:14;-1:-1:-1;;;;;52040:25:0;;52037:42;;-1:-1:-1;52074:5:0;52067:12;;52037:42;-1:-1:-1;;;;;52096:34:0;;;;;;:7;:34;;;;;;;;52094:36;52093:78;;;;;52156:14;-1:-1:-1;;;;;52136:34:0;:16;-1:-1:-1;;;;;52136:34:0;;;52093:78;52090:95;;;-1:-1:-1;52180:5:0;52173:12;;52090:95;52220:29;;;-1:-1:-1;;;52220:29:0;;52243:4;52220:29;;;;;;-1:-1:-1;;;;;52220:4:0;:14;;;;:29;;;;;;;;;;;;;;:14;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52220:29:0;52205:44;;;;;51842:415;-1:-1:-1;;;51842:415:0:o;42113:39::-;;;;;;;;;;;;;;;:::o;11374:79::-;11439:6;;-1:-1:-1;;;;;11439:6:0;11374:79;:::o;11740:92::-;11818:6;;-1:-1:-1;;;;;11818:6:0;11804:10;:20;;11740:92::o;5933:38::-;;;;;;;;;;;;;;-1:-1:-1;;;5933:38:0;;;;:::o;6531:271::-;6649:10;6590:12;6639:21;;;:9;:21;;;;;;:33;;6665:6;6639:33;:25;:33;:::i;:::-;6625:10;6615:21;;;;:9;:21;;;;;;:57;;;;-1:-1:-1;;;;;6699:13:0;;;;;;:25;;6717:6;6699:25;:17;:25;:::i;:::-;-1:-1:-1;;;;;6683:13:0;;;;;;:9;:13;;;;;;;;;:41;;;;6740:32;;;;;;;6683:13;;6749:10;;-1:-1:-1;;;;;;;;;;;6740:32:0;;;;;;;;;-1:-1:-1;6790:4:0;6531:271;;;;:::o;42608:37::-;42641:4;42608:37;:::o;45254:1873::-;-1:-1:-1;;;;;45365:32:0;;;45308:4;45365:32;;;:16;:32;;;;;;45308:4;;45365:32;45411:54;45408:67;;45474:1;45467:8;;;;;45408:67;45488:22;45521:26;45558:23;45655:15;-1:-1:-1;;;;;45655:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45655:26:0;;;45651:338;;45976:1;45969:8;;;;;;;;45651:338;45806:28;;;-1:-1:-1;46057:15:0;-1:-1:-1;;;;;46057:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46057:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;46053:589;;46629:1;46622:8;;;;;;;;46053:589;-1:-1:-1;46435:6:0;;-1:-1:-1;46478:9:0;;-1:-1:-1;;;46688:3:0;46657:18;46678:7;46657:28;:34;46654:47;;;46700:1;46693:8;;;;;;;;46654:47;-1:-1:-1;;;;;46784:34:0;;46731:26;46784:34;;;:18;:34;;;;;;46826:12;46764:54;;;46760:79;;46853:27;;46850:270;;46944:2;:34;;;46904:36;:21;42641:4;46904:36;:25;:36;:::i;:::-;:75;;;;;;46897:82;;;;;;;;;46850:270;47079:27;;;;47068:2;:39;47028:36;:21;42641:4;47028:36;:25;:36;:::i;:::-;:80;47021:87;;;;;;;45254:1873;;;;:::o;42200:40::-;;;:::o;41984:65::-;;;;;;;;;;;;-1:-1:-1;;;;;41984:65:0;;:::o;47728:917::-;15635:1;16241:7;;:19;;16233:63;;;;;-1:-1:-1;;;16233:63:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;16233:63:0;;;;;;;;;;;;;;;15635:1;16374:7;:18;;;;47828:14:::1;47845:4;-1:-1:-1::0;;;;;47845:14:0::1;;47868:4;47845:29;;;;;;;;;;;;;-1:-1:-1::0;;;;;47845:29:0::1;-1:-1:-1::0;;;;;47845:29:0::1;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;47845:29:0;;-1:-1:-1;47886:9:0::1;::::0;47914:20:::1;:18;:20::i;:::-;47885:49;;;;47955:4;47947:43;;;::::0;;-1:-1:-1;;;47947:43:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;48003:15;48021:23;:9:::0;48035:8;48021:23:::1;:13;:23;:::i;:::-;48003:41;;48237:1;48224:10;:14;:34;;;-1:-1:-1::0;48242:11:0::1;::::0;:16;48224:34:::1;48216:70;;;::::0;;-1:-1:-1;;;48216:70:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;48299:13;48338:11:::0;42641:4:::1;::::0;48338:15;48335:71:::1;;48366:11;::::0;48396:10;;48366:27:::1;::::0;48382:10;48366:27:::1;:15;:27;:::i;:::-;:40;;;;;;48355:51;;48335:71;48439:60;-1:-1:-1::0;;;;;48439:4:0::1;:21;48461:10;48481:4;48488:10:::0;48439:60:::1;:21;:60;:::i;:::-;48540:26;48545:10;48557:8;48540:4;:26::i;:::-;48584:45;::::0;;;;;::::1;::::0;::::1;::::0;;;;;48596:10:::1;::::0;48584:45:::1;::::0;;;;;;::::1;-1:-1:-1::0;;15591:1:0;16553:7;:22;-1:-1:-1;;;;47728:917:0:o;42542:33::-;;;:::o;41875:34::-;;;:::o;42247:::-;42278:3;42247:34;:::o;51079:718::-;51196:4;15635:1;16241:7;;:19;;16233:63;;;;;-1:-1:-1;;;16233:63:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;16233:63:0;;;;;;;;;;;;;;;15635:1;16374:7;:18;;;;51236:4:::1;-1:-1:-1::0;;;;;51221:19:0::1;:11;-1:-1:-1::0;;;;;51221:19:0::1;;;51213:49;;;::::0;;-1:-1:-1;;;51213:49:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;51213:49:0;;;;;;;;;;;;;::::1;;51275:17;51295:38;51309:10;51321:11;51295:13;:38::i;:::-;51275:58;;51370:9;51354:12;:25;;51346:54;;;::::0;;-1:-1:-1;;;51346:54:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;51346:54:0;;;;;;;;;;;;;::::1;;51413:60;-1:-1:-1::0;;;;;51413:4:0::1;:21;51435:10;51455:4;51462:10:::0;51413:60:::1;:21;:60;:::i;:::-;51486:14;51503:44;51536:10;51503:28;51510:10;51526:3;;51503:6;:28::i;:44::-;51486:61:::0;-1:-1:-1;51561:13:0;;51558:55:::1;;51576:37;-1:-1:-1::0;;;;;51576:4:0::1;:17;51594:7;51603:9:::0;51576:37:::1;:17;:37;:::i;:::-;51626:44;-1:-1:-1::0;;;;;51626:24:0;::::1;51651:4:::0;51657:12;51626:44:::1;:24;:44;:::i;:::-;51688:69;::::0;;;;;-1:-1:-1;;;;;51688:69:0;::::1;;::::0;::::1;::::0;;;;;;;51753:3:::1;51688:69:::0;;;;;;51702:10:::1;::::0;51688:69:::1;::::0;;;;;;;;::::1;-1:-1:-1::0;15591:1:0;16553:7;:22;51777:12;51079:718;-1:-1:-1;;;;;51079:718:0:o;47135:583::-;47246:4;47185:9;;47263:448;47284:11;:18;47280:22;;47263:448;;;47325:12;47340:11;47352:1;47340:14;;;;;;;;;;;;;;;;;;;;47380:30;;;-1:-1:-1;;;47380:30:0;;47404:4;47380:30;;;;;;-1:-1:-1;;;;;47340:14:0;;;;-1:-1:-1;47340:14:0;;47380:15;;:30;;;;;;;;;;47340:14;47380:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47380:30:0;;-1:-1:-1;47428:7:0;;47425:275;;47456:10;47469:17;47480:5;47469:10;:17::i;:::-;47456:30;-1:-1:-1;47508:10:0;47505:98;;47550:5;47543:12;;47578:5;;;;;47505:98;47631:37;42641:4;47641:14;:3;47649:5;47641:14;:7;:14;:::i;:::-;:26;;;;;47631:5;;47641:26;;47631:37;:9;:37;:::i;:::-;47623:45;;47425:275;;-1:-1:-1;;47305:3:0;;47263:448;;;;47135:583;;:::o;43957:776::-;11586:9;:7;:9::i;:::-;11578:54;;;;;-1:-1:-1;;;11578:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;11578:54:0;;;;;;;;;;;;;;;44054:12:::1;44069:6;-1:-1:-1::0;;;;;44069:17:0::1;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;44069:19:0;;-1:-1:-1;44142:4:0::1;-1:-1:-1::0;;;;;44133:13:0;;::::1;::::0;;::::1;;;44125:66;;;;-1:-1:-1::0;;;44125:66:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;44210:34:0;::::1;44202:74;;;::::0;;-1:-1:-1;;;44202:74:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;44297:24:0;::::1;;::::0;;;:7:::1;:24;::::0;;;;;::::1;;44295:26;44287:71;;;::::0;;-1:-1:-1;;;44287:71:0;;::::1;;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;44377:32:0;;::::1;44435:3;44377:32:::0;;;:16:::1;:32;::::0;;;;;::::1;:62:::0;44369:114:::1;;;;-1:-1:-1::0;;;44369:114:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44522:11;:23:::0;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;-1:-1:-1;;;;;44522:23:0;;::::1;-1:-1:-1::0;;;;;;44522:23:0;;::::1;::::0;::::1;::::0;;;-1:-1:-1;44556:32:0;;;:16:::1;44522:23;44556:32:::0;;;;;;;;:39;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;44643:32;;-1:-1:-1;;;44643:32:0;;;;:30:::1;::::0;:32:::1;::::0;;::::1;::::0;44522:23;44643:32;;;;;;44522:23;44643:32;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;44643:32:0;-1:-1:-1;;;;;44606:34:0;;::::1;;::::0;;;:18:::1;44643:32;44606:34:::0;;;;;;;:69:::1;::::0;;::::1;::::0;;;44686:24;;;::::1;::::0;;:7:::1;:24:::0;;;;;;;:31;;-1:-1:-1;;44686:31:0::1;44713:4;44686:31;::::0;;-1:-1:-1;43957:776:0:o;44741:505::-;11586:9;:7;:9::i;:::-;11578:54;;;;;-1:-1:-1;;;11578:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;11578:54:0;;;;;;;;;;;;;;;44813:12:::1;44828:6;-1:-1:-1::0;;;;;44828:17:0::1;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;44828:19:0;;-1:-1:-1;44864:6:0::1;44860:379;44881:11;:18:::0;44877:22;::::1;44860:379;;;44943:5;-1:-1:-1::0;;;;;44925:23:0::1;:11;44937:1;44925:14;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;44925:14:0::1;:23;44922:306;;;44986:11;44998:18:::0;;-1:-1:-1;;44998:22:0;;;44986:35;::::1;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;44969:11:::1;:14:::0;;-1:-1:-1;;;;;44986:35:0;;::::1;::::0;44981:1;;44969:14;::::1;;;;;;;;;;;;;:52;;;;;-1:-1:-1::0;;;;;44969:52:0::1;;;;;-1:-1:-1::0;;;;;44969:52:0::1;;;;;;45040:11;:17;;;;;;;;::::0;;;::::1;::::0;;;;;-1:-1:-1;;45040:17:0;;;;;-1:-1:-1;;;;;;45040:17:0;;::::1;::::0;;;;;;;;-1:-1:-1;;;;;45076:32:0;;::::1;::::0;;:16:::1;:32:::0;;;;;;:61;;;;::::1;::::0;;;45156:24;::::1;::::0;;:7:::1;:24:::0;;;;;:32;;-1:-1:-1;;45156:32:0::1;::::0;;45207:5:::1;;44922:306;44902:3;;44860:379;;;;11643:1;44741:505:::0;:::o;41840:28::-;;;:::o;6387:65::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;42348:19::-;;;;:::o;8731:638::-;8801:4;8821:6;;:16;;;;-1:-1:-1;8831:6:0;;8821:16;8818:29;;;-1:-1:-1;8846:1:0;8839:8;;8818:29;8860:8;8871;:1;8877;8871:8;:5;:8;:::i;:::-;8860:19;-1:-1:-1;8896:6:0;8892:447;8913:3;8909:1;:7;8892:447;;;8949:3;8986:17;9001:1;8987:8;:1;8993;8987:8;:5;:8;:::i;8986:17::-;8972:11;:2;8979:3;8972:11;:6;:11;:::i;:::-;:31;;;;;;;-1:-1:-1;9037:17:0;9052:1;9038:8;:1;9044;9038:8;:5;:8;:::i;9037:17::-;9023:11;:2;9030:3;9023:11;:6;:11;:::i;:::-;:31;;;;;;;-1:-1:-1;9086:3:0;9071:12;9115:48;9086:3;9116:37;9143:9;9023:31;9150:1;9143:9;:6;:9;:::i;:::-;9116:22;9129:8;:1;9135;9129:8;:5;:8;:::i;:::-;9116;:1;9122;9116:8;:5;:8;:::i;9115:48::-;9106:57;-1:-1:-1;9178:6:0;9188:24;9208:3;9188:15;9201:1;9188:8;:1;9194;9188:8;:5;:8;:::i;:24::-;9178:35;-1:-1:-1;9238:16:0;9244:9;:2;9251:1;9244:9;:6;:9;:::i;:::-;9238:1;;:16;:5;:16;:::i;:::-;9234:1;:20;;;;;;;-1:-1:-1;9281:14:0;:7;9293:1;9281:14;:11;:14;:::i;:::-;9274:3;:21;;:46;;;;-1:-1:-1;9310:10:0;:3;9318:1;9310:10;:7;:10;:::i;:::-;9299:7;:21;;9274:46;9271:56;;;9322:5;;;;;;9271:56;-1:-1:-1;;8919:3:0;;;;;-1:-1:-1;8892:447:0;;-1:-1:-1;8892:447:0;;-1:-1:-1;9358:3:0;8731:638;-1:-1:-1;;;;8731:638:0:o;42056:50::-;;;;;;;;;;;;;:::o;11840:192::-;11586:9;:7;:9::i;:::-;11578:54;;;;;-1:-1:-1;;;11578:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;11578:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;11929:22:0;::::1;11921:73;;;;-1:-1:-1::0;;;11921:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12005:19;12015:8;12005:9;:19::i;:::-;11840:192:::0;:::o;42434:18::-;;;;:::o;52292:959::-;52399:4;15635:1;16241:7;;:19;;16233:63;;;;;-1:-1:-1;;;16233:63:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;16233:63:0;;;;;;;;;;;;;;;15635:1;16374:7;:18;-1:-1:-1;;;;;52424:28:0;::::1;;::::0;;;:7:::1;:28;::::0;;;;;::::1;;::::0;:53:::1;;;52470:7;-1:-1:-1::0;;;;;52456:21:0::1;:10;-1:-1:-1::0;;;;;52456:21:0::1;;52424:53;52416:101;;;;-1:-1:-1::0;;;52416:101:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52530:15;52555:10;-1:-1:-1::0;;;;;52555:21:0::1;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;52555:23:0;52614:33:::1;::::0;;-1:-1:-1;;;52614:33:0;;52641:4:::1;52614:33;::::0;::::1;::::0;;;52555:23;;-1:-1:-1;52592:19:0::1;::::0;-1:-1:-1;;;;;52614:18:0;::::1;::::0;::::1;::::0;:33;;;;;52555:23:::1;::::0;52614:33;;;;;;;:18;:33;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;52614:33:0;52666:62:::1;::::0;;-1:-1:-1;;;52666:62:0;;-1:-1:-1;;;;;52666:62:0;;::::1;;::::0;::::1;::::0;;;;;;;;;::::1;::::0;;;;;;52614:33;;-1:-1:-1;52666:7:0::1;:23:::0;;::::1;::::0;::::1;::::0;:62;;;;;52614:33:::1;::::0;52666:62;;;;;;;;-1:-1:-1;52666:23:0;:62;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;52666:62:0;:67;52658:115:::1;;;;-1:-1:-1::0;;;52658:115:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52810:35;::::0;;-1:-1:-1;;;52810:35:0;;52839:4:::1;52810:35;::::0;::::1;::::0;;;-1:-1:-1;;;;;52792:17:0;::::1;::::0;::::1;::::0;;;52810:20:::1;::::0;:35;;;;;::::1;::::0;;;;;;;;52792:17;52810:35;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;52810:35:0;52792:54:::1;::::0;;-1:-1:-1;;;;;;52792:54:0::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;52810:35:::1;::::0;52792:54;;;;;;;-1:-1:-1;52792:54:0;;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;52792:54:0;:59;52784:113:::1;;;;-1:-1:-1::0;;;52784:113:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52936:33;::::0;;-1:-1:-1;;;52936:33:0;;52963:4:::1;52936:33;::::0;::::1;::::0;;;52915:18:::1;::::0;-1:-1:-1;;;;;52936:18:0;::::1;::::0;::::1;::::0;:33;;;;;::::1;::::0;;;;;;;;;:18;:33;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;52936:33:0;;-1:-1:-1;52982:15:0::1;53000:33;52936::::0;53018:14;53000:33:::1;:17;:33;:::i;:::-;52982:51;;53061:7;-1:-1:-1::0;;;;;53047:21:0::1;:10;-1:-1:-1::0;;;;;53047:21:0::1;;53044:45;;;-1:-1:-1::0;53083:6:0;53044:45:::1;53102:14;53119:50;53158:10;53119:34;53126:10;53142:9;;53119:6;:34::i;:50::-;53102:67:::0;-1:-1:-1;53183:13:0;;53180:63:::1;;53199:44;-1:-1:-1::0;;;;;53199:21:0;::::1;53221:10;53233:9:::0;53199:44:::1;:21;:44;:::i;:::-;-1:-1:-1::0;;15591:1:0;16553:7;:22;-1:-1:-1;52292:959:0;;;-1:-1:-1;;;;;52292:959:0:o;26872:622::-;27242:10;;;27241:62;;-1:-1:-1;27258:39:0;;;-1:-1:-1;;;27258:39:0;;27282:4;27258:39;;;;-1:-1:-1;;;;;27258:39:0;;;;;;;;;:15;;;;;;:39;;;;;;;;;;;;;;;:15;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27258:39:0;:44;27241:62;27233:152;;;;-1:-1:-1;;;27233:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27423:62;;;-1:-1:-1;;;;;27423:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;27423:62:0;-1:-1:-1;;;27423:62:0;;;27396:90;;27416:5;;27396:19;:90::i;23186:196::-;23289:12;23321:53;23344:6;23352:4;23358:1;23361:12;23321:22;:53::i;1146:181::-;1204:7;1236:5;;;1260:6;;;;1252:46;;;;;-1:-1:-1;;;1252:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;2518:471;2576:7;2821:6;2817:47;;-1:-1:-1;2851:1:0;2844:8;;2817:47;2888:5;;;2892:1;2888;:5;:1;2912:5;;;;;:10;2904:56;;;;-1:-1:-1;;;2904:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1602:136;1660:7;1687:43;1691:1;1694;1687:43;;;;;;;;;;;;;;;;;:3;:43::i;3457:132::-;3515:7;3542:39;3546:1;3549;3542:39;;;;;;;;;;;;;;;;;:3;:39::i;8352:226::-;-1:-1:-1;;;;;8433:16:0;;;;;;:9;:16;;;;;;:28;;8454:6;8433:28;:20;:28;:::i;:::-;-1:-1:-1;;;;;8414:16:0;;;;;;:9;:16;;;;;:47;;;;8486:11;:23;;8502:6;8486:23;:15;:23;:::i;:::-;8472:11;:37;;;8527:35;;;;;;;;-1:-1:-1;;;;;8527:35:0;;;-1:-1:-1;;;;;;;;;;;8527:35:0;;;;;;;;;8352:226;;:::o;26213:177::-;26323:58;;;-1:-1:-1;;;;;26323:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26323:58:0;-1:-1:-1;;;26323:58:0;;;26296:86;;26316:5;;26296:19;:86::i;49715:246::-;49770:4;49802:5;49795:3;:12;;49787:51;;;;;-1:-1:-1;;;49787:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;49857:3:0;:13;;49849:52;;;;;-1:-1:-1;;;49849:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;49948:5;49921:24;:1;49932:11;;;49921:24;:5;:24;:::i;:::-;:32;;;;;;;49715:246;-1:-1:-1;;;49715:246:0:o;26398:205::-;26526:68;;;-1:-1:-1;;;;;26526:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26526:68:0;-1:-1:-1;;;26526:68:0;;;26499:96;;26519:5;;26499:19;:96::i;:::-;26398:205;;;;:::o;8138:206::-;-1:-1:-1;;;;;8213:13:0;;;;;;:9;:13;;;;;;:25;;8231:6;8213:25;:17;:25;:::i;:::-;-1:-1:-1;;;;;8197:13:0;;;;;;:9;:13;;;;;:41;;;;8263:11;:23;;8279:6;8263:23;:15;:23;:::i;:::-;8249:11;:37;;;8304:32;;;;;;;;-1:-1:-1;;;;;8304:32:0;;;8249:11;-1:-1:-1;;;;;;;;;;;8304:32:0;;;;;;;;;8138:206;;:::o;12040:173::-;12115:6;;;-1:-1:-1;;;;;12132:17:0;;;-1:-1:-1;;;;;;12132:17:0;;;;;;;12165:40;;12115:6;;;12132:17;12115:6;;12165:40;;12096:16;;12165:40;12040:173;;:::o;28518:761::-;28942:23;28968:69;28996:4;28968:69;;;;;;;;;;;;;;;;;28976:5;-1:-1:-1;;;;;28968:27:0;;;:69;;;;;:::i;:::-;29052:17;;28942:95;;-1:-1:-1;29052:21:0;29048:224;;29194:10;29183:30;;;;;;;;;;;;;;;-1:-1:-1;29183:30:0;29175:85;;;;-1:-1:-1;;;29175:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24563:979;24693:12;24726:18;24737:6;24726:10;:18::i;:::-;24718:60;;;;;-1:-1:-1;;;24718:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;24852:12;24866:23;24893:6;-1:-1:-1;;;;;24893:11:0;24913:8;24924:4;24893:36;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;24893:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24851:78;;;;24944:7;24940:595;;;24975:10;-1:-1:-1;24968:17:0;;-1:-1:-1;24968:17:0;24940:595;25089:17;;:21;25085:439;;25352:10;25346:17;25413:15;25400:10;25396:2;25392:19;25385:44;25300:148;25495:12;25488:20;;-1:-1:-1;;;25488:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2075:192;2161:7;2197:12;2189:6;;;;2181:29;;;;-1:-1:-1;;;2181:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2233:5:0;;;2075:192::o;4119:345::-;4205:7;4307:12;4300:5;4292:28;;;;-1:-1:-1;;;4292:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4331:9;4347:1;4343;:5;;;;;;;4119:345;-1:-1:-1;;;;;4119:345:0:o;20268:422::-;20635:20;20674:8;;;20268:422::o

Swarm Source

ipfs://6590f3a0fe0d286e91fd7e2e7b9c63c88e70564e9a5e19d06948d6bcf4e4638e
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.