Skip to main content

Participate in Governance

This tutorial explains how to participate in ACDC on-chain governance, including viewing proposals, voting, and creating your own proposals.

Overview

ACDC uses on-chain governance for protocol decisions:

  • Proposals: Suggested changes to the protocol
  • Voting: Token holders vote based on stake
  • Execution: Approved proposals are automatically executed

Voting Power

Your voting power equals your staked ACDC:

  • 1 staked ACDC = 1 vote
  • Delegated stake counts for the validator, not the delegator
  • Votes can be: Yes, No, or Abstain

Proposal Types

TypeDescriptionThreshold
ParameterChange protocol parameters50% + 1
UpgradeProtocol upgrades66.7%
SpendTreasury spending50% + 1
EmergencyCritical fixes75%

Viewing Proposals

Using CLI

# List active proposals
acdc governance list

# Output:
# Active Proposals:
# #42 - Increase Block Gas Limit
# Status: Active | Ends: 2024-01-20
# For: 45.2% | Against: 12.1% | Abstain: 5.3%
#
# #43 - Add New Validator Rewards
# Status: Active | Ends: 2024-01-22
# For: 62.8% | Against: 8.4% | Abstain: 3.1%

# View proposal details
acdc governance show 42

# Output:
# Proposal #42: Increase Block Gas Limit
# ========================================
# Proposer: dx1proposer123...
# Type: Parameter
# Status: Active
# Voting Period: 2024-01-15 to 2024-01-20
#
# Description:
# This proposal increases the block gas limit from 30M to 50M
# to accommodate higher transaction throughput.
#
# Actions:
# - setParameter("blockGasLimit", 50000000)
#
# Votes:
# For: 45,234,567 ACDC (45.2%)
# Against: 12,123,456 ACDC (12.1%)
# Abstain: 5,345,678 ACDC (5.3%)
# Quorum: 37.6% of 50% required

# List all proposals (including past)
acdc governance list --all

# Filter by status
acdc governance list --status passed
acdc governance list --status rejected

Using TypeScript SDK

import { AcdcClient, Governance } from '@acdc/sdk';

async function viewProposals() {
const client = new AcdcClient({
chain: 'delta',
network: 'mainnet'
});

const governance = new Governance(client);

// Get active proposals
const active = await governance.getProposals({ status: 'active' });

console.log('Active Proposals:');
for (const proposal of active) {
console.log(`\n#${proposal.id}: ${proposal.title}`);
console.log(` Status: ${proposal.status}`);
console.log(` Ends: ${new Date(proposal.endTime * 1000).toISOString()}`);
console.log(` For: ${proposal.votesFor.percentage}%`);
console.log(` Against: ${proposal.votesAgainst.percentage}%`);
}

// Get specific proposal
const proposal = await governance.getProposal(42);
console.log('\nProposal Details:');
console.log('Title:', proposal.title);
console.log('Description:', proposal.description);
console.log('Proposer:', proposal.proposer);
console.log('Actions:', proposal.actions);
}

viewProposals().catch(console.error);

Voting on Proposals

Prerequisites

  1. Have staked ACDC tokens
  2. Not have voted on this proposal yet
  3. Proposal must be in active voting period

Using CLI

# Vote yes
acdc governance vote 42 yes

# Output:
# Voting YES on Proposal #42...
# Transaction: 0xabc123...
# Vote submitted successfully!
# Your voting power: 10,000 ACDC

# Vote no
acdc governance vote 42 no

# Vote abstain (counts toward quorum but not for/against)
acdc governance vote 42 abstain

Using TypeScript SDK

import { AcdcClient, Wallet, Governance } from '@acdc/sdk';

async function vote() {
const client = new AcdcClient({
chain: 'delta',
network: 'mainnet'
});

const wallet = Wallet.fromMnemonic(process.env.MNEMONIC!);
const signer = wallet.connect(client);

const governance = new Governance(signer);

// Check voting power
const power = await governance.getVotingPower(wallet.address);
console.log(`Your voting power: ${power.formatted} ACDC`);

if (power.raw === 0n) {
console.log('You need to stake ACDC to vote');
return;
}

// Check if already voted
const hasVoted = await governance.hasVoted(42, wallet.address);
if (hasVoted) {
console.log('You have already voted on this proposal');
return;
}

// Cast vote
console.log('Voting YES on proposal #42...');
const tx = await governance.vote(42, 'yes');

console.log('Transaction:', tx.hash);
await tx.wait();

console.log('Vote submitted successfully!');
}

vote().catch(console.error);

Creating Proposals

Requirements

  • Minimum 100,000 staked ACDC (proposal threshold)
  • Proposal deposit: 10,000 ACDC (returned if passed, slashed if rejected)

Using CLI

# Create parameter change proposal
acdc governance propose \
--type parameter \
--title "Increase Block Gas Limit" \
--description "Increase gas limit from 30M to 50M for higher throughput" \
--action "setParameter blockGasLimit 50000000"

# Create treasury spend proposal
acdc governance propose \
--type spend \
--title "Fund Development Grant" \
--description "Allocate 100,000 ACDC for ecosystem development" \
--action "transfer dx1recipient... 100000000000000000000000"

# Output:
# Creating proposal...
# Deposit: 10,000 ACDC
# Transaction: 0xdef456...
# Proposal created!
# Proposal ID: 44
# Voting starts: 2024-01-15
# Voting ends: 2024-01-22

Using TypeScript SDK

import { AcdcClient, Wallet, Governance, parseUnits } from '@acdc/sdk';

async function createProposal() {
const client = new AcdcClient({
chain: 'delta',
network: 'mainnet'
});

const wallet = Wallet.fromMnemonic(process.env.MNEMONIC!);
const signer = wallet.connect(client);

const governance = new Governance(signer);

// Check if eligible to propose
const power = await governance.getVotingPower(wallet.address);
const threshold = await governance.getProposalThreshold();

if (power.raw < threshold.raw) {
console.log(`Need ${threshold.formatted} staked ACDC to propose`);
console.log(`You have: ${power.formatted} staked ACDC`);
return;
}

// Create proposal
const proposal = {
title: 'Increase Block Gas Limit',
description: `
## Summary
This proposal increases the block gas limit from 30M to 50M.

## Motivation
Current gas limit restricts throughput during peak usage.

## Specification
Set blockGasLimit parameter to 50,000,000.

## Risk Assessment
Low risk - similar limits work well on other networks.
`,
type: 'parameter',
actions: [
{
target: 'dx1paramcontract...',
function: 'setParameter',
args: ['blockGasLimit', 50000000]
}
]
};

console.log('Creating proposal...');
console.log('Deposit required: 10,000 ACDC');

const tx = await governance.propose(proposal);
console.log('Transaction:', tx.hash);

const receipt = await tx.wait();

// Get proposal ID from event
const event = receipt.events.find(e => e.event === 'ProposalCreated');
const proposalId = event.args.proposalId;

console.log(`Proposal created! ID: ${proposalId}`);
}

createProposal().catch(console.error);

Delegation

Delegate your voting power to another address:

Using CLI

# Delegate to an address
acdc governance delegate dx1delegate...

# Check your delegate
acdc governance delegate --show

# Remove delegation (self-delegate)
acdc governance delegate --self

Using TypeScript SDK

// Delegate voting power
const tx = await governance.delegate('dx1delegate...');
await tx.wait();

// Check current delegate
const delegate = await governance.getDelegate(wallet.address);
console.log('Delegated to:', delegate);

// Self-delegate (remove delegation)
const selfTx = await governance.delegate(wallet.address);
await selfTx.wait();

Monitoring Governance

Subscribe to Events

// Subscribe to new proposals
governance.on('ProposalCreated', (id, proposer, title) => {
console.log(`New proposal #${id}: ${title}`);
console.log(`Proposer: ${proposer}`);
});

// Subscribe to votes
governance.on('VoteCast', (proposalId, voter, vote, weight) => {
console.log(`Vote on #${proposalId}: ${vote}`);
console.log(`Voter: ${voter}, Weight: ${weight}`);
});

// Subscribe to proposal state changes
governance.on('ProposalExecuted', (id) => {
console.log(`Proposal #${id} executed!`);
});

governance.on('ProposalCanceled', (id) => {
console.log(`Proposal #${id} canceled`);
});

Query Historical Data

// Get vote history for an address
const votes = await governance.getVoteHistory(wallet.address);

for (const vote of votes) {
console.log(`Proposal #${vote.proposalId}: ${vote.vote}`);
console.log(` Weight: ${vote.weight}`);
console.log(` Time: ${new Date(vote.timestamp * 1000)}`);
}

// Get proposals by proposer
const myProposals = await governance.getProposals({
proposer: wallet.address
});

Governance Parameters

View current governance settings:

acdc governance params

# Output:
# Governance Parameters:
# Proposal Threshold: 100,000 ACDC
# Proposal Deposit: 10,000 ACDC
# Voting Period: 7 days
# Quorum: 50%
# Pass Threshold: 50% + 1
# Upgrade Threshold: 66.7%
# Emergency Threshold: 75%
# Timelock Delay: 2 days

Complete Voting Script

// governance-voter.ts
import { AcdcClient, Wallet, Governance, formatUnits } from '@acdc/sdk';

async function main() {
const client = new AcdcClient({
chain: 'delta',
network: process.env.NETWORK || 'mainnet'
});

const wallet = Wallet.fromMnemonic(process.env.MNEMONIC!);
const signer = wallet.connect(client);
const governance = new Governance(signer);

console.log('ACDC Governance Voter');
console.log('=====================');
console.log('Address:', wallet.address);

// Check voting power
const power = await governance.getVotingPower(wallet.address);
console.log(`Voting Power: ${power.formatted} ACDC`);

if (power.raw === 0n) {
console.log('\nNo voting power. Stake ACDC to participate.');
return;
}

// Get active proposals
const proposals = await governance.getProposals({ status: 'active' });

if (proposals.length === 0) {
console.log('\nNo active proposals.');
return;
}

console.log('\nActive Proposals:');
for (const p of proposals) {
const hasVoted = await governance.hasVoted(p.id, wallet.address);

console.log(`\n#${p.id}: ${p.title}`);
console.log(` Type: ${p.type}`);
console.log(` Ends: ${new Date(p.endTime * 1000).toLocaleDateString()}`);
console.log(` For: ${p.votesFor.percentage}%`);
console.log(` Against: ${p.votesAgainst.percentage}%`);
console.log(` Your vote: ${hasVoted ? 'Already voted' : 'Not yet voted'}`);
}

// Vote on first unvoted proposal
const proposalId = process.env.PROPOSAL_ID;
const voteChoice = process.env.VOTE; // 'yes', 'no', or 'abstain'

if (proposalId && voteChoice) {
const hasVoted = await governance.hasVoted(
parseInt(proposalId),
wallet.address
);

if (hasVoted) {
console.log(`\nAlready voted on proposal #${proposalId}`);
return;
}

console.log(`\nVoting ${voteChoice.toUpperCase()} on proposal #${proposalId}...`);

const tx = await governance.vote(
parseInt(proposalId),
voteChoice as 'yes' | 'no' | 'abstain'
);

console.log('Transaction:', tx.hash);
await tx.wait();

console.log('Vote submitted successfully!');
}
}

main().catch(console.error);

Run:

MNEMONIC="your mnemonic" \
PROPOSAL_ID=42 \
VOTE=yes \
npx ts-node governance-voter.ts

Best Practices

  1. Research Before Voting

    • Read the full proposal description
    • Understand the technical implications
    • Check community discussion
  2. Consider Delegation

    • If you lack time to research, delegate to someone you trust
    • You can always override delegation by voting directly
  3. Participate Regularly

    • Governance requires active participation
    • Low turnout can lead to poor decisions
  4. Proposal Quality

    • Write clear, detailed proposals
    • Include risk assessments
    • Engage with community feedback

Next Steps