Exemple #1
0
def reserve_dai(mcd: DssDeployment,
                c: Collateral,
                usr: Address,
                amount: Wad,
                extra_collateral=Wad.from_number(1)):
    assert isinstance(mcd, DssDeployment)
    assert isinstance(c, Collateral)
    assert isinstance(usr, Address)
    assert isinstance(amount, Wad)
    assert amount > Wad(0)

    # Determine how much collateral is needed
    ilk = mcd.vat.ilk(c.ilk.name)
    rate = ilk.rate  # Ray
    spot = ilk.spot  # Ray
    assert rate >= Ray.from_number(1)
    collateral_required = Wad(
        (Ray(amount) / spot) * rate) * extra_collateral + Wad(1)
    print(
        f'collateral_required for {str(amount)} dai is {str(collateral_required)}'
    )

    wrap_eth(mcd, usr, collateral_required)
    c.approve(usr)
    assert c.adapter.join(usr, collateral_required).transact(from_address=usr)
    assert mcd.vat.frob(c.ilk, usr, collateral_required,
                        amount).transact(from_address=usr)
    assert mcd.vat.urn(c.ilk, usr).art >= Wad(amount)
Exemple #2
0
def cleanup_urn(mcd: DssDeployment, collateral: Collateral, address: Address):
    assert isinstance(mcd, DssDeployment)
    assert isinstance(collateral, Collateral)
    assert isinstance(address, Address)
    urn = mcd.vat.urn(collateral.ilk, address)
    ilk = mcd.vat.ilk(collateral.ilk.name)

    # If jug.drip has been called, we won't have sufficient dai to repay the CDP
    if ilk.rate > Ray.from_number(1):
        return

    # Repay borrowed Dai
    mcd.approve_dai(address)
    # Put all the user's Dai back into the vat
    if mcd.dai.balance_of(address) >= Wad(0):
        assert mcd.dai_adapter.join(address, mcd.dai.balance_of(address)).transact(from_address=address)
    # tab = Ray(urn.art) * ilk.rate
    # print(f'tab={str(tab)}, rate={str(ilk.rate)}, dai={str(mcd.vat.dai(address))}')
    if urn.art > Wad(0) and mcd.vat.dai(address) >= Rad(urn.art):
        frob(mcd, collateral, address, Wad(0), urn.art * -1)

    # Withdraw collateral
    collateral.approve(address)
    urn = mcd.vat.urn(collateral.ilk, address)
    # dink = Wad((Ray(urn.art) * ilk.rate) / ilk.spot)
    # print(f'dink={str(dink)}, ink={str(urn.ink)}')
    if urn.art == Wad(0) and urn.ink > Wad(0):
        frob(mcd, collateral, address, urn.ink * -1, Wad(0))
    assert collateral.adapter.exit(address, mcd.vat.gem(collateral.ilk, address)).transact(from_address=address)
Exemple #3
0
def create_cdp_with_surplus(mcd: DssDeployment, c: Collateral,
                            gal_address: Address) -> Urn:
    assert isinstance(mcd, DssDeployment)
    assert isinstance(c, Collateral)
    assert isinstance(gal_address, Address)

    # Ensure there is no debt which a previous test failed to clean up
    assert mcd.vat.sin(mcd.vow.address) == Rad(0)

    ink = Wad.from_number(10)
    art = Wad.from_number(500)
    wrap_eth(mcd, gal_address, ink)
    c.approve(gal_address)
    assert c.adapter.join(gal_address, ink).transact(from_address=gal_address)
    simulate_frob(mcd, c, gal_address, ink, art)
    assert mcd.vat.frob(c.ilk, gal_address, dink=ink,
                        dart=art).transact(from_address=gal_address)
    assert mcd.jug.drip(c.ilk).transact(from_address=gal_address)
    # total surplus > total debt + surplus auction lot size + surplus buffer
    print(
        f"dai(vow)={str(mcd.vat.dai(mcd.vow.address))} >? sin(vow)={str(mcd.vat.sin(mcd.vow.address))} "
        f"+ vow.bump={str(mcd.vow.bump())} + vow.hump={str(mcd.vow.hump())}")
    assert mcd.vat.dai(mcd.vow.address) > mcd.vat.sin(
        mcd.vow.address) + mcd.vow.bump() + mcd.vow.hump()
    return mcd.vat.urn(c.ilk, gal_address)
Exemple #4
0
def create_risky_cdp(mcd: DssDeployment,
                     c: Collateral,
                     collateral_amount: Wad,
                     gal_address: Address,
                     draw_dai=True) -> Urn:
    assert isinstance(mcd, DssDeployment)
    assert isinstance(c, Collateral)
    assert isinstance(gal_address, Address)

    # Ensure vault isn't already unsafe (if so, this shouldn't be called)
    urn = mcd.vat.urn(c.ilk, gal_address)
    assert is_cdp_safe(mcd.vat.ilk(c.ilk.name), urn)

    # Add collateral to gal vault if necessary
    c.approve(gal_address)
    token = Token(c.ilk.name, c.gem.address, c.adapter.dec())
    print(f"collateral_amount={collateral_amount} ink={urn.ink}")
    dink = collateral_amount - urn.ink
    if dink > Wad(0):
        vat_balance = mcd.vat.gem(c.ilk, gal_address)
        balance = token.normalize_amount(c.gem.balance_of(gal_address))
        print(
            f"before join: dink={dink} vat_balance={vat_balance} balance={balance} vat_gap={dink - vat_balance}"
        )
        if vat_balance < dink:
            vat_gap = dink - vat_balance
            if balance < vat_gap:
                if c.ilk.name.startswith("ETH"):
                    wrap_eth(mcd, gal_address, vat_gap)
                else:
                    raise RuntimeError("Insufficient collateral balance")
            amount_to_join = token.unnormalize_amount(vat_gap)
            if amount_to_join == Wad(
                    0):  # handle dusty balances with non-18-decimal tokens
                amount_to_join += token.unnormalize_amount(token.min_amount)
            assert c.adapter.join(
                gal_address, amount_to_join).transact(from_address=gal_address)
        vat_balance = mcd.vat.gem(c.ilk, gal_address)
        print(
            f"after join: dink={dink} vat_balance={vat_balance} balance={balance} vat_gap={dink - vat_balance}"
        )
        assert vat_balance >= dink
        assert mcd.vat.frob(c.ilk, gal_address, dink,
                            Wad(0)).transact(from_address=gal_address)

    # Put gal CDP at max possible debt
    dart = max_dart(mcd, c, gal_address) - Wad(1)
    if dart > Wad(0):
        print(f"Attempting to frob with dart={dart}")
        assert mcd.vat.frob(c.ilk, gal_address, Wad(0),
                            dart).transact(from_address=gal_address)

    # Draw our Dai, simulating the usual behavior
    urn = mcd.vat.urn(c.ilk, gal_address)
    if draw_dai and urn.art > Wad(0):
        mcd.approve_dai(gal_address)
        assert mcd.dai_adapter.exit(gal_address,
                                    urn.art).transact(from_address=gal_address)
        print(f"Exited {urn.art} Dai from urn")
Exemple #5
0
def open_cdp(mcd: DssDeployment, collateral: Collateral, address: Address, debtMultiplier: int = 1):
    assert isinstance(mcd, DssDeployment)
    assert isinstance(collateral, Collateral)
    assert isinstance(address, Address)

    collateral.approve(address)
    wrap_eth(mcd, address, Wad.from_number(20))
    assert collateral.adapter.join(address, Wad.from_number(20)).transact(from_address=address)
    frob(mcd, collateral, address, Wad.from_number(20), Wad.from_number(20 * debtMultiplier))

    assert mcd.vat.debt() >= Rad(Wad.from_number(20 * debtMultiplier))
    assert mcd.vat.dai(address) >= Rad.from_number(20 * debtMultiplier)
    def tend_with_dai(mcd: DssDeployment, c: Collateral, flipper: Flipper, id: int, address: Address, bid: Rad):
        assert (isinstance(mcd, DssDeployment))
        assert (isinstance(c, Collateral))
        assert (isinstance(flipper, Flipper))
        assert (isinstance(id, int))
        assert (isinstance(bid, Rad))

        flipper.approve(flipper.vat(), approval_function=hope_directly(from_address=address))
        previous_bid = flipper.bids(id)
        c.approve(address)
        reserve_dai(mcd, c, address, Wad(bid), extra_collateral=Wad.from_number(2))
        TestAuctionKeeperFlipper.tend(flipper, id, address, previous_bid.lot, bid)
Exemple #7
0
def create_unsafe_cdp(mcd: DssDeployment,
                      c: Collateral,
                      collateral_amount: Wad,
                      gal_address: Address,
                      draw_dai=True) -> Urn:
    assert isinstance(mcd, DssDeployment)
    assert isinstance(c, Collateral)
    assert isinstance(gal_address, Address)

    # Ensure CDP isn't already unsafe (if so, this shouldn't be called)
    urn = mcd.vat.urn(c.ilk, gal_address)
    assert is_cdp_safe(mcd.vat.ilk(c.ilk.name), urn)

    # Add collateral to gal CDP if necessary
    c.approve(gal_address)
    dink = collateral_amount - urn.ink
    if dink > Wad(0):
        balance = c.gem.balance_of(gal_address)
        if balance < dink:
            wrap_eth(mcd, gal_address, dink - balance)
            assert c.adapter.join(gal_address, dink -
                                  balance).transact(from_address=gal_address)
        simulate_frob(mcd, c, gal_address, dink, Wad(0))
        assert mcd.vat.frob(c.ilk, gal_address, dink,
                            Wad(0)).transact(from_address=gal_address)

    # Put gal CDP at max possible debt
    dart = max_dart(mcd, c, gal_address) - Wad(1)
    simulate_frob(mcd, c, gal_address, Wad(0), dart)
    assert mcd.vat.frob(c.ilk, gal_address, Wad(0),
                        dart).transact(from_address=gal_address)

    # Draw our Dai, simulating the usual behavior
    urn = mcd.vat.urn(c.ilk, gal_address)
    if draw_dai and urn.art > Wad(0):
        mcd.approve_dai(gal_address)
        assert mcd.dai_adapter.exit(gal_address,
                                    urn.art).transact(from_address=gal_address)
        print(f"Exited {urn.art} Dai from urn")

    # Manipulate price to make gal CDP underwater
    to_price = Wad(c.pip.read_as_int()) - Wad.from_number(1)
    set_collateral_price(mcd, c, to_price)

    # Ensure the CDP is unsafe
    assert not is_cdp_safe(mcd.vat.ilk(c.ilk.name), urn)
    return urn