Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: updates for the faucet community bot #400

Merged
merged 11 commits into from
Mar 12, 2023
73 changes: 56 additions & 17 deletions examples/gno.land/r/gnoland/faucet/admin.gno
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,83 @@ import (
"std"
)

func AdminSetInPause(inPause bool) error {
func AdminSetInPause(inPause bool) string {
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
if err := assertIsAdmin(); err != nil {
return err
return err.Error()
}
gInPause = inPause
return nil
return ""
}

func AdminSetMessage(message string) error {
func AdminSetMessage(message string) string {
if err := assertIsAdmin(); err != nil {
return err
return err.Error()
}
gMessage = message
return nil
return ""
}

func AdminSetPerTransferSend(send std.Coins) error {
func AdminSetTransferLimit(amount int64, denom string) string {
if err := assertIsAdmin(); err != nil {
return err
return err.Error()
}
gPerTransferSend = send
return nil
gLimit = std.Coins{std.Coin{Denom: denom, Amount: amount}}
piux2 marked this conversation as resolved.
Show resolved Hide resolved
return ""
}

func AdminSetAdminAddr(addr std.Address) error {
func AdminSetAdminAddr(addr std.Address) string {
if err := assertIsAdmin(); err != nil {
return err
return err.Error()
}
gAdminAddr = addr
return nil
return ""
}

func AdminSetControllerAddr(addr std.Address) error {
func AdminAddController(addr std.Address) string {
if err := assertIsAdmin(); err != nil {
return err
return err.Error()
}
gControllerAddr = addr
return nil

k := -1
for _, v := range gControllers {
if v == addr {
return addr.String() + " exists, no need to add."
}
}
for i, v := range gControllers {
if v == "" {

k = i
break
}
}
if k < 0 {
return "can not add more controllers than allowed"
}

gControllers[k] = addr

return ""
}

func AdminRemoveController(addr std.Address) string {
if err := assertIsAdmin(); err != nil {
return err.Error()
}

removed := false
for i, v := range gControllers {
if v == addr {

gControllers[i] = ""
removed = true
}
}

if removed == false {
return addr.String() + " is not on the controller list"
}
return ""
piux2 marked this conversation as resolved.
Show resolved Hide resolved
}

func assertIsAdmin() error {
Expand Down
67 changes: 46 additions & 21 deletions examples/gno.land/r/gnoland/faucet/faucet.gno
Original file line number Diff line number Diff line change
Expand Up @@ -9,60 +9,85 @@ import (

var (
// configurable by admin.
gAdminAddr std.Address = "g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq"
gControllerAddr std.Address = "g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq"
gPerTransferSend = std.Coins{std.Coin{"ugnot", 1000000}}
gInPause = false
gMessage = "# Community Faucet.\n\n"
gAdminAddr std.Address = "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
moul marked this conversation as resolved.
Show resolved Hide resolved

gControllers [10]std.Address = [10]std.Address{} // limit it to 10

gInPause = false
gMessage = "# Community Faucet.\n\n"

// internal vars, for stats.
gTotalTransferred std.Coins
gTotalTransfers = uint(0)

// per request limit, 350 gnot
gLimit std.Coins = std.Coins{std.Coin{"ugnot", 350000000}}
)

func Transfer(to std.Address) error {
func Transfer(to std.Address, send int64) string {
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
if err := assertIsController(); err != nil {
return err
return err.Error()
}

if gInPause {
return errors.New("faucet in pause")
return errors.New("faucet in pause").Error()
}

send := gPerTransferSend
var sendCoins std.Coins

// limit the pre request
if send <= gLimit.AmountOf("ugnot") {
sendCoins = std.Coins{std.Coin{Denom: "ugnot", Amount: send}}
} else {
return errors.New("Per request limit " + gLimit.String() + " exceed").Error()
}
piux2 marked this conversation as resolved.
Show resolved Hide resolved

gTotalTransferred = gTotalTransferred.Add(send)
gTotalTransferred = gTotalTransferred.Add(sendCoins)
gTotalTransfers++

banker := std.GetBanker(std.BankerTypeOrigSend)
banker := std.GetBanker(std.BankerTypeRealmSend)
pkgaddr := std.GetOrigPkgAddr()
banker.SendCoins(pkgaddr, to, send)
return nil
banker.SendCoins(pkgaddr, to, sendCoins)
return ""
}

func GetPerTransferLimit() int64 {
return gLimit.AmountOf("ugnot")
}

func Render(path string) string {
banker := std.GetBanker(std.BankerTypeOrigSend)
banker := std.GetBanker(std.BankerTypeRealmSend)
balance := banker.GetCoins(std.GetOrigPkgAddr())

output := gMessage
output := path + gMessage
if gInPause {
output += "Status: inactive.\n"
} else {
output += "Status: active.\n"
}
output += ufmt.Sprintf("Balance: %s.\n", balance.String())
output += ufmt.Sprintf("Rewarded: %s (in %d times).\n", gTotalTransferred.String(), gTotalTransfers)
output += ufmt.Sprintf("Total transfers: %s (in %d times).\n\n", gTotalTransferred.String(), gTotalTransfers)

output += "Package address: " + std.GetOrigPkgAddr().String() + "\n\n"
output += ufmt.Sprintf("Admin: %s\n\n ", gAdminAddr.String())
output += ufmt.Sprintf("Controllers:\n\n ")

if path == "?debug" {
output += ufmt.Sprintf("Admin: %s, Controller: %s\n", gAdminAddr.String(), gControllerAddr.String())
for _, v := range gControllers {
output += ufmt.Sprintf("%s ", v.String())
}
output += "\n\n"
output += ufmt.Sprintf("Per request limit: %s\n\n", gLimit.String())

return output
}

func assertIsController() error {
caller := std.GetOrigCaller()
if caller != gControllerAddr {
return errors.New("restricted for controller")

for _, v := range gControllers {
if caller == v {
return nil
}
}
return nil
return errors.New(caller.String() + " is not on the controller list")
}
75 changes: 0 additions & 75 deletions examples/gno.land/r/gnoland/faucet/faucet_filetest.gno

This file was deleted.

86 changes: 69 additions & 17 deletions examples/gno.land/r/gnoland/faucet/faucet_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,94 @@ import (

func TestPackage(t *testing.T) {
var (
adminaddr = std.Address("g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq")
controlleraddr = testutils.TestAddress("controller")
test1addr = testutils.TestAddress("test1")
adminaddr = std.Address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
faucetaddr = std.TestDerivePkgAddr("gno.land/r/faucet")
controlleraddr1 = testutils.TestAddress("controller1")
controlleraddr2 = testutils.TestAddress("controller2")
controlleraddr3 = testutils.TestAddress("controller3")
controlleraddr4 = testutils.TestAddress("controller4")
controlleraddr5 = testutils.TestAddress("controller5")
controlleraddr6 = testutils.TestAddress("controller6")
controlleraddr7 = testutils.TestAddress("controller7")
controlleraddr8 = testutils.TestAddress("controller8")
controlleraddr9 = testutils.TestAddress("controller9")
controlleraddr10 = testutils.TestAddress("controller10")
controlleraddr11 = testutils.TestAddress("controller11")

test1addr = testutils.TestAddress("test1")
)
// deposit 1000gnot to faucet contract

std.TestIssueCoins(faucetaddr, std.Coins{{"ugnot", 1000000000}})
std.TestSetOrigPkgAddr(faucetaddr)
assertBalance(t, faucetaddr, 1000000000)

// by default, balance is empty, and as a user I cannot call Transfer, or Admin commands.
std.TestSetOrigSend(std.Coins{{"ugnot", 2000000000}}, nil)

assertBalance(t, test1addr, 0)
assertErr(t, faucet.Transfer(test1addr))
assertErr(t, faucet.AdminSetControllerAddr(controlleraddr))
std.TestSetOrigCaller(controlleraddr)
assertErr(t, faucet.Transfer(test1addr))
assertErr(t, faucet.Transfer(test1addr, 1000000))
assertErr(t, faucet.AdminAddController(controlleraddr1))
std.TestSetOrigCaller(controlleraddr1)
assertErr(t, faucet.Transfer(test1addr, 1000000))

// as an admin, set the controller to controlleraddr.
// as an admin, add the controller to contract and deposit more 2000gnot to contract
std.TestSetOrigCaller(adminaddr)
assertNoErr(t, faucet.AdminSetControllerAddr(controlleraddr))
assertNoErr(t, faucet.AdminAddController(controlleraddr1))
assertBalance(t, faucetaddr, 1000000000)

// now, send some tokens as controller.
std.TestSetOrigCaller(controlleraddr)
assertNoErr(t, faucet.Transfer(test1addr))
std.TestSetOrigCaller(controlleraddr1)
assertNoErr(t, faucet.Transfer(test1addr, 1000000))
assertBalance(t, test1addr, 1000000)
assertNoErr(t, faucet.Transfer(test1addr))
assertNoErr(t, faucet.Transfer(test1addr, 1000000))
assertBalance(t, test1addr, 2000000)
assertBalance(t, faucetaddr, 998000000)

// remove controller
// as an admin, remove controller
std.TestSetOrigCaller(adminaddr)
assertNoErr(t, faucet.AdminRemoveController(controlleraddr1))
std.TestSetOrigCaller(controlleraddr1)
assertErr(t, faucet.Transfer(test1addr, 1000000))

// duplicate controller
std.TestSetOrigCaller(adminaddr)
assertNoErr(t, faucet.AdminAddController(controlleraddr1))
assertErr(t, faucet.AdminAddController(controlleraddr1))
// add more than more than allowed controllers
assertNoErr(t, faucet.AdminAddController(controlleraddr2))
assertNoErr(t, faucet.AdminAddController(controlleraddr3))
assertNoErr(t, faucet.AdminAddController(controlleraddr4))
assertNoErr(t, faucet.AdminAddController(controlleraddr5))
assertNoErr(t, faucet.AdminAddController(controlleraddr6))
assertNoErr(t, faucet.AdminAddController(controlleraddr7))
assertNoErr(t, faucet.AdminAddController(controlleraddr8))
assertNoErr(t, faucet.AdminAddController(controlleraddr9))
assertNoErr(t, faucet.AdminAddController(controlleraddr10))
assertErr(t, faucet.AdminAddController(controlleraddr11))

// send more than per transfer limit
std.TestSetOrigCaller(adminaddr)
faucet.AdminSetTransferLimit(300000000, "ugnot")
std.TestSetOrigCaller(controlleraddr1)
assertErr(t, faucet.Transfer(test1addr, 301000000))

// block transefer from the address not on the controllers list.
std.TestSetOrigCaller(controlleraddr11)
assertErr(t, faucet.Transfer(test1addr, 1000000))
}

func assertErr(t *testing.T, err error) {
func assertErr(t *testing.T, err string) {
t.Helper()
if err == nil {
if err == "" {
t.Logf("info: got err: %v", err)
t.Errorf("expected an error, got nil.")
}
}

func assertNoErr(t *testing.T, err error) {
func assertNoErr(t *testing.T, err string) {
t.Helper()
if err != nil {
if err != "" {
t.Errorf("got err: %v.", err)
}
}
Expand Down