Пример #1
0
def calculate_apy(gauge, swap):
    crv_price = uniswap.price_router(crv, uniswap.usdc)
    gauge_controller = interface.CurveGaugeController(gauge.controller())
    working_supply = gauge.working_supply() / 1e18
    relative_weight = gauge_controller.gauge_relative_weight(gauge) / 1e18
    inflation_rate = gauge.inflation_rate() / 1e18
    virtual_price = swap.get_virtual_price() / 1e18
    base_price = 1
    if str(swap) in constants.CURVE_BTC_SWAPS:
        base_price *= uniswap.price_router(uniswap.wbtc, uniswap.usdc)

    try:
        rate = (inflation_rate * relative_weight * 86400 * 365 /
                working_supply * 0.4) / (virtual_price * base_price)
    except ZeroDivisionError:
        rate = 0

    return {
        'crv price': crv_price,
        'relative weight': relative_weight,
        'inflation rate': inflation_rate,
        'virtual price': virtual_price,
        'base price': base_price,
        'crv reward rate': rate,
        'crv apy': rate * crv_price,
    }
Пример #2
0
def calculate_apy(gauge, swap):
    crv_price = uniswap.price_router(crv, uniswap.usdc)
    gauge_controller = interface.CurveGaugeController(gauge.controller())
    working_supply = gauge.working_supply() / 1e18
    relative_weight = gauge_controller.gauge_relative_weight(gauge) / 1e18
    inflation_rate = gauge.inflation_rate() / 1e18
    virtual_price = swap.get_virtual_price() / 1e18
    base_price = get_base_price(swap)
    try:
        rate = (inflation_rate * relative_weight * 86400 * 365 / working_supply * 0.4) / (virtual_price * base_price)
    except ZeroDivisionError:
        rate = 0

    return {
        "crv price": crv_price,
        "relative weight": relative_weight,
        "inflation rate": inflation_rate,
        "virtual price": virtual_price,
        "base price": base_price,
        "crv reward rate": rate,
        "crv apy": rate * crv_price,
        "token price": base_price * virtual_price,
    }
Пример #3
0
def simple(vault: Union[VaultV1, VaultV2], samples: ApySamples) -> Apy:
    lp_token = vault.token.address

    pool_address = get_pool(lp_token)
    gauge_addresses = curve_registry.get_gauges(pool_address)

    gauge_address = gauge_addresses[0][0]

    # FIXME: crvUSDP doesn't have a gauge connected in the registry
    if vault.vault.address == "0x1B5eb1173D2Bf770e50F10410C9a96F7a8eB6e75":
        gauge = "0x055be5DDB7A925BfEF3417FC157f53CA77cA7222"

    gauge = interface.CurveGauge(gauge_address)
    controller = gauge.controller()
    controller = interface.CurveGaugeController(controller)

    gauge_working_supply = gauge.working_supply()
    gauge_weight = controller.gauge_relative_weight(gauge_address)

    gauge_inflation_rate = gauge.inflation_rate()
    pool_price = curve_registry.get_virtual_price_from_lp_token(lp_token)

    underlying_coins = get_underlying_coins(lp_token)

    btc_like = any([coin in BTC_LIKE for coin in underlying_coins])
    eth_like = any([coin in ETH_LIKE for coin in underlying_coins])

    base_asset = WBTC if btc_like else WETH if eth_like else underlying_coins[0]
    base_asset_price = get_price(base_asset) or 1

    crv_price = get_price(CRV)

    y_working_balance = gauge.working_balances(YVECRV_VOTER)
    y_gauge_balance = gauge.balanceOf(YVECRV_VOTER)

    base_apr = (
        gauge_inflation_rate
        * gauge_weight
        * (SECONDS_PER_YEAR / gauge_working_supply)
        * (PER_MAX_BOOST / pool_price)
        * crv_price
    ) / base_asset_price

    if y_gauge_balance > 0:
        boost = y_working_balance / (PER_MAX_BOOST * y_gauge_balance) or 1
    else:
        boost = MAX_BOOST

    # FIXME: The HBTC v1 vault is currently still earning yield, but it is no longer boosted.
    if vault.vault.address == "0x46AFc2dfBd1ea0c0760CAD8262A5838e803A37e5":
        boost = 1

    boosted_apr = base_apr * boost

    if hasattr(gauge, "reward_contract"):
        try:
            reward_address = gauge.reward_contract()
            assert reward_address != ZERO_ADDRESS
            reward_apr = rewards(reward_address, pool_price, base_asset_price)
        except ValueError:
            reward_apr = 0
    else:
        reward_apr = 0

    price_per_share = curve_registry.get_virtual_price_from_lp_token
    now_price = price_per_share(lp_token, block_identifier=samples.now)
    try:
        week_ago_price = price_per_share(lp_token, block_identifier=samples.week_ago)
    except ValueError:
        raise ApyError("crv", "insufficient data")

    now_point = SharePricePoint(samples.now, now_price)
    week_ago_point = SharePricePoint(samples.week_ago, week_ago_price)

    pool_apr = calculate_roi(now_point, week_ago_point)
    pool_apy = (((pool_apr / 365) + 1) ** 365) - 1

    # FIXME: crvANKR's pool apy going crazy
    if vault.vault.address == "0xE625F5923303f1CE7A43ACFEFd11fd12f30DbcA4":
        pool_apy = 0

    if type(vault) is VaultV2:
        contract = vault.vault
        keep_crv = sum([strategy.keepCRV() for strategy in vault.strategies if hasattr(strategy, "keepCRV")])
        performance = (contract.performanceFee() * 2) if hasattr(contract, "performanceFee") else 0
        management = contract.managementFee() if hasattr(contract, "managementFee") else 0
    else:
        strategy = vault.strategy
        strategist_performance = strategy.performanceFee() if hasattr(strategy, "performanceFee") else 0
        strategist_reward = strategy.strategistReward() if hasattr(strategy, "strategistReward") else 0
        treasury = strategy.treasuryFee() if hasattr(strategy, "treasuryFee") else 0
        keep_crv = strategy.keepCRV() if hasattr(strategy, "keepCRV") else 0

        performance = strategist_reward + strategist_performance + treasury
        management = 0

    keep_crv /= 1e4
    performance /= 1e4
    management /= 1e4

    lose_crv = 1 - keep_crv

    gross_farmed_apy = (
        (boosted_apr * keep_crv) + (((boosted_apr * lose_crv + reward_apr) / COMPOUNDING) + 1) ** COMPOUNDING
    ) - 1

    apy = (gross_farmed_apy + 1) * (pool_apy + 1) - 1

    net_curve_apr = (boosted_apr * lose_crv + reward_apr) * (1 - performance) - management

    net_farmed_apy = ((net_curve_apr / COMPOUNDING) + 1) ** COMPOUNDING - 1
    net_apy = (net_farmed_apy + 1) * (pool_apy + 1) - 1

    fees = ApyFees(performance=performance, management=management, keep_crv=keep_crv)
    composite = {
        "boost": boost,
        "pool_apy": pool_apy,
        "boosted_apr": boosted_apr,
        "base_apr": base_apr,
        "rewards_apr": reward_apr,
    }
    return Apy("crv", apy, net_apy, fees, composite=composite)
Пример #4
0
from brownie import interface

from yearn import constants
from yearn import uniswap

crv = interface.ERC20('0xD533a949740bb3306d119CC777fa900bA034cd52')
gauge_controller = interface.CurveGaugeController(
    '0x2F50D538606Fa9EDD2B11E2446BEb18C9D5846bB')
voting_escrow = interface.CurveVotingEscrow(
    '0x5f3b5DfEb7B28CDbD7FAba78963EE202a494e2A2')


def calculate_boost(gauge, addr):
    gauge_balance = gauge.balanceOf(addr) / 1e18
    gauge_total = gauge.totalSupply() / 1e18
    working_balance = gauge.working_balances(addr) / 1e18
    working_supply = gauge.working_supply() / 1e18
    vecrv_balance = voting_escrow.balanceOf(addr) / 1e18
    vecrv_total = voting_escrow.totalSupply() / 1e18
    boost = working_balance / gauge_balance * 2.5

    min_vecrv = vecrv_total * gauge_balance / gauge_total
    lim = gauge_balance * 0.4 + gauge_total * min_vecrv / vecrv_total * 0.6
    lim = min(gauge_balance, lim)

    _working_supply = working_supply + lim - working_balance
    noboost_lim = gauge_balance * 0.4
    noboost_supply = working_supply + noboost_lim - working_balance
    max_boost_possible = (lim / _working_supply) / (noboost_lim /
                                                    noboost_supply)