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

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

answer.gno

3.01 Kb · 99 lines
 1package kourt
 2const answerWindow = 3 * epochBlocks
 3func PostAnswer(cur realm, courtSlug string, claimID uint64, verdict int) {
 4	if !cur.IsCurrent() {
 5		panic(errStaleRealm)
 6	}
 7	who := cur.Previous().Address()
 8	c := mustCourt(courtSlug)
 9	cs := mustClaim(c, claimID)
10	mustSide(verdict)
11	if cs.closed {
12		panic("kourtv2: this claim is closed")
13	}
14	if cs.frozenAt != 0 {
15		panic("kourtv2: this claim already has an answer")
16	}
17	now := heightNow()
18	if passed, known := pastDeadline(cs.openedAtTime, deadClaimSecs); (known && passed) ||
19		(!known && now >= cs.openedAt+deadClaimTimeout) {
20		panic("kourtv2: this claim is past the dead-claim timeout; it closes, it is not answered")
21	}
22	xbar, mature := cs.oi.Average(now, answerWindow)
23	if !mature {
24		panic("kourtv2: not enough stake history to answer yet")
25	}
26	if xbar < effMinAnswerX(c) {
27		panic("kourtv2: trailing stake is below the minimum to answer")
28	}
29	inPriority := false
30	if passed, known := pastDeadline(cs.openedAtTime,
31		blocksToSecs(c.params.stakeOpenDelayBlocks+answerWindow)+priorityWindowSecs); priorityGateActive(c) &&
32		((known && !passed) ||
33			(!known && now < cs.openedAt+c.params.stakeOpenDelayBlocks+answerWindow+priorityWindowBlocks)) {
34		if !mayAnswerInPriority(c, who) {
35			panic("kourtv2: the priority window is open — a qualified answerer may act first (wait ~24h)")
36		}
37		inPriority = true
38	}
39	touch(c)
40	advancePools(c, cs)
41	if life := lifeAvgStake(cs, now); life > xbar {
42		xbar = life
43	}
44	bond := xbar * answerBondBps / 10000
45	if c.params.answerBondCapCC > 0 && bond > c.params.answerBondCapCC {
46		bond = c.params.answerBondCapCC
47	}
48	convHi, convLo := cs.sideConv(verdict)
49	floor := bondFloorAt(xbar, convHi, convLo)
50	oppHi, oppLo := cs.sideConv(oppositeSide(verdict))
51	if opp := bondFloorAt(xbar, oppHi, oppLo); opp > floor {
52		floor = opp
53	}
54	if floor > bond {
55		bond = floor
56	}
57	if bond < 1 {
58		bond = 1
59	}
60	mustSpendable(c, who, bond)
61	c.coin.Transfer(who, c.escrow, bond)
62	cs.frozenAt = now
63	cs.rateAccAtFreeze = c.rateAccFP
64	cs.xBarFrozen = xbar
65	cs.tierRef = tierRefAt(c)
66	observeClaimSize(c, xbar)
67	cs.yesStakeAtFreeze, cs.noStakeAtFreeze = cs.yesStake, cs.noStake
68	cs.answer = int8(verdict)
69	cs.answerer = who
70	cs.answerBond = bond
71	cs.answerBond0 = bond
72	cs.answerHeight = now
73	cs.answeredAtTime = nowTime()
74	if inPriority {
75		holdPriority(c, who, claimID)
76	}
77	pendingExit(c, cs)
78	stripEnter(c, cs)
79	onClaimAnswered(c, cs)
80}
81func HasAnswer(courtSlug string, claimID uint64) bool {
82	return mustClaim(mustCourt(courtSlug), claimID).frozenAt != 0
83}
84func AnswerVerdict(courtSlug string, claimID uint64) int {
85	cs := mustClaim(mustCourt(courtSlug), claimID)
86	if cs.frozenAt == 0 {
87		panic("kourtv2: no answer yet")
88	}
89	return int(cs.answer)
90}
91func AnswerBond(courtSlug string, claimID uint64) int64 {
92	return mustClaim(mustCourt(courtSlug), claimID).answerBond
93}
94func Answerer(courtSlug string, claimID uint64) address {
95	return mustClaim(mustCourt(courtSlug), claimID).answerer
96}
97func XBarFrozen(courtSlug string, claimID uint64) int64 {
98	return mustClaim(mustCourt(courtSlug), claimID).xBarFrozen
99}