コード例 #1
0
    def test_check_settlement(self, geb: GfDeployment,
                              keeper: SettlementKeeper, our_address: Address,
                              other_address: Address):
        print_out("test_check_settlement")
        keeper.check_settlement()
        assert keeper.settlement_facilitated == False
        assert geb.global_settlement.contract_enabled() == 1
        prepare_esm(geb, our_address)
        fire_esm(geb, our_address)
        assert keeper.confirmations == 0
        for _ in range(0, 12):
            time_travel_by(geb.web3, 1)
            keeper.check_settlement()
        assert keeper.confirmations == 12

        keeper.check_settlement()  # Facilitate processing period
        assert keeper.settlement_facilitated == True

        shutdown_time = geb.global_settlement.shutdown_time()
        shutdown_cooldown = geb.global_settlement.shutdown_cooldown()
        shutdown_time_in_unix = shutdown_time.replace(
            tzinfo=timezone.utc).timestamp()
        block_number = geb.web3.eth.blockNumber
        now = geb.web3.eth.getBlock(block_number).timestamp
        set_outstanding_coin_supply_time = shutdown_time_in_unix + shutdown_cooldown
        assert now >= set_outstanding_coin_supply_time

        time_travel_by(geb.web3, 1)

        keeper.check_settlement(
        )  # Facilitate cooldown (setting outstanding coin supply)
        assert keeper.settlement_facilitated == True
コード例 #2
0
    def test_check_cage(self, mcd: DssDeployment, keeper: CageKeeper,
                        our_address: Address, other_address: Address):
        print_out("test_check_cage")
        keeper.check_cage()
        assert keeper.cageFacilitated == False
        assert mcd.end.live() == 1
        prepare_esm(mcd, our_address)
        fire_esm(mcd)
        assert keeper.confirmations == 0
        for i in range(0, 12):
            time_travel_by(mcd.web3, 1)
            keeper.check_cage()
        assert keeper.confirmations == 12

        keeper.check_cage()  # Facilitate processing period
        assert keeper.cageFacilitated == True

        when = mcd.end.when()
        wait = mcd.end.wait()
        whenInUnix = when.replace(tzinfo=timezone.utc).timestamp()
        blockNumber = mcd.web3.eth.blockNumber
        now = mcd.web3.eth.getBlock(blockNumber).timestamp
        thawedCage = whenInUnix + wait
        assert now >= thawedCage

        time_travel_by(mcd.web3, 1)

        keeper.check_cage()  # Facilitate cooldown (thawing cage)
コード例 #3
0
    def test_joy_and_boom(self, deployment: Deployment):
        # given
        deployment.tub.join(Wad.from_number(10)).transact()
        deployment.tub.mold_cap(Wad.from_number(100000)).transact()
        deployment.tub.mold_tax(Ray(1000100000000000000000000000)).transact()
        DSValue(web3=deployment.web3, address=deployment.tub.pip()).poke_with_int(Wad.from_number(250).value).transact()

        # and
        deployment.tub.open().transact()
        deployment.tub.lock(1, Wad.from_number(4)).transact()
        deployment.tub.draw(1, Wad.from_number(1000)).transact()

        # when
        time_travel_by(deployment.web3, 3600)
        deployment.tub.drip().transact()

        # then
        assert deployment.skr.balance_of(deployment.our_address) == Wad.from_number(6)
        assert deployment.tap.joy() == Wad(433303616582911495481)

        # when
        deployment.tap.boom(Wad.from_number(1)).transact()

        # then
        assert deployment.skr.balance_of(deployment.our_address) == Wad.from_number(5)
        assert deployment.tap.joy() == Wad(183303616582911495481)
コード例 #4
0
    def test_scenario(self, web3, mcd, flapper, our_address, other_address,
                      deployment_address):
        create_surplus(mcd, flapper, deployment_address)

        joy_before = mcd.vat.dai(mcd.vow.address)
        # total surplus > total debt + surplus auction lot size + surplus buffer
        assert joy_before > mcd.vat.sin(
            mcd.vow.address) + mcd.vow.bump() + mcd.vow.hump()
        assert (mcd.vat.sin(mcd.vow.address) -
                mcd.vow.sin()) - mcd.vow.ash() == Rad(0)
        assert mcd.vow.flap().transact()
        kick = flapper.kicks()
        assert kick == 1
        assert len(flapper.active_auctions()) == 1
        check_active_auctions(flapper)
        current_bid = flapper.bids(1)
        assert current_bid.lot > Rad(0)
        log = self.last_log(flapper)
        assert isinstance(log, Flapper.KickLog)
        assert log.id == kick
        assert log.lot == current_bid.lot
        assert log.bid == current_bid.bid

        # Allow the auction to expire, and then resurrect it
        time_travel_by(web3, flapper.tau() + 1)
        assert flapper.tick(kick).transact()

        # Bid on the resurrected auction
        mint_mkr(mcd.mkr, our_address, Wad.from_number(10))
        flapper.approve(mcd.mkr.address, directly(from_address=our_address))
        bid = Wad.from_number(0.001)
        assert mcd.mkr.balance_of(our_address) > bid
        TestFlapper.tend(flapper, kick, our_address, current_bid.lot, bid)
        current_bid = flapper.bids(kick)
        assert current_bid.bid == bid
        assert current_bid.guy == our_address

        # Exercise _deal_ after bid has expired
        time_travel_by(web3, flapper.ttl() + 1)
        now = datetime.now().timestamp()
        assert 0 < current_bid.tic < now or current_bid.end < now
        assert flapper.deal(kick).transact(from_address=our_address)
        joy_after = mcd.vat.dai(mcd.vow.address)
        print(f'joy_before={str(joy_before)}, joy_after={str(joy_after)}')
        assert joy_before - joy_after == mcd.vow.bump()
        log = self.last_log(flapper)
        assert isinstance(log, Flapper.DealLog)
        assert log.usr == our_address
        assert log.id == kick

        # Grab our dai
        mcd.approve_dai(our_address)
        assert mcd.dai_adapter.exit(our_address, Wad(
            current_bid.lot)).transact(from_address=our_address)
        assert mcd.dai.balance_of(our_address) >= Wad(current_bid.lot)
        assert (mcd.vat.sin(mcd.vow.address) -
                mcd.vow.sin()) - mcd.vow.ash() == Rad(0)
コード例 #5
0
ファイル: test_auctions.py プロジェクト: cryptopossum/pymaker
def create_debt(web3: Web3, mcd: DssDeployment, our_address: Address, deployment_address: Address):
    assert isinstance(web3, Web3)
    assert isinstance(mcd, DssDeployment)
    assert isinstance(our_address, Address)
    assert isinstance(deployment_address, Address)

    # Create a vault
    collateral = mcd.collaterals['ETH-A']
    ilk = collateral.ilk
    ink = Wad.from_number(10)
    wrap_eth(mcd, deployment_address, ink)
    collateral.approve(deployment_address)
    assert collateral.adapter.join(deployment_address, ink).transact(from_address=deployment_address)
    frob(mcd, collateral, deployment_address, dink=ink, dart=Wad(0))
    dart = max_dart(mcd, collateral, deployment_address) - Wad(1)
    frob(mcd, collateral, deployment_address, dink=Wad(0), dart=dart)
    assert not mcd.cat.can_bite(ilk, mcd.vat.urn(collateral.ilk, deployment_address))

    # Undercollateralize by dropping the spot price, and then bite the vault
    to_price = Wad(Web3.toInt(collateral.pip.read())) / Wad.from_number(2)
    set_collateral_price(mcd, collateral, to_price)
    urn = mcd.vat.urn(collateral.ilk, deployment_address)
    assert urn.ink is not None and urn.art is not None
    assert ilk.spot is not None
    assert mcd.cat.can_bite(collateral.ilk, urn)
    assert mcd.cat.bite(collateral.ilk, urn).transact()
    flip_kick = collateral.flipper.kicks()

    # Generate some Dai, submit a zero bid to win the flip auction without covering all the debt
    wrap_eth(mcd, our_address, Wad.from_number(10))
    collateral.approve(our_address)
    assert collateral.adapter.join(our_address, Wad.from_number(10)).transact(from_address=our_address)
    web3.eth.defaultAccount = our_address.address
    frob(mcd, collateral, our_address, dink=Wad.from_number(10), dart=Wad.from_number(20))
    collateral.flipper.approve(mcd.vat.address, approval_function=hope_directly())
    current_bid = collateral.flipper.bids(flip_kick)
    TestFlipper.tend(collateral.flipper, flip_kick, our_address, current_bid.lot, Rad(1))
    mcd.vat.can(our_address, collateral.flipper.address)
    time_travel_by(web3, collateral.flipper.ttl() + 1)
    assert collateral.flipper.deal(flip_kick).transact()

    # Raise debt from the queue (note that vow.wait is 0 on our testchain)
    assert mcd.vow.wait() == 0
    bites = mcd.cat.past_bites(100)
    assert len(bites) > 0
    for bite in bites:
        era_bite = bite.era(web3)
        assert era_bite > int(datetime.now().timestamp()) - 120
        assert mcd.vow.sin_of(era_bite) > Rad(0)
        assert mcd.vow.flog(era_bite).transact()
        assert mcd.vow.sin_of(era_bite) == Rad(0)
    # Cancel out surplus and debt
    dai_vow = mcd.vat.dai(mcd.vow.address)
    assert dai_vow <= mcd.vow.woe()
    assert mcd.vow.heal(dai_vow).transact()
    assert mcd.vow.woe() >= mcd.vow.sump()
コード例 #6
0
ファイル: test_dss.py プロジェクト: rmooreGroundhog/pymaker
    def test_flog(self, web3, d: DssDeployment, bite_event):
        # given
        time_travel_by(web3, d.vow.wait() + 10)
        era = web3.eth.getBlock(bite_event.raw['blockNumber'])['timestamp']
        assert d.vow.sin_of(era) != Wad(0)

        # when
        assert d.vow.flog(era).transact()

        # then
        assert d.vow.sin_of(era) == Wad(0)
コード例 #7
0
    def test_scenario(self, web3, mcd, flopper, our_address, other_address,
                      deployment_address):
        create_debt(web3, mcd, our_address, deployment_address)

        # Kick off the flop auction
        assert flopper.kicks() == 0
        assert len(flopper.active_auctions()) == 0
        assert mcd.vat.dai(mcd.vow.address) == Rad(0)
        assert mcd.vow.flop().transact()
        kick = flopper.kicks()
        assert kick == 1
        assert len(flopper.active_auctions()) == 1
        check_active_auctions(flopper)
        current_bid = flopper.bids(kick)
        log = self.last_log(flopper)
        assert isinstance(log, Flopper.KickLog)
        assert log.id == kick
        assert log.lot == current_bid.lot
        assert log.bid == current_bid.bid
        assert log.gal == mcd.vow.address

        # Allow the auction to expire, and then resurrect it
        time_travel_by(web3, flopper.tau() + 1)
        assert flopper.tick(kick).transact()
        assert flopper.bids(kick).lot == current_bid.lot * flopper.pad()

        # Bid on the resurrected auction
        bid = Wad.from_number(0.000005)
        flopper.approve(mcd.vat.address, hope_directly())
        assert mcd.vat.can(our_address, flopper.address)
        TestFlopper.dent(flopper, kick, our_address, bid, current_bid.bid)
        current_bid = flopper.bids(kick)
        assert current_bid.guy == our_address

        # Confirm victory
        time_travel_by(web3, flopper.ttl() + 1)
        assert flopper.live()
        now = int(datetime.now().timestamp())
        assert (current_bid.tic < now
                and current_bid.tic != 0) or current_bid.end < now
        mkr_before = mcd.mkr.balance_of(our_address)
        assert flopper.deal(kick).transact(from_address=our_address)
        mkr_after = mcd.mkr.balance_of(our_address)
        assert mkr_after > mkr_before
        log = self.last_log(flopper)
        assert isinstance(log, Flopper.DealLog)
        assert log.usr == our_address
        assert log.id == kick

        # Cleanup
        collateral = mcd.collaterals['ETH-A']
        set_collateral_price(mcd, collateral, Wad.from_number(230))
コード例 #8
0
    def test_drip_and_chi_and_rho(self, deployment: Deployment):
        # given
        deployment.tub.mold_tax(Ray(1000000000000000020000000000)).transact()
        old_chi = deployment.tub.chi()
        old_rho = deployment.tub.rho()

        # when
        time_travel_by(deployment.web3, 1000)
        deployment.tub.drip().transact()

        # then
        assert deployment.tub.chi() > old_chi
        assert deployment.tub.rho() > old_rho
コード例 #9
0
ファイル: test_dsrmanager.py プロジェクト: mtyou/pymaker
    def test_supply_pie_dai(self, mcd: DssDeployment, our_address: Address):

        dai = pytest.global_dai
        chi1 = mcd.pot.chi()
        # assert chi1 == Ray.from_number(1) Commented out in case there's some initial state on testchain
        pie = Wad(Rad(dai) / Rad(chi1))
        assert mcd.dsr_manager.supply() == pie
        assert mcd.dsr_manager.pie_of(our_address) == pie

        time_travel_by(web3=mcd.web3, seconds=10)
        assert mcd.pot.drip().transact(from_address=our_address)
        chi2 = mcd.pot.chi()
        assert chi1 != chi2
        dai = Rad(pie) * Rad(chi2)
        assert mcd.dsr_manager.dai_of(our_address) == dai
コード例 #10
0
    def test_scenario(self):
        # given
        self.dai_mint(Wad.from_number(100000))
        assert self.gem.mint(Wad.from_number(100)).transact()
        assert self.gem.transfer(self.other_address_1, Wad.from_number(100)).transact()
        assert self.dai_balance(self.our_address) == Wad.from_number(100000)

        # when
        self.flipper.kick(urn=self.other_address_1,
                          gal=self.other_address_1,
                          tab=Wad.from_number(5000),
                          lot=Wad.from_number(100),
                          bid=Wad.from_number(1000)).transact(from_address=self.other_address_1)
        # then
        assert self.dai_balance(self.our_address) == Wad.from_number(100000)
        assert self.dai_balance(self.other_address_1) == Wad.from_number(0)
        assert self.gem_balance(self.our_address) == Wad.from_number(0)
        assert self.gem_balance(self.other_address_1) == Wad.from_number(0)

        # when
        self.flipper.tend(1, Wad.from_number(100), Wad.from_number(2000)).transact()
        assert self.dai_balance(self.our_address) == Wad.from_number(100000) - Wad.from_number(2000)
        assert self.dai_balance(self.other_address_1) == Wad.from_number(2000)
        assert self.gem_balance(self.our_address) == Wad.from_number(0)
        assert self.gem_balance(self.other_address_1) == Wad.from_number(0)

        # when
        self.flipper.tend(1, Wad.from_number(100), Wad.from_number(5000)).transact()
        assert self.dai_balance(self.our_address) == Wad.from_number(100000) - Wad.from_number(5000)
        assert self.dai_balance(self.other_address_1) == Wad.from_number(5000)
        assert self.gem_balance(self.our_address) == Wad.from_number(0)
        assert self.gem_balance(self.other_address_1) == Wad.from_number(0)

        # when
        self.flipper.dent(1, Wad.from_number(80), Wad.from_number(5000)).transact()
        assert self.dai_balance(self.our_address) == Wad.from_number(100000) - Wad.from_number(5000)
        assert self.dai_balance(self.other_address_1) == Wad.from_number(5000)
        assert self.gem_balance(self.our_address) == Wad.from_number(0)
        assert self.gem_balance(self.other_address_1) == Wad.from_number(20)

        time_travel_by(self.web3, 60*60*24*8)

        # when
        self.flipper.deal(1).transact()
        assert self.dai_balance(self.our_address) == Wad.from_number(100000) - Wad.from_number(5000)
        assert self.dai_balance(self.other_address_1) == Wad.from_number(5000)
        assert self.gem_balance(self.our_address) == Wad.from_number(80)
        assert self.gem_balance(self.other_address_1) == Wad.from_number(20)
コード例 #11
0
    def test_close_cdp(self, web3, mcd, our_address):
        collateral = mcd.collaterals['ETH-A']
        ilk = collateral.ilk

        assert mcd.end.free(ilk).transact()
        assert mcd.vat.urn(ilk, our_address).ink == Wad(0)
        assert mcd.vat.gem(ilk, our_address) > Wad(0)
        assert collateral.adapter.exit(our_address,
                                       mcd.vat.gem(ilk,
                                                   our_address)).transact()

        assert mcd.end.wait() == 5
        time_travel_by(web3, 5)
        assert mcd.end.thaw().transact()
        assert mcd.end.flow(ilk).transact()
        assert mcd.end.fix(ilk) > Ray(0)
コード例 #12
0
    def test_scenario(self):
        # given
        pit = Address(self.web3.eth.accounts[1])
        # and
        self.dai.mint(Wad.from_number(50000000)).transact()
        self.gem.mint(Wad.from_number(1000)).transact()

        # when
        self.dai.approve(self.flapper.address).transact()
        self.flapper.kick(pit, Wad.from_number(20000), Wad.from_number(1)).transact()
        # then
        assert self.dai.balance_of(self.our_address) == Wad.from_number(49980000)
        assert self.gem.balance_of(pit) == Wad.from_number(0)
        # and
        assert self.flapper.bids(1).tic == 0

        self.flapper.approve(directly())

        # when
        self.flapper.tend(1, Wad.from_number(20000), Wad.from_number(1.5)).transact()
        # then
        assert self.dai.balance_of(self.our_address) == Wad.from_number(49980000)
        assert self.gem.balance_of(pit) == Wad.from_number(0.5)
        # and
        assert self.flapper.bids(1).tic > 0

        # when
        self.flapper.tend(1, Wad.from_number(20000), Wad.from_number(2.0)).transact()
        # then
        assert self.dai.balance_of(self.our_address) == Wad.from_number(49980000)
        assert self.gem.balance_of(pit) == Wad.from_number(1.0)
        # and
        assert self.flapper.bids(1).tic > 0

        time_travel_by(self.web3, 60*60*24*8)

        # when
        self.flapper.deal(1).transact()
        # then
        # assert self.dai.balance_of(self.our_address) == Wad.from_number(50000000)
        assert self.gem.balance_of(pit) == Wad.from_number(1.0)
コード例 #13
0
ファイル: test_shutdown.py プロジェクト: reflexer-labs/pyflex
    def test_close_safe(self, web3, geb, our_address):
        collateral = geb.collaterals['ETH-A']
        collateral_type = collateral.collateral_type

        assert geb.global_settlement.free_collateral(
            collateral_type).transact()
        assert geb.safe_engine.safe(collateral_type,
                                    our_address).locked_collateral == Wad(0)
        assert geb.safe_engine.token_collateral(collateral_type,
                                                our_address) > Wad(0)
        assert collateral.adapter.exit(
            our_address,
            geb.safe_engine.token_collateral(collateral_type,
                                             our_address)).transact()

        assert geb.global_settlement.shutdown_cooldown() == 0
        time_travel_by(web3, 5)
        assert geb.global_settlement.set_outstanding_coin_supply().transact()
        assert geb.global_settlement.calculate_cash_price(
            collateral_type).transact()
        assert geb.global_settlement.collateral_cash_price(
            collateral_type) > Ray(0)
コード例 #14
0
    def test_scenario(self):
        # given
        recidaint = Address(self.web3.eth.accounts[1])
        # and
        self.dai.mint(Wad.from_number(50000000)).transact()

        # when
        self.flopper.kick(recidaint, Wad.from_number(10), Wad.from_number(20000)).transact()
        # then
        assert self.dai.balance_of(recidaint) == Wad(0)
        assert self.gem.total_supply() == Wad(0)
        # and
        assert self.flopper.bids(1).tic == 0

        self.flopper.approve(directly())

        # when
        self.flopper.dent(1, Wad.from_number(9), Wad.from_number(20000)).transact()
        # then
        assert self.dai.balance_of(recidaint) == Wad.from_number(20000)
        assert self.gem.total_supply() == Wad(0)
        # and
        assert self.flopper.bids(1).tic > 0

        # when
        self.flopper.dent(1, Wad.from_number(8), Wad.from_number(20000)).transact()
        # then
        assert self.dai.balance_of(recidaint) == Wad.from_number(20000)
        assert self.gem.total_supply() == Wad(0)
        # and
        assert self.flopper.bids(1).tic > 0

        time_travel_by(self.web3, 60*60*24*8)

        # when
        self.flopper.deal(1).transact()
        # then
        assert self.dai.balance_of(recidaint) == Wad.from_number(20000)
        assert self.gem.total_supply() == Wad.from_number(8)
コード例 #15
0
    def test_get_orders_by_block(self):

        if isinstance(self.otc, MatchingMarket):
            token1_val = self.token1_tokenclass
            token2_val = self.token2_tokenclass

            # given
            maker1 = self.our_address

            # when
            self.otc.approve([self.token1], directly())
            made_order = self.otc.make(token1_val, Wad.from_number(1),
                          token2_val, Wad.from_number(2)).transact()
            block_number = made_order.raw_receipt.blockNumber

            # and when
            time_travel_by(self.web3, 10)
            assert len(self.otc.get_orders_by_maker(maker1)) == 1
            self.otc.kill(1).transact(gas=4000000)
            assert len(self.otc.get_orders_by_maker(maker1)) == 0

            # then
            time_travel_by(self.web3, 10)
            assert len(self.otc.get_orders(token1_val, token2_val, block_number)) == 1
コード例 #16
0
    def test_scenario(self, web3, mcd, collateral, clipper, our_address,
                      other_address, deployment_address):
        dirt_before = mcd.dog.dog_dirt()
        vice_before = mcd.vat.vice()
        sin_before = mcd.vow.sin()

        # Create a vault
        ilk = collateral.ilk
        ink = Wad.from_number(1)
        wrap_eth(mcd, deployment_address, ink)
        collateral.approve(deployment_address)
        assert collateral.adapter.join(
            deployment_address, ink).transact(from_address=deployment_address)
        frob(mcd, collateral, deployment_address, dink=ink, dart=Wad(0))
        dart = max_dart(mcd, collateral, deployment_address) - Wad(1)
        frob(mcd, collateral, deployment_address, dink=Wad(0), dart=dart)

        # Mint and withdraw all the Dai
        mcd.approve_dai(deployment_address)
        assert mcd.dai_adapter.exit(
            deployment_address, dart).transact(from_address=deployment_address)

        # Undercollateralize the vault
        to_price = Wad(Web3.toInt(collateral.pip.read())) / Wad.from_number(2)
        set_collateral_price(mcd, collateral, to_price)
        urn = mcd.vat.urn(collateral.ilk, deployment_address)
        ilk = mcd.vat.ilk(ilk.name)
        safe = Ray(urn.art) * mcd.vat.ilk(ilk.name).rate <= Ray(
            urn.ink) * ilk.spot
        assert not safe
        assert clipper.active_count() == 0

        # Bark the vault, which moves debt to the vow and kicks the clipper
        dai_before_bark: Rad = mcd.vat.dai(our_address)
        urn = mcd.vat.urn(collateral.ilk, deployment_address)
        assert urn.ink > Wad(0)
        tab = urn.art * ilk.rate  # Wad
        assert tab == dart
        assert mcd.dog.bark(ilk, urn).transact()
        barks = mcd.dog.past_barks(1)
        assert len(barks) == 1
        last_bite = barks[0]
        assert last_bite.due > Rad(0)
        assert clipper.active_count() == 1
        kick = clipper.kicks()
        assert kick == 1
        assert len(clipper.active_auctions()) == 1
        assert clipper.active_auctions()[0].id == 1
        assert mcd.active_auctions()['clips']['ETH-B'][0].id == 1
        urn = mcd.vat.urn(collateral.ilk, deployment_address)
        (needs_redo, price, lot, tab) = clipper.status(kick)
        assert not needs_redo
        assert price == Ray.from_number(172.5)
        assert lot == ink
        assert float(tab) == 105.0
        # Check vat, vow, and dog
        assert urn.ink == Wad(0)
        assert vice_before < mcd.vat.vice()
        assert sin_before < mcd.vow.sin()
        assert dirt_before < mcd.dog.dog_dirt()
        # Check the clipper
        current_sale = clipper.sales(kick)
        assert isinstance(current_sale, Clipper.Sale)
        assert current_sale.pos == 0
        assert float(current_sale.tab) == 105.0
        assert current_sale.lot == ink
        assert current_sale.usr == deployment_address
        assert current_sale.tic > 0
        assert round(current_sale.top, 1) == price
        coin = Rad(clipper.tip() + (current_sale.tab * clipper.chip()))
        # Confirm we received our liquidation reward
        dai_after_bark: Rad = mcd.vat.dai(our_address)
        assert dai_after_bark == dai_before_bark + coin
        kick_log = self.last_log(clipper)
        assert isinstance(kick_log, Clipper.KickLog)
        assert kick_log.id == kick
        assert kick_log.top == current_sale.top
        assert kick_log.tab == current_sale.tab
        assert kick_log.lot == current_sale.lot
        assert kick_log.usr == deployment_address
        assert kick_log.kpr == our_address
        assert kick_log.coin == coin

        # Wrap some eth and handle approvals before bidding
        eth_required = Wad(
            current_sale.tab / Rad(ilk.spot)) * Wad.from_number(1.1)
        wrap_eth(mcd, our_address, eth_required)
        collateral.approve(our_address)
        assert collateral.adapter.join(
            our_address, eth_required).transact(from_address=our_address)
        clipper.approve(
            mcd.vat.address,
            approval_function=hope_directly(from_address=our_address))

        # Ensure we cannot take collateral below the current price
        (needs_redo, price, lot, tab) = clipper.status(kick)
        with pytest.raises(AssertionError):
            clipper.validate_take(kick, ink, price - Ray.from_number(1))
        assert not clipper.take(
            kick, ink, Ray.from_number(140)).transact(from_address=our_address)

        # Take some collateral with max above the top price
        clipper.validate_take(kick, Wad.from_number(0.07),
                              Ray.from_number(180))
        assert web3.eth.defaultAccount == our_address.address
        assert clipper.take(
            kick, Wad.from_number(0.07),
            Ray.from_number(180)).transact(from_address=our_address)
        (needs_redo, price, lot, tab) = clipper.status(kick)
        assert not needs_redo
        current_sale = clipper.sales(kick)
        assert current_sale.lot > Wad(0)
        assert current_sale.top > price
        assert Rad(0) < current_sale.tab < kick_log.tab
        first_take_log = self.last_log(clipper)
        assert first_take_log.id == 1
        assert first_take_log.max == Ray.from_number(180)
        assert first_take_log.price == price
        assert first_take_log.lot == current_sale.lot
        assert first_take_log.usr == deployment_address
        assert first_take_log.sender == our_address
        assert round(first_take_log.owe,
                     18) == round(Rad.from_number(0.07) * Rad(price), 18)

        # Allow the auction to expire, and then resurrect it
        # TODO: If abaci contract is ever wrapped, read tau from it
        time_travel_by(web3, 24)
        (needs_redo, price, lot, tab) = clipper.status(kick)
        assert needs_redo
        assert len(clipper.active_auctions()) == clipper.active_count()
        assert clipper.redo(kick, our_address).transact()
        (needs_redo, price, lot, tab) = clipper.status(kick)
        assert not needs_redo
        current_sale = clipper.sales(kick)
        assert current_sale.lot > Wad(0)
        redo_log = self.last_log(clipper)
        assert isinstance(redo_log, Clipper.RedoLog)
        assert redo_log.id == kick
        assert redo_log.top == current_sale.top
        assert redo_log.tab == current_sale.tab
        assert redo_log.lot == current_sale.lot
        assert redo_log.usr == deployment_address
        assert redo_log.kpr == our_address
        coin = Rad(clipper.tip() + (current_sale.tab * clipper.chip()))
        assert round(float(redo_log.coin), 18) == round(float(coin), 18)

        # Sleep until price has gone down enough to bid with remaining Dai
        dai = mcd.vat.dai(our_address)
        last_price = price
        print(
            f"Bid cost={float(price * Ray(current_sale.lot))}, Dai balance={float(dai)}"
        )
        while price * Ray(current_sale.lot) > Ray(dai):
            print(
                f"Bid cost {price * Ray(current_sale.lot)} exceeds Dai balance {dai}"
            )
            time_travel_by(web3, 2)
            (needs_redo, price, lot, tab) = clipper.status(kick)
            assert price < last_price
            assert not needs_redo
            last_price = price
        clipper.validate_take(kick, current_sale.lot, price)
        assert clipper.take(kick, current_sale.lot,
                            price).transact(from_address=our_address)
        current_sale = clipper.sales(kick)
        assert current_sale.lot == Wad(0)
        assert current_sale.tab == Rad(0)
        assert clipper.active_count() == 0
        assert len(clipper.active_auctions()) == 0

        # Ensure we can retrieve our collateral
        collateral_before = collateral.gem.balance_of(our_address)
        assert collateral.adapter.exit(our_address,
                                       ink).transact(from_address=our_address)
        collateral_after = collateral.gem.balance_of(our_address)
        assert collateral_before < collateral_after

        # Cleanup
        set_collateral_price(mcd, collateral, Wad.from_number(230))
        cleanup_urn(mcd, collateral, our_address)
コード例 #17
0
    def test_scenario(self, web3, mcd, collateral, flipper, our_address,
                      other_address, deployment_address):
        # Create a vault
        kicks_before = flipper.kicks()
        ilk = collateral.ilk
        ink = Wad.from_number(0.5)
        wrap_eth(mcd, deployment_address, ink)
        collateral.approve(deployment_address)
        assert collateral.adapter.join(
            deployment_address, ink).transact(from_address=deployment_address)
        frob(mcd, collateral, deployment_address, dink=ink, dart=Wad(0))
        dart = max_dart(mcd, collateral, deployment_address) - Wad(1)
        frob(mcd, collateral, deployment_address, dink=Wad(0), dart=dart)

        # Mint and withdraw all the Dai
        mcd.approve_dai(deployment_address)
        assert mcd.dai_adapter.exit(
            deployment_address, dart).transact(from_address=deployment_address)
        assert mcd.dai.balance_of(deployment_address) == dart

        # Undercollateralize the vault
        to_price = Wad(Web3.toInt(collateral.pip.read())) / Wad.from_number(2)
        set_collateral_price(mcd, collateral, to_price)
        urn = mcd.vat.urn(collateral.ilk, deployment_address)
        ilk = mcd.vat.ilk(ilk.name)
        assert ilk.rate is not None
        assert ilk.spot is not None
        safe = Ray(urn.art) * mcd.vat.ilk(ilk.name).rate <= Ray(
            urn.ink) * ilk.spot
        assert not safe
        assert len(flipper.active_auctions()) == 0
        litter_before = mcd.cat.litter()

        # Bite the vault, which moves debt to the vow and kicks the flipper
        urn = mcd.vat.urn(collateral.ilk, deployment_address)
        assert urn.ink > Wad(0)
        art = min(urn.art, Wad(mcd.cat.dunk(ilk)))  # Wad
        tab = art * ilk.rate  # Wad
        assert tab == dart
        assert mcd.cat.can_bite(ilk, urn)
        assert mcd.cat.bite(ilk, urn).transact()
        kick = flipper.kicks()
        assert kick == kicks_before + 1
        urn = mcd.vat.urn(collateral.ilk, deployment_address)
        # Check vat, vow, and cat
        assert urn.ink == Wad(0)
        assert urn.art == dart - art
        assert mcd.vat.vice() > Rad(0)
        assert mcd.vow.sin() == Rad(tab)
        bites = mcd.cat.past_bites(1)
        assert len(bites) == 1
        last_bite = bites[0]
        assert last_bite.tab > Rad(0)
        assert last_bite.id == 1
        litter_after = mcd.cat.litter()
        assert litter_before < litter_after
        # Check the flipper
        current_bid = flipper.bids(kick)
        assert isinstance(current_bid, Flipper.Bid)
        assert current_bid.lot > Wad(0)
        assert current_bid.tab > Rad(0)
        assert current_bid.bid == Rad(0)
        # Cat doesn't incorporate the liquidation penalty (chop), but the kicker includes it.
        # Awaiting word from @dc why this is so.
        #assert last_bite.tab == current_bid.tab
        log = self.last_log(flipper)
        assert isinstance(log, Flipper.KickLog)
        assert log.id == kick
        assert log.lot == current_bid.lot
        assert log.bid == current_bid.bid
        assert log.tab == current_bid.tab
        assert log.usr == deployment_address
        assert log.gal == mcd.vow.address

        # Allow the auction to expire, and then resurrect it
        time_travel_by(web3, flipper.tau() + 1)
        assert flipper.tick(kick).transact()

        # Wrap some eth and handle approvals before bidding
        eth_required = Wad(
            current_bid.tab / Rad(ilk.spot)) * Wad.from_number(1.13)
        wrap_eth(mcd, other_address, eth_required)
        collateral.approve(other_address)
        assert collateral.adapter.join(
            other_address, eth_required).transact(from_address=other_address)
        wrap_eth(mcd, our_address, eth_required)
        collateral.approve(our_address)
        assert collateral.adapter.join(
            our_address, eth_required).transact(from_address=our_address)

        # Test the _tend_ phase of the auction
        flipper.approve(
            mcd.vat.address,
            approval_function=hope_directly(from_address=other_address))
        # Add Wad(1) to counter precision error converting tab from Rad to Wad
        frob(mcd,
             collateral,
             other_address,
             dink=eth_required,
             dart=Wad(current_bid.tab) + Wad(1))
        urn = mcd.vat.urn(collateral.ilk, other_address)
        assert Rad(urn.art) >= current_bid.tab
        # Bid the tab to instantly transition to dent stage
        TestFlipper.tend(flipper, kick, other_address, current_bid.lot,
                         current_bid.tab)
        current_bid = flipper.bids(kick)
        assert current_bid.guy == other_address
        assert current_bid.bid == current_bid.tab
        assert len(flipper.active_auctions()) == 1
        check_active_auctions(flipper)
        log = self.last_log(flipper)
        assert isinstance(log, Flipper.TendLog)
        assert log.guy == current_bid.guy
        assert log.id == current_bid.id
        assert log.lot == current_bid.lot
        assert log.bid == current_bid.bid

        # Test the _dent_ phase of the auction
        flipper.approve(
            mcd.vat.address,
            approval_function=hope_directly(from_address=our_address))
        frob(mcd,
             collateral,
             our_address,
             dink=eth_required,
             dart=Wad(current_bid.tab) + Wad(1))
        lot = current_bid.lot - Wad.from_number(0.3)
        assert flipper.beg() * lot <= current_bid.lot
        TestFlipper.dent(flipper, kick, our_address, lot, current_bid.tab)
        current_bid = flipper.bids(kick)
        assert current_bid.guy == our_address
        assert current_bid.bid == current_bid.tab
        assert current_bid.lot == lot
        log = self.last_log(flipper)
        assert isinstance(log, Flipper.DentLog)
        assert log.guy == current_bid.guy
        assert log.id == current_bid.id
        assert log.lot == current_bid.lot
        assert log.bid == current_bid.bid

        # Exercise _deal_ after bid has expired
        time_travel_by(web3, flipper.ttl() + 1)
        now = datetime.now().timestamp()
        assert 0 < current_bid.tic < now or current_bid.end < now
        assert flipper.deal(kick).transact(from_address=our_address)
        assert len(flipper.active_auctions()) == 0
        log = self.last_log(flipper)
        assert isinstance(log, Flipper.DealLog)
        assert log.usr == our_address

        # Grab our collateral
        collateral_before = collateral.gem.balance_of(our_address)
        assert collateral.adapter.exit(
            our_address, current_bid.lot).transact(from_address=our_address)
        collateral_after = collateral.gem.balance_of(our_address)
        assert collateral_before < collateral_after

        # Cleanup
        set_collateral_price(mcd, collateral, Wad.from_number(230))
        cleanup_urn(mcd, collateral, other_address)
コード例 #18
0
ファイル: test_dss.py プロジェクト: rmooreGroundhog/pymaker
 def test_empty_flog(self, web3, d: DssDeployment):
     time_travel_by(web3, d.vow.wait() + 10)
     assert d.vow.flog(0).transact()