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.

v0 source pure

Package bounty is the state machine behind Guildhall bounties.

Overview

Package bounty is the state machine behind Guildhall bounties.

It holds no funds and moves no coins. Every transition validates who is acting and what state the bounty is in, mutates the bounty, and returns the transfers the escrow realm must execute as a list of Payouts. Keeping the rules here, free of chain effects, lets them be tested exhaustively and reused by any realm that wants to escrow work.

Lifecycle:

Example
1Open ──Assign──▶ Active ──(every milestone settled)──▶ Completed
2  ▲                │
3  └──Unassign/Resign┘
4Open ──Cancel──▶ Cancelled (unpaid milestones refunded)

Milestones move independently once a bounty is Active:

Example
1Pending ──Submit──▶ Submitted ──Approve×quorum──▶ Paid
2   ▲                  │   │
3   └──RequestChanges──┘   └──OpenDispute──▶ Disputed ──Resolve──▶ Paid | Split | Refunded

A milestone with requested changes can be resubmitted or disputed.

Constants 4

Variables 1

Functions 3

func New

1func New(p Params) (*Bounty, error)
source

New validates p and returns a funded, open bounty.

When no reviewers are given, the poster reviews alone. When no arbiter is given, the caller is expected to fill in a default (the escrow realm's council) before calling New.

func ParseMilestones

1func ParseMilestones(s string, total int64) ([]MilestoneSpec, error)
source

ParseMilestones parses "Title=amount;Title=amount". An empty string yields a single "Complete the bounty" milestone worth total (which must be positive).

func ParseStatus

1func ParseStatus(s string) (Status, bool)
source

ParseStatus is the inverse of Status.String.

Types 10

type Application

struct
1type Application struct {
2	Applicant address
3	Pitch     string
4	At        time.Time
5}
source

Application is a contributor's request to be assigned.

type Bounty

struct
 1type Bounty struct {
 2	ID          uint64
 3	Poster      address
 4	Title       string
 5	Description string
 6	Link        string
 7	Tags        []string
 8	// Denom identifies what the escrow holds: a native coin denom, or a
 9	// grc20reg key when IsGRC20 is set.
10	Denom   string
11	IsGRC20 bool
12
13	Reviewers []address
14	Quorum    int
15	Arbiter   address
16
17	Assignee     address
18	Applications []Application
19	Milestones   []*Milestone
20	Status       Status
21	WorkWindow   time.Duration
22
23	CreatedAt  time.Time
24	AssignedAt time.Time
25	ClosedAt   time.Time
26}
source

Bounty is a funded task split into milestones.

Methods on Bounty

func Apply

method on Bounty
1func (b *Bounty) Apply(who address, pitch string, now time.Time) error
source

Apply files an application from a prospective contributor.

func Approve

method on Bounty
1func (b *Bounty) Approve(caller address, idx int, now time.Time) ([]Payout, error)
source

Approve records a reviewer's approval. When the quorum is reached the milestone is paid and the returned payout sends its full amount to the worker.

func Assign

method on Bounty
1func (b *Bounty) Assign(caller, who address, now time.Time) error
source

Assign hands the bounty to a contributor. Only the poster may assign, and the assignee cannot be the poster or a reviewer.

func Cancel

method on Bounty
1func (b *Bounty) Cancel(caller address, now time.Time) ([]Payout, error)
source

Cancel withdraws an open bounty and refunds every unsettled milestone. An active bounty must be unassigned first, so a poster cannot pull funds from under someone who is working.

func Escrowed

method on Bounty
1func (b *Bounty) Escrowed() int64
source

Escrowed is the amount still held for this bounty.

func HasApplied

method on Bounty
1func (b *Bounty) HasApplied(addr address) bool
source

HasApplied reports whether addr has an application on file.

func Involves

method on Bounty
1func (b *Bounty) Involves(addr address) bool
source

Involves reports whether addr plays any role in the bounty.

func IsReviewer

method on Bounty
1func (b *Bounty) IsReviewer(addr address) bool
source

IsReviewer reports whether addr is one of the bounty's reviewers.

func Milestone

method on Bounty
1func (b *Bounty) Milestone(idx int) (*Milestone, error)
source

Milestone returns the milestone at idx.

func OpenDispute

method on Bounty
1func (b *Bounty) OpenDispute(caller address, idx int, reason string, now time.Time) error
source

OpenDispute escalates a submitted or rejected milestone to the arbiter. Either the poster or the worker who submitted it may open a dispute.

func PaidOut

method on Bounty
1func (b *Bounty) PaidOut() int64
source

PaidOut is the amount released to workers.

func RequestChanges

method on Bounty
1func (b *Bounty) RequestChanges(caller address, idx int, feedback string) error
source

RequestChanges sends a submitted milestone back to the worker, discarding approvals collected so far.

func Resolve

method on Bounty
1func (b *Bounty) Resolve(caller address, idx int, workerBps int64, ruling string, now time.Time) ([]Payout, error)
source

Resolve settles a disputed milestone. The arbiter awards workerBps of the milestone to the worker and refunds the rest to the poster.

func Submit

method on Bounty
1func (b *Bounty) Submit(caller address, idx int, link string, now time.Time) error
source

Submit hands a milestone in for review.

func Total

method on Bounty
1func (b *Bounty) Total() int64
source

Total is the sum of all milestone amounts.

func Unassign

method on Bounty
1func (b *Bounty) Unassign(caller address, now time.Time) error
source

Unassign returns an active bounty to the open pool.

The assignee may step back at any time. The poster may reclaim the bounty once the work window has elapsed since assignment. Either way, no milestone may be awaiting review or arbitration: those are settled first.

type Dispute

struct
 1type Dispute struct {
 2	OpenedBy   address
 3	Reason     string
 4	OpenedAt   time.Time
 5	Resolved   bool
 6	ResolvedAt time.Time
 7	// WorkerBps is the share of the milestone the arbiter awarded the worker.
 8	WorkerBps int64
 9	Ruling    string
10}
source

Dispute records a contested milestone and how it was settled.

type Milestone

struct
 1type Milestone struct {
 2	Title       string
 3	Amount      int64
 4	Status      MilestoneStatus
 5	Submission  string
 6	SubmittedAt time.Time
 7	Approvals   []address
 8	Feedback    string
 9	Dispute     *Dispute
10	// Worker is the assignee at the time the milestone was submitted. It
11	// stays fixed through review and dispute so a later reassignment cannot
12	// redirect payment for work someone else delivered.
13	Worker   address
14	PaidOut  int64
15	Refunded int64
16	SettleAt time.Time
17}
source

Milestone is one independently payable slice of a bounty.

type MilestoneSpec

struct
1type MilestoneSpec struct {
2	Title  string
3	Amount int64
4}
source

MilestoneSpec describes a milestone when posting a bounty.

type MilestoneStatus

ident
1type MilestoneStatus int
source

MilestoneStatus is the state of a single milestone.

Methods on MilestoneStatus

func Settled

method on MilestoneStatus
1func (s MilestoneStatus) Settled() bool
source

Settled reports whether the milestone's escrow has been fully released.

func String

method on MilestoneStatus
1func (s MilestoneStatus) String() string
source

type Params

struct
 1type Params struct {
 2	ID          uint64
 3	Poster      address
 4	Title       string
 5	Description string
 6	Link        string
 7	Tags        []string
 8	Denom       string
 9	IsGRC20     bool
10	Reviewers   []address
11	Quorum      int
12	Arbiter     address
13	Milestones  []MilestoneSpec
14	WorkWindow  time.Duration
15	Now         time.Time
16}
source

Params are the inputs to New.

type Payout

struct
1type Payout struct {
2	Kind      PayoutKind
3	To        address
4	Amount    int64
5	Milestone int
6}
source

Payout is a transfer the escrow realm must execute.

type PayoutKind

ident
1type PayoutKind string
source

PayoutKind says why escrowed funds move.

type Status

ident
1type Status int
source

Status is the lifecycle state of a bounty.

Methods on Status

func String

method on Status
1func (s Status) String() string
source

Dependencies

Imports 4

/p/g1lnkytfqcjwllws63gvf0mv9yt04aswy4y9amhm/guildhall/bounty/v0

Imported by indexer

Source Files 2