BERT is an upgradeable, multi-contract protocol with explicit treasury accounting, role-gated state transitions, and milestone-based payout release. Its security model must therefore cover not only typical smart contract bugs, but also role misuse, dependency miswiring, treasury accounting failures, and operational errors during upgrades and live maintenance.
- Security Goals
- Threat Model
- Trust Assumptions
- Primary Attack Surfaces
- Access Control Risks
- Treasury and Capital Risks
- Voting and Round Risks
- Proposal Registry Risks
- Milestone Review Risks
- Upgradeability Risks
- Configuration Risks
- Operational Security Controls
- Incident Response Checklist
- Residual Risks
BERT aims to preserve the following properties:
- proposal metadata cannot be arbitrarily rewritten by unauthorized actors
- round outcomes cannot be altered after valid resolution
- capital cannot be released twice
- author stake cannot bypass configured intake rules
- reserve accounting remains separate from live distributable balances
- a losing pledge cannot be redirected to an unrelated winning proposal
- a round fee cannot become reserve revenue before a winning author starts the grant
- elevated user roles cannot be self-assigned by arbitrary wallets
- upgrades cannot silently corrupt storage or break dependency wiring
The protocol must defend against:
- unauthorized writes to idea, round, treasury, or payout state
- duplicate grant release
- incorrect role assignments
- dependency misconfiguration between upgradeable modules
- malicious or careless admin actions
- griefing and spam through cheap proposal or voting flows
- reviewer abuse during milestone approval
- accounting drift between token balances and internal pool state
- broken upgrades that preserve admin control but corrupt storage layout
- a malicious or incorrectly approved Community Factory routing reserve from an arbitrary Treasury
- a non-standard ERC-20 attempting callbacks during stake intake, payout, or refund
The protocol does not assume a fully trustless governance environment today. Admin authority, role assignment, and reviewer behavior remain meaningful trust boundaries.
Admins are trusted to:
- assign correct system roles
- configure correct dependency addresses
- manage pause and unpause responsibly
- perform upgrades with storage-safe implementations
- avoid malicious reserve allocation or dependency replacement
Admin compromise is one of the highest-severity scenarios in the system.
Core modules trust each other through configured addresses and role assignments. Incorrect wiring can break valid flows even when the contract code itself is correct.
FundingPoolUpgradeable maintains an explicit allowlist of Community Factories
for protocol-reserve intake. The protocol Admin is trusted to add only reviewed
Factory deployments and to revoke only after considering outstanding Community
flows. V3.0 and V3.1 Factories may be approved concurrently; replacing the
legacy Factory pointer is not an authorization migration strategy.
Curators and reviewers are not arbitrary users; they are earned-role or admin-granted actors. Even so, they remain a trust boundary because:
- curators can mark ideas as low quality
- reviewers can influence milestone release timing and success
- role registry and cross-contract authorization
- upgrade and dependency rewiring operations
- author bond intake and slashing logic
- per-round pledge, refund, and fee-escrow accounting
- milestone proof approval and rejection flow
- reserve allocation, fee finalization, and distribution logic
- admin-owned configuration parameters
- V3.1 Factory/Treasury/module activation and capability binding
- non-standard ERC-20 behavior at every transfer boundary
Critical system roles include:
VOTING_ROLEGRANT_ROLEDISTRIBUTOR_ROLEIREGISTRY_ROLEREPUTATION_MANAGER_ROLEAUTO_GRANT_ROLE
If misassigned, these can allow:
- unauthorized status changes
- unauthorized distributions
- unauthorized reputation mutations
- unauthorized user role grants
Critical user roles include:
CURATOR_ROLEREVIEWER_ROLE
If granted too broadly or without monitoring, these can allow:
- griefing through low-quality marking
- biased or low-quality milestone reviews
- social capture of protocol moderation surfaces
- only grant system roles to protocol contracts
- keep admin authority in a multisig for any serious environment
- verify role wiring after every deployment and upgrade
- maintain a human-readable role assignment ledger
BERT distinguishes:
- direct treasury deposits
- author submission bonds
- round and idea pledge capital
- pending successful-round fee escrow
- protocol reserve
- released grant payouts
Any bug or misconfiguration that merges these buckets incorrectly can distort:
- payout eligibility
- reserve accounting
- slashing behavior
- donor pool visibility
Grant manager payout flags and funding pool distribution state must prevent:
- repeated initial grant claim
- repeated milestone payout
- repeated reserve allocation for the same intended effect
- a losing pledge becoming grant capital for an idea the pledger did not select
- a cancelled winner's pending fee remaining in reserve
protocolReserve is intentionally separate from live round balances and refundable pledge liabilities. Admin or code errors that treat reserve like ordinary distributable liquidity can violate treasury expectations.
Internal accounting and actual token balances can drift if:
- external calls fail in unexpected ways
- deployment wiring points to the wrong token
- upgrades mutate accounting paths incorrectly
Mitigation:
- post-upgrade and post-incident reconciliation
- explicit pool balance validation
- controlled use of reserve allocation and pool reconciliation functions
Only an active Treasury recognised by an approved Community Factory may call
receiveCommunityReserve. The Factory list is bounded to keep the authorization
lookup predictable. Testers must attempt reserve routing from an arbitrary
Treasury, an inactive Treasury, and a Treasury belonging to a revoked Factory.
They must also confirm that approving V3.1 leaves V3.0 routing functional.
Rounds are built from the global idea sequence using lastUsedIdeaId. Bugs here can:
- reuse ideas
- skip ideas
- create malformed rounds
Voting is capital-backed. Risks include:
- wrong minimum stake configuration
- disabled or weak verified-human gating
- weak single-vote cap tuning
- wrong USDC token address
- faulty accounting for
recordPledgeFrom - duplicate or misattributed idea membership
- a funding target or fee policy that makes ordinary proposals systematically non-viable
When a round ends, the protocol updates:
- winning and losing idea status
- reputation changes
- winning vote registration
It also settles escrow policy: losing pledges become refundable, a no-winner round refunds all pledges, and a viable winner's fee stays pending until author claim. Any inconsistency between these outcome and accounting paths is security-relevant.
This is a multi-side-effect step. Partial failure handling and dependency correctness matter because a broken outcome propagation can create inconsistent social or lifecycle state even if the round result itself is known.
The author stake requirement exists to raise the cost of low-signal proposals. If authorMinStake is misconfigured too low, spam pressure rises. If set too high, legitimate participation becomes too expensive.
Curators can mark ideas as low quality. This introduces:
- abuse risk by biased actors
- coordination risk if user role thresholds are too easy to satisfy
Rejected ideas can have their author bond moved into reserve. Incorrect status checks or wrong registry-to-pool wiring can cause:
- unslashed rejected stake
- slash attempts on non-rejected ideas
- reserve inflation or accounting mismatch
Milestone release depends on reviewer approvals. A captured reviewer set could:
- approve weak proof too early
- delay legitimate execution through coordinated rejection
The protocol must ensure a single reviewer cannot count multiple times in the same active milestone request.
Rejected milestone requests record lastRejectedAt. If cooldown logic is bypassed or broken:
- authors can spam reviewer bandwidth
- repeated low-quality proof can flood the review surface
The protocol must prevent:
- completion payout before in-process payout
- milestone release before initial grant claim
- payout after already-settled stage state
All upgradeable modules must preserve storage layout compatibility. The main hazards are:
- reordering existing variables
- removing variables in inherited storage chains
- inserting new variables in the middle of storage
- changing inheritance order
An upgrade that changes storage safely can still break the protocol if it changes or forgets:
- funding pool address
- idea registry address
- role registry address
- reputation system address
- voter progression address
The V3.1 deployment requires an append-only FundingPool upgrade and a one-time
initializer that seeds the historical Factory into the allowlist. The migration
must run while the V2 operational modules are paused. Before authorizing V3.1,
operators must snapshot totalPoolBalance, protocolReserve, legacy Factory
approval, and the configured USDC address; each value must match after the
migration.
Wrong proxy or wrong admin usage can:
- block upgrades
- apply upgrades to the wrong target
- create operator confusion about which implementation is live
Critical parameters include:
IDEAS_PER_ROUNDVOTING_DURATIONminStakeauthorMinStake- proposal-level
minimumNetFunding pledgeFeeBps
Configuration mistakes can cause:
- impossible round creation
- spammy or economically weak voting
- excessive author friction
- proposals that cannot become viable
- unfair or unintended fee/refund behavior
Security posture is not only contract correctness. It also depends on operator discipline around parameter changes.
Recommended controls:
- use a dedicated admin signer or multisig
- keep deployment logs with proxy, implementation, and role assignment data
- verify role wiring after deploy and after each upgrade
- record parameter baselines and changes
- monitor pause status for
FundingPoolUpgradeable,VotingSystemUpgradeable, andGrantManagerUpgradeable - monitor role change events in
RolesRegistryUpgradeable - monitor large treasury inflows and outflows
- monitor unclaimed-grant, expired-grant, and pledge-refund events
- rehearse every upgrade on localhost and Sepolia before live execution
- determine whether the issue is:
- access control
- treasury accounting
- round resolution
- milestone release
- upgrade misconfiguration
- pause affected modules if live loss or state corruption is plausible
- preserve addresses, tx hashes, and current configuration state
- verify dependency wiring and role assignments
- verify storage-safe remediation path
- patch or upgrade the affected module
- validate state consistency before unpausing
- document the root cause and corrective controls
BERT still has residual risks that should be treated honestly:
- admin centralization remains a major trust boundary
- reviewer quality is a social and governance risk, not only a code risk
- role-based moderation can be captured if progression policy is weak
- wrong deployment wiring can break flows even with correct code
- upgrade safety depends on disciplined operator behavior
Security therefore depends on both:
- contract-level correctness
- operational maturity