ETH Price: $3,258.79 (-0.31%)

Contract

0xAA5C1D7D88DAEFaE9aCD8B8BC058B590B268F062
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Redeem Fy Tokens146614162022-04-26 17:18:201000 days ago1650993500IN
0xAA5C1D7D...0B268F062
0 ETH0.0035209439.52745032
Supply Underlyin...118843632021-02-19 1:33:051432 days ago1613698385IN
0xAA5C1D7D...0B268F062
0 ETH0.02069544171
Supply Underlyin...118753752021-02-17 16:17:031433 days ago1613578623IN
0xAA5C1D7D...0B268F062
0 ETH0.03242233214.6805
_transfer Admin118735842021-02-17 9:40:221433 days ago1613554822IN
0xAA5C1D7D...0B268F062
0 ETH0.0027730290.001
_set Non Recover...118734982021-02-17 9:21:171433 days ago1613553677IN
0xAA5C1D7D...0B268F062
0 ETH0.0071389688.0006

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
118704822021-02-16 22:15:471434 days ago1613513747  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RedemptionPool

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU LGPLv3 license

Contract Source Code (Solidity Multiple files format)

File 1 of 26: RedemptionPool.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

import "./Admin.sol";
import "./CarefulMath.sol";
import "./Erc20Interface.sol";
import "./Erc20Recover.sol";
import "./SafeErc20.sol";
import "./ReentrancyGuard.sol";

import "./FintrollerInterface.sol";
import "./RedemptionPoolInterface.sol";

/**
 * @title RedemptionPool
 * @author Hifi
 * @notice Mints 1 fyToken in exhchange for 1 underlying before maturation and burns 1 fyToken
 * in exchange for 1 underlying after maturation.
 * @dev Instantiated by the fyToken in its constructor.
 */
contract RedemptionPool is
    CarefulMath, /* no dependency */
    ReentrancyGuard, /* no dependency */
    RedemptionPoolInterface, /* one dependency */
    Admin, /* two dependencies */
    Erc20Recover /* five dependencies */
{
    using SafeErc20 for Erc20Interface;

    /**
     * @param fintroller_ The address of the Fintroller contract.
     * @param fyToken_ The address of the fyToken contract.
     */
    constructor(FintrollerInterface fintroller_, FyTokenInterface fyToken_) Admin() {
        /* Set the Fintroller contract and sanity check it. */
        fintroller = fintroller_;
        fintroller.isFintroller();

        /**
         * Set the fyToken contract. It cannot be sanity-checked because the fyToken creates this
         * contract in its own constructor and contracts cannot be called while initializing.
         */
        fyToken = fyToken_;
    }

    struct RedeemFyTokensLocalVars {
        MathError mathErr;
        uint256 newUnderlyingTotalSupply;
        uint256 underlyingPrecisionScalar;
        uint256 underlyingAmount;
    }

    /**
     * @notice Pays the token holder the face value at maturation time.
     *
     * @dev Emits a {RedeemFyTokens} event.
     *
     * Requirements:
     *
     * - Must be called after maturation.
     * - The amount to redeem cannot be zero.
     * - The Fintroller must allow this action to be performed.
     * - There must be enough liquidity in the Redemption Pool.
     *
     * @param fyTokenAmount The amount of fyTokens to redeem for the underlying asset.
     * @return bool true = success, otherwise it reverts.
     */
    function redeemFyTokens(uint256 fyTokenAmount) external override nonReentrant returns (bool) {
        RedeemFyTokensLocalVars memory vars;

        /* Checks: maturation time. */
        require(block.timestamp >= fyToken.expirationTime(), "ERR_BOND_NOT_MATURED");

        /* Checks: the zero edge case. */
        require(fyTokenAmount > 0, "ERR_REDEEM_FYTOKENS_ZERO");

        /* Checks: the Fintroller allows this action to be performed. */
        require(fintroller.getRedeemFyTokensAllowed(fyToken), "ERR_REDEEM_FYTOKENS_NOT_ALLOWED");

        /**
         * fyTokens always have 18 decimals so the underlying amount needs to be downscaled.
         * If the precision scalar is 1, it means that the underlying also has 18 decimals.
         */
        vars.underlyingPrecisionScalar = fyToken.underlyingPrecisionScalar();
        if (vars.underlyingPrecisionScalar != 1) {
            (vars.mathErr, vars.underlyingAmount) = divUInt(fyTokenAmount, vars.underlyingPrecisionScalar);
            require(vars.mathErr == MathError.NO_ERROR, "ERR_REDEEM_FYTOKENS_MATH_ERROR");
        } else {
            vars.underlyingAmount = fyTokenAmount;
        }

        /* Checks: there is enough liquidity. */
        require(vars.underlyingAmount <= totalUnderlyingSupply, "ERR_REDEEM_FYTOKENS_INSUFFICIENT_UNDERLYING");

        /* Effects: decrease the remaining supply of underlying. */
        (vars.mathErr, vars.newUnderlyingTotalSupply) = subUInt(totalUnderlyingSupply, vars.underlyingAmount);
        assert(vars.mathErr == MathError.NO_ERROR);
        totalUnderlyingSupply = vars.newUnderlyingTotalSupply;

        /* Interactions: burn the fyTokens. */
        require(fyToken.burn(msg.sender, fyTokenAmount), "ERR_SUPPLY_UNDERLYING_CALL_BURN");

        /* Interactions: perform the Erc20 transfer. */
        fyToken.underlying().safeTransfer(msg.sender, vars.underlyingAmount);

        emit RedeemFyTokens(msg.sender, fyTokenAmount, vars.underlyingAmount);

        return true;
    }

    struct SupplyUnderlyingLocalVars {
        MathError mathErr;
        uint256 fyTokenAmount;
        uint256 newUnderlyingTotalSupply;
        uint256 underlyingPrecisionScalar;
    }

    /**
     * @notice An alternative to the usual minting method that does not involve taking on debt.
     *
     * @dev Emits a {SupplyUnderlying} event.
     *
     * Requirements:
     *
     * - Must be called prior to maturation.
     * - The amount to supply cannot be zero.
     * - The Fintroller must allow this action to be performed.
     * - The caller must have allowed this contract to spend `underlyingAmount` tokens.
     *
     * @param underlyingAmount The amount of underlying to supply to the Redemption Pool.
     * @return bool true = success, otherwise it reverts.
     */
    function supplyUnderlying(uint256 underlyingAmount) external override nonReentrant returns (bool) {
        SupplyUnderlyingLocalVars memory vars;

        /* Checks: maturation time. */
        require(block.timestamp < fyToken.expirationTime(), "ERR_BOND_MATURED");

        /* Checks: the zero edge case. */
        require(underlyingAmount > 0, "ERR_SUPPLY_UNDERLYING_ZERO");

        /* Checks: the Fintroller allows this action to be performed. */
        require(fintroller.getSupplyUnderlyingAllowed(fyToken), "ERR_SUPPLY_UNDERLYING_NOT_ALLOWED");

        /* Effects: update storage. */
        (vars.mathErr, vars.newUnderlyingTotalSupply) = addUInt(totalUnderlyingSupply, underlyingAmount);
        require(vars.mathErr == MathError.NO_ERROR, "ERR_SUPPLY_UNDERLYING_MATH_ERROR");
        totalUnderlyingSupply = vars.newUnderlyingTotalSupply;

        /**
         * fyTokens always have 18 decimals so the underlying amount needs to be upscaled.
         * If the precision scalar is 1, it means that the underlying also has 18 decimals.
         */
        vars.underlyingPrecisionScalar = fyToken.underlyingPrecisionScalar();
        if (vars.underlyingPrecisionScalar != 1) {
            (vars.mathErr, vars.fyTokenAmount) = mulUInt(underlyingAmount, vars.underlyingPrecisionScalar);
            require(vars.mathErr == MathError.NO_ERROR, "ERR_SUPPLY_UNDERLYING_MATH_ERROR");
        } else {
            vars.fyTokenAmount = underlyingAmount;
        }

        /* Interactions: mint the fyTokens. */
        require(fyToken.mint(msg.sender, vars.fyTokenAmount), "ERR_SUPPLY_UNDERLYING_CALL_MINT");

        /* Interactions: perform the Erc20 transfer. */
        fyToken.underlying().safeTransferFrom(msg.sender, address(this), underlyingAmount);

        emit SupplyUnderlying(msg.sender, underlyingAmount, vars.fyTokenAmount);

        return true;
    }
}

File 2 of 26: Address.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

/**
 * @title Address
 * @author Paul Razvan Berg
 * @notice Collection of functions related to the address type.
 * @dev Forked from OpenZeppelin
 * https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v3.1.0/contracts/utils/Address.sol
 */
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) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`.
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        /* solhint-disable-next-line no-inline-assembly */
        assembly {
            codehash := extcodehash(account)
        }
        return (codehash != accountHash && codehash != 0x0);
    }
}

File 3 of 26: Admin.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

import "./AdminInterface.sol";

/**
 * @title Admin
 * @author Paul Razvan Berg
 * @notice Contract module which provides a basic access control mechanism, where there is
 * an account (an admin) that can be granted exclusive access to specific functions.
 *
 * By default, the admin account will be the one that deploys the contract. This can later
 * be changed with {transferAdmin}.
 *
 * This module is used through inheritance. It will make available the modifier `onlyAdmin`,
 * which can be applied to your functions to restrict their use to the admin.
 *
 * @dev Forked from OpenZeppelin
 * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.1.0/contracts/access/Ownable.sol
 */
abstract contract Admin is AdminInterface {
    /**
     * @notice Throws if called by any account other than the admin.
     */
    modifier onlyAdmin() {
        require(admin == msg.sender, "ERR_NOT_ADMIN");
        _;
    }

    /**
     * @notice Initializes the contract setting the deployer as the initial admin.
     */
    constructor() {
        address msgSender = msg.sender;
        admin = msgSender;
        emit TransferAdmin(address(0x00), msgSender);
    }

    /**
     * @notice Leaves the contract without admin, so it will not be possible to call
     * `onlyAdmin` functions anymore.
     *
     * Requirements:
     *
     * - The caller must be the administrator.
     *
     * WARNING: Doing this will leave the contract without an admin,
     * thereby removing any functionality that is only available to the admin.
     */
    function _renounceAdmin() external virtual override onlyAdmin {
        emit TransferAdmin(admin, address(0x00));
        admin = address(0x00);
    }

    /**
     * @notice Transfers the admin of the contract to a new account (`newAdmin`).
     * Can only be called by the current admin.
     * @param newAdmin The acount of the new admin.
     */
    function _transferAdmin(address newAdmin) external virtual override onlyAdmin {
        require(newAdmin != address(0x00), "ERR_SET_ADMIN_ZERO_ADDRESS");
        emit TransferAdmin(admin, newAdmin);
        admin = newAdmin;
    }
}

File 4 of 26: AdminInterface.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

import "./AdminStorage.sol";

/**
 * @title AdminInterface
 * @author Paul Razvan Berg
 */
abstract contract AdminInterface is AdminStorage {
    /**
     * NON-CONSTANT FUNCTIONS
     */
    function _renounceAdmin() external virtual;

    function _transferAdmin(address newAdmin) external virtual;

    /**
     * EVENTS
     */
    event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);
}

File 5 of 26: AdminStorage.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

abstract contract AdminStorage {
    /**
     * @notice The address of the administrator account or contract.
     */
    address public admin;
}

File 6 of 26: AggregatorV3Interface.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

/**
 * @title AggregatorV3Interface
 * @author Hifi
 * @dev Forked from Chainlink
 * https://github.com/smartcontractkit/chainlink/blob/v0.9.9/evm-contracts/src/v0.7/interfaces/AggregatorV3Interface.sol
 */
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 7 of 26: BalanceSheetInterface.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

import "./BalanceSheetStorage.sol";

/**
 * @title BalanceSheetInterface
 * @author Hifi
 */
abstract contract BalanceSheetInterface is BalanceSheetStorage {
    /**
     * CONSTANT FUNCTIONS
     */
    function getClutchableCollateral(FyTokenInterface fyToken, uint256 repayAmount)
        external
        view
        virtual
        returns (uint256);

    function getCurrentCollateralizationRatio(FyTokenInterface fyToken, address borrower)
        public
        view
        virtual
        returns (uint256);

    function getHypotheticalCollateralizationRatio(
        FyTokenInterface fyToken,
        address borrower,
        uint256 lockedCollateral,
        uint256 debt
    ) public view virtual returns (uint256);

    function getVault(FyTokenInterface fyToken, address borrower)
        external
        view
        virtual
        returns (
            uint256,
            uint256,
            uint256,
            bool
        );

    function getVaultDebt(FyTokenInterface fyToken, address borrower) external view virtual returns (uint256);

    function getVaultLockedCollateral(FyTokenInterface fyToken, address borrower)
        external
        view
        virtual
        returns (uint256);

    function isAccountUnderwater(FyTokenInterface fyToken, address borrower) external view virtual returns (bool);

    function isVaultOpen(FyTokenInterface fyToken, address borrower) external view virtual returns (bool);

    /**
     * NON-CONSTANT FUNCTIONS
     */

    function clutchCollateral(
        FyTokenInterface fyToken,
        address liquidator,
        address borrower,
        uint256 clutchedCollateralAmount
    ) external virtual returns (bool);

    function depositCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external virtual returns (bool);

    function freeCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external virtual returns (bool);

    function lockCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external virtual returns (bool);

    function openVault(FyTokenInterface fyToken) external virtual returns (bool);

    function setVaultDebt(
        FyTokenInterface fyToken,
        address borrower,
        uint256 newVaultDebt
    ) external virtual returns (bool);

    function withdrawCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external virtual returns (bool);

    /**
     * EVENTS
     */

    event ClutchCollateral(
        FyTokenInterface indexed fyToken,
        address indexed liquidator,
        address indexed borrower,
        uint256 clutchedCollateralAmount
    );

    event DepositCollateral(FyTokenInterface indexed fyToken, address indexed borrower, uint256 collateralAmount);

    event FreeCollateral(FyTokenInterface indexed fyToken, address indexed borrower, uint256 collateralAmount);

    event LockCollateral(FyTokenInterface indexed fyToken, address indexed borrower, uint256 collateralAmount);

    event OpenVault(FyTokenInterface indexed fyToken, address indexed borrower);

    event SetVaultDebt(FyTokenInterface indexed fyToken, address indexed borrower, uint256 oldDebt, uint256 newDebt);

    event WithdrawCollateral(FyTokenInterface indexed fyToken, address indexed borrower, uint256 collateralAmount);
}

File 8 of 26: BalanceSheetStorage.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

import "./FyTokenInterface.sol";

/**
 * @title BalanceSheetStorage
 * @author Hifi
 */
abstract contract BalanceSheetStorage {
    struct Vault {
        uint256 debt;
        uint256 freeCollateral;
        uint256 lockedCollateral;
        bool isOpen;
    }

    /**
     * @notice The unique Fintroller associated with this contract.
     */
    FintrollerInterface public fintroller;

    /**
     * @dev One vault for each fyToken for each account.
     */
    mapping(address => mapping(address => Vault)) internal vaults;

    /**
     * @notice Indicator that this is a BalanceSheet contract, for inspection.
     */
    bool public constant isBalanceSheet = true;
}

File 9 of 26: CarefulMath.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

/**
 * @notice Possible error codes that can be returned.
 */
enum MathError { NO_ERROR, DIVISION_BY_ZERO, INTEGER_OVERFLOW, INTEGER_UNDERFLOW, MODULO_BY_ZERO }

/**
 * @title CarefulMath
 * @author Paul Razvan Berg
 * @notice Exponential module for storing fixed-precision decimals.
 * @dev Forked from Compound
 * https://github.com/compound-finance/compound-protocol/blob/v2.8.1/contracts/CarefulMath.sol
 */
abstract contract CarefulMath {
    /**
     * @notice Adds two numbers, returns an error on overflow.
     */
    function addUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) {
        uint256 c = a + b;

        if (c >= a) {
            return (MathError.NO_ERROR, c);
        } else {
            return (MathError.INTEGER_OVERFLOW, 0);
        }
    }

    /**
     * @notice Add `a` and `b` and then subtract `c`.
     */
    function addThenSubUInt(
        uint256 a,
        uint256 b,
        uint256 c
    ) internal pure returns (MathError, uint256) {
        (MathError err0, uint256 sum) = addUInt(a, b);

        if (err0 != MathError.NO_ERROR) {
            return (err0, 0);
        }

        return subUInt(sum, c);
    }

    /**
     * @notice Integer division of two numbers, truncating the quotient.
     */
    function divUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) {
        if (b == 0) {
            return (MathError.DIVISION_BY_ZERO, 0);
        }

        return (MathError.NO_ERROR, a / b);
    }

    /**
     * @notice Returns the remainder of dividing two numbers.
     * @dev 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).
     */
    function modUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) {
        if (b == 0) {
            return (MathError.MODULO_BY_ZERO, 0);
        }

        return (MathError.NO_ERROR, a % b);
    }

    /**
     * @notice Multiplies two numbers, returns an error on overflow.
     */
    function mulUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) {
        if (a == 0) {
            return (MathError.NO_ERROR, 0);
        }

        uint256 c = a * b;

        if (c / a != b) {
            return (MathError.INTEGER_OVERFLOW, 0);
        } else {
            return (MathError.NO_ERROR, c);
        }
    }

    /**
     * @notice Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).
     */
    function subUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) {
        if (b <= a) {
            return (MathError.NO_ERROR, a - b);
        } else {
            return (MathError.INTEGER_UNDERFLOW, 0);
        }
    }
}

File 10 of 26: ChainlinkOperatorInterface.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

import "./CarefulMath.sol";
import "./Erc20Interface.sol";

import "./ChainlinkOperatorStorage.sol";
import "./AggregatorV3Interface.sol";

/**
 * @title ChainlinkOperatorInterface
 * @author Hifi
 */
abstract contract ChainlinkOperatorInterface is ChainlinkOperatorStorage {
    /**
     * EVENTS
     */
    event DeleteFeed(Erc20Interface indexed asset, AggregatorV3Interface indexed feed);

    event SetFeed(Erc20Interface indexed asset, AggregatorV3Interface indexed feed);

    /**
     * CONSTANT FUNCTIONS.
     */
    function getAdjustedPrice(string memory symbol) external view virtual returns (uint256);

    function getFeed(string memory symbol)
        external
        view
        virtual
        returns (
            Erc20Interface,
            AggregatorV3Interface,
            bool
        );

    function getPrice(string memory symbol) public view virtual returns (uint256);

    /**
     * NON-CONSTANT FUNCTIONS.
     */
    function deleteFeed(string memory symbol) external virtual returns (bool);

    function setFeed(Erc20Interface asset, AggregatorV3Interface feed) external virtual returns (bool);
}

File 11 of 26: ChainlinkOperatorStorage.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

import "./Erc20Interface.sol";

import "./AggregatorV3Interface.sol";

/**
 * @title ChainlinkOperatorStorage
 * @author Hifi
 */
abstract contract ChainlinkOperatorStorage {
    struct Feed {
        Erc20Interface asset;
        AggregatorV3Interface id;
        bool isSet;
    }

    /**
     * @dev Mapping between Erc20 symbols and Feed structs.
     */
    mapping(string => Feed) internal feeds;

    /**
     * @notice Chainlink price precision for USD-quoted data.
     */
    uint256 public constant pricePrecision = 8;

    /**
     * @notice The ratio between mantissa precision (1e18) and the Chainlink price precision (1e8).
     */
    uint256 public constant pricePrecisionScalar = 1.0e10;
}

File 12 of 26: Erc20Interface.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

import "./Erc20Storage.sol";

/**
 * @title Erc20Interface
 * @author Paul Razvan Berg
 * @notice Interface of the Erc20 standard
 * @dev Forked from OpenZeppelin
 * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.2.0/contracts/token/ERC20/IERC20.sol
 */
abstract contract Erc20Interface is Erc20Storage {
    /**
     * CONSTANT FUNCTIONS
     */
    function allowance(address owner, address spender) external view virtual returns (uint256);

    function balanceOf(address account) external view virtual returns (uint256);

    /**
     * NON-CONSTANT FUNCTIONS
     */
    function approve(address spender, uint256 amount) external virtual returns (bool);

    function transfer(address recipient, uint256 amount) external virtual returns (bool);

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external virtual returns (bool);

    /**
     * EVENTS
     */
    event Approval(address indexed owner, address indexed spender, uint256 amount);

    event Burn(address indexed holder, uint256 burnAmount);

    event Mint(address indexed beneficiary, uint256 mintAmount);

    event Transfer(address indexed from, address indexed to, uint256 amount);
}

File 13 of 26: Erc20Recover.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

import "./Admin.sol";
import "./Erc20Interface.sol";
import "./Erc20RecoverInterface.sol";
import "./SafeErc20.sol";

/**
 * @title Erc20Recover
 * @author Paul Razvan Berg
 * @notice Gives the administrator the ability to recover the Erc20 tokens that
 * had been sent (accidentally, or not) to the contract.
 */
abstract contract Erc20Recover is
    Erc20RecoverInterface, /* one dependency */
    Admin /* two dependencies */
{
    using SafeErc20 for Erc20Interface;

    /**
     * @notice Sets the tokens that this contract cannot recover.
     *
     * @dev Emits a {SetNonRecoverableTokens} event.
     *
     * Requirements:
     *
     * - The caller must be the administrator.
     * - The contract must be non-initialized.
     * - The array of given tokens cannot be empty.
     *
     * @param tokens The array of tokens to set as non-recoverable.
     */
    function _setNonRecoverableTokens(Erc20Interface[] calldata tokens) external override onlyAdmin {
        /* Checks */
        require(isRecoverInitialized == false, "ERR_INITALIZED");

        /* Iterate over the token list, sanity check each and update the mapping. */
        uint256 length = tokens.length;
        for (uint256 i = 0; i < length; i += 1) {
            tokens[i].symbol();
            nonRecoverableTokens.push(tokens[i]);
        }

        /* Effects: prevent this function from ever being called again. */
        isRecoverInitialized = true;

        emit SetNonRecoverableTokens(admin, tokens);
    }

    /**
     * @notice Recover Erc20 tokens sent to this contract (by accident or otherwise).
     * @dev Emits a {RecoverToken} event.
     *
     * Requirements:
     *
     * - The caller must be the administrator.
     * - The contract must be initialized.
     * - The amount to recover cannot be zero.
     * - The token to recover cannot be among the non-recoverable tokens.
     *
     * @param token The token to make the recover for.
     * @param recoverAmount The uint256 amount to recover, specified in the token's decimal system.
     */
    function _recover(Erc20Interface token, uint256 recoverAmount) external override onlyAdmin {
        /* Checks */
        require(isRecoverInitialized == true, "ERR_NOT_INITALIZED");
        require(recoverAmount > 0, "ERR_RECOVER_ZERO");

        bytes32 tokenSymbolHash = keccak256(bytes(token.symbol()));
        uint256 length = nonRecoverableTokens.length;

        /**
         * We iterate over the non-recoverable token array and check that:
         *
         *   1. The addresses of the tokens are not the same
         *   2. The symbols of the tokens are not the same
         *
         * It is true that the second check may lead to a false positive, but
         * there is no better way to fend off against proxied tokens.
         */
        for (uint256 i = 0; i < length; i += 1) {
            require(
                address(token) != address(nonRecoverableTokens[i]) &&
                    tokenSymbolHash != keccak256(bytes(nonRecoverableTokens[i].symbol())),
                "ERR_RECOVER_NON_RECOVERABLE_TOKEN"
            );
        }

        /* Interactions */
        token.safeTransfer(admin, recoverAmount);

        emit Recover(admin, token, recoverAmount);
    }
}

File 14 of 26: Erc20RecoverInterface.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

import "./Erc20Interface.sol";
import "./Erc20RecoverStorage.sol";

abstract contract Erc20RecoverInterface is Erc20RecoverStorage {
    /**
     * NON-CONSTANT FUNCTIONS
     */
    function _recover(Erc20Interface token, uint256 recoverAmount) external virtual;

    function _setNonRecoverableTokens(Erc20Interface[] calldata tokens) external virtual;

    /**
     * EVENTS
     */
    event Recover(address indexed admin, Erc20Interface token, uint256 recoverAmount);
    event SetNonRecoverableTokens(address indexed admin, Erc20Interface[] nonRecoverableTokens);
}

File 15 of 26: Erc20RecoverStorage.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

import "./Erc20Interface.sol";

abstract contract Erc20RecoverStorage {
    /**
     * @notice The tokens that can be recovered cannot be in this mapping.
     */
    Erc20Interface[] public nonRecoverableTokens;

    /**
     * @dev A flag that signals whether the the non-recoverable tokens were set or not.
     */
    bool internal isRecoverInitialized;
}

File 16 of 26: Erc20Storage.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

/**
 * @title ExponentialStorage
 * @author Paul Razvan Berg
 * @notice The storage interface ancillary to an Erc20 contract.
 */
abstract contract Erc20Storage {
    /**
     * @notice Returns the number of decimals used to get its user representation.
     */
    uint8 public decimals;

    /**
     * @notice Returns the name of the token.
     */
    string public name;

    /**
     * @notice Returns the symbol of the token, usually a shorter version of
     * the name.
     */
    string public symbol;

    /**
     * @notice Returns the amount of tokens in existence.
     */
    uint256 public totalSupply;

    mapping(address => mapping(address => uint256)) internal allowances;

    mapping(address => uint256) internal balances;
}

File 17 of 26: Exponential.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

import "./CarefulMath.sol";
import "./ExponentialStorage.sol";

/**
 * @title Exponential module for storing fixed-precision decimals.
 * @author Paul Razvan Berg
 * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.
 * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is: `Exp({mantissa: 5100000000000000000})`.
 * @dev Forked from Compound
 * https://github.com/compound-finance/compound-protocol/blob/v2.6/contracts/Exponential.sol
 */
abstract contract Exponential is
    CarefulMath, /* no dependency */
    ExponentialStorage /* no dependency */
{
    /**
     * @dev Adds two exponentials, returning a new exponential.
     */
    function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {
        (MathError error, uint256 result) = addUInt(a.mantissa, b.mantissa);

        return (error, Exp({ mantissa: result }));
    }

    /**
     * @dev Divides two exponentials, returning a new exponential.
     * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b.
     * NOTE: Returns an error if (`num` * 10e18) > MAX_INT, or if `denom` is zero.
     */
    function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {
        (MathError err0, uint256 scaledNumerator) = mulUInt(a.mantissa, expScale);
        if (err0 != MathError.NO_ERROR) {
            return (err0, Exp({ mantissa: 0 }));
        }

        (MathError err1, uint256 rational) = divUInt(scaledNumerator, b.mantissa);
        if (err1 != MathError.NO_ERROR) {
            return (err1, Exp({ mantissa: 0 }));
        }

        return (MathError.NO_ERROR, Exp({ mantissa: rational }));
    }

    /**
     * @dev Multiplies two exponentials, returning a new exponential.
     */
    function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {
        (MathError err0, uint256 doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);
        if (err0 != MathError.NO_ERROR) {
            return (err0, Exp({ mantissa: 0 }));
        }

        /*
         * We add half the scale before dividing so that we get rounding instead of truncation.
         * See "Listing 6" and text above it at https://accu.org/index.php/journals/1717
         * Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.
         */
        (MathError err1, uint256 doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);
        if (err1 != MathError.NO_ERROR) {
            return (err1, Exp({ mantissa: 0 }));
        }

        (MathError err2, uint256 product) = divUInt(doubleScaledProductWithHalfScale, expScale);
        /* The only possible error `div` is MathError.DIVISION_BY_ZERO but we control `expScale` and it's not zero. */
        assert(err2 == MathError.NO_ERROR);

        return (MathError.NO_ERROR, Exp({ mantissa: product }));
    }

    /**
     * @dev Multiplies three exponentials, returning a new exponential.
     */
    function mulExp3(
        Exp memory a,
        Exp memory b,
        Exp memory c
    ) internal pure returns (MathError, Exp memory) {
        (MathError err, Exp memory ab) = mulExp(a, b);
        if (err != MathError.NO_ERROR) {
            return (err, ab);
        }
        return mulExp(ab, c);
    }

    /**
     * @dev Subtracts two exponentials, returning a new exponential.
     */
    function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {
        (MathError error, uint256 result) = subUInt(a.mantissa, b.mantissa);

        return (error, Exp({ mantissa: result }));
    }
}

File 18 of 26: ExponentialStorage.sol
/* SPDX-License-Identifier: LPGL-3.0-or-later */
pragma solidity ^0.7.0;

/**
 * @title ExponentialStorage
 * @author Paul Razvan Berg
 * @notice The storage interface ancillary to an Exponential contract.
 */
abstract contract ExponentialStorage {
    struct Exp {
        uint256 mantissa;
    }

    /**
     * @dev In Exponential denomination, 1e18 is 1.
     */
    uint256 internal constant expScale = 1e18;
    uint256 internal constant halfExpScale = expScale / 2;
    uint256 internal constant mantissaOne = expScale;
}

File 19 of 26: FintrollerInterface.sol
/* SPDX-License-Identifier: LPGL-3.0-or-later */
pragma solidity ^0.7.0;

import "./FintrollerStorage.sol";
import "./FyTokenInterface.sol";
import "./ChainlinkOperatorInterface.sol";

abstract contract FintrollerInterface is FintrollerStorage {
    /**
     * CONSTANT FUNCTIONS
     */

    function getBond(FyTokenInterface fyToken)
        external
        view
        virtual
        returns (
            uint256 debtCeiling,
            uint256 collateralizationRatioMantissa,
            bool isBorrowAllowed,
            bool isDepositCollateralAllowed,
            bool isLiquidateBorrowAllowed,
            bool isListed,
            bool isRedeemFyTokenAllowed,
            bool isRepayBorrowAllowed,
            bool isSupplyUnderlyingAllowed
        );

    function getBorrowAllowed(FyTokenInterface fyToken) external view virtual returns (bool);

    function getBondCollateralizationRatio(FyTokenInterface fyToken) external view virtual returns (uint256);

    function getBondDebtCeiling(FyTokenInterface fyToken) external view virtual returns (uint256);

    function getDepositCollateralAllowed(FyTokenInterface fyToken) external view virtual returns (bool);

    function getLiquidateBorrowAllowed(FyTokenInterface fyToken) external view virtual returns (bool);

    function getRedeemFyTokensAllowed(FyTokenInterface fyToken) external view virtual returns (bool);

    function getRepayBorrowAllowed(FyTokenInterface fyToken) external view virtual returns (bool);

    function getSupplyUnderlyingAllowed(FyTokenInterface fyToken) external view virtual returns (bool);

    /**
     * NON-CONSTANT FUNCTIONS
     */

    function listBond(FyTokenInterface fyToken) external virtual returns (bool);

    function setBondCollateralizationRatio(FyTokenInterface fyToken, uint256 newCollateralizationRatioMantissa)
        external
        virtual
        returns (bool);

    function setBondDebtCeiling(FyTokenInterface fyToken, uint256 newDebtCeiling) external virtual returns (bool);

    function setBorrowAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool);

    function setDepositCollateralAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool);

    function setLiquidateBorrowAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool);

    function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external virtual returns (bool);

    function setOracle(ChainlinkOperatorInterface newOracle) external virtual returns (bool);

    function setRedeemFyTokensAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool);

    function setRepayBorrowAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool);

    function setSupplyUnderlyingAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool);

    /**
     * EVENTS
     */
    event ListBond(address indexed admin, FyTokenInterface indexed fyToken);

    event SetBorrowAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state);

    event SetBondCollateralizationRatio(
        address indexed admin,
        FyTokenInterface indexed fyToken,
        uint256 oldCollateralizationRatio,
        uint256 newCollateralizationRatio
    );

    event SetBondDebtCeiling(
        address indexed admin,
        FyTokenInterface indexed fyToken,
        uint256 oldDebtCeiling,
        uint256 newDebtCeiling
    );

    event SetDepositCollateralAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state);

    event SetLiquidateBorrowAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state);

    event SetLiquidationIncentive(
        address indexed admin,
        uint256 oldLiquidationIncentive,
        uint256 newLiquidationIncentive
    );

    event SetRedeemFyTokensAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state);

    event SetRepayBorrowAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state);

    event SetOracle(address indexed admin, address oldOracle, address newOracle);

    event SetSupplyUnderlyingAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state);
}

File 20 of 26: FintrollerStorage.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

import "./Exponential.sol";

import "./FyTokenInterface.sol";
import "./ChainlinkOperatorInterface.sol";

/**
 * @title FintrollerStorage
 * @author Hifi
 */
abstract contract FintrollerStorage is Exponential {
    struct Bond {
        Exp collateralizationRatio;
        uint256 debtCeiling;
        bool isBorrowAllowed;
        bool isDepositCollateralAllowed;
        bool isLiquidateBorrowAllowed;
        bool isListed;
        bool isRedeemFyTokenAllowed;
        bool isRepayBorrowAllowed;
        bool isSupplyUnderlyingAllowed;
    }

    /**
     * @dev Maps the fyToken address to the Bond structs.
     */
    mapping(FyTokenInterface => Bond) internal bonds;

    /**
     * @notice The contract that provides price data for the collateral and the underlying asset.
     */
    ChainlinkOperatorInterface public oracle;

    /**
     * @notice Multiplier representing the discount on collateral that a liquidator receives.
     */
    uint256 public liquidationIncentiveMantissa;

    /**
     * @dev The threshold below which the collateralization ratio cannot be set, equivalent to 100%.
     */
    uint256 internal constant collateralizationRatioLowerBoundMantissa = 1.0e18;

    /**
     * @dev The threshold above which the collateralization ratio cannot be set, equivalent to 10,000%.
     */
    uint256 internal constant collateralizationRatioUpperBoundMantissa = 1.0e20;

    /**
     * @dev The dafault collateralization ratio set when a new bond is listed, equivalent to 150%.
     */
    uint256 internal constant defaultCollateralizationRatioMantissa = 1.5e18;

    /**
     * @dev The threshold below which the liquidation incentive cannot be set, equivalent to 100%.
     */
    uint256 internal constant liquidationIncentiveLowerBoundMantissa = 1.0e18;

    /**
     * @dev The threshold above which the liquidation incentive cannot be set, equivalent to 150%.
     */
    uint256 internal constant liquidationIncentiveUpperBoundMantissa = 1.5e18;

    /**
     * @notice Indicator that this is a Fintroller contract, for inspection.
     */
    bool public constant isFintroller = true;
}

File 21 of 26: FyTokenInterface.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

import "./Erc20Interface.sol";
import "./FyTokenStorage.sol";

/**
 * @title FyTokenInterface
 * @author Hifi
 */
abstract contract FyTokenInterface is
    FyTokenStorage, /* no dependency */
    Erc20Interface /* one dependency */
{
    /**
     * CONSTANT FUNCTIONS
     */
    function isMatured() public view virtual returns (bool);

    /**
     * NON-CONSTANT FUNCTIONS
     */
    function borrow(uint256 borrowAmount) external virtual returns (bool);

    function burn(address holder, uint256 burnAmount) external virtual returns (bool);

    function liquidateBorrow(address borrower, uint256 repayAmount) external virtual returns (bool);

    function mint(address beneficiary, uint256 mintAmount) external virtual returns (bool);

    function repayBorrow(uint256 repayAmount) external virtual returns (bool);

    function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (bool);

    function _setFintroller(FintrollerInterface newFintroller) external virtual returns (bool);

    /**
     * EVENTS
     */
    event Borrow(address indexed borrower, uint256 borrowAmount);

    event LiquidateBorrow(
        address indexed liquidator,
        address indexed borrower,
        uint256 repayAmount,
        uint256 clutchedCollateralAmount
    );

    event RepayBorrow(address indexed payer, address indexed borrower, uint256 repayAmount, uint256 newDebt);

    event SetFintroller(address indexed admin, FintrollerInterface oldFintroller, FintrollerInterface newFintroller);
}

File 22 of 26: FyTokenStorage.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

import "./Erc20Interface.sol";
import "./BalanceSheetInterface.sol";
import "./FintrollerInterface.sol";
import "./RedemptionPoolInterface.sol";

/**
 * @title FyTokenStorage
 * @author Hifi
 */
abstract contract FyTokenStorage {
    /**
     * STORAGE PROPERTIES
     */

    /**
     * @notice The global debt registry.
     */
    BalanceSheetInterface public balanceSheet;

    /**
     * @notice The Erc20 asset that backs the borrows of this fyToken.
     */
    Erc20Interface public collateral;

    /**
     * @notice The ratio between mantissa precision (1e18) and the collateral precision.
     */
    uint256 public collateralPrecisionScalar;

    /**
     * @notice Unix timestamp in seconds for when this token expires.
     */
    uint256 public expirationTime;

    /**
     * @notice The unique Fintroller associated with this contract.
     */
    FintrollerInterface public fintroller;

    /**
     * @notice The unique Redemption Pool associated with this contract.
     */
    RedemptionPoolInterface public redemptionPool;

    /**
     * @notice The Erc20 underlying, or target, asset for this fyToken.
     */
    Erc20Interface public underlying;

    /**
     * @notice The ratio between mantissa precision (1e18) and the underlying precision.
     */
    uint256 public underlyingPrecisionScalar;

    /**
     * @notice Indicator that this is a FyToken contract, for inspection.
     */
    bool public constant isFyToken = true;
}

File 23 of 26: RedemptionPoolInterface.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

import "./RedemptionPoolStorage.sol";

/**
 * @title RedemptionPoolInterface
 * @author Hifi
 */
abstract contract RedemptionPoolInterface is RedemptionPoolStorage {
    /**
     * NON-CONSTANT FUNCTIONS
     */
    function redeemFyTokens(uint256 fyTokenAmount) external virtual returns (bool);

    function supplyUnderlying(uint256 underlyingAmount) external virtual returns (bool);

    /**
     * EVENTS
     */
    event RedeemFyTokens(address indexed account, uint256 fyTokenAmount, uint256 underlyingAmount);

    event SupplyUnderlying(address indexed account, uint256 underlyingAmount, uint256 fyTokenAmount);
}

File 24 of 26: RedemptionPoolStorage.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

import "./FintrollerInterface.sol";
import "./FyTokenInterface.sol";

/**
 * @title RedemptionPoolStorage
 * @author Hifi
 */
abstract contract RedemptionPoolStorage {
    /**
     * @notice The unique Fintroller associated with this contract.
     */
    FintrollerInterface public fintroller;

    /**
     * @notice The amount of the underlying asset available to be redeemed after maturation.
     */
    uint256 public totalUnderlyingSupply;

    /**
     * The unique fyToken associated with this Redemption Pool.
     */
    FyTokenInterface public fyToken;

    /**
     * @notice Indicator that this is a Redemption Pool contract, for inspection.
     */
    bool public constant isRedemptionPool = true;
}

File 25 of 26: ReentrancyGuard.sol
/* SPDX-License-Identifier: LGPL-3.0-or-later */
pragma solidity ^0.7.0;

/**
 * @title ReentrancyGuard
 * @author Paul Razvan Berg
 * @notice 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.
 *
 * @dev Forked from OpenZeppelin
 * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.1.0/contracts/math/ReentrancyGuard.sol
 */
abstract contract ReentrancyGuard {
    bool private notEntered;

    /*
     * Storing an initial 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 percetange 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.
     */
    constructor() {
        notEntered = true;
    }

    /**
     * @notice Prevents a contract from calling itself, directly or indirectly.
     * @dev 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(notEntered, "ERR_REENTRANT_CALL");

        /* Any calls to nonReentrant after this point will fail. */
        notEntered = false;

        _;

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

File 26 of 26: SafeErc20.sol
/* SPDX-License-Identifier: MIT */
pragma solidity ^0.7.0;

import "./Erc20Interface.sol";
import "./Address.sol";

/**
 * @title SafeErc20.sol
 * @author Paul Razvan Berg
 * @notice Wraps 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 Erc20Interface;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 *
 * @dev Forked from OpenZeppelin
 * https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v3.1.0/contracts/utils/Address.sol
 */
library SafeErc20 {
    using Address for address;

    /**
     * INTERNAL FUNCTIONS
     */

    function safeTransfer(
        Erc20Interface token,
        address to,
        uint256 amount
    ) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, amount));
    }

    function safeTransferFrom(
        Erc20Interface token,
        address from,
        address to,
        uint256 amount
    ) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, amount));
    }

    /**
     * PRIVATE FUNCTIONS
     */

    /**
     * @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 cannot 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(Erc20Interface 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 = functionCall(address(token), data, "ERR_SAFE_ERC20_LOW_LEVEL_CALL");
        if (returndata.length > 0) {
            /* Return data is optional. */
            require(abi.decode(returndata, (bool)), "ERR_SAFE_ERC20_ERC20_OPERATION");
        }
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) private returns (bytes memory) {
        require(target.isContract(), "ERR_SAFE_ERC20_CALL_TO_NON_CONTRACT");

        /* solhint-disable-next-line avoid-low-level-calls */
        (bool success, bytes memory returndata) = target.call(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);
            }
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract FintrollerInterface","name":"fintroller_","type":"address"},{"internalType":"contract FyTokenInterface","name":"fyToken_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"contract Erc20Interface","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"recoverAmount","type":"uint256"}],"name":"Recover","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"fyTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"RedeemFyTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"contract Erc20Interface[]","name":"nonRecoverableTokens","type":"address[]"}],"name":"SetNonRecoverableTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"underlyingAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fyTokenAmount","type":"uint256"}],"name":"SupplyUnderlying","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"TransferAdmin","type":"event"},{"inputs":[{"internalType":"contract Erc20Interface","name":"token","type":"address"},{"internalType":"uint256","name":"recoverAmount","type":"uint256"}],"name":"_recover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"_renounceAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Erc20Interface[]","name":"tokens","type":"address[]"}],"name":"_setNonRecoverableTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"_transferAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fintroller","outputs":[{"internalType":"contract FintrollerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fyToken","outputs":[{"internalType":"contract FyTokenInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRedemptionPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nonRecoverableTokens","outputs":[{"internalType":"contract Erc20Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fyTokenAmount","type":"uint256"}],"name":"redeemFyTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"supplyUnderlying","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalUnderlyingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b50604051611d4c380380611d4c8339818101604052604081101561003357600080fd5b5080516020909101516000805460ff1916600117815560048054336101008102610100600160a81b031990921691909117909155604051909182917fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908290a35081600060016101000a8154816001600160a01b0302191690836001600160a01b03160217905550600060019054906101000a90046001600160a01b03166001600160a01b03166358f25c506040518163ffffffff1660e01b815260040160206040518083038186803b15801561010957600080fd5b505afa15801561011d573d6000803e3d6000fd5b505050506040513d602081101561013357600080fd5b5050600280546001600160a01b0319166001600160a01b039290921691909117905550611be7806101656000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063dde4bec011610071578063dde4bec014610166578063e02dcb17146101d4578063e6abb5ae146101f1578063ede4c0cc14610217578063f1374d181461021f578063f851a4401461023c576100b4565b8063143a08d4146100b95780631c2872aa146100d357806373805ae2146101015780639e6ae5a01461011d578063bfa2530814610156578063dc3bfba91461015e575b600080fd5b6100c1610244565b60408051918252519081900360200190f35b6100ff600480360360408110156100e957600080fd5b506001600160a01b03813516906020013561024a565b005b6101096106ad565b604080519115158252519081900360200190f35b61013a6004803603602081101561013357600080fd5b50356106b2565b604080516001600160a01b039092168252519081900360200190f35b6100ff6106dc565b61013a610780565b6100ff6004803603602081101561017c57600080fd5b810190602081018135600160201b81111561019657600080fd5b8201836020820111156101a857600080fd5b803590602001918460208302840111600160201b831117156101c957600080fd5b50909250905061078f565b610109600480360360208110156101ea57600080fd5b5035610a56565b6100ff6004803603602081101561020757600080fd5b50356001600160a01b0316611018565b61013a61112e565b6101096004803603602081101561023557600080fd5b5035611142565b61013a6116e6565b60015481565b60045461010090046001600160a01b0316331461029e576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60045460ff1615156001146102ef576040805162461bcd60e51b815260206004820152601260248201527111549497d393d517d253925510531256915160721b604482015290519081900360640190fd5b60008111610337576040805162461bcd60e51b815260206004820152601060248201526f4552525f5245434f5645525f5a45524f60801b604482015290519081900360640190fd5b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561037257600080fd5b505afa158015610386573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156103af57600080fd5b8101908080516040519392919084600160201b8211156103ce57600080fd5b9083019060208201858111156103e357600080fd5b8251600160201b8111828201881017156103fc57600080fd5b82525081516020918201929091019080838360005b83811015610429578181015183820152602001610411565b50505050905090810190601f1680156104565780820380516001836020036101000a031916815260200191505b506040525050508051906020012090506000600380549050905060005b81811015610637576003818154811061048857fe5b6000918252602090912001546001600160a01b038681169116148015906105f45750600381815481106104b757fe5b6000918252602082200154604080516395d89b4160e01b815290516001600160a01b03909216926395d89b4192600480840193829003018186803b1580156104fe57600080fd5b505afa158015610512573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561053b57600080fd5b8101908080516040519392919084600160201b82111561055a57600080fd5b90830190602082018581111561056f57600080fd5b8251600160201b81118282018810171561058857600080fd5b82525081516020918201929091019080838360005b838110156105b557818101518382015260200161059d565b50505050905090810190601f1680156105e25780820380516001836020036101000a031916815260200191505b50604052505050805190602001208314155b61062f5760405162461bcd60e51b8152600401808060200182810382526021815260200180611b226021913960400191505060405180910390fd5b600101610473565b50600454610657906001600160a01b0386811691610100900416856116fa565b600454604080516001600160a01b03878116825260208201879052825161010090940416927ff6891c84a6c6af32a6d052172a8acc4c631b1d5057ffa2bc1da268b6938ea2da929181900390910190a250505050565b600181565b600381815481106106c257600080fd5b6000918252602090912001546001600160a01b0316905081565b60045461010090046001600160a01b03163314610730576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60045460405160009161010090046001600160a01b0316907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908390a360048054610100600160a81b0319169055565b6002546001600160a01b031681565b60045461010090046001600160a01b031633146107e3576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60045460ff161561082c576040805162461bcd60e51b815260206004820152600e60248201526d11549497d253925510531256915160921b604482015290519081900360640190fd5b8060005b818110156109c95783838281811061084457fe5b905060200201356001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561088c57600080fd5b505afa1580156108a0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156108c957600080fd5b8101908080516040519392919084600160201b8211156108e857600080fd5b9083019060208201858111156108fd57600080fd5b8251600160201b81118282018810171561091657600080fd5b82525081516020918201929091019080838360005b8381101561094357818101518382015260200161092b565b50505050905090810190601f1680156109705780820380516001836020036101000a031916815260200191505b5060405250505050600384848381811061098657fe5b835460018181018655600095865260209586902090910180546001600160a01b0319166001600160a01b0396909302949094013594909416179091555001610830565b5060048054600160ff1990911617908190556040805160208082528082018690526101009093046001600160a01b0316927fd877543bef27da9036243421e623413c8fdd78d7d183cc93d8f3cddbd657a2ed928792879290918291908201908590850280828437600083820152604051601f909101601f19169092018290039550909350505050a2505050565b6000805460ff16610aa3576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff19169055610ab5611af8565b600260009054906101000a90046001600160a01b03166001600160a01b031663da284dcc6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0357600080fd5b505afa158015610b17573d6000803e3d6000fd5b505050506040513d6020811015610b2d57600080fd5b5051421015610b7a576040805162461bcd60e51b815260206004820152601460248201527311549497d093d39117d393d517d350551554915160621b604482015290519081900360640190fd5b60008311610bcf576040805162461bcd60e51b815260206004820152601860248201527f4552525f52454445454d5f4659544f4b454e535f5a45524f0000000000000000604482015290519081900360640190fd5b6000546002546040805163162fdba360e01b81526001600160a01b03928316600482015290516101009093049091169163162fdba391602480820192602092909190829003018186803b158015610c2557600080fd5b505afa158015610c39573d6000803e3d6000fd5b505050506040513d6020811015610c4f57600080fd5b5051610ca2576040805162461bcd60e51b815260206004820152601f60248201527f4552525f52454445454d5f4659544f4b454e535f4e4f545f414c4c4f57454400604482015290519081900360640190fd5b600260009054906101000a90046001600160a01b03166001600160a01b0316631a0de6fa6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cf057600080fd5b505afa158015610d04573d6000803e3d6000fd5b505050506040513d6020811015610d1a57600080fd5b505160408201819052600114610dc257610d38838260400151611751565b6060830181905282826004811115610d4c57fe5b6004811115610d5757fe5b9052506000905081516004811115610d6b57fe5b14610dbd576040805162461bcd60e51b815260206004820152601e60248201527f4552525f52454445454d5f4659544f4b454e535f4d4154485f4552524f520000604482015290519081900360640190fd5b610dca565b606081018390525b60015481606001511115610e0f5760405162461bcd60e51b815260040180806020018281038252602b815260200180611b43602b913960400191505060405180910390fd5b610e1f600154826060015161177d565b6020830181905282826004811115610e3357fe5b6004811115610e3e57fe5b9052506000905081516004811115610e5257fe5b14610e5957fe5b60208082015160015560025460408051632770a7eb60e21b81523360048201526024810187905290516001600160a01b0390921692639dc29fac926044808401938290030181600087803b158015610eb057600080fd5b505af1158015610ec4573d6000803e3d6000fd5b505050506040513d6020811015610eda57600080fd5b5051610f2d576040805162461bcd60e51b815260206004820152601f60248201527f4552525f535550504c595f554e4445524c59494e475f43414c4c5f4255524e00604482015290519081900360640190fd5b610fc0338260600151600260009054906101000a90046001600160a01b03166001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8457600080fd5b505afa158015610f98573d6000803e3d6000fd5b505050506040513d6020811015610fae57600080fd5b50516001600160a01b031691906116fa565b6060810151604080518581526020810192909252805133927f885a0ef214a8c0b5d41cbf3cd2292d459773279061790ae6c1e654483828048792908290030190a260019150506000805460ff19166001179055919050565b60045461010090046001600160a01b0316331461106c576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b6001600160a01b0381166110c7576040805162461bcd60e51b815260206004820152601a60248201527f4552525f5345545f41444d494e5f5a45524f5f41444452455353000000000000604482015290519081900360640190fd5b6004546040516001600160a01b0380841692610100900416907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf8090600090a3600480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60005461010090046001600160a01b031681565b6000805460ff1661118f576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556111a1611af8565b600260009054906101000a90046001600160a01b03166001600160a01b031663da284dcc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156111ef57600080fd5b505afa158015611203573d6000803e3d6000fd5b505050506040513d602081101561121957600080fd5b50514210611261576040805162461bcd60e51b815260206004820152601060248201526f11549497d093d39117d350551554915160821b604482015290519081900360640190fd5b600083116112b6576040805162461bcd60e51b815260206004820152601a60248201527f4552525f535550504c595f554e4445524c59494e475f5a45524f000000000000604482015290519081900360640190fd5b6000546002546040805163e79628ab60e01b81526001600160a01b03928316600482015290516101009093049091169163e79628ab91602480820192602092909190829003018186803b15801561130c57600080fd5b505afa158015611320573d6000803e3d6000fd5b505050506040513d602081101561133657600080fd5b50516113735760405162461bcd60e51b8152600401808060200182810382526021815260200180611b6e6021913960400191505060405180910390fd5b61137f600154846117a0565b604083018190528282600481111561139357fe5b600481111561139e57fe5b90525060009050815160048111156113b257fe5b14611404576040805162461bcd60e51b815260206004820181905260248201527f4552525f535550504c595f554e4445524c59494e475f4d4154485f4552524f52604482015290519081900360640190fd5b6040808201516001556002548151630d06f37d60e11b815291516001600160a01b0390911691631a0de6fa916004808301926020929190829003018186803b15801561144f57600080fd5b505afa158015611463573d6000803e3d6000fd5b505050506040513d602081101561147957600080fd5b505160608201819052600114611521576114978382606001516117c6565b60208301819052828260048111156114ab57fe5b60048111156114b657fe5b90525060009050815160048111156114ca57fe5b1461151c576040805162461bcd60e51b815260206004820181905260248201527f4552525f535550504c595f554e4445524c59494e475f4d4154485f4552524f52604482015290519081900360640190fd5b611529565b602081018390525b600254602080830151604080516340c10f1960e01b81523360048201526024810192909252516001600160a01b03909316926340c10f19926044808401939192918290030181600087803b15801561158057600080fd5b505af1158015611594573d6000803e3d6000fd5b505050506040513d60208110156115aa57600080fd5b50516115fd576040805162461bcd60e51b815260206004820152601f60248201527f4552525f535550504c595f554e4445524c59494e475f43414c4c5f4d494e5400604482015290519081900360640190fd5b61168e333085600260009054906101000a90046001600160a01b03166001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561165157600080fd5b505afa158015611665573d6000803e3d6000fd5b505050506040513d602081101561167b57600080fd5b50516001600160a01b0316929190611805565b6020808201516040805186815292830191909152805133927fc460d7cbd3e39052de48c19518b5af10728a5349bc2870e47b5a67ffc32d200d92908290030190a260019150506000805460ff19166001179055919050565b60045461010090046001600160a01b031681565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261174c908490611865565b505050565b600080826117655750600190506000611776565b600083858161177057fe5b04915091505b9250929050565b600080838311611794575060009050818303611776565b50600390506000611776565b6000808383018481106117b857600092509050611776565b600260009250925050611776565b600080836117d957506000905080611776565b838302838582816117e657fe5b04146117fa57600260009250925050611776565b600092509050611776565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261185f908590611865565b50505050565b60006118a783836040518060400160405280601d81526020017f4552525f534146455f45524332305f4c4f575f4c4556454c5f43414c4c000000815250611919565b80519091501561174c578080602001905160208110156118c657600080fd5b505161174c576040805162461bcd60e51b815260206004820152601e60248201527f4552525f534146455f45524332305f45524332305f4f5045524154494f4e0000604482015290519081900360640190fd5b606061192d846001600160a01b0316611abc565b6119685760405162461bcd60e51b8152600401808060200182810382526023815260200180611b8f6023913960400191505060405180910390fd5b600080856001600160a01b0316856040518082805190602001908083835b602083106119a55780518252601f199092019160209182019101611986565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611a07576040519150601f19603f3d011682016040523d82523d6000602084013e611a0c565b606091505b50915091508115611a20579150611ab59050565b805115611a305780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611a7a578181015183820152602001611a62565b50505050905090810190601f168015611aa75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611af057508115155b949350505050565b60408051608081019091528060008152602001600081526020016000815260200160008152509056fe4552525f5245434f5645525f4e4f4e5f5245434f56455241424c455f544f4b454e4552525f52454445454d5f4659544f4b454e535f494e53554646494349454e545f554e4445524c59494e474552525f535550504c595f554e4445524c59494e475f4e4f545f414c4c4f5745444552525f534146455f45524332305f43414c4c5f544f5f4e4f4e5f434f4e5452414354a2646970667358221220504e7960f16a46f68ab102d0a6c00cc3b4e3021515e5b688b79030739924e0a964736f6c63430007060033000000000000000000000000ed4348fc8b1b634b3a0eadabfd32530046b89c60000000000000000000000000db64e1f7bbb2b8bd35b63633bb1e664cb34ae540

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063dde4bec011610071578063dde4bec014610166578063e02dcb17146101d4578063e6abb5ae146101f1578063ede4c0cc14610217578063f1374d181461021f578063f851a4401461023c576100b4565b8063143a08d4146100b95780631c2872aa146100d357806373805ae2146101015780639e6ae5a01461011d578063bfa2530814610156578063dc3bfba91461015e575b600080fd5b6100c1610244565b60408051918252519081900360200190f35b6100ff600480360360408110156100e957600080fd5b506001600160a01b03813516906020013561024a565b005b6101096106ad565b604080519115158252519081900360200190f35b61013a6004803603602081101561013357600080fd5b50356106b2565b604080516001600160a01b039092168252519081900360200190f35b6100ff6106dc565b61013a610780565b6100ff6004803603602081101561017c57600080fd5b810190602081018135600160201b81111561019657600080fd5b8201836020820111156101a857600080fd5b803590602001918460208302840111600160201b831117156101c957600080fd5b50909250905061078f565b610109600480360360208110156101ea57600080fd5b5035610a56565b6100ff6004803603602081101561020757600080fd5b50356001600160a01b0316611018565b61013a61112e565b6101096004803603602081101561023557600080fd5b5035611142565b61013a6116e6565b60015481565b60045461010090046001600160a01b0316331461029e576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60045460ff1615156001146102ef576040805162461bcd60e51b815260206004820152601260248201527111549497d393d517d253925510531256915160721b604482015290519081900360640190fd5b60008111610337576040805162461bcd60e51b815260206004820152601060248201526f4552525f5245434f5645525f5a45524f60801b604482015290519081900360640190fd5b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561037257600080fd5b505afa158015610386573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156103af57600080fd5b8101908080516040519392919084600160201b8211156103ce57600080fd5b9083019060208201858111156103e357600080fd5b8251600160201b8111828201881017156103fc57600080fd5b82525081516020918201929091019080838360005b83811015610429578181015183820152602001610411565b50505050905090810190601f1680156104565780820380516001836020036101000a031916815260200191505b506040525050508051906020012090506000600380549050905060005b81811015610637576003818154811061048857fe5b6000918252602090912001546001600160a01b038681169116148015906105f45750600381815481106104b757fe5b6000918252602082200154604080516395d89b4160e01b815290516001600160a01b03909216926395d89b4192600480840193829003018186803b1580156104fe57600080fd5b505afa158015610512573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561053b57600080fd5b8101908080516040519392919084600160201b82111561055a57600080fd5b90830190602082018581111561056f57600080fd5b8251600160201b81118282018810171561058857600080fd5b82525081516020918201929091019080838360005b838110156105b557818101518382015260200161059d565b50505050905090810190601f1680156105e25780820380516001836020036101000a031916815260200191505b50604052505050805190602001208314155b61062f5760405162461bcd60e51b8152600401808060200182810382526021815260200180611b226021913960400191505060405180910390fd5b600101610473565b50600454610657906001600160a01b0386811691610100900416856116fa565b600454604080516001600160a01b03878116825260208201879052825161010090940416927ff6891c84a6c6af32a6d052172a8acc4c631b1d5057ffa2bc1da268b6938ea2da929181900390910190a250505050565b600181565b600381815481106106c257600080fd5b6000918252602090912001546001600160a01b0316905081565b60045461010090046001600160a01b03163314610730576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60045460405160009161010090046001600160a01b0316907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908390a360048054610100600160a81b0319169055565b6002546001600160a01b031681565b60045461010090046001600160a01b031633146107e3576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60045460ff161561082c576040805162461bcd60e51b815260206004820152600e60248201526d11549497d253925510531256915160921b604482015290519081900360640190fd5b8060005b818110156109c95783838281811061084457fe5b905060200201356001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561088c57600080fd5b505afa1580156108a0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156108c957600080fd5b8101908080516040519392919084600160201b8211156108e857600080fd5b9083019060208201858111156108fd57600080fd5b8251600160201b81118282018810171561091657600080fd5b82525081516020918201929091019080838360005b8381101561094357818101518382015260200161092b565b50505050905090810190601f1680156109705780820380516001836020036101000a031916815260200191505b5060405250505050600384848381811061098657fe5b835460018181018655600095865260209586902090910180546001600160a01b0319166001600160a01b0396909302949094013594909416179091555001610830565b5060048054600160ff1990911617908190556040805160208082528082018690526101009093046001600160a01b0316927fd877543bef27da9036243421e623413c8fdd78d7d183cc93d8f3cddbd657a2ed928792879290918291908201908590850280828437600083820152604051601f909101601f19169092018290039550909350505050a2505050565b6000805460ff16610aa3576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff19169055610ab5611af8565b600260009054906101000a90046001600160a01b03166001600160a01b031663da284dcc6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0357600080fd5b505afa158015610b17573d6000803e3d6000fd5b505050506040513d6020811015610b2d57600080fd5b5051421015610b7a576040805162461bcd60e51b815260206004820152601460248201527311549497d093d39117d393d517d350551554915160621b604482015290519081900360640190fd5b60008311610bcf576040805162461bcd60e51b815260206004820152601860248201527f4552525f52454445454d5f4659544f4b454e535f5a45524f0000000000000000604482015290519081900360640190fd5b6000546002546040805163162fdba360e01b81526001600160a01b03928316600482015290516101009093049091169163162fdba391602480820192602092909190829003018186803b158015610c2557600080fd5b505afa158015610c39573d6000803e3d6000fd5b505050506040513d6020811015610c4f57600080fd5b5051610ca2576040805162461bcd60e51b815260206004820152601f60248201527f4552525f52454445454d5f4659544f4b454e535f4e4f545f414c4c4f57454400604482015290519081900360640190fd5b600260009054906101000a90046001600160a01b03166001600160a01b0316631a0de6fa6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cf057600080fd5b505afa158015610d04573d6000803e3d6000fd5b505050506040513d6020811015610d1a57600080fd5b505160408201819052600114610dc257610d38838260400151611751565b6060830181905282826004811115610d4c57fe5b6004811115610d5757fe5b9052506000905081516004811115610d6b57fe5b14610dbd576040805162461bcd60e51b815260206004820152601e60248201527f4552525f52454445454d5f4659544f4b454e535f4d4154485f4552524f520000604482015290519081900360640190fd5b610dca565b606081018390525b60015481606001511115610e0f5760405162461bcd60e51b815260040180806020018281038252602b815260200180611b43602b913960400191505060405180910390fd5b610e1f600154826060015161177d565b6020830181905282826004811115610e3357fe5b6004811115610e3e57fe5b9052506000905081516004811115610e5257fe5b14610e5957fe5b60208082015160015560025460408051632770a7eb60e21b81523360048201526024810187905290516001600160a01b0390921692639dc29fac926044808401938290030181600087803b158015610eb057600080fd5b505af1158015610ec4573d6000803e3d6000fd5b505050506040513d6020811015610eda57600080fd5b5051610f2d576040805162461bcd60e51b815260206004820152601f60248201527f4552525f535550504c595f554e4445524c59494e475f43414c4c5f4255524e00604482015290519081900360640190fd5b610fc0338260600151600260009054906101000a90046001600160a01b03166001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8457600080fd5b505afa158015610f98573d6000803e3d6000fd5b505050506040513d6020811015610fae57600080fd5b50516001600160a01b031691906116fa565b6060810151604080518581526020810192909252805133927f885a0ef214a8c0b5d41cbf3cd2292d459773279061790ae6c1e654483828048792908290030190a260019150506000805460ff19166001179055919050565b60045461010090046001600160a01b0316331461106c576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b6001600160a01b0381166110c7576040805162461bcd60e51b815260206004820152601a60248201527f4552525f5345545f41444d494e5f5a45524f5f41444452455353000000000000604482015290519081900360640190fd5b6004546040516001600160a01b0380841692610100900416907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf8090600090a3600480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60005461010090046001600160a01b031681565b6000805460ff1661118f576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556111a1611af8565b600260009054906101000a90046001600160a01b03166001600160a01b031663da284dcc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156111ef57600080fd5b505afa158015611203573d6000803e3d6000fd5b505050506040513d602081101561121957600080fd5b50514210611261576040805162461bcd60e51b815260206004820152601060248201526f11549497d093d39117d350551554915160821b604482015290519081900360640190fd5b600083116112b6576040805162461bcd60e51b815260206004820152601a60248201527f4552525f535550504c595f554e4445524c59494e475f5a45524f000000000000604482015290519081900360640190fd5b6000546002546040805163e79628ab60e01b81526001600160a01b03928316600482015290516101009093049091169163e79628ab91602480820192602092909190829003018186803b15801561130c57600080fd5b505afa158015611320573d6000803e3d6000fd5b505050506040513d602081101561133657600080fd5b50516113735760405162461bcd60e51b8152600401808060200182810382526021815260200180611b6e6021913960400191505060405180910390fd5b61137f600154846117a0565b604083018190528282600481111561139357fe5b600481111561139e57fe5b90525060009050815160048111156113b257fe5b14611404576040805162461bcd60e51b815260206004820181905260248201527f4552525f535550504c595f554e4445524c59494e475f4d4154485f4552524f52604482015290519081900360640190fd5b6040808201516001556002548151630d06f37d60e11b815291516001600160a01b0390911691631a0de6fa916004808301926020929190829003018186803b15801561144f57600080fd5b505afa158015611463573d6000803e3d6000fd5b505050506040513d602081101561147957600080fd5b505160608201819052600114611521576114978382606001516117c6565b60208301819052828260048111156114ab57fe5b60048111156114b657fe5b90525060009050815160048111156114ca57fe5b1461151c576040805162461bcd60e51b815260206004820181905260248201527f4552525f535550504c595f554e4445524c59494e475f4d4154485f4552524f52604482015290519081900360640190fd5b611529565b602081018390525b600254602080830151604080516340c10f1960e01b81523360048201526024810192909252516001600160a01b03909316926340c10f19926044808401939192918290030181600087803b15801561158057600080fd5b505af1158015611594573d6000803e3d6000fd5b505050506040513d60208110156115aa57600080fd5b50516115fd576040805162461bcd60e51b815260206004820152601f60248201527f4552525f535550504c595f554e4445524c59494e475f43414c4c5f4d494e5400604482015290519081900360640190fd5b61168e333085600260009054906101000a90046001600160a01b03166001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561165157600080fd5b505afa158015611665573d6000803e3d6000fd5b505050506040513d602081101561167b57600080fd5b50516001600160a01b0316929190611805565b6020808201516040805186815292830191909152805133927fc460d7cbd3e39052de48c19518b5af10728a5349bc2870e47b5a67ffc32d200d92908290030190a260019150506000805460ff19166001179055919050565b60045461010090046001600160a01b031681565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261174c908490611865565b505050565b600080826117655750600190506000611776565b600083858161177057fe5b04915091505b9250929050565b600080838311611794575060009050818303611776565b50600390506000611776565b6000808383018481106117b857600092509050611776565b600260009250925050611776565b600080836117d957506000905080611776565b838302838582816117e657fe5b04146117fa57600260009250925050611776565b600092509050611776565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261185f908590611865565b50505050565b60006118a783836040518060400160405280601d81526020017f4552525f534146455f45524332305f4c4f575f4c4556454c5f43414c4c000000815250611919565b80519091501561174c578080602001905160208110156118c657600080fd5b505161174c576040805162461bcd60e51b815260206004820152601e60248201527f4552525f534146455f45524332305f45524332305f4f5045524154494f4e0000604482015290519081900360640190fd5b606061192d846001600160a01b0316611abc565b6119685760405162461bcd60e51b8152600401808060200182810382526023815260200180611b8f6023913960400191505060405180910390fd5b600080856001600160a01b0316856040518082805190602001908083835b602083106119a55780518252601f199092019160209182019101611986565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611a07576040519150601f19603f3d011682016040523d82523d6000602084013e611a0c565b606091505b50915091508115611a20579150611ab59050565b805115611a305780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611a7a578181015183820152602001611a62565b50505050905090810190601f168015611aa75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611af057508115155b949350505050565b60408051608081019091528060008152602001600081526020016000815260200160008152509056fe4552525f5245434f5645525f4e4f4e5f5245434f56455241424c455f544f4b454e4552525f52454445454d5f4659544f4b454e535f494e53554646494349454e545f554e4445524c59494e474552525f535550504c595f554e4445524c59494e475f4e4f545f414c4c4f5745444552525f534146455f45524332305f43414c4c5f544f5f4e4f4e5f434f4e5452414354a2646970667358221220504e7960f16a46f68ab102d0a6c00cc3b4e3021515e5b688b79030739924e0a964736f6c63430007060033

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

000000000000000000000000ed4348fc8b1b634b3a0eadabfd32530046b89c60000000000000000000000000db64e1f7bbb2b8bd35b63633bb1e664cb34ae540

-----Decoded View---------------
Arg [0] : fintroller_ (address): 0xED4348fC8B1B634b3A0eadabFD32530046B89C60
Arg [1] : fyToken_ (address): 0xDB64e1F7bbb2B8bD35b63633BB1E664CB34aE540

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000ed4348fc8b1b634b3a0eadabfd32530046b89c60
Arg [1] : 000000000000000000000000db64e1f7bbb2b8bd35b63633bb1e664cb34ae540


Deployed Bytecode Sourcemap

570:6291:21:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;483:36:23;;;:::i;:::-;;;;;;;;;;;;;;;;2117:1196:11;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;2117:1196:11;;;;;;;;:::i;:::-;;742:44:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;227::13;;;;;;;;;;;;;;;;-1:-1:-1;227:44:13;;:::i;:::-;;;;-1:-1:-1;;;;;227:44:13;;;;;;;;;;;;;;1615:150:1;;;:::i;606:31:23:-;;;:::i;934:625:11:-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;934:625:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;934:625:11;;;;;;;;;;-1:-1:-1;934:625:11;;-1:-1:-1;934:625:11;-1:-1:-1;934:625:11;:::i;2191:2001:21:-;;;;;;;;;;;;;;;;-1:-1:-1;2191:2001:21;;:::i;1969:230:1:-;;;;;;;;;;;;;;;;-1:-1:-1;1969:230:1;-1:-1:-1;;;;;1969:230:1;;:::i;330:37:23:-;;;:::i;4985:1874:21:-;;;;;;;;;;;;;;;;-1:-1:-1;4985:1874:21;;:::i;182:20:3:-;;;:::i;483:36:23:-;;;;:::o;2117:1196:11:-;931:5:1;;;;;-1:-1:-1;;;;;931:5:1;940:10;931:19;923:45;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;;;;2247:20:11::1;::::0;::::1;;:28;;:20:::0;:28:::1;2239:59;;;::::0;;-1:-1:-1;;;2239:59:11;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;2239:59:11;;;;;;;;;;;;;::::1;;2332:1;2316:13;:17;2308:46;;;::::0;;-1:-1:-1;;;2308:46:11;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;2308:46:11;;;;;;;;;;;;;::::1;;2365:23;2407:5;-1:-1:-1::0;;;;;2407:12:11::1;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;2407:14:11::1;::::0;::::1;;::::0;::::1;::::0;::::1;;;;;::::0;::::1;;;;;;;;;;;;;;;-1:-1:-1::0;;;2407:14:11::1;;;;;;::::0;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;;;2407:14:11;::::1;::::0;;::::1;::::0;-1:-1:-1;2407:14:11::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;2407:14:11;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;;::::1;;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;2391:32;;;;;;2365:58;;2433:14;2450:20;:27;;;;2433:44;;2882:9;2877:300;2901:6;2897:1;:10;2877:300;;;2982:20;3003:1;2982:23;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;2956:50:11;;::::1;2982:23:::0;::::1;2956:50;::::0;::::1;::::0;:143:::1;;;3065:20;3086:1;3065:23;;;;;;;;;::::0;;;::::1;::::0;;::::1;::::0;:32:::1;::::0;;-1:-1:-1;;;3065:32:11;;;;-1:-1:-1;;;;;3065:23:11;;::::1;::::0;:30:::1;::::0;:32:::1;::::0;;::::1;::::0;;;;;;:23;:32;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;3065:32:11::1;::::0;::::1;;::::0;::::1;::::0;::::1;;;;;::::0;::::1;;;;;;;;;;;;;;;-1:-1:-1::0;;;3065:32:11::1;;;;;;::::0;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;;;3065:32:11;::::1;::::0;;::::1;::::0;-1:-1:-1;3065:32:11::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;3065:32:11;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;;::::1;;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;3049:50;;;;;;3030:15;:69;;2956:143;2931:235;;;;-1:-1:-1::0;;;2931:235:11::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2914:1;2909:6;2877:300;;;-1:-1:-1::0;3233:5:11::1;::::0;3214:40:::1;::::0;-1:-1:-1;;;;;3214:18:11;;::::1;::::0;3233:5:::1;::::0;::::1;;3240:13:::0;3214:18:::1;:40::i;:::-;3278:5;::::0;3270:36:::1;::::0;;-1:-1:-1;;;;;3270:36:11;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;3278:5:::1;::::0;;::::1;;::::0;3270:36:::1;::::0;;;;;;;;;::::1;978:1:1;;2117:1196:11::0;;:::o;742:44:23:-;782:4;742:44;:::o;227::13:-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;227:44:13;;-1:-1:-1;227:44:13;:::o;1615:150:1:-;931:5;;;;;-1:-1:-1;;;;;931:5:1;940:10;931:19;923:45;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;;;;1706:5:::1;::::0;1692:35:::1;::::0;1721:4:::1;::::0;1706:5:::1;::::0;::::1;-1:-1:-1::0;;;;;1706:5:1::1;::::0;1692:35:::1;::::0;1721:4;;1692:35:::1;1737:5;:21:::0;;-1:-1:-1;;;;;;1737:21:1::1;::::0;;1615:150::o;606:31:23:-;;;-1:-1:-1;;;;;606:31:23;;:::o;934:625:11:-;931:5:1;;;;;-1:-1:-1;;;;;931:5:1;940:10;931:19;923:45;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;;;;1069:20:11::1;::::0;::::1;;:29;1061:56;;;::::0;;-1:-1:-1;;;1061:56:11;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1061:56:11;;;;;;;;;;;;;::::1;;1230:6:::0;1213:14:::1;1253:133;1277:6;1273:1;:10;1253:133;;;1307:6;;1314:1;1307:9;;;;;;;;;;;;;-1:-1:-1::0;;;;;1307:9:11::1;-1:-1:-1::0;;;;;1307:16:11::1;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;1307:18:11::1;::::0;::::1;;::::0;::::1;::::0;::::1;;;;;::::0;::::1;;;;;;;;;;;;;;;-1:-1:-1::0;;;1307:18:11::1;;;;;;::::0;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;;;1307:18:11;::::1;::::0;;::::1;::::0;-1:-1:-1;1307:18:11::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;1307:18:11;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;;::::1;;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;1339:20;1365:6;;1372:1;1365:9;;;;;;;1339:36:::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;1339:36:11;;;1365:9:::1;1339:36:::0;;;;;;::::1;::::0;;-1:-1:-1;;;;;;1339:36:11::1;-1:-1:-1::0;;;;;1365:9:11;;;::::1;::::0;;;::::1;;::::0;;;::::1;1339:36;::::0;;;-1:-1:-1;1285:6:11::1;1253:133;;;-1:-1:-1::0;1471:20:11::1;:27:::0;;1494:4:::1;-1:-1:-1::0;;1471:27:11;;::::1;;::::0;;;;1514:38:::1;::::0;;::::1;::::0;;;;;::::1;::::0;;;1471:27:::1;1538:5:::0;;::::1;-1:-1:-1::0;;;;;1538:5:11::1;::::0;1514:38:::1;::::0;1545:6;;1514:38;;;;;;;;;;1545:6;;1514:38;::::1;::::0;1545:6;1514:38;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;-1:-1:-1::0;;1514:38:11::1;::::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;1514:38:11;;-1:-1:-1;;;;1514:38:11::1;978:1:1;934:625:11::0;;:::o;2191:2001:21:-;2278:4;1817:10:24;;;;1809:41;;;;;-1:-1:-1;;;1809:41:24;;;;;;;;;;;;-1:-1:-1;;;1809:41:24;;;;;;;;;;;;;;;1942:5;1929:18;;-1:-1:-1;;1929:18:24;;;2294:35:21::1;;:::i;:::-;2406:7;;;;;;;;;-1:-1:-1::0;;;;;2406:7:21::1;-1:-1:-1::0;;;;;2406:22:21::1;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;2406:24:21;2387:15:::1;:43;;2379:76;;;::::0;;-1:-1:-1;;;2379:76:21;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;2379:76:21;;;;;;;;;;;;;::::1;;2532:1;2516:13;:17;2508:54;;;::::0;;-1:-1:-1;;;2508:54:21;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;2654:10;::::0;2690:7:::1;::::0;2654:44:::1;::::0;;-1:-1:-1;;;2654:44:21;;-1:-1:-1;;;;;2690:7:21;;::::1;2654:44;::::0;::::1;::::0;;;:10:::1;::::0;;::::1;::::0;;::::1;::::0;:35:::1;::::0;:44;;;;;::::1;::::0;;;;;;;;;:10;:44;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;2654:44:21;2646:88:::1;;;::::0;;-1:-1:-1;;;2646:88:21;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;2987:7;;;;;;;;;-1:-1:-1::0;;;;;2987:7:21::1;-1:-1:-1::0;;;;;2987:33:21::1;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;2987:35:21;2954:30:::1;::::0;::::1;:68:::0;;;3070:1:::1;3036:35;3032:319;;3127:54;3135:13;3150:4;:30;;;3127:7;:54::i;:::-;3102:21;::::0;::::1;3087:94:::0;;;3088:4;3087:94;::::1;::::0;::::1;;;;;;;;;;;;;;::::0;;-1:-1:-1;3219:18:21::1;::::0;-1:-1:-1;3203:12:21;;:34:::1;::::0;::::1;;;;;;;3195:77;;;::::0;;-1:-1:-1;;;3195:77:21;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;3032:319;;;3303:21;::::0;::::1;:37:::0;;;3032:319:::1;3443:21;;3418:4;:21;;;:46;;3410:102;;;;-1:-1:-1::0;;;3410:102:21::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3639:53;3647:21;;3670:4;:21;;;3639:7;:53::i;:::-;3606:29;::::0;::::1;3591:101:::0;;;3592:4;3591:101;::::1;::::0;::::1;;;;;;;;;;;;;;::::0;;-1:-1:-1;3725:18:21::1;::::0;-1:-1:-1;3709:12:21;;:34:::1;::::0;::::1;;;;;;;3702:42;;;;3778:29;::::0;;::::1;::::0;3754:21:::1;:53:::0;3873:7:::1;::::0;:39:::1;::::0;;-1:-1:-1;;;3873:39:21;;3886:10:::1;3873:39;::::0;::::1;::::0;;;;;;;;;-1:-1:-1;;;;;3873:7:21;;::::1;::::0;:12:::1;::::0;:39;;;;;;;;;;:7:::1;::::0;:39;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;3873:39:21;3865:83:::1;;;::::0;;-1:-1:-1;;;3865:83:21;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;4015:68;4049:10;4061:4;:21;;;4015:7;;;;;;;;;-1:-1:-1::0;;;;;4015:7:21::1;-1:-1:-1::0;;;;;4015:18:21::1;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;4015:20:21;-1:-1:-1;;;;;4015:33:21::1;::::0;:68;:33:::1;:68::i;:::-;4141:21;::::0;::::1;::::0;4099:64:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;4114:10:::1;::::0;4099:64:::1;::::0;;;;;;;::::1;4181:4;4174:11;;;2126:10:24::0;:17;;-1:-1:-1;;2126:17:24;2139:4;2126:17;;;2191:2001:21;;-1:-1:-1;2191:2001:21:o;1969:230:1:-;931:5;;;;;-1:-1:-1;;;;;931:5:1;940:10;931:19;923:45;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;;;;-1:-1:-1;;;;;2065:25:1;::::1;2057:64;;;::::0;;-1:-1:-1;;;2057:64:1;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;2150:5;::::0;2136:30:::1;::::0;-1:-1:-1;;;;;2136:30:1;;::::1;::::0;2150:5:::1;::::0;::::1;;::::0;2136:30:::1;::::0;;;::::1;2176:5;:16:::0;;-1:-1:-1;;;;;2176:16:1;;::::1;;;-1:-1:-1::0;;;;;;2176:16:1;;::::1;::::0;;;::::1;::::0;;1969:230::o;330:37:23:-;;;;;;-1:-1:-1;;;;;330:37:23;;:::o;4985:1874:21:-;5077:4;1817:10:24;;;;1809:41;;;;;-1:-1:-1;;;1809:41:24;;;;;;;;;;;;-1:-1:-1;;;1809:41:24;;;;;;;;;;;;;;;1942:5;1929:18;;-1:-1:-1;;1929:18:24;;;5093:37:21::1;;:::i;:::-;5206:7;;;;;;;;;-1:-1:-1::0;;;;;5206:7:21::1;-1:-1:-1::0;;;;;5206:22:21::1;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;5206:24:21;5188:15:::1;:42;5180:71;;;::::0;;-1:-1:-1;;;5180:71:21;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;5180:71:21;;;;;;;;;;;;;::::1;;5331:1;5312:16;:20;5304:59;;;::::0;;-1:-1:-1;;;5304:59:21;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;5455:10;::::0;5493:7:::1;::::0;5455:46:::1;::::0;;-1:-1:-1;;;5455:46:21;;-1:-1:-1;;;;;5493:7:21;;::::1;5455:46;::::0;::::1;::::0;;;:10:::1;::::0;;::::1;::::0;;::::1;::::0;:37:::1;::::0;:46;;;;;::::1;::::0;;;;;;;;;:10;:46;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;5455:46:21;5447:92:::1;;;;-1:-1:-1::0;;;5447:92:21::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5637:48;5645:21;;5668:16;5637:7;:48::i;:::-;5604:29;::::0;::::1;5589:96:::0;;;5590:4;5589:96;::::1;::::0;::::1;;;;;;;;;;;;;;::::0;;-1:-1:-1;5719:18:21::1;::::0;-1:-1:-1;5703:12:21;;:34:::1;::::0;::::1;;;;;;;5695:79;;;::::0;;-1:-1:-1;;;5695:79:21;;::::1;;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;5808:29;::::0;;::::1;::::0;5784:21:::1;:53:::0;6088:7:::1;::::0;:35;;-1:-1:-1;;;6088:35:21;;;;-1:-1:-1;;;;;6088:7:21;;::::1;::::0;:33:::1;::::0;:35:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:7;:35;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;6088:35:21;6055:30:::1;::::0;::::1;:68:::0;;;6171:1:::1;6137:35;6133:321;;6225:57;6233:16;6251:4;:30;;;6225:7;:57::i;:::-;6203:18;::::0;::::1;6188:94:::0;;;6189:4;6188:94;::::1;::::0;::::1;;;;;;;;;;;;;;::::0;;-1:-1:-1;6320:18:21::1;::::0;-1:-1:-1;6304:12:21;;:34:::1;::::0;::::1;;;;;;;6296:79;;;::::0;;-1:-1:-1;;;6296:79:21;;::::1;;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;6133:321;;;6406:18;::::0;::::1;:37:::0;;;6133:321:::1;6519:7;::::0;6544:18:::1;::::0;;::::1;::::0;6519:44:::1;::::0;;-1:-1:-1;;;6519:44:21;;6532:10:::1;6519:44;::::0;::::1;::::0;;;;;;;;;-1:-1:-1;;;;;6519:7:21;;::::1;::::0;:12:::1;::::0;:44;;;;;6544:18;;6519:44;;;;;;:7:::1;::::0;:44;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;6519:44:21;6511:88:::1;;;::::0;;-1:-1:-1;;;6511:88:21;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;6666:82;6704:10;6724:4;6731:16;6666:7;;;;;;;;;-1:-1:-1::0;;;;;6666:7:21::1;-1:-1:-1::0;;;;;6666:18:21::1;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;6666:20:21;-1:-1:-1;;;;;6666:37:21::1;::::0;:82;;:37:::1;:82::i;:::-;6811:18;::::0;;::::1;::::0;6764:66:::1;::::0;;;;;;;::::1;::::0;;;;;;6781:10:::1;::::0;6764:66:::1;::::0;;;;;;;::::1;6848:4;6841:11;;;2126:10:24::0;:17;;-1:-1:-1;;2126:17:24;2139:4;2126:17;;;4985:1874:21;;-1:-1:-1;4985:1874:21:o;182:20:3:-;;;;;;-1:-1:-1;;;;;182:20:3;;:::o;857:214:25:-;1004:59;;;-1:-1:-1;;;;;1004:59:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1004:59:25;-1:-1:-1;;;1004:59:25;;;978:86;;997:5;;978:18;:86::i;:::-;857:214;;;:::o;1328:218:7:-;1390:9;;1424:6;1420:75;;-1:-1:-1;1454:26:7;;-1:-1:-1;1482:1:7;1446:38;;1420:75;1513:18;1537:1;1533;:5;;;;;;1505:34;;;;1328:218;;;;;;:::o;2701:239::-;2763:9;2774:7;2802:1;2797;:6;2793:141;;-1:-1:-1;2827:18:7;;-1:-1:-1;2847:5:7;;;2819:34;;2793:141;-1:-1:-1;2892:27:7;;-1:-1:-1;2921:1:7;2884:39;;587:262;649:9;;691:5;;;711:6;;;707:136;;741:18;;-1:-1:-1;761:1:7;-1:-1:-1;733:30:7;;707:136;802:26;830:1;794:38;;;;;;;2223:343;2285:9;;2319:6;2315:67;;-1:-1:-1;2349:18:7;;-1:-1:-1;2349:18:7;2341:30;;2315:67;2404:5;;;2408:1;2404;:5;:1;2424:5;;;;;:10;2420:140;;2458:26;2486:1;2450:38;;;;;;;2420:140;2527:18;;-1:-1:-1;2547:1:7;-1:-1:-1;2519:30:7;;1077:250:25;1250:69;;;-1:-1:-1;;;;;1250:69:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1250:69:25;-1:-1:-1;;;1250:69:25;;;1224:96;;1243:5;;1224:18;:96::i;:::-;1077:250;;;;:::o;1750:702::-;2175:23;2201:67;2222:5;2230:4;2201:67;;;;;;;;;;;;;;;;;:12;:67::i;:::-;2282:17;;2175:93;;-1:-1:-1;2282:21:25;2278:168;;2381:10;2370:30;;;;;;;;;;;;;;;-1:-1:-1;2370:30:25;2362:73;;;;;-1:-1:-1;;;2362:73:25;;;;;;;;;;;;;;;;;;;;;;;;;;;2458:961;2590:12;2622:19;:6;-1:-1:-1;;;;;2622:17:25;;:19::i;:::-;2614:67;;;;-1:-1:-1;;;2614:67:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2755:12;2769:23;2796:6;-1:-1:-1;;;;;2796:11:25;2808:4;2796:17;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2796:17:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2754:59;;;;2827:7;2823:590;;;2857:10;-1:-1:-1;2850:17:25;;-1:-1:-1;2850:17:25;2823:590;2971:17;;:21;2967:436;;3236:10;3230:17;3296:15;3283:10;3279:2;3275:19;3268:44;3185:145;3375:12;3368:20;;-1:-1:-1;;;3368:20:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2458:961;;;;;;:::o;911:634:0:-;971:4;1448:20;;1278:66;1495:23;;;;;;:42;;-1:-1:-1;1522:15:0;;;1495:42;1487:51;911:634;-1:-1:-1;;;;911:634:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://504e7960f16a46f68ab102d0a6c00cc3b4e3021515e5b688b79030739924e0a9

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.