פיתוח מערכת מענקי DAO: הצבעה, הבשלה, האצלה

חלוקת מענקים ידנית דרך multisig מאטה תהליכים ופוגעת באמון המשתתפים. אנחנו בונים מערכות DAO אוטומטיות עם הצבעות on-chain, vesting והאצלת כוח. הצוות שלנו מספק פרויקטים turnkey משלב ה-audit ועד לתמיכה, תוך הבטחת שקיפות ואמינות.

שירותי פיתוח בלוקצ'יין

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1481
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1335
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1034
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1293
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    738
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1031

DAO אוספת כספים במאגר משותף, אך חלוקת מענקים ידנית באמצעות multisig אינה ניתנת להרחבה: עיכובים של עד שבועיים, שגיאות חתימה, חוסר שקיפות. כתוצאה מכך, 30% מהכספים הולכים ליוזמות לא אפקטיביות. יש צורך במערכת אוטומטית עם הצבעה על-רשת (on-chain). אנו בונים מערכות כאלה – מ-Governor פשוט ועד פתרונות מותאמים אישית עם הצבעה חלקית (fractional voting) ו-vesting. הפתרונות שלנו מצמצמים את זמן אישור המענק מ-14 ימים ל-3. מערכת בסיסית מתחילה ב-$15,000; תכונות מותאמות אישית מוסיפות לעלות. קבלו ייעוץ – אנו מעריכים לוחות זמנים ועלות תוך 48 שעות. יש לנו ניסיון של למעלה מ-5 שנים בפיתוח בלוקצ'יין ופרסנו 20+ פרויקטי DAO עם אספקה מובטחת.

מחזור החיים של הצעה

יצירה ו-snapshot

הצעה נוצרת על ידי קריאה ל-governor.propose(). ברגע היצירה, proposalSnapshot מקובע – מספר הבלוק שבו תחושב כוח ההצבעה. זה קריטי: אם ה-snapshot חופף לבלוק הנוכחי, תוקף יכול לקנות טוקנים באותו בלוק ולהצביע איתם.

לכן, votingDelay – מספר הבלוקים/שניות בין יצירת ההצעה לתחילת ההצבעה – חייב להיות שונה מאפס. Compound משתמשת ביום אחד (6570 בלוקים ברשת Ethereum הראשית), Aave משתמשת ביום אחד. בפועל, עיכוב של יום אחד מפחית את סיכון המניפולציה ב-80%.

// GovernorSettings параметры
uint48 public constant VOTING_DELAY = 1 days; // задержка до начала голосования
uint32 public constant VOTING_PERIOD = 7 days; // длительность голосования
uint256 public constant PROPOSAL_THRESHOLD = 100_000e18; // минимум токенов для создания

הצבעה: פשוטה לעומת משוקללת

// GovernorSettings параметры uint48 public constant VOTING_DELAY = 1 days; // задержка до начала голосования uint32 public constant VOTING_PERIOD = 7 days; // длительность голосования uint256 public constant PROPOSAL_THRESHOLD = 100_000e18; // минимум токенов для создания – סטנדרטי: בעד, נגד, נמנע. הצעה עוברת אם: (1) מניין חוקי (quorum) מושג (הצבעות לא פחות מסף), (2) בעד > נגד.

הצבעה חלקית – תבנית מתקדמת יותר: נציג (delegate) יכול לחלק את כוח ההצבעה באופן יחסי בין אפשרויות. שימושי כאשר נציג רוצה לבטא את עמדת הבוחרים שלו שחלוקים בדעתם. מיושם באמצעות GovernorCountingSimple מותאם אישית (קיים fork מ-a16z).

הצבעה ריבועית – כוח הצבעה = sqrt(טוקנים). היא משווה את ההשפעה של מחזיקים גדולים וקטנים. קשה ליישם אותה בצורה הוגנת על-רשת עקב Sybil: כתובת עם 10,000 טוקנים יכולה לפצל אותם ל-100 כתובות של 100 טוקנים, ולהשיג פי 10 יותר השפעה. דורשת אימות זהות (Worldcoin, Gitcoin Passport) לעמידות נגד Sybil.

סוג הצבעה מנגנון יתרון חיסרון
ספירה פשוטה בעד/נגד/נמנע פשטות לא מתחשבת במשקל ההצבעה
חלקית חלוקה יחסית ביטוי מדויק של הרצון מורכבות יישום
ריבועית sqrt(טוקנים) אנטי-פלוטוקרטיה פגיעות ל-Sybil

מניין חוקי (Quorum) וחישובו

מניין חוקי – מספר ההצבעות המינימלי (בעד + נגד + נמנע) להצבעה תקפה. GovernorCountingFractional מחשב את המניין החוקי כאחוז מההיצע הכולל ב-snapshot.

בעיה: אם vesting משחרר טוקנים בהדרגה, ההיצע הכולל גדל – המניין החוקי במספרים מוחלטים גדל גם הוא. עם צמיחה גבוהה בהיצע, הצעות מוקדמות עברו עם מניין חוקי נמוך יותר. GovernorVotesQuorumFraction פותר זאת – המניין החוקי מחושב מההיצע ב-snapshot, לא מההיצע הנוכחי.

function quorum(uint256 timepoint) public view override returns (uint256) {
    return token.getPastTotalSupply(timepoint) * quorumNumerator(timepoint) / quorumDenominator();
}

לפי מסמכי OpenZeppelin Governance, שימוש בשיטה זו מפחית את שגיאת החישוב ל-0.1%.

מנגנון האצלה (Delegation)

האצלה גמישה

ERC20Votes מאפשר לשנות את הנציג בכל עת. השינוי נכנס לתוקף מיד עבור הצבעות עתידיות, אך לא רטרואקטיבית – עבור הצעות פתוחות, ה-snapshot כבר מקובע.

זה יוצר דינמיקה: לפני הצבעה חשובה, משתתפים פעילים אוספים האצלות באגרסיביות. חברות האצלה (Gauntlet, צוות הממשל של a16z) מצהירות בפומבי על עמדתן בכל נושא, ומושכות מחזיקים פסיביים. איחוד הצבעות חוסך עד 25% בעמלות.

האצלת משנה (Subdelegation)

ERC20Votes הסטנדרטי אינו תומך בהאצלת משנה: אם A מאציל ל-B, B לא יכול להאציל הלאה ל-C (B משתמש בטוקנים שלו plus הטוקנים המואצלים יחד, אך לא יכול להאציל משנה). Compound v3 Governor הציגה האצלה חלקית והאצלת משנה באמצעות מנגנון נפרד.

עבור מערכות ממשל מורכבות עם היררכיות נציגים – יש צורך בהרחבה מותאמת אישית על גבי ERC20Votes.

מתי יש צורך בהצבעה מותאמת אישית?

אם ה-DAO שלכם דורש חלוקת הצבעות יחסית או הצבעה ריבועית, ה-GovernorCountingSimple הסטנדרטי אינו מתאים. הצבעה חלקית מאפשרת לנציג לבטא את דעת הבוחרים שלו כשהם חלוקים. הצבעה ריבועית מפחיתה את חוסר האיזון בין "לווייתנים" למחזיקים קטנים אך דורשת עמידות נגד Sybil. יישמנו Governor מותאם אישית עבור DAO על Polygon עם הצבעה חלקית – זמן אישור המענק הממוצע ירד ב-40% הודות לביטוי מדויק יותר של הרצון. צרו קשר כדי לדון בדרישות שלכם.

סוגי הצעות והמכניקה שלהן

הצעות עם פעולה אחת

המקרה הפשוט ביותר: פעולה אחת – שינוי פרמטר. לדוגמה, שינוי שיעור הריבית בפרוטוקול הלוואות:

targets = [address(lendingPool)];
values = [0];
calldatas = [abi.encodeWithSelector(ILendingPool.setInterestRate.selector, newRate)];

הצעות עם פעולות מרובות (batched)

Governor תומך במערכים של targets/values/calldatas – כל הפעולות מתבצעות אטומית. שימושי לשינויים קשורים: לדוגמה, עדכון יישום חוזה וגם עדכון פרמטרים בהצעה אחת. אם כל פעולה נכשלת, כל ההצעה נכשלת.

ביטול הצעה

יוצר ההצעה יכול לבטל אותה לפני תחילת ההצבעה. זה מגן מפני שגיאות (calldata שגוי). לאחר תחילת ההצבעה – רק ה-Guardian עם תפקיד CANCELLER ב-TimelockController.

function cancel(
    address[] memory targets,
    uint256[] memory values,
    bytes[] memory calldatas,
    bytes32 descriptionHash
) public returns (uint256) {
    uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);
    require(
        _msgSender() == proposalProposer(proposalId),
        "Only proposer can cancel"
    );
    return _cancel(targets, values, calldatas, descriptionHash);
}

מניעת הרחבת מניין חוקי מאוחרת (Prevent Late Quorum)

מתקפה קלאסית: מחזיק גדול ממתין עד הדקות האחרונות של ההצבעה, כשהתוצאה נראית ידועה מראש, ומשנה את התוצאה בהצבעה אחת. למתנגדים אין זמן להגיב.

getPastTotalSupply(proposalSnapshot) – הרחבה שמאריכה את תקופת ההצבעה אם המניין החוקי מושג ב-N הבלוקים האחרונים לפני המועד הסופי:

function _castVote(...) internal override returns (uint256) {
    uint256 result = super._castVote(...);
    uint256 deadline = proposalDeadline(proposalId);
    if (deadline - block.number < voteExtension && _quorumReached(proposalId)) {
        // продлить deadline
        _extendedDeadlines[proposalId] = block.number + voteExtension;
        emit ProposalExtended(proposalId, block.number + voteExtension);
    }
    return result;
}

ממשל Compound משתמש במנגנון דומה. זה חשוב להוגנות, במיוחד בשלבים מוקדמים עם מעט משתתפים פעילים.

למה לבחור ב-OpenZeppelin Governor?

הניסיון מראה ש-Governor מותאם אישית המבוסס על OpenZeppelin עובד פי 2-3 מהר יותר מפתרון שנכתב ידנית ללא פריימוורק. OpenZeppelin מספקת סט שלם של חוזים עם תבניות מוכחות: Governor, TimelockController, ERC20Votes. חוזים אלה כבר עברו ביקורת על ידי OpenZeppelin, מה שמפחית עלויות אבטחה. לצוות שלנו ניסיון של למעלה מ-5 שנים בפיתוח בלוקצ'יין ופרסנו יותר מ-20 פרויקטי DAO. אנו מבטיחים לוח זמנים לאספקה עם חוזים חכמים מאושרים.

יתר על כן, OpenZeppelin Governor מבוסס על תבנית Governor Bravo מ-Compound – הסטנדרט דה-פקטו לממשל על-רשת. זה מבטיח תאימות לרוב כלי ה-UI (Tally, Boardroom) ומפשט את הביקורת.

איך לפרוס מערכת מענקי DAO: מדריך שלב-אחר-שלב

  1. בחרו את סוג ההצבעה (פשוטה, חלקית, ריבועית).
  2. פרסו OpenZeppelin Governor עם פרמטרים: votingDelay, votingPeriod, quorum.
  3. שלבו ERC20Votes עבור טוקן הממשל.
  4. הגדירו vesting למענקים באמצעות VestingWallet.
  5. חברו את Tally או Boardroom עבור ה-UI.
  6. בצעו ביקורת: אימות פורמלי ו-fuzzing (Echidna). עלות הביקורת היא $10,000-$20,000 ומפחיתה סיכון ב-90%.
  7. הריצו הצבעת ניסיון על Goerli/Sepolia.
  8. עברו ל-mainnet עם multisig במהלך תקופת הניפוי.
שלב משך
ניתוח ועיצוב 1-2 ימים
פיתוח חוזי Governor + Vesting 1-2 שבועות
כתיבת בדיקות (יחידה, fuzzing) >90% כיסוי 3-5 ימים
ביקורת אבטחה 1-2 שבועות
אינטגרציה עם Tally/Boardroom שבוע אחד
פריסה על mainnet 1-2 ימים

מערכת בסיסית על OpenZeppelin Governor מתחילה מ-$15,000. מכניקות מותאמות אישית (חלקית, ריבועית) מוסיפות לעלות. ביקורת אבטחה מוסיפה $10,000-$20,000. העלות הסופית מחושבת באופן אישי לאחר ניתוח דרישות.

מה כלול בעבודה

  • ניתוח דרישות ובחירת סוג הצבעה (פשוטה/חלקית/ריבועית)
  • עיצוב חוזים חכמים של Governor + Vesting
  • פיתוח ב-Solidity באמצעות Foundry
  • כתיבת בדיקות (יחידה, אינטגרציה, fuzzing) עם >90% כיסוי
  • ביקורת אבטחה (אימות פורמלי, fuzzing עם Echidna)
  • אינטגרציה עם Tally או Boardroom עבור ה-UI
  • תיעוד והדרכת צוות

קבלו ייעוץ על הפרויקט שלכם – אנו נעריך לוחות זמנים ועלות תוך 48 שעות. הזמינו ביקורת על מערכת ההצבעות כדי למנוע הפסדים של עד 50% מהאוצר. יש לנו ניסיון של 5+ שנים בבלוקצ'יין וצוות של 15 מהנדסים מוסמכים.