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

escrow_actions.gno

3.79 Kb · 113 lines
  1package memba_weighted_host
  2
  3import (
  4	"chain"
  5	"gno.land/p/samcrew/memba_weighted_policy"
  6	"strconv"
  7)
  8
  9const EscrowPath = "gno.land/r/samcrew/escrow_v4"
 10
 11type EscrowActionKind string
 12
 13const (
 14	EscrowAcceptOwner   EscrowActionKind = "accept-owner"
 15	EscrowReturnOwner   EscrowActionKind = "return-owner"
 16	EscrowAbortReturn   EscrowActionKind = "abort-return"
 17	EscrowUnpause       EscrowActionKind = "unpause"
 18	EscrowRefundClient  EscrowActionKind = "refund-client"
 19	EscrowPayFreelancer EscrowActionKind = "pay-freelancer"
 20	// EscrowSetFeeRecipient stages a new fallback fee recipient (escrow_v4
 21	// two-step rotation); the staged address accepts with its own transaction.
 22	EscrowSetFeeRecipient EscrowActionKind = "set-fee-recipient"
 23)
 24
 25type EscrowPolicy struct{ dao, successor address }
 26
 27func NewEscrowPolicy(dao, successor address) EscrowPolicy {
 28	if !dao.IsValid() || dao != chain.PackageAddress("gno.land/r/samcrew/memba_dao") {
 29		panic("escrow policy requires the founding DAO address")
 30	}
 31	if !successor.IsValid() || successor == dao || successor == chain.PackageAddress(EscrowPath) {
 32		panic("escrow policy requires a valid distinct successor")
 33	}
 34	return EscrowPolicy{dao: dao, successor: successor}
 35}
 36func (p EscrowPolicy) DAO() address       { return p.dao }
 37func (p EscrowPolicy) Successor() address { return p.successor }
 38
 39type EscrowAction struct {
 40	kind       EscrowActionKind
 41	recipient  address
 42	contractID string
 43	milestone  int
 44}
 45
 46func (p EscrowPolicy) Accept() EscrowAction { return EscrowAction{kind: EscrowAcceptOwner} }
 47func (p EscrowPolicy) Return() EscrowAction {
 48	return EscrowAction{kind: EscrowReturnOwner, recipient: p.successor}
 49}
 50func (p EscrowPolicy) AbortReturn() EscrowAction {
 51	return EscrowAction{kind: EscrowAbortReturn, recipient: p.successor}
 52}
 53func EscrowResume() EscrowAction { return EscrowAction{kind: EscrowUnpause} }
 54func EscrowFeeRecipient(recipient address) EscrowAction {
 55	a := EscrowAction{kind: EscrowSetFeeRecipient, recipient: recipient}
 56	a.Bytes()
 57	return a
 58}
 59func EscrowResolution(id string, index int, refund bool) EscrowAction {
 60	kind := EscrowPayFreelancer
 61	if refund {
 62		kind = EscrowRefundClient
 63	}
 64	a := EscrowAction{kind: kind, contractID: id, milestone: index}
 65	a.Bytes()
 66	return a
 67}
 68func (a EscrowAction) Kind() EscrowActionKind { return a.kind }
 69func (a EscrowAction) Recipient() address     { return a.recipient }
 70func (a EscrowAction) ContractID() string     { return a.contractID }
 71func (a EscrowAction) Milestone() int         { return a.milestone }
 72func (a EscrowAction) IsResolution() bool {
 73	return a.kind == EscrowRefundClient || a.kind == EscrowPayFreelancer
 74}
 75func (a EscrowAction) Bytes() string {
 76	base := "escrow/v1|" + EscrowPath + "|" + string(a.kind)
 77	if a.IsResolution() {
 78		n, err := strconv.ParseUint(a.contractID, 10, 64)
 79		if err != nil || strconv.FormatUint(n, 10) != a.contractID || a.milestone < 0 || a.milestone >= 20 || a.recipient != "" {
 80			panic("invalid escrow resolution action")
 81		}
 82		return base + "|" + a.contractID + "|" + strconv.Itoa(a.milestone)
 83	}
 84	if a.contractID != "" || a.milestone != 0 {
 85		panic("malformed escrow action")
 86	}
 87	switch a.kind {
 88	case EscrowAcceptOwner, EscrowUnpause:
 89		if a.recipient != "" {
 90			panic("malformed escrow action")
 91		}
 92		return base
 93	case EscrowReturnOwner, EscrowAbortReturn:
 94		if !a.recipient.IsValid() {
 95			panic("invalid escrow return action")
 96		}
 97		return base + "|" + string(a.recipient)
 98	case EscrowSetFeeRecipient:
 99		if !a.recipient.IsValid() {
100			panic("invalid escrow fee recipient action")
101		}
102		return base + "|" + string(a.recipient)
103	default:
104		panic("unsupported escrow action")
105	}
106}
107func (a EscrowAction) Category() memba_weighted_policy.Category {
108	a.Bytes()
109	if a.IsResolution() || a.kind == EscrowUnpause || a.kind == EscrowSetFeeRecipient {
110		return memba_weighted_policy.Financial
111	}
112	return memba_weighted_policy.Critical
113}