Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

book.gno

3.84 Kb · 165 lines
  1package bazaargens3
  2
  3import (
  4	"chain"
  5	"chain/banker"
  6	"strconv"
  7
  8	"gno.land/p/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/bazaar/fee/v1"
  9	factory "gno.land/r/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/bazaar/bazaarv4"
 10)
 11
 12func List(cur realm, id int, priceUgnot int64) {
 13	caller := requireUser(cur)
 14	if priceUgnot <= 0 {
 15		panic("col: price")
 16	}
 17	it := mustItem(id)
 18	if it.listed {
 19		panic("col: listed")
 20	}
 21	if it.owner != caller {
 22		panic("col: not owner")
 23	}
 24	grcTransfer(caller, caller, self, id)
 25	it.listed = true
 26	it.seller = caller
 27	it.price = priceUgnot
 28	it.owner = self
 29	items.Set(itemKey(id), it)
 30	chain.Emit("List", "id", strconv.Itoa(id), "seller", caller.String(), "price", strconv.FormatInt(priceUgnot, 10))
 31}
 32
 33func UpdatePrice(cur realm, id int, priceUgnot int64) {
 34	caller := requireUser(cur)
 35	if priceUgnot <= 0 {
 36		panic("col: price")
 37	}
 38	it := mustItem(id)
 39	if !it.listed {
 40		panic("col: not listed")
 41	}
 42	if it.seller != caller {
 43		panic("col: not seller")
 44	}
 45	it.price = priceUgnot
 46	items.Set(itemKey(id), it)
 47	chain.Emit("List", "id", strconv.Itoa(id), "seller", caller.String(), "price", strconv.FormatInt(priceUgnot, 10))
 48}
 49
 50func Cancel(cur realm, id int) {
 51	caller := requireUser(cur)
 52	it := mustItem(id)
 53	if !it.listed {
 54		panic("col: not listed")
 55	}
 56	if caller != it.seller {
 57		panic("col: not seller")
 58	}
 59	grcTransfer(self, self, it.seller, id)
 60	it.listed = false
 61	it.owner = it.seller
 62	it.seller = address("")
 63	it.price = 0
 64	items.Set(itemKey(id), it)
 65	chain.Emit("Cancel", "id", strconv.Itoa(id))
 66}
 67
 68func Buy(cur realm, id int) {
 69	caller := requireUser(cur)
 70	it := mustItem(id)
 71	if !it.listed {
 72		panic("col: not listed")
 73	}
 74	if caller == it.seller {
 75		panic("col: self buy")
 76	}
 77	takeExact(it.price)
 78	price := it.price
 79	proto := fee.ProtocolFee(price, tradeProtocolBps(it.seller, caller))
 80	royal := int64(0)
 81	if royaltyBps > 0 {
 82		royal = fee.ProtocolFee(price, int64(royaltyBps))
 83	}
 84	if proto+royal > price {
 85		panic("col: fee")
 86	}
 87	sellerAmt := price - proto - royal
 88	share := int64(0)
 89	if proto > 0 {
 90		share = fee.ProtocolFee(proto, factory.GenesisShareBps())
 91	}
 92	sinkAmt := proto - share
 93	sink := factory.ProtocolSink()
 94	if proto > 0 && !sink.IsValid() {
 95		panic("col: sink")
 96	}
 97	bk := banker.NewBanker(banker.BankerTypeRealmSend, cur)
 98	if sellerAmt > 0 {
 99		bk.SendCoins(self, it.seller, chain.Coins{{Denom: nativeDenom, Amount: sellerAmt}})
100	}
101	if royal > 0 {
102		bk.SendCoins(self, creator, chain.Coins{{Denom: nativeDenom, Amount: royal}})
103	}
104	if sinkAmt > 0 {
105		bk.SendCoins(self, sink, chain.Coins{{Denom: nativeDenom, Amount: sinkAmt}})
106	}
107	if share > 0 {
108		gaddr := factory.GenesisSink()
109		if !gaddr.IsValid() {
110			panic("col: genesis")
111		}
112		bk.SendCoins(self, gaddr, chain.Coins{{Denom: nativeDenom, Amount: share}})
113	}
114	grcTransfer(self, self, caller, id)
115	it.listed = false
116	it.owner = caller
117	it.seller = address("")
118	it.price = 0
119	items.Set(itemKey(id), it)
120	chain.Emit("Buy", "id", strconv.Itoa(id), "buyer", caller.String(), "fee", strconv.FormatInt(proto, 10))
121}
122
123func Transfer(cur realm, to address, id int) {
124	caller := requireUser(cur)
125	if !to.IsValid() {
126		panic("col: invalid address")
127	}
128	if to == caller || to == self {
129		panic("col: invalid address")
130	}
131	it := mustItem(id)
132	if it.listed {
133		panic("col: listed")
134	}
135	if it.owner != caller {
136		panic("col: not owner")
137	}
138	grcTransfer(caller, caller, to, id)
139	it.owner = to
140	items.Set(itemKey(id), it)
141	chain.Emit("Transfer", "id", strconv.Itoa(id), "to", to.String())
142}
143
144func ProtocolBps() int64 {
145	return factory.ProtocolBps()
146}
147
148func tradeProtocolBps(seller, buyer address) int64 {
149	bps := ProtocolBps()
150	d := factory.HolderDiscount(seller.String())
151	if bd := factory.HolderDiscount(buyer.String()); bd > d {
152		d = bd
153	}
154	if d > bps {
155		return 0
156	}
157	return bps - d
158}
159
160func grcTransfer(spender, from, to address, id int) {
161	err := ledger.TransferFrom(spender, from, to, itemTid(id))
162	if err != nil {
163		panic("col: transfer")
164	}
165}