def join(self, sender, usr, wad): require(wad >= Wad(0), "GemJoin/overflow") self.vat.slip(self.ilk_id, usr, wad) require( self.gem.transferFrom(sender, self.ADDRESS, float(wad)), "GemJoin/failed-transfer", )
def exit(self, sender, usr, wad): require(wad <= Wad(2**255), "GemJoin/overflow") self.vat.slip(self.ilk_id, sender, Wad(0) - wad) require( self.gem.transferFrom(self.ADDRESS, usr, float(wad)), "GemJoin/failed-transfer", )
def init(self, ilk_id): """ This specifically is *not* the __init__ method. """ require(not self.ilks.get(ilk_id), "Vat/ilk-already-init") self.ilks[ilk_id] = Ilk(ilk_id) self.ilks[ilk_id].rate = Ray.from_number(1) # This is not canon lol self.urns[ilk_id] = {} self.gem[ilk_id] = {}
def deal(self, bid_id, now): require(self.live == 1, "Flapper/not-live") require( self.bids[bid_id].tic != 0 and (self.bids[bid_id].tic < now or self.bids[bid_id].end < now), "Flapper/not-finished", ) self.gem.mint(bid_id, self.bids[bid_id].bid) del self.bids[bid_id]
def transferFrom(self, from_address, to_address, value): require( not from_address or self.balances[from_address] >= value, f"{self.symbol}/insufficient-transferFrom", ) if from_address: self.balances[from_address] -= value self.balances[to_address] = self.balances.get(to_address, 0) + value return True
def file(self, what, data): if what == "cut": require(data <= 10**27, "StairstepExponentialDecrease/cut-gt-RAY") self.cut = data elif what == "step": self.step = data else: raise Exception( "StairstepExponentialDecrease/file-unrecognized-param")
def kick(self, gal, lot, bid, now): require(self.live == 1, "Flapper/not-live") require(self.kicks > -1, "Flapper/overflow") self.kicks += 1 bid_id = self.kicks self.bids[bid_id].bid = bid self.bids[bid_id].lot = lot self.bids[bid_id].guy = gal self.bids[bid_id].end = now + self.tau
def deal(self, bid_id, now): """Deals out a Flipper auction.""" curr_bid = self.bids[bid_id] require( curr_bid.tic != 0 and (curr_bid.tic <= now or curr_bid.end <= now), "Flipper/not-finished", ) self.cat.claw(curr_bid.tab) self.vat.flux(self.ilk_id, self.ADDRESS, curr_bid.guy, curr_bid.lot) del self.bids[bid_id]
def kick(self, tab, lot, usr, kpr, now): require(tab > Rad(0), "Clipper/zero-tab") require(lot > Wad(0), "Clipper/zero-lot") require(bool(usr), "Clipper/zero-usr") require(self.kicks < (1 << 31) - 1, "Clipper/overflow") self.kicks += 1 sale_id = self.kicks self.active.append(sale_id) pip = self.spotter.ilks[self.ilk_id].pip val = pip.peek(now) self.sales[sale_id] = Sale( len(self.active) - 1, tab, lot, usr, now, Ray(val / Wad(self.spotter.par)) * self.buf, sale_id, ) if self.tip > Rad(0) or self.chip > Wad(0): self.vat.suck(self.vow.ADDRESS, kpr, self.tip + tab * Rad(self.chip))
def frob(self, i, u, v, w, dink, dart): urn = self.urns[i].get(u, Urn(u, Wad(0), Wad(0))) ilk = self.ilks[i] urn.ink += dink urn.art += dart ilk.Art += dart dtab = Rad(ilk.rate * dart) tab = Rad(ilk.rate * urn.art) self.debt += dtab require( dart <= Wad(0) or (Rad(ilk.Art * ilk.rate) <= ilk.line and self.debt <= self.Line), "Vat/ceiling-exceeded", ) require(dart <= Wad(0) <= dink or tab <= Rad(urn.ink * ilk.spot), "Vat/not-safe") require(urn.art == Wad(0) or tab >= ilk.dust, "Vat/dust") self.gem[i][v] -= dink w_dai = self.dai.get(w, Rad(0)) w_dai += dtab self.dai[w] = w_dai self.urns[i][u] = urn self.ilks[i] = ilk
def take(self, sale_id, amt, max_price, who, data, now, sender): require(self.sales.get(sale_id), "Clipper/not-running-auction") usr = self.sales[sale_id].usr tic = self.sales[sale_id].tic (done, price) = self.status(tic, self.sales[sale_id].top, now) require(not done, "Clipper/needs-reset") require(max_price >= price, "Clipper/too-expensive") lot = self.sales[sale_id].lot tab = self.sales[sale_id].tab lot_slice = min(lot, amt) owe = Rad(price * lot_slice) if owe > tab: owe = tab lot_slice = Wad(owe / Rad(price)) elif owe < tab and lot_slice < lot: dust = self.vat.ilks[self.ilk_id].dust if tab - owe < dust: require(tab > dust, "Clipper/no-partial-purchase") owe = tab - dust lot_slice = Wad(owe / Rad(price)) tab = tab - owe lot = lot - lot_slice self.vat.flux(self.ilk_id, self.ADDRESS, who, lot_slice) if len(data ) > 0 and who != self.vat.ADDRESS and who != self.dog.ADDRESS: who.clipperCall(sender, owe, lot_slice, data) self.vat.move(sender, self.vow.ADDRESS, owe) self.dog.digs(self.ilk_id, owe) if lot == Wad(0): self._remove(sale_id) elif tab == Rad(0): self.vat.flux(self.ilk_id, self.ADDRESS, usr, lot) self._remove(sale_id) else: self.sales[sale_id].tab = tab self.sales[sale_id].lot = lot return [owe, self.vat.urns]
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]
def redo(self, sale_id, kpr, now): usr = self.sales[sale_id].usr tic = self.sales[sale_id].tic top = self.sales[sale_id].top require(bool(usr), "Clipper/not-running-auction") (done, _) = self.status(tic, top, now) require(done, "Clipper/cannot-reset") tab = self.sales[sale_id].tab lot = self.sales[sale_id].lot self.sales[sale_id].tic = now pip = self.spotter.ilks[self.ilk_id].pip val = pip.peek(now) price = Ray(val / Wad(self.spotter.par)) self.sales[sale_id].top = price * self.buf if self.tip > Rad(0) or self.chip > Wad(0): dust = self.vat.ilks[self.ilk_id].dust if tab >= dust and Rad(lot * price) >= dust: self.vat.suck(self.vow.ADDRESS, kpr, self.tip + tab * Rad(self.chip))
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)
def burn(self, owner, value): require(self.balances[owner] >= value, f"{self.symbol}/insufficient-burn") self.balances[owner] -= value self.totalSupply -= value return True
def dent(self, bid_id, lot, bid, sender, now): require((self.live == 1), "Flopper/not-live") require((self.bids[bid_id].guy != 0), "Flopper/guy-not-set") require( (self.bids[bid_id].tic > now or self.bids[id].tic == 0), "Flopper/already-finished-tic", ) require(self.bids[bid_id].end > now, "Flopper/already-finished-end") require(bid == self.bids[bid_id].bid, "Flopper/not-matching-bid") require(self.lot < self.bids[bid_id].lot, "Flopper/lot-not-lower") require(self.beg * lot <= self.bids[bid_id].lot, "Flopper/insufficient-decrease") if sender != self.bids[bid_id].guy: self.vat.move(sender, self.bids[bid_id].guy, bid) if self.bids[bid_id].tic == 0: Ash = self.bids[bid_id].guy.Ash() self.bids[bid_id].guy.kiss(min(bid, Ash)) self.bids[bid_id].guy = sender self.bids[bid_id].lot = lot self.bids[bid_id].tic = int(now) + self.ttl
def tick(self, bid_id, now): require(self.bids[bid_id].end <= now, "Flapper/not-finished") require(self.bids[bid_id].tic == 0, "Flapper/bid-already-placed") self.bids[bid_id].lot = self.pad * self.bids[bid_id].lot self.bids[bid_id].end = now + self.tau
def dent(self, bid_id, usr, lot, bid, now): """Places a dent bid on a Flipper auction.""" curr_bid = self.bids[bid_id] require(curr_bid.tic > now or curr_bid.tic == 0, "Flipper/already-finished-tic") require(curr_bid.end > now, "Flipper/already-finished-end") require(bid == curr_bid.bid, "Flipper/not-matching-bid") require(bid == curr_bid.tab, "Flipper/tend-not-finished") require(lot < curr_bid.lot, "Flipper/lot-not-lower") require(lot * self.beg <= curr_bid.lot, "Flipper/insufficient-decrease") if usr != curr_bid.guy: self.vat.move(usr, curr_bid.guy, curr_bid.bid) curr_bid.guy = usr self.vat.flux(self.ilk_id, self.ADDRESS, curr_bid.usr, curr_bid.lot - lot) curr_bid.lot = lot curr_bid.tic = now + self.ttl
def wrapped_func(self, *args, **kwargs): require(self.stopped < level, "Clipper/stopped-incorrect") func(self, *args, **kwargs)
def tend(self, bid_id, usr, lot, bid, now): """Places a tend bid on a Flipper auction.""" curr_bid = self.bids[bid_id] require( curr_bid.tic > now or curr_bid.tic == 0, "Flipper/already-finished-tic", ) require(curr_bid.end > now, "Flipper/already-finished-end") require(lot == curr_bid.lot, "Flipper/lot-not-matching") require(bid <= curr_bid.tab, "Flipper/higher-than-tab") require(bid > curr_bid.bid, "Flipper/bid-not-higher") require( bid >= curr_bid.bid * self.beg or bid == curr_bid.tab, "Flipper/insufficient-increase", ) if usr != curr_bid.guy: self.vat.move(usr, curr_bid.guy, curr_bid.bid) curr_bid.guy = usr self.vat.move(usr, curr_bid.gal, bid - curr_bid.bid) curr_bid.bid = bid curr_bid.tic = now + self.ttl
def wrapped_func(self, *args, **kwargs): require(self.locked == 0, "Clipper/system-locked") self.locked = 1 func(self, *args, **kwargs) self.locked = 0