Skip to content

Commit

Permalink
feat: add dao cw721 members handlers
Browse files Browse the repository at this point in the history
Signed-off-by: Norman Meier <[email protected]>
  • Loading branch information
n0izn0iz committed Aug 18, 2023
1 parent af2f240 commit 1fa74c0
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 2 deletions.
2 changes: 2 additions & 0 deletions go/internal/indexerdb/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type DAO struct {
UnstakingDuration uint
PreProposeModuleAddress string `gorm:"index"`
GroupContractAddress string `gorm:"index"`
VotingModuleAddress string `gorm:"index"`
ProposalModuleAddress string `gorm:"index"`
Members []*DAOMember
Proposals []*DAOProposal
Expand All @@ -30,6 +31,7 @@ type DAOMember struct {
DAONetworkID string `gorm:"primaryKey"`
DAOContractAddress string `gorm:"primaryKey"`
MemberAddress string `gorm:"primaryKey"`
Weight uint64
}

type DAOProposal struct {
Expand Down
88 changes: 86 additions & 2 deletions go/internal/indexerhandler/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package indexerhandler

import (
"encoding/json"
"fmt"
"strconv"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
Expand Down Expand Up @@ -84,16 +85,22 @@ func (h *Handler) handleExecuteInstantiateContractWithSelfAdmin(e *Message, exec
return nil
}

votingModuleAddress, err := e.Events.First("wasm.voting_module")
if err != nil {
h.logger.Debug("ignored instantiate dao with no voting module address", zap.String("tx", e.TxHash), zap.Error(err))
return nil
}

preProposeAddress, err := e.Events.First("wasm.update_pre_propose_module")
if err != nil {
h.logger.Debug("ignored instantiate dao with no pre-propose module address", zap.String("tx", e.TxHash), zap.Error(err))
return nil
}

// TODO: support other dao kinds (only supports member-based for now)
groupContractAddress, err := e.Events.First("wasm.group_contract_address")
if err != nil {
groupContractAddress = ""
// group contract address only exists for member-based daos
groupContractAddress = ""
}

var msg InstantiateContractWithSelfAdminMsg
Expand Down Expand Up @@ -144,6 +151,7 @@ func (h *Handler) handleExecuteInstantiateContractWithSelfAdmin(e *Message, exec
GroupContractAddress: groupContractAddress,
PreProposeModuleAddress: preProposeAddress,
ProposalModuleAddress: proposalModuleAddress,
VotingModuleAddress: votingModuleAddress,
}

if votingModuleInstantiateMsg.TokenInfo != nil {
Expand Down Expand Up @@ -389,3 +397,79 @@ func (h *Handler) handleExecuteDAOPropose(e *Message, execMsg *wasmtypes.MsgExec
h.logger.Info("created dao proposal", zap.Any("proposal", dbProposal))
return nil
}

func (h *Handler) handleExecuteDAOCW721VotingStake(e *Message, execMsg *wasmtypes.MsgExecuteContract, sendNFTMsg *SendNFTExecuteMsg) (bool, error) {
votingModuleAddr := sendNFTMsg.Data.Contract

var dao indexerdb.DAO
daoRes := h.db.Find(&dao, "network_id = ? AND voting_module_address = ?", h.config.Network.ID, votingModuleAddr)
if err := daoRes.Error; err != nil {
return false, errors.Wrap(err, "failed to query dao")
}
if daoRes.RowsAffected == 0 {
h.logger.Debug("ignored cw721 voting stake for unknown dao", zap.String("tx", e.TxHash), zap.String("contract", votingModuleAddr))
return false, nil
}

var member indexerdb.DAOMember
memberRes := h.db.Find(&member, "dao_network_id = ? AND dao_contract_address = ? AND member_address = ?", h.config.Network.ID, dao.ContractAddress, execMsg.Sender)
if err := memberRes.Error; err != nil {
return false, errors.Wrap(err, "failed to query dao member")
}

if memberRes.RowsAffected == 0 {
if err := h.db.Create(&indexerdb.DAOMember{
DAONetworkID: h.config.Network.ID,
DAOContractAddress: dao.ContractAddress,
MemberAddress: execMsg.Sender,
Weight: 1,
}).Error; err != nil {
return false, errors.Wrap(err, "failed to create dao member")
}
}

member.Weight += 1
if err := h.db.Save(&member).Error; err != nil {
return false, errors.Wrap(err, "failed to update dao member")
}

h.logger.Info("cw721 voting stake", zap.String("tx", e.TxHash), zap.String("contract", votingModuleAddr), zap.String("sender", execMsg.Sender))
return true, nil
}

func (h *Handler) handleExecuteDAOCW721VotingUnstake(e *Message, execMsg *wasmtypes.MsgExecuteContract) (bool, error) {
votingModuleAddr := execMsg.Contract

var dao indexerdb.DAO
daoRes := h.db.Find(&dao, "network_id = ? AND voting_module_address = ?", h.config.Network.ID, votingModuleAddr)
if err := daoRes.Error; err != nil {
return false, errors.Wrap(err, "failed to query dao")
}
if daoRes.RowsAffected == 0 {
h.logger.Debug("ignored cw721 voting unstake for unknown dao", zap.String("tx", e.TxHash), zap.String("contract", votingModuleAddr))
return false, nil
}

var member indexerdb.DAOMember
memberRes := h.db.Find(&member, "dao_network_id = ? AND dao_contract_address = ? AND member_address = ?", h.config.Network.ID, dao.ContractAddress, execMsg.Sender)
if err := memberRes.Error; err != nil {
return false, errors.Wrap(err, "failed to query dao member")
}
if memberRes.RowsAffected == 0 {
return false, fmt.Errorf("member %s not found in dao %s", execMsg.Sender, dao.ContractAddress)
}

member.Weight -= 1
if member.Weight == 0 {
if err := h.db.Delete(&member).Error; err != nil {
return false, errors.Wrap(err, "failed to delete dao member")
}
} else {
if err := h.db.Save(&member).Error; err != nil {
return false, errors.Wrap(err, "failed to update dao member")
}
}

h.logger.Info("cw721 voting unstake", zap.String("tx", e.TxHash), zap.String("contract", votingModuleAddr), zap.String("sender", execMsg.Sender))
return true, nil
}
4 changes: 4 additions & 0 deletions go/internal/indexerhandler/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,10 @@ func (h *Handler) handleExecute(e *Message) error {
if err := h.handleExecuteDAOExecute(e, &executeMsg); err != nil {
return errors.Wrap(err, "failed to handle dao execute")
}
case "unstake":
if _, err := h.handleExecuteDAOCW721VotingUnstake(e, &executeMsg); err != nil {
return errors.Wrap(err, "failed to handle dao cw721 voting unstake")
}
}

return nil
Expand Down
9 changes: 9 additions & 0 deletions go/internal/indexerhandler/nft.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ func (h *Handler) handleExecuteSendNFT(e *Message, execMsg *wasmtypes.MsgExecute
return nil
}

// cw721 dao
handled, err := h.handleExecuteDAOCW721VotingStake(e, execMsg, &sendNFTMsg)
if err != nil {
return errors.Wrap(err, "failed to handle dao cw721 voting stake")
}
if handled {
return nil
}

// fallback
if err := h.handleExecuteSendNFTFallback(e, execMsg, &sendNFTMsg); err != nil {
return errors.Wrap(err, "failed to handle fallback send_nft")
Expand Down

0 comments on commit 1fa74c0

Please sign in to comment.