def test_bite_and_flip(self, web3, mcd, gal_address, keeper_address): # given c = mcd.collaterals['ETH-A'] keeper = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flip " f"--from-block 1 " f"--ilk {c.ilk.name} " f"--model ./bogus-model.sh"), web3=mcd.web3) keeper.approve() unsafe_cdp = create_unsafe_cdp(mcd, c, Wad.from_number(1.2), gal_address) assert len(mcd.active_auctions()["flips"][c.ilk.name]) == 0 # Keeper won't bid with a 0 Dai balance purchase_dai(Wad(20), keeper_address) assert mcd.dai_adapter.join( keeper_address, Wad(20)).transact(from_address=keeper_address) # when keeper.check_cdps() wait_for_other_threads() # then print(mcd.cat.past_bites(10)) assert len(mcd.cat.past_bites(10)) > 0 urn = mcd.vat.urn(unsafe_cdp.ilk, unsafe_cdp.address) assert urn.art == Wad(0) # unsafe cdp has been bitten assert urn.ink == Wad(0) # unsafe cdp is now safe ... assert c.flipper.kicks() == 1 # One auction started
def test_bark_and_clip(self, mcd, gal_address): # setup repay_urn(mcd, self.collateral, gal_address) # given 21 Dai / (200 price * 2.0 mat) == 0.21 vault size unsafe_cdp = create_unsafe_cdp(mcd, self.collateral, Wad.from_number(0.21), gal_address, draw_dai=False) assert self.clipper.active_count() == 0 kicks_before = self.clipper.kicks() # when self.keeper.check_vaults() wait_for_other_threads() # then print(mcd.dog.past_barks(10)) assert len(mcd.dog.past_barks(10)) > 0 urn = mcd.vat.urn(unsafe_cdp.ilk, unsafe_cdp.address) assert urn.art == Wad(0) # unsafe vault has been barked assert urn.ink == Wad(0) # unsafe vault is now safe ... assert self.clipper.kicks() == kicks_before + 1 # One auction started # cleanup kick = self.collateral.clipper.kicks() (needs_redo, auction_price, lot, tab) = self.clipper.status(kick) bid_price = Ray(get_collateral_price(self.collateral)) self.take_below_price(kick, bid_price, self.keeper_address)
def test_should_detect_flop(self, web3, c, mcd, other_address, keeper_address): # given a count of flop auctions reserve_dai(mcd, c, keeper_address, Wad.from_number(230)) kicks = mcd.flopper.kicks() # and an undercollateralized CDP is bitten unsafe_cdp = create_unsafe_cdp(mcd, c, Wad.from_number(1), other_address, draw_dai=False) assert mcd.cat.bite(unsafe_cdp.ilk, unsafe_cdp).transact() # when the auction ends without debt being covered time_travel_by(web3, c.flipper.tau() + 1) # then ensure testchain is in the appropriate state joy = mcd.vat.dai(mcd.vow.address) awe = mcd.vat.sin(mcd.vow.address) woe = (mcd.vat.sin(mcd.vow.address) - mcd.vow.sin()) - mcd.vow.ash() sin = mcd.vow.sin() sump = mcd.vow.sump() wait = mcd.vow.wait() assert joy < awe assert woe + sin >= sump assert wait == 0 # when self.keeper.check_flop() wait_for_other_threads() # then ensure another flop auction was kicked off assert mcd.flopper.kicks() == kicks + 1 # clean up by letting the auction expire time_travel_by(web3, mcd.flopper.tau() + 1)
def kick(web3: Web3, mcd: DssDeployment, gal_address, other_address) -> int: joy = mcd.vat.dai(mcd.vow.address) woe = (mcd.vat.sin(mcd.vow.address) - mcd.vow.sin()) - mcd.vow.ash() print(f'joy={str(joy)[:6]}, woe={str(woe)[:6]}') if woe < joy: # Bite gal CDP c = mcd.collaterals['ETH-B'] unsafe_cdp = create_unsafe_cdp(mcd, c, Wad.from_number(2), other_address, draw_dai=False) flip_kick = bite(mcd, c, unsafe_cdp) # Generate some Dai, bid on and win the flip auction without covering all the debt reserve_dai(mcd, c, gal_address, Wad.from_number(100), extra_collateral=Wad.from_number(1.1)) c.flipper.approve(mcd.vat.address, approval_function=hope_directly(from_address=gal_address)) current_bid = c.flipper.bids(flip_kick) bid = Rad.from_number(1.9) assert mcd.vat.dai(gal_address) > bid assert c.flipper.tend(flip_kick, current_bid.lot, bid).transact(from_address=gal_address) time_travel_by(web3, c.flipper.ttl()+1) assert c.flipper.deal(flip_kick).transact() flog_and_heal(web3, mcd, past_blocks=1200, kiss=False) # Kick off the flop auction woe = (mcd.vat.sin(mcd.vow.address) - mcd.vow.sin()) - mcd.vow.ash() assert mcd.vow.sump() <= woe assert mcd.vat.dai(mcd.vow.address) == Rad(0) assert mcd.vow.flop().transact(from_address=gal_address) return mcd.flopper.kicks()
def kick(mcd, c: Collateral, gal_address) -> int: # Ensure we start with a clean urn urn = mcd.vat.urn(c.ilk, gal_address) assert urn.ink == Wad(0) assert urn.art == Wad(0) # Bite gal CDP unsafe_cdp = create_unsafe_cdp(mcd, c, tend_lot, gal_address) return bite(mcd, c, unsafe_cdp)
def kick(mcd, collateral_clip: Collateral, gal_address) -> int: # Ensure we start with a clean urn urn = mcd.vat.urn(collateral_clip.ilk, gal_address) assert urn.ink == Wad(0) assert urn.art == Wad(0) # Bark an unsafe vault and return the id unsafe_cdp = create_unsafe_cdp(mcd, collateral_clip, Wad.from_number(1.0), gal_address) mcd.dog.bark(collateral_clip.ilk, unsafe_cdp).transact() barks = mcd.dog.past_barks(1) assert len(barks) == 1 return collateral_clip.clipper.kicks()
def test_bite_and_flip(self, mcd, gal_address): # given 21 Dai / (200 price * 1.2 mat) == 0.0875 vault size unsafe_cdp = create_unsafe_cdp(mcd, self.c, Wad.from_number(0.0875), gal_address, draw_dai=False) assert len(mcd.active_auctions()["flips"][self.c.ilk.name]) == 0 # when self.keeper.check_vaults() wait_for_other_threads() # then print(mcd.cat.past_bites(10)) assert len(mcd.cat.past_bites(10)) > 0 urn = mcd.vat.urn(unsafe_cdp.ilk, unsafe_cdp.address) assert urn.art == Wad(0) # unsafe cdp has been bitten assert urn.ink == Wad(0) # unsafe cdp is now safe ... assert self.c.flipper.kicks() == 1 # One auction started
def test_bite_and_flip(self, web3, mcd, gal_address, keeper_address): # given c = mcd.collaterals['ETH-A'] keeper = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flip " f"--network testnet " f"--ilk {c.ilk.name} " f"--model ./bogus-model.sh"), web3=mcd.web3) keeper.approve() unsafe_cdp = create_unsafe_cdp(mcd, c, Wad.from_number(1.2), gal_address) assert len(mcd.active_auctions()["flips"][c.ilk.name]) == 0 # when keeper.check_cdps() wait_for_other_threads() # then urn = mcd.vat.urn(unsafe_cdp.ilk, unsafe_cdp.address) assert urn.art == Wad(0) # unsafe cdp has been bitten assert urn.ink == Wad(0) # unsafe cdp is now safe ... assert c.flipper.kicks() == 1 # One auction started
def kick_small_lot(mcd, c: Collateral, gal_address) -> int: unsafe_cdp = create_unsafe_cdp(mcd, c, tend_small_lot, gal_address) return bite(mcd, c, unsafe_cdp)
# (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import sys from pymaker.numeric import Wad, Ray, Rad from tests.conftest import create_unsafe_cdp, is_cdp_safe, mcd, gal_address, web3 mcd = mcd(web3()) address = gal_address(web3()) collateral_amount = Wad.from_number(float( sys.argv[1])) if len(sys.argv) > 1 else 1.0 collateral = mcd.collaterals[str( sys.argv[2])] if len(sys.argv) > 2 else mcd.collaterals['ETH-C'] urn = mcd.vat.urn(collateral.ilk, address) if not is_cdp_safe(mcd.vat.ilk(collateral.ilk.name), urn): print("CDP is already unsafe; no action taken") else: create_unsafe_cdp(mcd, collateral, Wad.from_number(collateral_amount), address, False) print("Created unsafe CDP")