interface StakingInterface {
    /// @notice This emits when the `owner` whitelists a new token and its underlying.
    event WhitelistToken(address indexed tokenAddress);

    /// @notice This emits when the `owner` discard a token.
    event DiscardToken(address indexed tokenAddress);

    /// @notice This emits when a new stake is created.
    event StakeEvent(
        address indexed staker,
        address indexed tokenAddress,
        uint256 tokenBalance
    );

    /// @notice This emits when either the staker or the `owner` redeems the stake. The deposit plus
    ///  any accrued interest is returned back to the staker and the `owner` withholds their fee.
    event Redeem(
        address indexed staker,
        address indexed tokenAddress,
        uint256 tokenWithdrawal
    );

    /// @notice This emits when the `owner` withdraws a portion or all of the accrued profits.
    event TakeEarnings(address indexed tokenAddress, uint256 indexed amount);

    /// @notice This emits when the `owner` updates the fee practiced by the contract.
//    event UpdateFee(uint256 indexed fee);

    /// @notice Returns the owner of the contract.
    /// @dev This address can whitelist and discard tokens and withdraw profits accrued over time.
    function owner() external view returns (address);

    /// @notice Returns the stake that consists of the initial deposit plus the interest accrued over time.
    /// @dev Reverts if `staker` doesn't have an active stake. Reverts if `tokenAddress` doesn't match either
    ///  the token or the underlying of the stake.
    /// @param staker The address of the user that has an active stake.
    /// @param tokenAddress The address of either the token or the underlying of the stake.
    function balanceOf(address staker, address tokenAddress) external view returns (uint256);

    /// @notice Whistelists a token to automatically convert its underlying when deposited.
    /// @dev Reverts if token is whitelisted. Reverts if `msg.sender` is not `owner`.
    /// @param tokenAddress The address of the token.
    function whitelistToken(address tokenAddress) external;

    /// @notice Discards a token that has been whitelisted before.
    /// @dev Reverts if token is not whitelisted. Reverts if `msg.sender` is not `owner`.
    /// @param tokenAddress The address of the token to discard.
    function discardToken(address tokenAddress) external;

    /// @notice Creates a new stake object for `msg.sender`. It automatically converts an underlying to
    ///  its token form so that the contract can earn interest.
    /// @dev Reverts if `msg.sender` already has an active stake. Reverts if the token/ underlying pair has not been whitelisted.
    /// @param tokenAddress The address of either the token or the underlying.
    /// @param amount The amount of tokens to deposit.
    function stake(address tokenAddress, uint256 amount) external;

    /// @notice Returns the deposit plus any accrued interest to the staker and takes the fee for the `owner`.
    /// @dev Note that the fee can only be levied on the accrued interest, never on the base deposit.
    ///  Reverts if `msg.sender` is not the staker or the `owner`.
    /// @param staker The address for whom to redeem the stake.
    /// @param tokenAddress The address of the Staking address.
    function redeem(address staker, address tokenAddress, uint256 amount) external;

    /// @notice Withdraws the earnings accrued over time to owner.
    /// @dev Reverts if `amount` is more than what's available. Reverts if `msg.sender` is not `owner`.
    /// @param tokenAddress The address of the currency for which to withdraw the funds.
    /// @param amount The amount of funds to withdraw.
    function takeEarnings(address tokenAddress, uint256 amount) external;
}
function takeEarnings(address tokenAddress, uint256 amount) external;

/// @notice Withdraws the earnings accrued over time to owner.
/// @dev Reverts if `amount` is more than what's available. Reverts if `msg.sender` is not `owner`.
/// @param tokenAddress The address of the currency for which to withdraw the funds.
/// @param amount The amount of funds to withdraw.