Skip to content

Commit

Permalink
Merge branch 'master' into dev/aeddi/fix-bot
Browse files Browse the repository at this point in the history
  • Loading branch information
thehowl authored Dec 2, 2024
2 parents 241a755 + 7b7e758 commit 5d271ac
Show file tree
Hide file tree
Showing 13 changed files with 486 additions and 217 deletions.
10 changes: 1 addition & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ install_gnokey: install.gnokey
install_gno: install.gno

.PHONY: test
test: test.components test.docker
test: test.components

.PHONY: test.components
test.components:
Expand All @@ -64,14 +64,6 @@ test.components:
$(MAKE) --no-print-directory -C examples test
$(MAKE) --no-print-directory -C misc test

.PHONY: test.docker
test.docker:
@if hash docker 2>/dev/null; then \
go test --tags=docker -count=1 -v ./misc/docker-integration; \
else \
echo "[-] 'docker' is missing, skipping ./misc/docker-integration tests."; \
fi

.PHONY: fmt
fmt:
$(MAKE) --no-print-directory -C tm2 fmt imports
Expand Down
1 change: 1 addition & 0 deletions examples/gno.land/p/demo/dao/dao.gno
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const (
// that contains the necessary information to
// log and generate a valid proposal
type ProposalRequest struct {
Title string // the title associated with the proposal
Description string // the description associated with the proposal
Executor Executor // the proposal executor
}
Expand Down
5 changes: 4 additions & 1 deletion examples/gno.land/p/demo/dao/proposals.gno
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var (
Accepted ProposalStatus = "accepted" // proposal gathered quorum
NotAccepted ProposalStatus = "not accepted" // proposal failed to gather quorum
ExecutionSuccessful ProposalStatus = "execution successful" // proposal is executed successfully
ExecutionFailed ProposalStatus = "execution failed" // proposal is failed during execution
ExecutionFailed ProposalStatus = "execution failed" // proposal has failed during execution
)

func (s ProposalStatus) String() string {
Expand All @@ -42,6 +42,9 @@ type Proposal interface {
// Author returns the author of the proposal
Author() std.Address

// Title returns the title of the proposal
Title() string

// Description returns the description of the proposal
Description() string

Expand Down
8 changes: 8 additions & 0 deletions examples/gno.land/p/demo/simpledao/dao.gno
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package simpledao
import (
"errors"
"std"
"strings"

"gno.land/p/demo/avl"
"gno.land/p/demo/dao"
Expand All @@ -12,6 +13,7 @@ import (

var (
ErrInvalidExecutor = errors.New("invalid executor provided")
ErrInvalidTitle = errors.New("invalid proposal title provided")
ErrInsufficientProposalFunds = errors.New("insufficient funds for proposal")
ErrInsufficientExecuteFunds = errors.New("insufficient funds for executing proposal")
ErrProposalExecuted = errors.New("proposal already executed")
Expand Down Expand Up @@ -47,6 +49,11 @@ func (s *SimpleDAO) Propose(request dao.ProposalRequest) (uint64, error) {
return 0, ErrInvalidExecutor
}

// Make sure the title is set
if strings.TrimSpace(request.Title) == "" {
return 0, ErrInvalidTitle
}

var (
caller = getDAOCaller()
sentCoins = std.GetOrigSend() // Get the sent coins, if any
Expand All @@ -61,6 +68,7 @@ func (s *SimpleDAO) Propose(request dao.ProposalRequest) (uint64, error) {
// Create the wrapped proposal
prop := &proposal{
author: caller,
title: request.Title,
description: request.Description,
executor: request.Executor,
status: dao.Active,
Expand Down
49 changes: 49 additions & 0 deletions examples/gno.land/p/demo/simpledao/dao_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,50 @@ func TestSimpleDAO_Propose(t *testing.T) {
)
})

t.Run("invalid title", func(t *testing.T) {
t.Parallel()

var (
called = false
cb = func() error {
called = true

return nil
}
ex = &mockExecutor{
executeFn: cb,
}

sentCoins = std.NewCoins(
std.NewCoin(
"ugnot",
minProposalFeeValue,
),
)

ms = &mockMemberStore{
isMemberFn: func(_ std.Address) bool {
return false
},
}
s = New(ms)
)

std.TestSetOrigSend(sentCoins, std.Coins{})

_, err := s.Propose(dao.ProposalRequest{
Executor: ex,
Title: "", // Set invalid title
})
uassert.ErrorIs(
t,
err,
ErrInvalidTitle,
)

uassert.False(t, called)
})

t.Run("caller cannot cover fee", func(t *testing.T) {
t.Parallel()

Expand All @@ -58,6 +102,7 @@ func TestSimpleDAO_Propose(t *testing.T) {
ex = &mockExecutor{
executeFn: cb,
}
title = "Proposal title"

sentCoins = std.NewCoins(
std.NewCoin(
Expand All @@ -80,6 +125,7 @@ func TestSimpleDAO_Propose(t *testing.T) {

_, err := s.Propose(dao.ProposalRequest{
Executor: ex,
Title: title,
})
uassert.ErrorIs(
t,
Expand All @@ -105,6 +151,7 @@ func TestSimpleDAO_Propose(t *testing.T) {
executeFn: cb,
}
description = "Proposal description"
title = "Proposal title"

proposer = testutils.TestAddress("proposer")
sentCoins = std.NewCoins(
Expand All @@ -129,6 +176,7 @@ func TestSimpleDAO_Propose(t *testing.T) {

// Make sure the proposal was added
id, err := s.Propose(dao.ProposalRequest{
Title: title,
Description: description,
Executor: ex,
})
Expand All @@ -141,6 +189,7 @@ func TestSimpleDAO_Propose(t *testing.T) {

uassert.Equal(t, proposer.String(), prop.Author().String())
uassert.Equal(t, description, prop.Description())
uassert.Equal(t, title, prop.Title())
uassert.Equal(t, dao.Active.String(), prop.Status().String())

stats := prop.Stats()
Expand Down
38 changes: 26 additions & 12 deletions examples/gno.land/p/demo/simpledao/propstore.gno
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package simpledao
import (
"errors"
"std"
"strings"

"gno.land/p/demo/dao"
"gno.land/p/demo/seqid"
Expand All @@ -18,6 +19,7 @@ const maxRequestProposals = 10
// proposal is the internal simpledao proposal implementation
type proposal struct {
author std.Address // initiator of the proposal
title string // title of the proposal
description string // description of the proposal

executor dao.Executor // executor for the proposal
Expand All @@ -31,6 +33,10 @@ func (p *proposal) Author() std.Address {
return p.author
}

func (p *proposal) Title() string {
return p.title
}

func (p *proposal) Description() string {
return p.description
}
Expand Down Expand Up @@ -63,15 +69,20 @@ func (p *proposal) Render() string {
// Fetch the voting stats
stats := p.Stats()

output := ""
output += ufmt.Sprintf("Author: %s", p.Author().String())
output += "\n\n"
output += p.Description()
output += "\n\n"
output += ufmt.Sprintf("Status: %s", p.Status().String())
output += "\n\n"
output += ufmt.Sprintf(
"Voting stats: YES %d (%d%%), NO %d (%d%%), ABSTAIN %d (%d%%), MISSING VOTE %d (%d%%)",
var out string

out += "## Description\n\n"
if strings.TrimSpace(p.description) != "" {
out += ufmt.Sprintf("%s\n\n", p.description)
} else {
out += "No description provided.\n\n"
}

out += "## Proposal information\n\n"
out += ufmt.Sprintf("**Status: %s**\n\n", strings.ToUpper(p.Status().String()))

out += ufmt.Sprintf(
"**Voting stats:**\n- YES %d (%d%%)\n- NO %d (%d%%)\n- ABSTAIN %d (%d%%)\n- MISSING VOTES %d (%d%%)\n",
stats.YayVotes,
stats.YayPercent(),
stats.NayVotes,
Expand All @@ -81,10 +92,13 @@ func (p *proposal) Render() string {
stats.MissingVotes(),
stats.MissingVotesPercent(),
)
output += "\n\n"
output += ufmt.Sprintf("Threshold met: %t", stats.YayVotes > (2*stats.TotalVotingPower)/3)

return output
out += "\n\n"
thresholdOut := strings.ToUpper(ufmt.Sprintf("%t", stats.YayVotes > (2*stats.TotalVotingPower)/3))

out += ufmt.Sprintf("**Threshold met: %s**\n\n", thresholdOut)

return out
}

// addProposal adds a new simpledao proposal to the store
Expand Down
54 changes: 0 additions & 54 deletions examples/gno.land/r/gov/dao/v2/dao.gno
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package govdao

import (
"std"
"strconv"

"gno.land/p/demo/dao"
"gno.land/p/demo/membstore"
"gno.land/p/demo/simpledao"
"gno.land/p/demo/ufmt"
)

var (
Expand Down Expand Up @@ -65,55 +63,3 @@ func GetPropStore() dao.PropStore {
func GetMembStore() membstore.MemberStore {
return members
}

func Render(path string) string {
if path == "" {
numProposals := d.Size()

if numProposals == 0 {
return "No proposals found :(" // corner case
}

output := ""

offset := uint64(0)
if numProposals >= 10 {
offset = uint64(numProposals) - 10
}

// Fetch the last 10 proposals
for idx, prop := range d.Proposals(offset, uint64(10)) {
output += ufmt.Sprintf(
"- [Proposal #%d](%s:%d) - (**%s**)(by %s)\n",
idx,
"/r/gov/dao/v2",
idx,
prop.Status().String(),
prop.Author().String(),
)
}

return output
}

// Display the detailed proposal
idx, err := strconv.Atoi(path)
if err != nil {
return "404: Invalid proposal ID"
}

// Fetch the proposal
prop, err := d.ProposalByID(uint64(idx))
if err != nil {
return ufmt.Sprintf("unable to fetch proposal, %s", err.Error())
}

// Render the proposal
output := ""
output += ufmt.Sprintf("# Prop #%d", idx)
output += "\n\n"
output += prop.Render()
output += "\n\n"

return output
}
2 changes: 2 additions & 0 deletions examples/gno.land/r/gov/dao/v2/gno.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ require (
gno.land/p/demo/simpledao v0.0.0-latest
gno.land/p/demo/ufmt v0.0.0-latest
gno.land/p/gov/executor v0.0.0-latest
gno.land/p/moul/txlink v0.0.0-latest
gno.land/r/demo/users v0.0.0-latest
)
Loading

0 comments on commit 5d271ac

Please sign in to comment.