- Kind
- Pure package
- Name
- v1
- Namespace
- gnoswap / rbac
- Exported functions
- n/a — not supported for pure packages by the node (vm/qfuncs)
- Module
- gno.land/p/gnoswap/rbac/v1
- gno
- 0.9
ownable.gnogno
1package rbac23import (4 "chain"5 "errors"6)78
not supported for pure packages by the node (vm/qfuncs)
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
const
(
9 OwnershipTransferEvent = "OwnershipTransfer"
10 OwnershipTransferStartedEvent = "OwnershipTransferStarted"
11)
12
13// Ownable2Step implements a two-step ownership transfer mechanism.
14// It requires the new owner to explicitly accept ownership before the transfer is completed,
15// preventing accidental transfers to incorrect addresses.
16//
17// Note: This package does not verify callers. Consuming realms must extract the actual
18// caller from the live realm context and pass it to these methods.
19type Ownable2Step struct {
20 owner address
21 pendingOwner address
22}
23
24// newOwnable2StepWithAddress creates a new Ownable2Step instance with addr as owner.
25func newOwnable2StepWithAddress(addr address) *Ownable2Step {
26 return &Ownable2Step{
27 owner: addr,
28 pendingOwner: "",
29 }
30}
31
32// TransferOwnershipBy initiates ownership transfer by setting newOwner as pending owner.
33// The newOwner must call AcceptOwnershipBy to complete the transfer.
34//
35// Parameters:
36// - newOwner: Non-zero, syntactically valid address to record as the pending owner.
37// - caller: Address authorized to initiate the transfer; it must equal the current owner.
38//
39// Errors:
40// - ErrUnauthorized: caller is not the current owner
41// - ErrInvalidAddress: newOwner is empty or has an invalid format
42//
43// Returns:
44// - error: nil when the pending owner is set; otherwise ErrUnauthorized or ErrInvalidAddress.
45func (o *Ownable2Step) TransferOwnershipBy(newOwner, caller address) error {
46 if !o.IsOwner(caller) {
47 return errors.New(ErrUnauthorized)
48 }
49
50 if newOwner == zeroAddress || !newOwner.IsValid() {
51 return errors.New(ErrInvalidAddress)
52 }
53
54 o.pendingOwner = newOwner
55
56 chain.Emit(
57 OwnershipTransferStartedEvent,
58 "from", o.owner.String(),
59 "to", newOwner.String(),
60 )
61
62 return nil
63}
64
65// AcceptOwnershipBy completes the ownership transfer.
66// Must be called by the pending owner.
67//
68// Parameters:
69// - caller: Address attempting to accept ownership; it must equal the recorded pending owner.
70//
71// Errors:
72// - ErrNoPendingOwner: no ownership transfer is pending
73// - ErrPendingUnauthorized: caller is not the pending owner
74//
75// Returns:
76// - error: nil when ownership is transferred to caller; otherwise ErrNoPendingOwner or ErrPendingUnauthorized.
77func (o *Ownable2Step) AcceptOwnershipBy(caller address) error {
78 if o.pendingOwner == zeroAddress {
79 return errors.New(ErrNoPendingOwner)
80 }
81
82 if !o.IsPendingOwner(caller) {
83 return errors.New(ErrPendingUnauthorized)
84 }
85
86 prevOwner := o.owner
87 o.owner = o.pendingOwner
88 o.pendingOwner = ""
89
90 chain.Emit(
91 OwnershipTransferEvent,
92 "from", prevOwner.String(),
93 "to", o.owner.String(),
94 )
95
96 return nil
97}
98
99// DropOwnershipBy removes the owner, disabling all owner-only actions.
100// This is irreversible - when ownership is dropped, no future owner-only operations can be performed.
101//
102// Parameters:
103// - caller: Address requesting the drop; it must equal the current owner.
104//
105// Errors:
106// - ErrUnauthorized: caller is not the current owner
107//
108// Returns:
109// - error: nil when owner and pending owner are cleared; otherwise ErrUnauthorized.
110func (o *Ownable2Step) DropOwnershipBy(caller address) error {
111 if !o.IsOwner(caller) {
112 return errors.New(ErrUnauthorized)
113 }
114
115 prevOwner := o.owner
116 o.owner = ""
117 o.pendingOwner = ""
118
119 chain.Emit(
120 OwnershipTransferEvent,
121 "from", prevOwner.String(),
122 "to", "",
123 )
124
125 return nil
126}
127
128// Owner returns the current owner address. Returns empty address if ownership has been dropped.
129//
130// Returns:
131// - address: Current owner address, or the empty address after ownership is dropped.
132func (o *Ownable2Step) Owner() address {
133 return o.owner
134}
135
136// PendingOwner returns the pending owner address during ownership transfer. Returns empty address if no transfer is pending.
137//
138// Returns:
139// - address: Pending owner address, or the empty address when no transfer is pending.
140func (o *Ownable2Step) PendingOwner() address {
141 return o.pendingOwner
142}
143
144// IsOwner returns true if the provided caller address is the current owner.
145//
146// Parameters:
147// - caller: Address to compare with the stored current owner address.
148//
149// Returns:
150// - bool: true when caller exactly equals the current owner address; false otherwise.
151func (o *Ownable2Step) IsOwner(caller address) bool {
152 return o.owner == caller
153}
154
155// IsPendingOwner returns true if the provided caller address is the pending owner.
156//
157// Parameters:
158// - caller: Address to compare with the stored pending owner address.
159//
160// Returns:
161// - bool: true when caller exactly equals the pending owner address; false otherwise.
162func (o *Ownable2Step) IsPendingOwner(caller address) bool {
163 return o.pendingOwner == caller
164}
165