Version: 1.0
Last Updated: 2026-06-28
Status: Active
Stellar-Save uses on-chain governance to manage protocol parameters, upgrades, and major decisions. This document explains how governance works, who can participate, and how proposals move from creation to execution.
Who are governors?
- Initial governors: Project founders and core contributors
- Selection criteria: Technical expertise, community trust, stake in protocol success
- Current governor set: Stored on-chain in the governance contract
Governor responsibilities:
- Vote on proposals
- Review code changes for security
- Participate in emergency response
- Represent community interests
How the governor set changes:
- Adding governors: Requires 75% approval from existing governors
- Removing governors: Requires 75% approval (excluding the governor being removed)
- Minimum governors: 3 (to ensure decentralization)
- Maximum governors: 11 (to maintain efficiency)
What can be proposed?
- Contract parameter changes (contribution limits, cycle durations)
- Contract upgrades (bug fixes, new features)
- Emergency pause/unpause of the protocol
- Treasury fund allocation
- Governor set changes
Who can create proposals?
- Any current governor
- Community members with sufficient stake (future feature)
A governor creates a proposal with:
- Title: Brief description (max 100 characters)
- Description: Detailed explanation with rationale
- Action: Specific on-chain operation to execute
- Execution Data: Encoded function call and parameters
Example: Change Maximum Members
// Proposal to increase max_members from 20 to 50
Proposal {
title: "Increase maximum group size to 50",
description: "Allow larger savings groups to accommodate community demand...",
action: ProposalAction::UpdateConfig,
data: encode_config_update({
param: "max_members",
new_value: 50
})
}CLI Example:
stellar contract invoke \
--id GOVERNANCE_CONTRACT_ID \
--network mainnet \
-- create_proposal \
--proposer GOVERNOR_ADDRESS \
--title "Increase maximum group size to 50" \
--description "$(cat proposal-description.md)" \
--action UpdateConfig \
--data "$(cat encoded-data.bin | base64)"Duration: 7 days (604,800 seconds)
Voting options:
- Yes: Support the proposal
- No: Oppose the proposal
- Abstain: Counted for quorum, not for approval
Vote weight:
- One vote per governor (equal weight)
- Future: Weighted by stake amount
Voting on-chain:
stellar contract invoke \
--id GOVERNANCE_CONTRACT_ID \
--network mainnet \
-- vote \
--proposal_id 1 \
--voter GOVERNOR_ADDRESS \
--vote YesVoting via frontend:
- Navigate to Governance page
- Click on active proposal
- Review details and discussion
- Click "Vote Yes" / "Vote No" / "Abstain"
- Sign transaction in wallet
Quorum requirement: 51% of governors must vote (any option)
Example:
- Total governors: 7
- Quorum threshold: 4 governors (7 * 0.51 = 3.57, rounded up to 4)
- Votes cast: 5 (Yes: 3, No: 1, Abstain: 1)
- Quorum met: ✅ (5 ≥ 4)
If quorum not met:
- Proposal fails automatically after voting period
- Can be re-submitted with modifications
Approval requirement: 66% of voting governors (excluding abstentions)
Example:
- Yes votes: 4
- No votes: 2
- Abstain: 1 (not counted)
- Approval: 4 / (4 + 2) = 66.67% ✅
If approval not met:
- Proposal rejected
- Cannot be executed
- Can be re-submitted with changes
Purpose: Allow community review and emergency response before execution
Timelock duration: 48 hours (172,800 seconds)
What happens during timelock:
- Proposal cannot be executed
- Community can review the code changes
- Emergency pause available if security issue found
- Governors can prepare execution environment
Emergency cancellation:
- Requires 75% governor approval
- Only during timelock period
- Used for critical security issues
Example timeline:
Day 0: Proposal created
Day 7: Voting ends (quorum: ✅, approval: ✅)
Day 7: Timelock begins
Day 9: Timelock ends, proposal executable
Day 16: Execution window closes (7 days after timelock)
Who can execute:
- Any governor
- Automated keeper bot (future feature)
Execution window: 7 days after timelock expires
Execution on-chain:
stellar contract invoke \
--id GOVERNANCE_CONTRACT_ID \
--network mainnet \
-- execute_proposal \
--proposal_id 1 \
--executor GOVERNOR_ADDRESSWhat happens on execution:
- Encoded data is decoded
- Target contract function is called
- State changes are applied
- Execution event is emitted
If not executed within window:
- Proposal expires
- Must be re-created and re-voted
Examples:
- Change min/max contribution amounts
- Adjust min/max cycle durations
- Modify min/max member counts
Encoded data structure:
struct ParamChange {
param_name: String,
new_value: Value
}Impact: Takes effect immediately on execution
Rollback: Requires new proposal to revert
Examples:
- Bug fix releases
- New feature implementations
- Security patches
Encoded data structure:
struct ContractUpgrade {
new_wasm_hash: BytesN<32>,
migration_data: Option<Bytes>
}Safety measures:
- WASM hash must match uploaded contract
- Audit report required for major upgrades
- Rollback plan documented in proposal
Testing requirements:
- Comprehensive test suite passes
- Testnet deployment and validation
- Security audit for critical changes
Examples:
- Pause all groups
- Unpause after incident resolution
- Emergency fund recovery
Encoded data structure:
enum EmergencyAction {
PauseProtocol,
UnpauseProtocol,
RecoverFunds(Address)
}Reduced timelock: 6 hours for emergency proposals
Approval requirement: 75% (higher than normal)
Examples:
- Add new governor
- Remove inactive governor
- Replace compromised governor
Encoded data structure:
enum GovernorChange {
Add(Address),
Remove(Address),
Replace { old: Address, new: Address }
}Special rules:
- Governor being removed cannot vote
- Requires 75% approval
- Immediate effect (no timelock for removals)
Scenario: Increase maximum group size from 20 to 50 members
Governor Alice creates the proposal:
const proposalId = await governanceContract.create_proposal({
proposer: aliceAddress,
title: "Increase max_members to 50",
description: `
## Rationale
Current 20-member limit is too restrictive for larger communities.
User feedback shows demand for 30-50 member groups.
## Impact
- Allows larger savings circles
- Increases protocol usage
- No security concerns (tested on testnet)
## Testing
- Testnet deployment: successful
- Max tested: 75 members
- Gas costs remain acceptable
`,
action: ProposalAction.UpdateConfig,
data: encodeConfigUpdate({
param: 'max_members',
newValue: 50
})
});
console.log('Proposal created:', proposalId);On-chain event:
{
"type": "ProposalCreated",
"proposalId": 1,
"proposer": "GALICE...",
"title": "Increase max_members to 50",
"votingEnds": 1719590400
}Governors cast their votes:
Day 1 - Bob votes Yes:
stellar contract invoke --id GOV_CONTRACT -- vote \
--proposal_id 1 --voter GBOB... --vote YesDay 3 - Carol votes Yes:
stellar contract invoke --id GOV_CONTRACT -- vote \
--proposal_id 1 --voter GCAROL... --vote YesDay 5 - Dave votes No:
stellar contract invoke --id GOV_CONTRACT -- vote \
--proposal_id 1 --voter GDAVE... --vote NoDay 7 - Eve votes Yes:
stellar contract invoke --id GOV_CONTRACT -- vote \
--proposal_id 1 --voter GEVE... --vote YesFinal tally:
- Total governors: 7
- Voted: 5 (Alice, Bob, Carol, Dave, Eve)
- Yes: 4 (Alice, Bob, Carol, Eve)
- No: 1 (Dave)
- Abstain: 0
- Did not vote: 2
Checks:
- Quorum: 5/7 = 71% ✅ (need 51%)
- Approval: 4/5 = 80% ✅ (need 66%)
Proposal enters 48-hour timelock:
Day 7 event:
{
"type": "ProposalQueued",
"proposalId": 1,
"executionEligible": 1719763200
}Community actions during timelock:
- Review code changes on GitHub
- Test on testnet
- Raise concerns if any
- Prepare for execution
No issues found → timelock expires on Day 9
Governor Alice executes the proposal:
stellar contract invoke --id GOV_CONTRACT \
-- execute_proposal \
--proposal_id 1 \
--executor GALICE...On-chain execution:
- Governance contract calls StellarSave contract
update_configfunction is invokedmax_membersis set to 50- Configuration stored on-chain
Execution event:
{
"type": "ProposalExecuted",
"proposalId": 1,
"executor": "GALICE...",
"result": "success"
}Verification:
stellar contract invoke --id STELLARSAVE_CONTRACT \
-- get_config
# Output shows max_members: 50 ✅Immediate impact:
- All new groups can have up to 50 members
- Existing groups unchanged (grandfathered)
- Frontend UI updated to allow 50 max
Monitoring:
- Track group creation with new limits
- Monitor gas costs for large groups
- Gather user feedback
Follow-up (if needed):
- Adjust further if 50 still too limiting
- Revert if issues arise
Automatic checks:
- Proposer is a valid governor
- Encoded data is well-formed
- Action type matches data structure
- No duplicate active proposals
Manual review:
- Code changes audited by governors
- Security implications discussed
- Community concerns addressed
Why 48 hours?
- Sufficient time for review
- Not so long that urgent fixes are delayed
- Balances security with agility
Emergency override:
- Critical security issues can be fast-tracked
- Requires 75% approval
- Fully transparent on-chain
Who can execute?
- Only governors (initially)
- Future: Permissionless execution after timelock
What if execution fails?
- Proposal remains executable
- Can be re-attempted
- Debug logs available
Reentrancy protection:
- Proposal marked as executed before calling target
- Cannot be executed twice
All governance actions emit events:
pub enum GovernanceEvent {
ProposalCreated { id, proposer, title },
VoteCast { proposal_id, voter, vote },
ProposalQueued { id, execution_eligible },
ProposalExecuted { id, executor, result },
ProposalCancelled { id, reason },
GovernorAdded { address },
GovernorRemoved { address },
}Frontend dashboard:
- Active proposals
- Voting status
- Historical proposals
- Governor activity
Notifications:
- Email alerts for new proposals
- Discord/Telegram bot announcements
- RSS feed for governance events
Analytics:
- Proposal success rate
- Average voting participation
- Time to execution
- Governor voting patterns
A: Currently only governors. Community proposals are planned for a future release.
A: It expires after 7 days. Any governor can execute during this window.
A: Yes, during the timelock period with 75% governor approval.
A: No cooldown period, but frequent changes discourage community trust.
A: Timelock allows detection. Emergency pause available. Governor reputation at stake.
A: Re-submit with modifications addressing governor concerns.
A: Multi-sig hardware wallets recommended. Key rotation policy enforced.
A: Governor set can vote to remove inactive governor and add replacement.
View the governance contract implementation:
- Repository: contracts/governance
- Audit Report: docs/security-audit-report.md
- Testnet Deployment:
CGOV...(see deployment.md)
- Initial governance process documentation
- Defined proposal lifecycle
- Documented parameter change flow
- Established governor selection criteria