fishlab.gno
2.15 Kb · 104 lines
1// Package fishlab is a small onyx trial of the corrected kill rule.
2// A full copy of shoal/fish did not become live under the deploy deposit.
3// This realm does not replace gno.land/r/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/shoal/fish.
4// Strike has no size penalty and no prey bonus.
5// PayCovered draws 1 whole FISH per 1 whole GNOT of the covered stake.
6// The covered stake is the smaller of the two pools. A zero stake pays nothing.
7// The draw comes from an approved reserve. It does not mint FISH.
8package fishlab
9
10import (
11 "chain"
12 "chain/runtime/unsafe"
13 "strconv"
14
15 shoaltoken "gno.land/r/g10ragdr3cjqkael8rslpw4y6rlelhev4h0fswcx/fishcoin"
16)
17
18const unit int64 = 1_000_000
19
20var (
21 inited bool
22 self address
23 reserve address
24 creator address
25)
26
27func Init(cur realm, who address) {
28 if !cur.IsCurrent() {
29 panic("fishlab: realm")
30 }
31 if !cur.Previous().IsUserCall() {
32 panic("fishlab: eoa")
33 }
34 takeExact(0)
35 if inited {
36 panic("fishlab: init")
37 }
38 if !who.IsValid() {
39 panic("fishlab: reserve")
40 }
41 inited = true
42 self = cur.Address()
43 reserve = who
44 creator = cur.Previous().Address()
45 chain.Emit("Init", "self", self.String(), "reserve", who.String())
46}
47
48func Realm() string {
49 return self.String()
50}
51
52func Reserve() string {
53 return reserve.String()
54}
55
56func Strike(bite, hpMax int) int {
57 if hpMax < 0 {
58 hpMax = 0
59 }
60 dmg := bite * 100 / (hpMax + 100)
61 if dmg < 1 {
62 return 1
63 }
64 return dmg
65}
66
67func PayCovered(cur realm, coveredUgnot int64) int64 {
68 if !cur.IsCurrent() {
69 panic("fishlab: realm")
70 }
71 caller := cur.Previous()
72 if !caller.IsUserCall() {
73 panic("fishlab: eoa")
74 }
75 takeExact(0)
76 if !inited {
77 panic("fishlab: init")
78 }
79 if coveredUgnot <= 0 {
80 return 0
81 }
82 whole := coveredUgnot / unit
83 if whole <= 0 {
84 return 0
85 }
86 if shoaltoken.Spender() != self {
87 panic("fishlab: spender")
88 }
89 units := whole * unit
90 got := shoaltoken.Draw(cross(cur), reserve, caller.Address(), units)
91 chain.Emit("PayCovered", "whole", strconv.FormatInt(whole, 10), "got", strconv.FormatInt(got, 10))
92 return got
93}
94
95func takeExact(n int64) {
96 sent := unsafe.OriginSend()
97 if n == 0 {
98 if len(sent) != 0 {
99 panic("fishlab: payment")
100 }
101 return
102 }
103 panic("fishlab: payment")
104}