On-chain governance system for the PACT protocol, built in collaboration with Aptos Labs.
The Pact governance system enables decentralized decision-making through a vote-escrowed token model. Token holders lock PACT to accrue vePACT, gaining voting power that increases over time (up to 52 weeks). This incentivizes long-term alignment between token holders and protocol direction.
flowchart TD
subgraph system[Pact Governance System]
PACT[PACT Token] -->|lock| vePACT[vePACT]
vePACT -->|vote on proposals| GOV[Governance<br/>voting]
PACT -->|lockup tokens<br/>investors/team only| VEST[Vesting]
VEST -->|lock<br/>NOT eligible for rewards| vePACT
vePACT -->|receive rewards<br/>prorata| DIST[Distribution<br/>rewards]
end
These contracts have been audited by Adevar Security. The full audit report is available at:
- Vote-Escrowed Tokens (vePACT): Lock PACT to accrue time-weighted voting power
- Growing Voting Power: Voting power increases linearly with lock duration (up to 52 epochs/weeks)
- On-Chain Governance: Create and vote on proposals with configurable thresholds
- Token Vesting: Flexible vesting schedules with cliff periods
- Reward Distribution: Epoch-based reward distribution proportional to voting power
- Multi-Step Proposals: Support for complex proposals requiring multiple execution steps
- Lock Tokens: Users lock PACT to receive vePACT
- Create Proposal: Users with sufficient voting power can create proposals
- Vote: vePACT holders vote yes/no during the voting period
- Execute: Passing proposals can be executed after the voting period
| Module | Description |
|---|---|
governance |
Proposal creation, voting, and execution |
ve_token |
Vote-escrowed token with time-weighted voting power |
ve_token_public_api |
Public interface for ve_token operations |
vote_token |
PACT token definition |
vesting |
Token vesting with configurable schedules |
distribution |
Epoch-based reward distribution |
- Aptos CLI (v4.0.0 or later)
aptos move compile --devaptos move test# Compile for a specific network
bin/compile mainnet
bin/compile testnet
# Build publish payload
bin/build-payload mainnet
# Package bytecode for governance upgrade
bin/package mainnet ./mainnet-bytecodeNetwork addresses are stored in JSON files under bin/deploy/deployments/:
bin/deploy/deployments/
├── mainnet.json
└── testnet.json
Each file contains addresses for that network:
{
"voting": { "address": "0x..." },
"pact_token": { "address": "0x..." },
"pact_multisig": { "address": "0x..." },
"initializer": { "address": "0x..." }
}Helper scripts parse these files for CLI commands:
# Get all addresses as CLI args
bin/deploy/parse-deployment bin/deploy/deployments/mainnet.json
# Output: voting=0x...,pact_token=0x...,...
# Get a single address
bin/deploy/extract-address bin/deploy/deployments/mainnet.json voting
# Output: 0x...Releases are created via manual workflow dispatch in GitHub Actions:
# Trigger a release via GitHub CLI
gh workflow run release.yml -f version=v1.0.0 -f network=testnet
gh workflow run release.yml -f version=v1.0.0 -f network=mainnetRequirements:
- The version must have an entry in
CHANGELOG.mdbefore releasing - Mainnet releases require a corresponding testnet release to exist first
Release tags:
| Network | Tag Format | Example | Notes |
|---|---|---|---|
| Testnet | vX.Y.Z-testnet |
v1.0.0-testnet |
Marked as prerelease |
| Mainnet | vX.Y.Z |
v1.0.0 |
Links to testnet release |
Typical flow:
- Add changelog entry for
v1.0.0 - Dispatch release workflow with
version=v1.0.0andnetwork=testnet - Deploy and verify on testnet
- Dispatch release workflow with
version=v1.0.0andnetwork=mainnet - Deploy to mainnet via governance proposal
Each release produces a bytecode package with:
package_metadata.bcs- Serialized package metadatamodule_N.mv- Bytecode in dependency ordermodules.json- Module hashes and orderingPACKAGE_HASH- SHA3-256 hash for governance verification
See .github/workflows/release.yml for details.
| Parameter | Value | Description |
|---|---|---|
| Epoch Duration | 7 days | Length of each voting epoch |
| Unlock Delay | 30 days | Waiting period after requesting unlock |
| Max Lock Epochs | 52 | Maximum epochs for voting power calculation |
| Voting Duration | 7 days | Default proposal voting period |
| Min Proposal Power | 1M PACT | Minimum voting power to create proposals |
| Min Voting Threshold | 100M PACT | Minimum total votes for proposal validity |
Voting power grows linearly based on lock duration:
voting_power = locked_amount + (locked_amount × epochs_locked × time-multiplier)
Where:
epochs_locked= min(current_epoch - lock_epoch, 52)
A proposal goes through these stages:
Created → Voting → Succeeded/Failed → Executed (if passed)
1. Creation
Any user with at least 1M PACT in voting power can create a proposal. The proposal includes:
- Title, summary, and description
- Execution hash (hash of the script that will run if passed)
- Whether it's a single-step or multi-step proposal
Multi-step proposals chain multiple execution scripts together. Each step specifies the hash of the next script to run.
2. Voting Period
Once created, proposals enter a 7-day voting window. During this time:
- vePACT holders can vote yes or no
- Each address can only vote once per proposal
- Voting power is calculated at the current epoch (cannot be changed mid-vote)
- Votes are final and cannot be changed
3. Resolution
After the voting period ends, the proposal outcome is determined:
- Passes if yes votes > no votes AND total votes >= 100M PACT
- Fails otherwise
If a success threshold is configured, the proposal must also meet a minimum percentage of yes votes (e.g., 60% yes to pass).
4. Execution
Passing proposals can be executed by anyone. The execution script must match the hash submitted during creation. For multi-step proposals, each step must be executed in sequence, with each step specifying the next script hash.
The vesting module supports:
- Multiple vesting schedules (team, investors, etc.)
- Cliff periods before vesting begins
- Linear vesting after cliff
- Amendment of vesting schedules by admins
- Voting through vested tokens (tokens vote while vesting)
MIT License - see LICENSE for details.