Example #1
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)
Example #2
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:
            # handle dusty balances with non-18-decimal tokens
            vat_gap = dink - vat_balance + token.min_amount
            if balance < vat_gap:
                if c.ilk.name.startswith("ETH"):
                    wrap_eth(mcd, gal_address, vat_gap)
                else:
                    raise RuntimeError("Insufficient collateral balance")
            assert c.adapter.join(gal_address,
                                  token.unnormalize_amount(vat_gap)).transact(
                                      from_address=gal_address)
        vat_balance = mcd.vat.gem(c.ilk, gal_address)
        balance = token.normalize_amount(c.gem.balance_of(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)
        urn = mcd.vat.urn(c.ilk, gal_address)

    # Put gal CDP at max possible debt
    dart = max_dart(mcd, c, gal_address) - Wad(1)
    if dart > Wad(0):
        print(f"Frobbing {c.ilk.name} with ink={urn.ink} and 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")
    return urn
Example #3
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