def __init__(self, vat, gem):
     self.ADDRESS = "flopper"
     self.vat = vat
     self.gem = gem
     self.bids = dict()
     self.kicks = 0
     self.pad = Wad.from_number(1.5)
     self.beg = Wad.from_number(1.05)
     self.ttl = 3 * 60 * 60
     self.tau = 2 * 24 * 60 * 60
Example #2
0
 def get_slippage(self, pair_id, in_token, in_amt, t):
     self.tick(t)
     out_token = next(
         filter(lambda x: x != in_token, self.pairs[pair_id].keys()))
     in_reserve = Wad.from_number(float(self.pairs[pair_id][in_token]))
     out_reserve = Wad.from_number(float(self.pairs[pair_id][out_token]))
     initial_rate = out_reserve / in_reserve
     k = in_reserve * out_reserve
     new_in_reserve = in_reserve + in_amt
     new_out_reserve = k / new_in_reserve
     new_rate = new_out_reserve / new_in_reserve
     return (
         Rad(out_reserve - new_out_reserve),
         (new_rate - initial_rate) / initial_rate,
     )
Example #3
0
    def run_bidding_model(self, bid, ilk_id):
        curr_price = Wad(bid.bid) / bid.lot
        if (bid.guy == self.ADDRESS or bid.lot == Wad(0) or curr_price > Wad(
                self.vat.ilks[ilk_id].spot * self.spotter.ilks[ilk_id].mat)):
            return {"price": Wad(0)}

        if bid.bid == Rad(0):
            return {
                "price": Wad.from_number(0.05) * Wad(bid.tab / Rad(bid.lot))
            }

        return {
            "price":
            curr_price * (self.flippers[ilk_id].beg +
                          Wad.from_number(random.uniform(0, 0.15)))
        }
Example #4
0
    def bark(self, ilk_id, urn_id, kpr, now):
        ink = self.vat.urns[ilk_id][urn_id].ink
        art = self.vat.urns[ilk_id][urn_id].art
        milk = self.ilks[ilk_id]

        rate = self.vat.ilks[ilk_id].rate
        spot = self.vat.ilks[ilk_id].spot
        dust = self.vat.ilks[ilk_id].dust
        require(spot > Ray(0) and spot * ink < rate * art, "Dog/not-unsafe")

        room = min(self.Hole - self.Dirt, milk.hole - milk.dirt)
        require(room > Rad(0) and room >= dust, "Dog/liquidation-limit-hit")

        dart = min(art, Wad(room / Rad(rate)) / milk.chop)

        if Rad(rate * (art - dart)) < dust:
            # Q: What if art > room?
            # Resetting dart = art here can push past liq limit
            dart = art

        dink = ink * dart / art

        require(dink > Wad(0), "Dog/null-auction")
        require(
            dart <= Wad.from_number(2**255)
            and dink <= Wad.from_number(2**255),
            "Dog/overflow",
        )

        self.vat.grab(
            ilk_id,
            urn_id,
            milk.clip.ADDRESS,
            self.vow.ADDRESS,
            Wad(0) - dink,
            Wad(0) - dart,
        )

        due = Rad(rate * dart)
        self.vow.fess(due, now)

        tab = due * Rad(milk.chop)
        self.Dirt += tab
        self.ilks[ilk_id].dirt = milk.dirt + tab

        milk.clip.kick(tab, dink, urn_id, kpr, now)
        return [tab]
Example #5
0
    def bite(self, ilk_id, urn, now):
        # TODO: Remove `now` once better timekeeping solution is implemented

        rate = self.vat.ilks[ilk_id].rate
        spot = self.vat.ilks[ilk_id].spot
        dust = self.vat.ilks[ilk_id].dust
        ink = self.vat.urns[ilk_id][urn].ink
        art = self.vat.urns[ilk_id][urn].art

        require(spot > Ray(0) and Rad(ink * spot) < Rad(art * rate),
                "Cat/not-unsafe")

        milk = self.ilks[ilk_id]

        room = self.box - self.litter
        require(self.litter < self.box and room >= dust,
                "Cat/liquidation-limit-hit")

        dart = Wad.min(art,
                       Wad(Rad.min(milk.dunk, room)) / Wad(rate) / milk.chop)
        dink = Wad.min(ink, ink * dart / art)

        require(dart > Wad(0) and dink > Wad(0), "Cat/null-auction")
        require(
            dart <= Wad.from_number(2**255)
            and dink <= Wad.from_number(2**255),
            "Cat/overflow",
        )

        self.vat.grab(ilk_id, urn, self.ADDRESS, self.vow.ADDRESS,
                      Wad(0) - dink,
                      Wad(0) - dart)
        self.vow.fess(Rad(dart * rate), now)

        tab = Rad(dart * rate * milk.chop)
        self.litter += tab

        milk.flip.kick(urn, self.vow.ADDRESS, tab, dink, Rad(0), now)
Example #6
0
 def open_max_vaults(self, actions):
     for ilk_id in self.ilks:
         vat_ilk = self.vat.ilks[ilk_id]
         if self.ilks[ilk_id].balanceOf(
                 self.ADDRESS) > 0 and vat_ilk.spot > Ray(0):
             dink = Wad.from_number(self.ilks[ilk_id].balanceOf(
                 self.ADDRESS))
             dart = self.spot_paddings[ilk_id] * vat_ilk.spot * dink
             if dart > Wad(vat_ilk.dust) and Rad(
                     dart * vat_ilk.rate) <= Rad(dink * vat_ilk.spot):
                 actions.append({
                     "key": "OPEN_VAULT",
                     "keeper": self,
                     "handler": self.open_vault,
                     "args": [ilk_id, dink, dart],
                     "kwargs": {},
                 })
 def peek(self, now):
     with open(self.price_feed_file) as price_feed_json:
         return Wad.from_number(
             # TODO: Constantize the "price_close" field here
             json.load(price_feed_json)[now]["price_close"])
Example #8
0
 def track_stat(state, action, _results):
     if action["key"] == "T_START":
         state["stats"]["gas_price_gwei"] = float(
             state["gas_oracle"].peek(state["t"]) * Wad.from_number(10 ** -9)
         )
Example #9
0
            # "09-05-2020",
    ]:
        timeframe_params = deepcopy(parameters)
        timeframe_params["Spotter"]["WETH"]["pip"] = PipLike(
            f"feeds/eth/{timeframe}.json")
        timeframe_params["GasOracle"][
            "price_feed_file"] = f"feeds/gas/{timeframe}.json"
        timeframe_params["Uniswap"]["pairs"][
            "0xa478c2975ab1ea89e8196811f51a7b7ade33eb11"][
                "path"] = f"feeds/eth_dai_liquidity/{timeframe}.json"

        swept_params = sweep(
            {
                # "Clipper.WETH.chip": [Wad.from_number(0.001), Wad.from_number(0.01), Wad.from_number(0.1)],
                # "Clipper.WETH.tip": [Rad.from_number(100), Rad.from_number(500), Rad.from_number(1000)],
                "Clipper.WETH.chip": [Wad.from_number(0.001)],
                "Clipper.WETH.tip": [Rad.from_number(1000)],
            },
            timeframe_params,
        )

        DutchAuctionsSims = [
            DutchAuctionsExperiment(
                contracts,
                keepers,
                sort_actions,
                ilk_ids,
                Token,
                stat_trackers,
                params,
            ) for params in swept_params
 def peek(self, now):
     with open(self.price_feed_file) as price_feed_json:
         # TODO: Constantize the "avgGasDay" field here
         # TODO: Format gas feed file to get rid of "data"
         return Wad.from_number(
             json.load(price_feed_json)["data"][now]["avgGasDay"])
Example #11
0
     }
 },
 "Keepers": {
     "NaiveVaultKeeper": {
         "amount":
         500,
         "get_params":
         lambda state: [
             state["vat"],
             state["dai_join"],
             [{
                 "ilk_id": "WETH",
                 "token": state["ilks"]["WETH"],
                 "init_balance": random.gauss(10, 2.155),
                 "gem_join": state["gem_joins"]["WETH"],
                 "spot_padding": Wad.from_number(
                     random.gauss(12 / 14, 0.216)),
             }],
             state["uniswap"],
         ],
     },
     "NaiveFlipperKeeper": {
         "amount":
         5,
         "get_params":
         lambda state: [
             state["vat"],
             state["dai_join"],
             [{
                 "ilk_id": "WETH",
                 "token": state["ilks"]["WETH"],
                 "init_balance": random.gauss(250, 64.655),
Example #12
0
    num_sales_taken(),
    auction_debt(),
    ilk_price("WETH"),
    gas_price_gwei(),
    avg_time_to_liquidation("WETH"),
]
parameters = {
    "Abacus": {
        "tau": 72
    },
    "Clipper": {
        "WETH": {
            "buf": Ray.from_number(1.05),
            "tail": 72,
            "cusp": Ray.from_number(0.5),
            "chip": Wad.from_number(0.08),
            "tip": Rad.from_number(1000),
        }
    },
    "Dog": {
        "Hole": Rad(15000000000000000000000000000000000000000000000000000),
        "WETH": {
            "chop": Wad.from_number(1.13),
            "hole": Rad(15000000000000000000000000000000000000000000000000000),
        },
    },
    "Keepers": {
        "NaiveVaultKeeper": {
            "amount":
            50,
            "get_params":