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)
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
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