Esempio n. 1
0
def test_borrowing_no_collateral():
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # Attempt to `borrow()` with no collateral
    with reverts('9'):
        borrow_amount = 5
        lending_pool.borrow(
            weth,
            borrow_amount,
            INTEREST_RATE_MODE_STABLE,
            0,
            accounts[9],
            {'from': accounts[9]},
        )

    with reverts('9'):
        borrow_amount = 5
        lending_pool.borrow(
            weth,
            borrow_amount,
            INTEREST_RATE_MODE_VARIABLE,
            0,
            accounts[9],
            {'from': accounts[9]},
        )
Esempio n. 2
0
def test_rebalance_below_liquidity_threshold():
    # Deploy and initialize contracts (initializes a weth reserve)
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # `borrow()`
    borrow_amount = terc20_deposit_amount // 1_000
    tx = lending_pool.borrow(
        weth,
        borrow_amount,
        INTEREST_RATE_MODE_STABLE,
        0,
        borrower,
        {'from': borrower},
    )

    # `rebalanceStableBorrowRate()` with less than the liquidity threshold
    available_liquidity = weth.balanceOf(weth_atoken)
    total_debt = weth_stable_debt.totalSupply()
    assert total_debt / (available_liquidity + total_debt) < 0.95
    with reverts('22'):
        lending_pool.rebalanceStableBorrowRate(
            weth,
            borrower,
            {'from': accounts[-1]}
        )
Esempio n. 3
0
def test_borrowing_stable_borrow_more_than_max():
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # Increase price to ensure we have sufficient colalteral
    price_oracle.setAssetPrice(terc20, price * 1000, {'from': accounts[0]})

    # Attempt to `borrow()` more than 25% of the asset's liquidity
    borrow_amount = deposit_amount * 3 // 10 # > 25% of liquidity
    with reverts('14'):
        lending_pool.borrow(
            weth,
            borrow_amount,
            INTEREST_RATE_MODE_STABLE,
            0,
            borrower,
            {'from': borrower},
        )

    # Variable borrowing is still allowed
    lending_pool.borrow(
        weth,
        borrow_amount,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )
Esempio n. 4
0
def test_swap_rate_to_stable_with_collateral():
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # `borrow()`
    lending_pool.borrow(
        weth,
        10,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )

    # Deposit WETH to use as collateral
    weth.deposit({'from': borrower, 'value': WEI})
    weth.approve(lending_pool, WEI, {'from': borrower})
    lending_pool.deposit(weth, WEI, borrower, 0, {'from': borrower})

    # Attempt to swap with collateral
    with reverts('13'):
        lending_pool.swapBorrowRateMode(
            weth,
            INTEREST_RATE_MODE_VARIABLE,
            {'from': borrower}
        )
Esempio n. 5
0
def test_borrowing_disable_stable_borrowing_on_reserve():
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # Attempt to `borrow()` while stable borrowing is disabled
    configurator.disableReserveStableRate(weth, {'from': pool_admin})
    borrow_amount = 5
    with reverts('12'):
        lending_pool.borrow(
            weth,
            borrow_amount,
            INTEREST_RATE_MODE_STABLE,
            0,
            borrower,
            {'from': borrower},
        )

    # Variable borrowing is still allowed
    lending_pool.borrow(
        weth,
        borrow_amount,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )
Esempio n. 6
0
def test_borrowing_stable_borrow_same_as_collateral():
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # Attempt to `borrow()` the same currency as the collateral (but less than the collateral)
    borrow_amount = 5
    with reverts('13'):
        lending_pool.borrow(
            terc20,
            borrow_amount,
            INTEREST_RATE_MODE_STABLE,
            0,
            borrower,
            {'from': borrower},
        )

    # Variable borrowing is still allowed
    lending_pool.borrow(
        terc20,
        borrow_amount,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )
Esempio n. 7
0
def test_liquidation_call_health_factor():
    # Deploy and initialize contracts (initializes a weth reserve)
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # `borrow()` variable to set a high overall rate
    borrow_amount = terc20_deposit_amount / 100
    tx = lending_pool.borrow(
        weth,
        borrow_amount,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )

    with reverts('42'):
        # Good health factor
        lending_pool.liquidationCall(weth, terc20, borrower, 1, False, {'from': accounts[7]})

    with reverts('42'):
        # Maximum health factor
        lending_pool.liquidationCall(weth, terc20, depositer, 1, False, {'from': accounts[7]})
Esempio n. 8
0
def test_borrowing_insufficient_colalteral():
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # Attempt to `borrow()` with insufficient collateral
    borrow_amount = terc20_deposit_amount # Note terc20 is priced less than Eth
    with reverts('11'):
        lending_pool.borrow(
            weth,
            borrow_amount,
            INTEREST_RATE_MODE_STABLE,
            0,
            borrower,
            {'from': borrower},
        )

    with reverts('11'):
        lending_pool.borrow(
            weth,
            borrow_amount,
            INTEREST_RATE_MODE_VARIABLE,
            0,
            borrower,
            {'from': borrower},
        )
Esempio n. 9
0
def test_borrowing_bad_interest_rate_mode():
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # Attempt to `borrow()` with interest made node none or just invalid
    with reverts('8'):
        borrow_amount = 5
        lending_pool.borrow(
            weth,
            borrow_amount,
            INTEREST_RATE_MODE_NONE,
            0,
            borrower,
            {'from': borrower},
        )

    with reverts('8'):
        borrow_amount = 5
        lending_pool.borrow(
            weth,
            borrow_amount,
            10,
            0,
            borrower,
            {'from': borrower},
        )
Esempio n. 10
0
def test_borrow_while_frozen():
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # Attempt to `borrow()` while frozen
    configurator.freezeReserve(weth, {'from': pool_admin})
    with reverts('3'):
        borrow_amount = 5
        lending_pool.borrow(
            weth,
            borrow_amount,
            INTEREST_RATE_MODE_STABLE,
            0,
            borrower,
            {'from': borrower},
        )

    with reverts('3'):
        borrow_amount = 5
        lending_pool.borrow(
            weth,
            borrow_amount,
            INTEREST_RATE_MODE_VARIABLE,
            0,
            borrower,
            {'from': borrower},
        )
Esempio n. 11
0
def test_liquidation_call_with_no_debt():
    # Deploy and initialize contracts (initializes a weth reserve)
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    a_erc20, a_erc20_atoken, a_erc20_stable_debt, a_erc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    a_erc20_deposit_amount, price_a) = setup_borrow()

    # `borrow()` variable to set a high overall rate
    borrow_amount = a_erc20_deposit_amount / 100
    tx = lending_pool.borrow(
        weth,
        borrow_amount,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )

    # Tank price for aERC20 so we have bad health factor
    price_a = price_a // 1_000
    price_oracle.setAssetPrice(a_erc20, price_a, {'from': accounts[0]})

    with reverts('44'):
        lending_pool.liquidationCall(a_erc20, a_erc20, borrower, 1, False, {'from': accounts[7]})
Esempio n. 12
0
def test_liquidation_call_not_used_as_collateral():
    # Deploy and initialize contracts (initializes a weth reserve)
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    a_erc20, a_erc20_atoken, a_erc20_stable_debt, a_erc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    a_erc20_deposit_amount, price_a) = setup_borrow()

    # `borrow()` variable to set a high overall rate
    borrow_amount = a_erc20_deposit_amount / 100
    tx = lending_pool.borrow(
        weth,
        borrow_amount,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )

    # Add additional reserve
    b_erc20 = accounts[0].deploy(
        MintableDelegationERC20,
        "b ERC20",
        "bERC20",
        5,
    )

    # Initialise reserve tERC20
    (b_erc20_atoken, b_erc20_stable_debt, b_erc20_variable_debt) = setup_new_reserve(configurator, b_erc20, lending_pool, pool_admin)

    # Turn on collateral and borrowing
    (b_ecr20_ltv, b_ecr20_threshold, b_ecr20_bonus) = allow_reserve_collateral_and_borrowing(configurator, b_erc20, pool_admin)

    # Setup price for tERC20
    price_b = WEI // 10 # 1 bERC20 : 0.1 ETH
    price_oracle.setAssetPrice(b_erc20, price_b, {'from': accounts[0]})

    # `deposit()` some b_erc20 and turn off use as collateral
    b_erc20_deposit_amount = deposit_amount
    b_erc20.mint(b_erc20_deposit_amount, {'from': borrower})
    b_erc20.approve(lending_pool, b_erc20_deposit_amount, {'from': borrower})
    lending_pool.deposit(b_erc20, b_erc20_deposit_amount, borrower, 0, {'from': borrower})
    lending_pool.setUserUseReserveAsCollateral(b_erc20, False, {'from': borrower})

    # Tank price for aERC20 so we have bad health factor
    price_a = price_a // 1_000
    price_oracle.setAssetPrice(a_erc20, price_a, {'from': accounts[0]})

    with reverts('43'):
        # Attempt to liquidate collateral that is not being used as collateral
        lending_pool.liquidationCall(weth, b_erc20, borrower, 1, False, {'from': accounts[7]})
Esempio n. 13
0
def test_swap_rate_bad_mode():
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # `borrow()`
    lending_pool.borrow(
        weth,
        10,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )
    lending_pool.borrow(
        weth,
        10,
        INTEREST_RATE_MODE_STABLE,
        0,
        borrower,
        {'from': borrower},
    )

    # Attempt to swap with collateral
    with reverts('8'):
        lending_pool.swapBorrowRateMode(
            weth,
            INTEREST_RATE_MODE_NONE,
            {'from': borrower}
        )

    # Attempt to swap with collateral
    with reverts():
        lending_pool.swapBorrowRateMode(
            weth,
            3,
            {'from': borrower}
        )

    # Attempt to swap with collateral
    with reverts():
        lending_pool.swapBorrowRateMode(
            weth,
            (1 << 256) - 1,
            {'from': borrower}
        )
Esempio n. 14
0
def test_rebalance_below_rate_threshold():
    # Deploy and initialize contracts (initializes a weth reserve)
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # Setup price for tERC20
    price = WEI * 1000 # 1 tERC20 : 1000 ETH
    price_oracle.setAssetPrice(terc20, price, {'from': accounts[0]})

    available_liquidity = weth.balanceOf(weth_atoken)

    # `borrow()` variable to set a high overall rate
    borrow_amount = available_liquidity * 99 // 100
    tx = lending_pool.borrow(
        weth,
        borrow_amount,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )

    # `borrow()` stable getting a very high rate
    available_liquidity = weth.balanceOf(weth_atoken)
    tx = lending_pool.borrow(
        weth,
        available_liquidity,
        INTEREST_RATE_MODE_STABLE,
        0,
        borrower,
        {'from': borrower},
    )

    # `rebalanceStableBorrowRate()` with less than the rate threshold (but more than liquidity threshold)
    available_liquidity = weth.balanceOf(weth_atoken)
    total_debt = weth_stable_debt.totalSupply()
    assert total_debt / (available_liquidity + total_debt) >= 0.95 # ensure we pass the liquidity threshold check
    with reverts('22'):
        lending_pool.rebalanceStableBorrowRate(
            weth,
            borrower,
            {'from': accounts[-1]}
        )
Esempio n. 15
0
def test_validate_flash_loan():
    # Deploy and initialize contracts (initializes a weth reserve)
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    a_erc20, a_erc20_atoken, a_erc20_stable_debt, a_erc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    a_erc20_deposit_amount, price_a) = setup_borrow()

    with reverts('73'):
        lending_pool.flashLoan(
            accounts[0],
            [weth, weth],
            [1],
            [INTEREST_RATE_MODE_NONE],
            accounts[1],
            b'',
            0,
            {'from': accounts[1]}
        )
Esempio n. 16
0
def test_validate_transfer():
    # Deploy and initialize contracts (initializes a weth reserve)
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # `borrow()`
    borrow_amount = terc20_deposit_amount * price // WEI // 10 # 10% of collateral in ETH
    tx = lending_pool.borrow(
        weth,
        borrow_amount,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )

    with reverts('6'):
        terc20_atoken.transfer(accounts[2], terc20_deposit_amount * 9 // 10, {'from': borrower})
Esempio n. 17
0
def test_borrowing_bad_health_factor():
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # `borrow()` so we can manipulate health factor
    borrow_amount = int(terc20_deposit_amount // 10 * 0.3)
    lending_pool.borrow(
        weth,
        borrow_amount,
        INTEREST_RATE_MODE_STABLE,
        0,
        borrower,
        {'from': borrower},
    )

    # Decrease tERC20 to 10% of it's value to ruin our health factor
    price_oracle.setAssetPrice(terc20, price // 10, {'from': accounts[0]})

    # We now have bad health factor
    with reverts('10'):
        lending_pool.borrow(
            weth,
            1,
            INTEREST_RATE_MODE_STABLE,
            0,
            borrower,
            {'from': borrower},
        )
    with reverts('10'):
        lending_pool.borrow(
            weth,
            1,
            INTEREST_RATE_MODE_VARIABLE,
            0,
            borrower,
            {'from': borrower},
        )
Esempio n. 18
0
def test_validate_reserve_as_collateral_deposit_used():
    # Deploy and initialize contracts (initializes a weth reserve)
    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # `borrow()` variable to set a high overall rate
    borrow_amount = terc20_deposit_amount / 100
    tx = lending_pool.borrow(
        weth,
        borrow_amount,
        INTEREST_RATE_MODE_VARIABLE,
        0,
        borrower,
        {'from': borrower},
    )

    # `setUserUseReserveAsCollateral()`
    with reverts('20'):
        lending_pool.setUserUseReserveAsCollateral(terc20, False, {'from': borrower})
Esempio n. 19
0
def test_rebalance_attack():
    attack_contract = accounts[0].deploy(RebalanceFlashloanAttack)

    (addresses_provider, lending_pool, configurator, collateral_manager,
    pool_admin, emergency_admin, price_oracle, lending_rate_oracle, weth, weth_atoken,
    weth_stable_debt, weth_variable_debt, strategy, depositer, deposit_amount, borrower,
    terc20, terc20_atoken, terc20_stable_debt, terc20_variable_debt, tecr20_ltv, tecr20_threshold, tecr20_bonus,
    terc20_deposit_amount, price) = setup_borrow()

    # `borrow()` stable rate for a user
    borrow_amount = terc20_deposit_amount // 100
    tx = lending_pool.borrow(
        weth.address,
        borrow_amount,
        INTEREST_RATE_MODE_STABLE,
        0,
        borrower,
        {'from': borrower},
    )

    # Deposit WETH and transfer to attack_contract (enough to cover premium of flashloan)
    weth.deposit({'from': accounts[0], 'value': deposit_amount})
    weth.transfer(attack_contract.address, deposit_amount, {'from': accounts[0]})

    # Use flashloan to manipulate users rate to max stable rate
    available_liquidity = weth.balanceOf(weth_atoken.address)
    tx_b = attack_contract.attackRebalanceFlashloan(
        lending_pool.address,
        [weth.address],
        [available_liquidity],
        [INTEREST_RATE_MODE_NONE],
        borrower,
        b'',
    )

    max_stable_rate = strategy.stableRateSlope1() + strategy.stableRateSlope2() + lending_rate_oracle.getMarketBorrowRate(weth)
    assert weth_stable_debt.getUserStableRate(borrower) < max_stable_rate