ERGO
Multisig & Governance
Advanced
1-2 weeks

DAO Treasury & Voting Pattern

Simple on-chain DAO: proposal boxes, token-weighted voting, timelocked execution

GitHub

課題

You need decentralized governance where token holders can propose and vote on treasury spending or protocol changes.

解決策

Use proposal boxes that collect votes as separate voting boxes. After voting period, proposals with sufficient support can be executed with timelock for safety.

仕組み

  1. 1Create governance token distributed to stakeholders
  2. 2Proposals are created as special boxes with action details in registers
  3. 3Token holders lock governance tokens in voting boxes pointing to proposal
  4. 4After voting period, tally votes from voting boxes
  5. 5If quorum and threshold met, proposal enters timelock period
  6. 6After timelock, anyone can execute the approved action

コード例

{
  // Proposal box structure
  // R4: Proposal ID (unique identifier)
  // R5: Action type (0=spend, 1=parameter change, 2=upgrade)
  // R6: Action data (recipient address, amount, or new parameter)
  // R7: Voting start height
  // R8: Voting end height
  // R9: Execution timelock (blocks after vote ends)
  
  val proposalId = SELF.R4[Coll[Byte]].get
  val actionType = SELF.R5[Int].get
  val votingEnd = SELF.R8[Int].get
  val timelock = SELF.R9[Int].get
  val executionHeight = votingEnd + timelock
  
  val governanceNFT = fromBase64("DAO_NFT_ID")
  
  // Proposal can be executed after timelock if:
  // 1. Voting period ended
  // 2. Timelock passed
  // 3. Vote passed (checked via data inputs)
  
  val votingEnded = HEIGHT > votingEnd
  val timelockPassed = HEIGHT > executionHeight
  
  // Vote tally from data inputs (voting boxes)
  val votingBoxes = CONTEXT.dataInputs.filter(b => 
    b.R4[Coll[Byte]].get == proposalId
  )
  val yesVotes = votingBoxes.filter(b => b.R5[Boolean].get == true)
    .map(b => b.tokens(0)._2).fold(0L, (a, b) => a + b)
  val totalVotes = votingBoxes.map(b => b.tokens(0)._2)
    .fold(0L, (a, b) => a + b)
  
  val quorum = 1000000L  // Minimum total votes
  val threshold = 500    // 50% approval needed (in basis points)
  
  val quorumMet = totalVotes >= quorum
  val thresholdMet = yesVotes * 1000 / totalVotes >= threshold
  
  votingEnded && timelockPassed && quorumMet && thresholdMet
}

Proposal box that can only be spent (executed) after voting passes and timelock expires. Votes are tallied from voting boxes.

ユースケース

  • Protocol governance
  • Community treasury management
  • Grant programs
  • Parameter changes (fees, thresholds)
  • Protocol upgrades
  • Emergency actions with timelock

セキュリティ考慮事項

  • !Use sufficient timelock for security (e.g., 7 days)
  • !Implement emergency pause mechanism
  • !Consider vote delegation for participation
  • !Guard against flash loan attacks on voting
  • !Audit proposal validation thoroughly

実装事例

Paideia

Full DAO framework on Ergo

リソース

手数料の考慮事項

Multiple transactions: create proposal, vote, tally, execute. Budget ~0.1 ERG total.

ErgoScriptスキルを向上させよう

新しいパターン、チュートリアル、開発者リソースの通知を受け取りましょう。

Follow for daily updates