F Tokens

fTokens are yield-generating tokens that are minted and burned upon deposit and withdraw. The fTokens' value is pegged to the value of the corresponding deposited asset at a 1:1 ratio, and can be safely stored, transferred or traded. All interest collected by the fTokens reserves are distributed to fTokens holders directly by continuously increasing their wallet balance.

For all minting and burning actions, see Deposit() and Withdraw() methods in the LendingPool contract.

EIP20 Methods

All standard EIP20 methods are implemented, such as balanceOf(), transfer(), transferFrom(), approve(), totalSupply(), etc.

balanceOf() will always return the most up to date balance of the user, which includes their principal balance + the interest generated by the principal balance.

EIP2612 Methods

permit()

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

Allows a user to permit another account (or contract) to use their funds using a signed message. This enables gas-less transactions and single approval/transfer transactions.

import { signTypedData_v4 } from 'eth-sig-util'
import { fromRpcSig } from 'ethereumjs-util'

// ... other imports

import fTokenAbi from "./fTokenAbi.json"

// ... setup your web3 provider

const fTokenAddress = "FTOKEN_ADDRESS"
const fTokenContract = new web3.eth.Contract(fTokenAbi, fTokenAddress)

const privateKey = "YOUR_PRIVATE_KEY_WITHOUT_0x"
const chainId = 1
const owner = "OWNER_ADDRESS"
const spender = "SPENDER_ADDRESS"
const value = 100 // Amount the spender is permitted
const nonce = 1 // The next valid nonce, use `_nonces()`
const deadline = 1600093162

const permitParams = {
  types: {
    EIP712Domain: [
      { name: "name", type: "string" },
      { name: "version", type: "string" },
      { name: "chainId", type: "uint256" },
      { name: "verifyingContract", type: "address" },
    ],
    Permit: [
      { name: "owner", type: "address" },
      { name: "spender", type: "address" },
      { name: "value", type: "uint256" },
      { name: "nonce", type: "uint256" },
      { name: "deadline", type: "uint256" },
    ],
  },
  primaryType: "Permit",
  domain: {
    name: "fTOKEN_NAME",
    version: "1",
    chainId: chainId,
    verifyingContract: fTokenAddress,
  },
  message: {
    owner,
    spender,
    value,
    nonce,
    deadline,
  },
}

const signature = signTypedData_v4(
  Buffer.from(privateKey, "hex"),
  { data: permitParams }
)

// The signature can now be used to execute the transaction

const { v, r, s } = fromRpcSig(signature)

await fTokenContract.methods
    .permit({
      owner,
      spender,
      value,
      deadline,
      v,
      r,
      s
    })
    .send()
    .catch((e) => {
        throw Error(`Error permitting: ${e.message}`)
    })

_nonces()

function _nonces(address owner) public

Returns the next valid nonce to submit when calling permit()

Methods

UNDERLYING_ASSET_ADDRESS()

function UNDERLYING_ASSET_ADDRESS()

Returns the underlying asset of the fToken.

RESERVE_TREASURY_ADDRESS()

function RESERVE_TREASURY_ADDRESS()

Returns the address of the fTokens reserve treasury.

POOL()

function POOL()

Returns the address of the associated LendingPool for the fToken.

scaledBalanceOf()

function scaledBalanceOf(address user)

Returns the scaled balance of user as a uint256.

The scaled balance is the balance of the underlying asset of the user (amount deposited), divided by the current liquidity index at the moment of the update.

This essentially 'marks' when a user has deposited in the reserve pool, and can be used to calculate the users current compounded fToken balance.

Example:

  • User A deposits 100 ETH at the liquidity index of 1.1

  • User B deposits another amount into the same pool

  • The liquidity index is now 1.2.

getScaledUserBalanceAndSupply()

function getScaledUserBalanceAndSupply(address user)

Returns the scaled balance of user and the principal total supply.

Return values

scaledTotalSupply()

function scaledTotalSupply()

Returns the scaled total supply of the fToken as uint256.

The scaled total supply is the sum of all the updated stored balances, divided by the reserve index at the moment of the update.

function isTransferAllowed(address user, uint256 amount)

Returns true if a transfer is allowed.

Specifically, a transfer will fail if the resulting Health Factor of user will end up being below 1.

FToken ABI
{
  "abi": [
    {
      "inputs": [],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "spender",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        }
      ],
      "name": "Approval",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "from",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "to",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "index",
          "type": "uint256"
        }
      ],
      "name": "BalanceTransfer",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "from",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "target",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "index",
          "type": "uint256"
        }
      ],
      "name": "Burn",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "creatorAddress",
          "type": "uint256"
        }
      ],
      "name": "CreatorAddressUpdated",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "creatorPercentage",
          "type": "uint256"
        }
      ],
      "name": "CreatorPecentageUpdated",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "underlyingCollateral",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "underlyingAsset",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "lendingPool",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "incentivesController",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "treasury",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "creator",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "creatorPercentage",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "auctionCallerPercentage",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "auctionCreatorPercentage",
          "type": "uint256"
        }
      ],
      "name": "Initialized",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "uint8",
          "name": "version",
          "type": "uint8"
        }
      ],
      "name": "Initialized",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "from",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "index",
          "type": "uint256"
        }
      ],
      "name": "Mint",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "from",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "to",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        }
      ],
      "name": "Transfer",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "POOL",
      "outputs": [
        {
          "internalType": "contract ILendingPool",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "RESERVE_TREASURY_ADDRESS",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "UNDERLYING_ASSET_ADDRESS",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "UNDERLYING_COLLATERAL_ADDRESS",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "UNDERLYING_MAX_TOKEN_ID",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "UNDERLYING_MIN_TOKEN_ID",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "spender",
          "type": "address"
        }
      ],
      "name": "allowance",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "spender",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "approve",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "user",
          "type": "address"
        }
      ],
      "name": "balanceOf",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "user",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "receiverOfUnderlying",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "index",
          "type": "uint256"
        }
      ],
      "name": "burn",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "decimals",
      "outputs": [
        {
          "internalType": "uint8",
          "name": "",
          "type": "uint8"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "spender",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "subtractedValue",
          "type": "uint256"
        }
      ],
      "name": "decreaseAllowance",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "exchangeRate",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "getAuctionCallerPercentage",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "getAuctionCreatorPercentage",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "getPoolIncentivesController",
      "outputs": [
        {
          "internalType": "contract IPoolIncentivesController",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "getReserveCreatorAddress",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "getReserveCreatorPercentage",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "getReserveNormalizationFactor",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "user",
          "type": "address"
        }
      ],
      "name": "getScaledUserBalanceAndSupply",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "spender",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "addedValue",
          "type": "uint256"
        }
      ],
      "name": "increaseAllowance",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IAddressProvider",
          "name": "addressProvider",
          "type": "address"
        },
        {
          "components": [
            {
              "internalType": "address",
              "name": "underlyingCollateral",
              "type": "address"
            },
            {
              "internalType": "string",
              "name": "underlyingCollateralName",
              "type": "string"
            },
            {
              "internalType": "string",
              "name": "underlyingCollateralSymbol",
              "type": "string"
            },
            {
              "internalType": "uint256",
              "name": "underlyingMaxTokenId",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "underlyingMinTokenId",
              "type": "uint256"
            },
            {
              "internalType": "address",
              "name": "underlyingAsset",
              "type": "address"
            },
            {
              "internalType": "string",
              "name": "underlyingAssetName",
              "type": "string"
            },
            {
              "internalType": "string",
              "name": "underlyingAssetSymbol",
              "type": "string"
            },
            {
              "internalType": "uint8",
              "name": "underlyingAssetDecimals",
              "type": "uint8"
            },
            {
              "internalType": "address",
              "name": "fTokenImpl",
              "type": "address"
            },
            {
              "internalType": "string",
              "name": "fTokenName",
              "type": "string"
            },
            {
              "internalType": "string",
              "name": "fTokenSymbol",
              "type": "string"
            },
            {
              "internalType": "address",
              "name": "stableDebtTokenImpl",
              "type": "address"
            },
            {
              "internalType": "string",
              "name": "stableDebtTokenName",
              "type": "string"
            },
            {
              "internalType": "string",
              "name": "stableDebtTokenSymbol",
              "type": "string"
            },
            {
              "internalType": "address",
              "name": "variableDebtTokenImpl",
              "type": "address"
            },
            {
              "internalType": "string",
              "name": "variableDebtTokenName",
              "type": "string"
            },
            {
              "internalType": "string",
              "name": "variableDebtTokenSymbol",
              "type": "string"
            },
            {
              "internalType": "address",
              "name": "interestRateStrategy",
              "type": "address"
            },
            {
              "internalType": "uint256",
              "name": "baseLTV",
              "type": "uint256"
            },
            {
              "internalType": "address",
              "name": "treasury",
              "type": "address"
            },
            {
              "internalType": "address",
              "name": "creator",
              "type": "address"
            },
            {
              "internalType": "uint256",
              "name": "creatorPercentage",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "auctionCallerPercentage",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "auctionCreatorPercentage",
              "type": "uint256"
            },
            {
              "internalType": "string",
              "name": "assetPriceFeed",
              "type": "string"
            }
          ],
          "internalType": "struct ConfigTypes.InitReserveInput",
          "name": "input",
          "type": "tuple"
        }
      ],
      "name": "initialize",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "user",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "index",
          "type": "uint256"
        }
      ],
      "name": "mint",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "user",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "caller",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "owner",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "liquidationFee",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "index",
          "type": "uint256"
        }
      ],
      "name": "mintAuctionPaymentToStakeholders",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "user",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "index",
          "type": "uint256"
        }
      ],
      "name": "mintStableDebtRepaymentToStakeholders",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "index",
          "type": "uint256"
        }
      ],
      "name": "mintVariableDebtRepaymentToStakeholders",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "name",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "user",
          "type": "address"
        }
      ],
      "name": "scaledBalanceOf",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "scaledTotalSupply",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "auctionCallerPercentage",
          "type": "uint256"
        }
      ],
      "name": "setAuctionCallerPercentage",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "auctionCreatorPercentage",
          "type": "uint256"
        }
      ],
      "name": "setAuctionCreatorPercentage",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "creator",
          "type": "address"
        }
      ],
      "name": "setReserveCreatorAddress",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "creatorPercentage",
          "type": "uint256"
        }
      ],
      "name": "setReserveCreatorPercentage",
      "outputs": [],
      "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": "amount",
          "type": "uint256"
        }
      ],
      "name": "transfer",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "from",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "to",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "transferFrom",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "target",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "transferUnderlyingTo",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "bytecode": {
    "object": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e4565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e2576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b612c6680620000f46000396000f3fe608060405234801561001057600080fd5b50600436106102325760003560e01c806357f1b83711610130578063acac18e4116100b8578063c35be0171161007c578063c35be01714610486578063d7020d0a1461048e578063dd62ed3e146104a1578063e8f7a1a5146104b4578063f9e2bf6b146104c757600080fd5b8063acac18e414610436578063ae16733514610449578063b16a19de1461045a578063b1bf962d1461046b578063bc1d19dd1461047357600080fd5b80637535d246116100ff5780637535d246146103ed5780637ccd3b46146103f557806395d89b4114610408578063a457c2d714610410578063a9059cbb1461042357600080fd5b806357f1b837146103a3578063679d0095146103b45780636b8465f8146103c757806370a08231146103da57600080fd5b80631da24f3e116101be57806336a722341161018257806336a722341461035c57806339509351146103645780633ba0b9a91461037757806347bec6f01461037f5780634efecaa51461039057600080fd5b80631da24f3e1461030657806323b872dd146103195780632d6aa1281461032c57806330c1e38b14610334578063313ce5671461034757600080fd5b806314ff75c91161020557806314ff75c9146102ae578063156e29f6146102b657806318160ddd146102c957806319ef9268146102d15780631d165564146102f157600080fd5b8063046016081461023757806306fdde031461024e578063095ea7b3146102635780630afbcdc914610286575b600080fd5b606a545b6040519081526020015b60405180910390f35b6102566104cf565b6040516102459190612654565b61027661027136600461269f565b610561565b6040519015158152602001610245565b6102996102943660046126cb565b61057b565b60408051928352602083019190915201610245565b606e5461023b565b6102766102c43660046126e8565b610593565b61023b610690565b6102d96107b3565b6040516001600160a01b039091168152602001610245565b6103046102ff36600461271d565b6107c2565b005b61023b6103143660046126cb565b610bcc565b610276610327366004612775565b610bd7565b606c5461023b565b6103046103423660046127b6565b610bfb565b60655460405160ff9091168152602001610245565b61023b610c68565b61027661037236600461269f565b610d66565b61023b610d88565b6066546001600160a01b03166102d9565b61023b61039e36600461269f565b610e92565b6068546001600160a01b03166102d9565b6103046103c23660046126e8565b610f08565b6103046103d536600461281b565b610f6f565b61023b6103e83660046126cb565b610fcb565b6102d96110dd565b61030461040336600461281b565b6110e7565b610256611143565b61027661041e36600461269f565b611152565b61027661043136600461269f565b6111cd565b61030461044436600461281b565b6111db565b6067546001600160a01b03166102d9565b6069546001600160a01b03166102d9565b61023b611237565b6103046104813660046126cb565b611242565b606b5461023b565b61030461049c366004612834565b6112bb565b61023b6104af36600461287a565b6113d8565b6103046104c23660046128a8565b611403565b606d5461023b565b6060603680546104de906128ca565b80601f016020809104026020016040519081016040528092919081815260200182805461050a906128ca565b80156105575780601f1061052c57610100808354040283529160200191610557565b820191906000526020600020905b81548152906001019060200180831161053a57829003601f168201915b5050505050905090565b60003361056f81858561146f565b60019150505b92915050565b60008061058783611593565b60355491509150915091565b600061059d6115ae565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b815250906105f45760405162461bcd60e51b81526004016105eb9190612654565b60405180910390fd5b50600061060085611593565b9050600061060e8585611627565b60408051808201909152600381526235303160e81b6020820152909150816106495760405162461bcd60e51b81526004016105eb9190612654565b506106548682611661565b60408051868152602081018690526001600160a01b03881691600080516020612bf1833981519152910160405180910390a25015949350505050565b60008061069b6115ae565b905060006106a860355490565b9050806000036106bb5760009250505090565b606854606954606a54606b546040516352120e2360e01b81526107ac946001600160a01b038881169563dcc5cded9587956352120e239561070595851694909316926004016128fe565b602060405180830381865afa158015610722573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107469190612927565b6040518263ffffffff1660e01b815260040161076491815260200190565b602060405180830381865afa158015610781573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a59190612927565b8290611717565b9250505090565b60006107bd611753565b905090565b600054610100900460ff16158080156107e25750600054600160ff909116105b806107fc5750303b1580156107fc575060005460ff166001145b61085f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105eb565b6000805460ff191660011790558015610882576000805461ff0019166101001790555b610922610893610140840184612940565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506108d692505050610160850185612940565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061091d925050506101208601610100870161298e565b6117a8565b6109346102a0830161028084016126cb565b606780546001600160a01b0319166001600160a01b03929092169190911790556109666102c083016102a084016126cb565b606680546001600160a01b0319166001600160a01b03929092169190911790556102c0820135606c556102e0820135606d55610300820135606e556109b160c0830160a084016126cb565b606980546001600160a01b0319166001600160a01b03929092169190911790556109de60208301836126cb565b606880546001600160a01b0319166001600160a01b039283161790556060830135606a556080830135606b5560658054610100600160a81b0319166101008684168102919091179182905560408051630261bf8b60e01b815290519190920490921691630261bf8b916004808201926020929091908290030181865afa158015610a6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9091906129b1565b6069546068546065546040805163033df24d60e31b815290516001600160a01b039586169594851694938416937f4b3932defc851859c0883ec898429ef20ab50bf24355077458d5b5c266d8087593610100900416916319ef92689160048083019260209291908290030181865afa158015610b10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3491906129b1565b606754606654606c54606d54606e54604080516001600160a01b039788168152958716602087015295909316848601526060840191909152608083015260a082015290519081900360c00190a48015610bc7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600061057582611593565b600033610be58582856117ca565b610bf085858561183e565b506001949350505050565b610c036115ae565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b81525090610c515760405162461bcd60e51b81526004016105eb9190612654565b50610c6086868686868661184b565b505050505050565b600080610c736115ae565b606854606954606a54606b546040516352120e2360e01b81529495506001600160a01b038087169563dcc5cded9587956352120e2395610cc09592851694909116929091906004016128fe565b602060405180830381865afa158015610cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d019190612927565b6040518263ffffffff1660e01b8152600401610d1f91815260200190565b602060405180830381865afa158015610d3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d609190612927565b91505090565b60003361056f818585610d7983836113d8565b610d8391906129e4565b61146f565b600080610d936115ae565b606854606954606a54606b546040516352120e2360e01b81529495506000946001600160a01b03808816956352120e2395610dda95918316949216929091906004016128fe565b602060405180830381865afa158015610df7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1b9190612927565b60405163dcc5cded60e01b8152600481018290529091506000906001600160a01b0384169063dcc5cded90602401602060405180830381865afa158015610e66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8a9190612927565b949350505050565b6000610e9c6115ae565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b81525090610eea5760405162461bcd60e51b81526004016105eb9190612654565b50606954610f02906001600160a01b03168484611ac0565b50919050565b610f106115ae565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b81525090610f5e5760405162461bcd60e51b81526004016105eb9190612654565b50610bc7836000808560008661184b565b610f776115ae565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b81525090610fc55760405162461bcd60e51b81526004016105eb9190612654565b50606e55565b600080610fd66115ae565b606854606954606a54606b546040516352120e2360e01b81529495506110d6946001600160a01b038088169563dcc5cded9587956352120e23956110279593851694909216929091906004016128fe565b602060405180830381865afa158015611044573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110689190612927565b6040518263ffffffff1660e01b815260040161108691815260200190565b602060405180830381865afa1580156110a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c79190612927565b6110d085611593565b90611717565b9392505050565b60006107bd6115ae565b6110ef6115ae565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b8152509061113d5760405162461bcd60e51b81526004016105eb9190612654565b50606d55565b6060603780546104de906128ca565b6000338161116082866113d8565b9050838110156111c05760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016105eb565b610bf0828686840361146f565b60003361056f81858561183e565b6111e36115ae565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b815250906112315760405162461bcd60e51b81526004016105eb9190612654565b50606c55565b60006107bd60355490565b61124a6115ae565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b815250906112985760405162461bcd60e51b81526004016105eb9190612654565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b6112c36115ae565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b815250906113115760405162461bcd60e51b81526004016105eb9190612654565b50600061131e8383611627565b6040805180820190915260038152621a981960e91b6020820152909150816113595760405162461bcd60e51b81526004016105eb9190612654565b506113648582611b12565b60695461137b906001600160a01b03168585611ac0565b836001600160a01b0316856001600160a01b03167f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa285856040516113c9929190918252602082015260400190565b60405180910390a35050505050565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b61140b6115ae565b6001600160a01b0316336001600160a01b0316146040518060400160405280600381526020016203530360ec1b815250906114595760405162461bcd60e51b81526004016105eb9190612654565b5061146b60008060008560008661184b565b5050565b6001600160a01b0383166114d15760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016105eb565b6001600160a01b0382166115325760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016105eb565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b031660009081526033602052604090205490565b6000606560019054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611603573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bd91906129b1565b6000806116356002846129f7565b9050610e8a8361165b611654876b033b2e3c9fd0803ce8000000611b36565b8490611b42565b90611b4e565b600061166c60355490565b9050600061167984611593565b90506116858484611b5a565b600061168f611753565b6001600160a01b031614611711576116a5611753565b6040516318c39f1760e11b81526001600160a01b038681166004830152602482018590526044820184905291909116906331873e2e90606401600060405180830381600087803b1580156116f857600080fd5b505af115801561170c573d6000803e3d6000fd5b505050505b50505050565b60006110d66b033b2e3c9fd0803ce800000061165b6117368686611b36565b61174d60026b033b2e3c9fd0803ce80000006129f7565b90611b42565b6000606560019054906101000a90046001600160a01b03166001600160a01b03166319ef92686040518163ffffffff1660e01b8152600401602060405180830381865afa158015611603573d6000803e3d6000fd5b6117b28383611c09565b6065805460ff191660ff929092169190911790555050565b60006117d684846113d8565b9050600019811461171157818110156118315760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016105eb565b611711848484840361146f565b610bc78383836001611c3a565b82158015611857575081155b610c60576066546067546001600160a01b039182169190811690600090819081908a166118915761188788611e58565b90925090506118a2565b61189a87611e86565b919450925090505b6118b5846118b08389611627565b611661565b6118c3856118b08489611627565b836001600160a01b03168b6001600160a01b0316600080516020612c11833981519152836040516118f691815260200190565b60405180910390a3846001600160a01b03168b6001600160a01b0316600080516020612c118339815191528460405161193191815260200190565b60405180910390a360408051828152602081018890526001600160a01b03861691600080516020612bf1833981519152910160405180910390a260408051838152602081018890526001600160a01b03871691600080516020612bf1833981519152910160405180910390a26001600160a01b038a1615611a28576119ba8a6118b08589611627565b896001600160a01b03168b6001600160a01b0316600080516020612c11833981519152856040516119ed91815260200190565b60405180910390a360408051848152602081018890526001600160a01b038c1691600080516020612bf1833981519152910160405180910390a25b6001600160a01b03891615611ab357611a45896118b08a89611627565b886001600160a01b03168b6001600160a01b0316600080516020612c118339815191528a604051611a7891815260200190565b60405180910390a360408051898152602081018890526001600160a01b038b1691600080516020612bf1833981519152910160405180910390a25b5050505050505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610bc7908490611ee1565b6000611b1d60355490565b90506000611b2a84611593565b90506116858484611fb3565b60006110d68284612a19565b60006110d682846129e4565b60006110d682846129f7565b6001600160a01b038216611bb05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105eb565b8060356000828254611bc291906129e4565b90915550506001600160a01b038216600081815260336020908152604080832080548601905551848152600080516020612c11833981519152910160405180910390a35050565b600054610100900460ff16611c305760405162461bcd60e51b81526004016105eb90612a38565b61146b82826120d5565b6000611c446115ae565b606854606954606a54606b546040516352120e2360e01b81529495506000946001600160a01b03808816956352120e2395611c8b95918316949216929091906004016128fe565b602060405180830381865afa158015611ca8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ccc9190612927565b60405163dcc5cded60e01b8152600481018290529091506000906001600160a01b0384169063dcc5cded90602401602060405180830381865afa158015611d17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3b9190612927565b90506000611d4c826110d08a611593565b90506000611d5d836110d08a611593565b9050611d738989611d6e8a87611627565b612115565b8515611df757604051636c130dc760e01b8152600481018590526001600160a01b038a811660248301528981166044830152606482018990526084820184905260a48201839052861690636c130dc79060c40160006040518083038186803b158015611dde57600080fd5b505afa158015611df2573d6000803e3d6000fd5b505050505b876001600160a01b0316896001600160a01b03167f4beccb90f994c31aced7a23b5611020728a23d8ec5cddd1a3e9d97b96fda86668986604051611e45929190918252602082015260400190565b60405180910390a3505050505050505050565b606c54600090819081611e6b8583612267565b90506000611e798287612a83565b9196919550909350505050565b600080600080611ea1606d548661226790919063ffffffff16565b90506000611eba606e548761226790919063ffffffff16565b9050600081611ec98489612a83565b611ed39190612a83565b929791965091945092505050565b6000611f36826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661230f9092919063ffffffff16565b805190915015610bc75780806020019051810190611f549190612a96565b610bc75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105eb565b6001600160a01b0382166120135760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016105eb565b6001600160a01b038216600090815260336020526040902054818110156120875760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016105eb565b6001600160a01b0383166000818152603360209081526040808320868603905560358054879003905551858152919291600080516020612c11833981519152910160405180910390a3505050565b600054610100900460ff166120fc5760405162461bcd60e51b81526004016105eb90612a38565b60366121088382612b14565b506037610bc78282612b14565b600061212084611593565b9050600061212d84611593565b905061213a85858561231e565b6000612144611753565b6001600160a01b03161461226057600061215d60355490565b9050612167611753565b6040516318c39f1760e11b81526001600160a01b038881166004830152602482018490526044820186905291909116906331873e2e90606401600060405180830381600087803b1580156121ba57600080fd5b505af11580156121ce573d6000803e3d6000fd5b50505050846001600160a01b0316866001600160a01b031614610c60576121f3611753565b6040516318c39f1760e11b81526001600160a01b038781166004830152602482018490526044820185905291909116906331873e2e90606401600060405180830381600087803b15801561224657600080fd5b505af115801561225a573d6000803e3d6000fd5b50505050505b5050505050565b6000821580612274575081155b1561228157506000610575565b8161228f60026127106129f7565b61229b90600019612a83565b6122a591906129f7565b8311156040518060400160405280600381526020016203230360ec1b815250906122e25760405162461bcd60e51b81526004016105eb9190612654565b506127106122f16002826129f7565b6122fb8486612a19565b61230591906129e4565b6110d691906129f7565b6060610e8a84846000856124b7565b6001600160a01b0383166123825760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016105eb565b6001600160a01b0382166123e45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016105eb565b6001600160a01b0383166000908152603360205260409020548181101561245c5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016105eb565b6001600160a01b038085166000818152603360205260408082208686039055928616808252908390208054860190559151600080516020612c11833981519152906124aa9086815260200190565b60405180910390a3611711565b6060824710156125185760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105eb565b600080866001600160a01b031685876040516125349190612bd4565b60006040518083038185875af1925050503d8060008114612571576040519150601f19603f3d011682016040523d82523d6000602084013e612576565b606091505b509150915061258787838387612592565b979650505050505050565b606083156126015782516000036125fa576001600160a01b0385163b6125fa5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105eb565b5081610e8a565b610e8a83838151156126165781518083602001fd5b8060405162461bcd60e51b81526004016105eb9190612654565b60005b8381101561264b578181015183820152602001612633565b50506000910152565b6020815260008251806020840152612673816040850160208701612630565b601f01601f19169190910160400192915050565b6001600160a01b038116811461269c57600080fd5b50565b600080604083850312156126b257600080fd5b82356126bd81612687565b946020939093013593505050565b6000602082840312156126dd57600080fd5b81356110d681612687565b6000806000606084860312156126fd57600080fd5b833561270881612687565b95602085013595506040909401359392505050565b6000806040838503121561273057600080fd5b823561273b81612687565b9150602083013567ffffffffffffffff81111561275757600080fd5b8301610340818603121561276a57600080fd5b809150509250929050565b60008060006060848603121561278a57600080fd5b833561279581612687565b925060208401356127a581612687565b929592945050506040919091013590565b60008060008060008060c087890312156127cf57600080fd5b86356127da81612687565b955060208701356127ea81612687565b945060408701356127fa81612687565b959894975094956060810135955060808101359460a0909101359350915050565b60006020828403121561282d57600080fd5b5035919050565b6000806000806080858703121561284a57600080fd5b843561285581612687565b9350602085013561286581612687565b93969395505050506040820135916060013590565b6000806040838503121561288d57600080fd5b823561289881612687565b9150602083013561276a81612687565b600080604083850312156128bb57600080fd5b50508035926020909101359150565b600181811c908216806128de57607f821691505b602082108103610f0257634e487b7160e01b600052602260045260246000fd5b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b60006020828403121561293957600080fd5b5051919050565b6000808335601e1984360301811261295757600080fd5b83018035915067ffffffffffffffff82111561297257600080fd5b60200191503681900382131561298757600080fd5b9250929050565b6000602082840312156129a057600080fd5b813560ff811681146110d657600080fd5b6000602082840312156129c357600080fd5b81516110d681612687565b634e487b7160e01b600052601160045260246000fd5b80820180821115610575576105756129ce565b600082612a1457634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612a3357612a336129ce565b500290565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b81810381811115610575576105756129ce565b600060208284031215612aa857600080fd5b815180151581146110d657600080fd5b634e487b7160e01b600052604160045260246000fd5b601f821115610bc757600081815260208120601f850160051c81016020861015612af55750805b601f850160051c820191505b81811015610c6057828155600101612b01565b815167ffffffffffffffff811115612b2e57612b2e612ab8565b612b4281612b3c84546128ca565b84612ace565b602080601f831160018114612b775760008415612b5f5750858301515b600019600386901b1c1916600185901b178555610c60565b600085815260208120601f198616915b82811015612ba657888601518255948401946001909101908401612b87565b5085821015612bc45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251612be6818460208701612630565b919091019291505056fe4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220803dae48baefc31ac1ca6f12fce04b1028be511e5d6355449d118c23fb9bfd7d64736f6c63430008100033",
    "sourceMap": "1311:22032:158:-:0;;;2129:53;;;;;;;;;-1:-1:-1;2153:22:158;:20;:22::i;:::-;1311:22032;;5928:279:18;5996:13;;;;;;;5995:14;5987:66;;;;-1:-1:-1;;;5987:66:18;;216:2:187;5987:66:18;;;198:21:187;255:2;235:18;;;228:30;294:34;274:18;;;267:62;-1:-1:-1;;;345:18:187;;;338:37;392:19;;5987:66:18;;;;;;;;6067:12;;6082:15;6067:12;;;:30;6063:138;;;6113:12;:30;;-1:-1:-1;;6113:30:18;6128:15;6113:30;;;;;;6162:28;;564:36:187;;;6162:28:18;;552:2:187;537:18;6162:28:18;;;;;;;6063:138;5928:279::o;422:184:187:-;1311:22032:158;;;;;;",