Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 76b75e9

Browse files
committedOct 17, 2024·
chore: fixup
Signed-off-by: moul <[email protected]>
1 parent 1d59dfe commit 76b75e9

File tree

12 files changed

+94
-109
lines changed

12 files changed

+94
-109
lines changed
 

‎examples/gno.land/p/demo/grc/grc20/examples_test.gno

-28
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,3 @@ func ExampleApprove() {}
1414
func ExampleTransferFrom() {}
1515
func ExampleMint() {}
1616
func ExampleBurn() {}
17-
18-
/*
19-
Users
20-
- token creator (root)
21-
- token holder / enduser / basic realm (GRC20)
22-
- dao/intermediary-realm (vault) contracts
23-
- user banker. (prevrealm)
24-
- realm banker.
25-
- compatible with govdao. (and async closures).
26-
- working from top-level variable.
27-
- working from from proxified.
28-
- compatible with custom implementation/rules.
29-
- compatible with custom getCaller as a callback?
30-
- support addresseable OR sub treasuries.
31-
- single bnaker for multiple grc20 tokens; like std.Coin{}
32-
- consider returning `std.Coin`
33-
- grc20factory.gno // var banks avl.Tree // key -> Bank
34-
bank.LocalBankerWithSuffix(key).Transfer()
35-
- boundingtoken.gno // tokenA, boundA
36-
- think about the r/grc20factory special contract
37-
- create new user token
38-
- what about being seen by another contract as the prevRealm (dex)
39-
- wugnot
40-
- GOOD NAMES!
41-
- GOOD NAMES!
42-
- GOOD NAMES!
43-
- GOOD NAMES!
44-
*/

‎examples/gno.land/p/demo/grc/grc20/tellers.gno

+31-17
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import (
44
"std"
55
)
66

7-
func PrevRealmTeller(b *Token) GRC20 {
8-
if b == nil {
7+
// CallerTeller returns a GRC20 compatible teller that checks the PrevRealm caller for each calls.
8+
// It's usually safe to expose it publicly to let people manipulate their tokens directly or services to use their allowance.
9+
func (tok *Token) CallerTeller() GRC20 {
10+
if tok == nil {
911
panic("Token cannot be nil")
1012
}
1113

@@ -14,37 +16,43 @@ func PrevRealmTeller(b *Token) GRC20 {
1416
caller := std.PrevRealm().Addr()
1517
return caller
1618
},
17-
Token: b,
19+
Token: tok,
1820
}
1921
}
2022

21-
func RealmTeller(b *Token) GRC20 {
22-
if b == nil {
23+
// ReadonlyTeller is a GRC20 compatible teller that panics for each write operations.
24+
func (tok *Token) ReadonlyTeller() GRC20 {
25+
if tok == nil {
2326
panic("Token cannot be nil")
2427
}
2528

2629
return &fnTeller{
27-
accountFn: func() std.Address {
28-
caller := std.CurrentRealm().Addr()
29-
return caller
30-
},
31-
Token: b,
30+
accountFn: nil,
31+
Token: tok,
3232
}
3333
}
3434

35-
func ReadonlyTeller(b *Token) GRC20 {
36-
if b == nil {
35+
// RealmTeller returns a GRC20 compatible teller that will store the CurrentRealm caller and then reuse the stored caller for each call.
36+
// It allows a realm contract to interact with a GRC20 with its own account.
37+
// The initializer of this teller should usually never share a pointer to its RealmTeller except maybe for advanced delegation flows such as a DAO treasury management.
38+
func (tok *Token) RealmTeller() GRC20 {
39+
if tok == nil {
3740
panic("Token cannot be nil")
3841
}
3942

43+
caller := std.CurrentRealm().Addr()
44+
4045
return &fnTeller{
41-
accountFn: nil,
42-
Token: b,
46+
accountFn: func() std.Address {
47+
return caller
48+
},
49+
Token: tok,
4350
}
4451
}
4552

46-
func SubAccountTeller(b *Token, slug string) GRC20 {
47-
if b == nil {
53+
// RealmSubTeller is like RealmTeller but uses the provided slug to derivate a subaccount.
54+
func (tok *Token) RealmSubTeller(slug string) GRC20 {
55+
if tok == nil {
4856
panic("Token cannot be nil")
4957
}
5058

@@ -55,10 +63,13 @@ func SubAccountTeller(b *Token, slug string) GRC20 {
5563
accountFn: func() std.Address {
5664
return account
5765
},
58-
Token: b,
66+
Token: tok,
5967
}
6068
}
6169

70+
// generic tellers methods.
71+
//
72+
6273
func (ft *fnTeller) Transfer(to std.Address, amount uint64) error {
6374
if ft.accountFn == nil {
6475
return ErrReadonly
@@ -83,6 +94,9 @@ func (ft *fnTeller) TransferFrom(owner, to std.Address, amount uint64) error {
8394
return ft.Token.ledger.TransferFrom(owner, spender, to, amount)
8495
}
8596

97+
// helpers
98+
//
99+
86100
// accountSlugAddr returns the address derived from the specified address and slug.
87101
func accountSlugAddr(addr std.Address, slug string) std.Address {
88102
// XXX: use a new `std.XXX` call for this.

‎examples/gno.land/p/demo/grc/grc20/tellers_test.gno

+6-6
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import (
1010
"gno.land/p/demo/urequire"
1111
)
1212

13-
func TestPrevRealmTellerImpl(t *testing.T) {
14-
token, _ := NewToken("Dummy", "DUMMY", 4)
15-
teller := PrevRealmTeller(token)
16-
urequire.False(t, token == nil)
13+
func TestCallerTellerImpl(t *testing.T) {
14+
tok, _ := NewToken("Dummy", "DUMMY", 4)
15+
teller := tok.CallerTeller()
16+
urequire.False(t, tok == nil)
1717
var _ GRC20 = teller
1818
}
1919

@@ -81,13 +81,13 @@ func TestTeller(t *testing.T) {
8181
checkAllowances(200, 0, 0, 0, 0, 0)
8282
}
8383

84-
func TestPrevRealmTeller(t *testing.T) {
84+
func TestCallerTeller(t *testing.T) {
8585
alice := testutils.TestAddress("alice")
8686
bob := testutils.TestAddress("bob")
8787
carl := testutils.TestAddress("carl")
8888

8989
token, ledger := NewToken("Dummy", "DUMMY", 6)
90-
teller := PrevRealmTeller(token)
90+
teller := token.CallerTeller()
9191

9292
checkBalances := func(aliceEB, bobEB, carlEB uint64) {
9393
t.Helper()

‎examples/gno.land/p/demo/grc/grc20/types.gno

+32-32
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,6 @@ import (
88
"gno.land/p/demo/grc/exts"
99
)
1010

11-
var (
12-
ErrInsufficientBalance = errors.New("insufficient balance")
13-
ErrInsufficientAllowance = errors.New("insufficient allowance")
14-
ErrInvalidAddress = errors.New("invalid address")
15-
ErrCannotTransferToSelf = errors.New("cannot send transfer to self")
16-
ErrReadonly = errors.New("banker is readonly")
17-
ErrRestrictedTokenOwner = errors.New("restricted to bank owner")
18-
)
19-
20-
const (
21-
MintEvent = "Mint"
22-
BurnEvent = "Burn"
23-
TransferEvent = "Transfer"
24-
ApprovalEvent = "Approval"
25-
)
26-
27-
// Token represents a token's bank, including its name, symbol,
28-
// decimals, and administrative functions.
29-
type Token struct {
30-
name string
31-
symbol string
32-
decimals uint
33-
ledger *AdminLedger
34-
}
35-
36-
// AdminLedger is a struct that holds administrative functions for the token.
37-
type AdminLedger struct {
38-
totalSupply uint64
39-
balances avl.Tree // std.Address -> uint64
40-
allowances avl.Tree // owner.(std.Address)+":"+spender.(std.Address)) -> uint64
41-
}
42-
4311
// GRC20 interface defines the methods that a GRC20 token must implement.
4412
type GRC20 interface {
4513
exts.TokenMetadata
@@ -82,6 +50,38 @@ type GRC20 interface {
8250
TransferFrom(from, to std.Address, amount uint64) error
8351
}
8452

53+
var (
54+
ErrInsufficientBalance = errors.New("insufficient balance")
55+
ErrInsufficientAllowance = errors.New("insufficient allowance")
56+
ErrInvalidAddress = errors.New("invalid address")
57+
ErrCannotTransferToSelf = errors.New("cannot send transfer to self")
58+
ErrReadonly = errors.New("banker is readonly")
59+
ErrRestrictedTokenOwner = errors.New("restricted to bank owner")
60+
)
61+
62+
const (
63+
MintEvent = "Mint"
64+
BurnEvent = "Burn"
65+
TransferEvent = "Transfer"
66+
ApprovalEvent = "Approval"
67+
)
68+
69+
type Token struct {
70+
name string
71+
symbol string
72+
decimals uint
73+
ledger *AdminLedger
74+
}
75+
76+
// AdminLedger is a struct that holds the balances and allowances and exposes
77+
// administrative functions.
78+
// It is unsafe to expose it publicly.
79+
type AdminLedger struct {
80+
totalSupply uint64
81+
balances avl.Tree // std.Address -> uint64
82+
allowances avl.Tree // owner.(std.Address)+":"+spender.(std.Address)) -> uint64
83+
}
84+
8585
type fnTeller struct {
8686
accountFn func() std.Address
8787
*Token

‎examples/gno.land/r/demo/atomicswap/atomicswap.gno

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ func NewCustomCoinSwap(recipient std.Address, hashlock string, timelock time.Tim
6161
func NewCustomGRC20Swap(recipient std.Address, hashlock string, timelock time.Time, token *grc20.Token) (int, *Swap) {
6262
sender := std.PrevRealm().Addr()
6363
curAddr := std.CurrentRealm().Addr()
64-
// userTeller := grc20.PrevRealmTeller(token)
65-
userTeller := grc20.SubAccountTeller(token, "") // FIXME(bug): should be the other one?
64+
// userTeller := token.CallerTeller()
65+
userTeller := token.RealmTeller() // FIXME(bug): should be the other one?
6666

6767
allowance := userTeller.Allowance(sender, curAddr)
6868
require(allowance > 0, "no allowance")

‎examples/gno.land/r/demo/bar20/bar20.gno

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414

1515
var (
1616
Token, adm = grc20.NewToken("Bar", "BAR", 4)
17-
UserTeller = grc20.PrevRealmTeller(Token)
17+
UserTeller = Token.CallerTeller()
1818
)
1919

2020
func init() {

‎examples/gno.land/r/demo/foo20/foo20.gno

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616

1717
var (
1818
Token, adminLedger = grc20.NewToken("Foo", "FOO", 4)
19-
UserTeller = grc20.PrevRealmTeller(Token)
19+
UserTeller = Token.CallerTeller()
2020
owner = ownable.NewWithAddress("g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq") // @manfred
2121
)
2222

‎examples/gno.land/r/demo/grc20factory/grc20factory.gno

+9-9
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ func NewWithAdmin(name, symbol string, decimals uint, initialMint, faucet uint64
4646
grc20reg.Register(token, symbol)
4747
}
4848

49-
func (inst instance) PrevRealmTeller() grc20.GRC20 {
50-
return grc20.PrevRealmTeller(inst.token)
49+
func (inst instance) CallerTeller() grc20.GRC20 {
50+
return inst.token.CallerTeller()
5151
}
5252

5353
func Bank(symbol string) *grc20.Token {
@@ -57,32 +57,32 @@ func Bank(symbol string) *grc20.Token {
5757

5858
func TotalSupply(symbol string) uint64 {
5959
inst := mustGetInstance(symbol)
60-
return grc20.PrevRealmTeller(inst.token).TotalSupply()
60+
return inst.token.CallerTeller().TotalSupply()
6161
}
6262

6363
func BalanceOf(symbol string, owner std.Address) uint64 {
6464
inst := mustGetInstance(symbol)
65-
return grc20.PrevRealmTeller(inst.token).BalanceOf(owner)
65+
return inst.token.CallerTeller().BalanceOf(owner)
6666
}
6767

6868
func Allowance(symbol string, owner, spender std.Address) uint64 {
6969
inst := mustGetInstance(symbol)
70-
return grc20.PrevRealmTeller(inst.token).Allowance(owner, spender)
70+
return inst.token.CallerTeller().Allowance(owner, spender)
7171
}
7272

7373
func Transfer(symbol string, to std.Address, amount uint64) {
7474
inst := mustGetInstance(symbol)
75-
checkErr(grc20.PrevRealmTeller(inst.token).Transfer(to, amount))
75+
checkErr(inst.token.CallerTeller().Transfer(to, amount))
7676
}
7777

7878
func Approve(symbol string, spender std.Address, amount uint64) {
7979
inst := mustGetInstance(symbol)
80-
checkErr(grc20.PrevRealmTeller(inst.token).Approve(spender, amount))
80+
checkErr(inst.token.CallerTeller().Approve(spender, amount))
8181
}
8282

8383
func TransferFrom(symbol string, from, to std.Address, amount uint64) {
8484
inst := mustGetInstance(symbol)
85-
checkErr(grc20.PrevRealmTeller(inst.token).TransferFrom(from, to, amount))
85+
checkErr(inst.token.CallerTeller().TransferFrom(from, to, amount))
8686
}
8787

8888
// faucet.
@@ -124,7 +124,7 @@ func Render(path string) string {
124124
symbol := parts[0]
125125
inst := mustGetInstance(symbol)
126126
owner := std.Address(parts[2])
127-
balance := grc20.PrevRealmTeller(inst.token).BalanceOf(owner)
127+
balance := inst.token.CallerTeller().BalanceOf(owner)
128128
return ufmt.Sprintf("%d", balance)
129129
default:
130130
return "404\n"

‎examples/gno.land/r/demo/minidex/minidex.gno

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func NewDEX() *DEX {
3737
func (dex *DEX) PlaceOrder(tokenFrom, tokenTo *grc20.Token, amount uint64, isBuy bool) int {
3838
trader := std.PrevRealm().Addr()
3939
curAddr := std.CurrentRealm().Addr()
40-
userBanker := grc20.SubAccountTeller(tokenFrom, "")
40+
userBanker := tokenFrom.RealmTeller()
4141

4242
allowance := userBanker.Allowance(trader, curAddr)
4343
require(allowance >= amount, "insufficient allowance")
@@ -91,8 +91,8 @@ func (dex *DEX) matchPairOrders(tokenFrom, tokenTo *grc20.Token) int {
9191
amount := min(order1.amount, order2.amount)
9292
order1.amount -= amount
9393
order2.amount -= amount
94-
banker1 := grc20.SubAccountTeller(order1.tokenFrom, "")
95-
banker2 := grc20.SubAccountTeller(order2.tokenFrom, "")
94+
banker1 := order1.tokenFrom.RealmTeller()
95+
banker2 := order2.tokenFrom.RealmTeller()
9696
banker1.Transfer(order2.trader, amount)
9797
banker2.Transfer(order1.trader, amount)
9898
matched++
@@ -127,7 +127,7 @@ func (dex *DEX) CancelOrders() {
127127
ordersTree.Iterate("", "", func(key string, value interface{}) bool {
128128
order := value.(*Order)
129129
if order.trader == trader {
130-
userBanker := grc20.SubAccountTeller(order.tokenFrom, "")
130+
userBanker := order.tokenFrom.RealmTeller()
131131
err := userBanker.Transfer(trader, order.amount)
132132
checkErr(err, "cannot refund tokens")
133133
ordersTree.Remove(key)

‎examples/gno.land/r/demo/minidex/minidex_test.gno

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"std"
55
"testing"
66

7-
"gno.land/p/demo/grc/grc20"
87
"gno.land/p/demo/testutils"
98
"gno.land/p/demo/uassert"
109
"gno.land/p/demo/ufmt"
@@ -70,7 +69,7 @@ func TestPackage(t *testing.T) {
7069
checkBalances(1000, 0, 0, 0, 0, 0)
7170
checkAllowances(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
7271

73-
grc20.PrevRealmTeller(test20.Token).Approve(dexAddr, 100)
72+
test20.Token.CallerTeller().Approve(dexAddr, 100)
7473
checkBalances(1000, 0, 0, 0, 0, 0)
7574
checkAllowances(0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
7675
uassert.Equal(t, dex.Size(), 0, "A")
@@ -89,7 +88,7 @@ Sell: Test20 -> Foo 100
8988
checkBalances(900, 0, 100, 0, 10000000, 0)
9089
checkAllowances(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
9190

92-
grc20.PrevRealmTeller(foo20.Token).Approve(dexAddr, 2000)
91+
foo20.Token.CallerTeller().Approve(dexAddr, 2000)
9392
checkBalances(900, 0, 100, 0, 10000000, 0)
9493
checkAllowances(0, 0, 0, 0, 0, 0, 0, 0, 0, 2000, 0, 0)
9594
uassert.Equal(t, dex.Size(), 1, "D")

‎examples/gno.land/r/demo/tests/test20/test20.gno

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ import (
1414

1515
var (
1616
Token, AdminLedger = grc20.NewToken("Test20", "TST", 4)
17-
PrevRealmTeller = grc20.PrevRealmTeller(Token)
18-
AccountTeller = grc20.SubAccountTeller(Token, "")
19-
AccountTellerFoo = grc20.SubAccountTeller(Token, "foo")
17+
CallerTeller = Token.CallerTeller()
18+
RealmTeller = Token.RealmTeller()
19+
RealmTellerFoo = Token.RealmSubTeller("foo")
2020
)
2121

2222
// XXX func init() { grc20reg.Register(Pub, "") } // circular dep (testing)

‎examples/gno.land/r/demo/wugnot/wugnot.gno

+3-3
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,20 @@ func Allowance(owner, spender pusers.AddressOrName) uint64 {
7878

7979
func Transfer(to pusers.AddressOrName, amount uint64) {
8080
toAddr := users.Resolve(to)
81-
userTeller := grc20.PrevRealmTeller(Token)
81+
userTeller := Token.CallerTeller()
8282
checkErr(userTeller.Transfer(toAddr, amount))
8383
}
8484

8585
func Approve(spender pusers.AddressOrName, amount uint64) {
8686
spenderAddr := users.Resolve(spender)
87-
userTeller := grc20.PrevRealmTeller(Token)
87+
userTeller := Token.CallerTeller()
8888
checkErr(userTeller.Approve(spenderAddr, amount))
8989
}
9090

9191
func TransferFrom(from, to pusers.AddressOrName, amount uint64) {
9292
fromAddr := users.Resolve(from)
9393
toAddr := users.Resolve(to)
94-
userTeller := grc20.PrevRealmTeller(Token)
94+
userTeller := Token.CallerTeller()
9595
checkErr(userTeller.TransferFrom(fromAddr, toAddr, amount))
9696
}
9797

0 commit comments

Comments
 (0)
Please sign in to comment.