Skip to content

fix(coredaos): defer MsgVetoProposal deposit/vote cleanup to EndBlocker - #365

Open
giunatale wants to merge 6 commits into
mainfrom
fix/coredaos-veto-gas-exhaustion
Open

fix(coredaos): defer MsgVetoProposal deposit/vote cleanup to EndBlocker#365
giunatale wants to merge 6 commits into
mainfrom
fix/coredaos-veto-gas-exhaustion

Conversation

@giunatale

Copy link
Copy Markdown
Collaborator

The x/coredaos MsgVetoProposal refunded/burned every deposit and deleted every vote of the target proposal inline, inside the message handler. That handler runs under the metered transaction gas meter, which is itself bounded by block.max_gas. Both loops are unbounded and scale linearly with the number of depositors and votes, quantities anyone can inflate during the voting period.

Once the cumulative cost exceeds block.max_gas (100,000,000 on mainnet), no veto transaction for that proposal can be included in any block, and the Oversight DAO's constitutional veto becomes permanently unavailable for it.

Fix

x/gov's EndBlocker (which already performs exactly these deletions for rejected proposals under the infinite block gas meter) lives in the AtomOne-SDK, so deferring there would be a two-repo change. Moreover, while the fix affect proposals, it's related to behavior implemented in the x/coredaos module. For these reasons the fix stays entirely within x/coredaos:

  • VetoProposal is now O(1): it marks the proposal Vetoed, resets the tally,
    ends voting immediately, removes the proposal from the gov active queue (so
    gov never tallies or executes it), and enqueues its id for cleanup.
  • A new module EndBlocker drains that queue, performing the (potentially
    unbounded) deposit refund/burn and vote deletion. EndBlock runs under the
    infinite block gas meter, exactly like gov's own cleanup of rejected
    proposals, so it can never be priced out of a block.

Comment thread x/coredaos/keeper/abci.go
Comment thread x/coredaos/keeper/abci.go Outdated
Comment thread x/coredaos/keeper/abci.go Outdated
The veto's deposit/vote cleanup is deferred to the coredaos EndBlocker. Because
gov's EndBlocker ran first, its quorum check (QuorumCheckQueue) could still
observe a vetoed proposal's votes, pass quorum, and re-insert the proposal into
the ActiveProposalsQueue, resurrecting it.

Order the coredaos EndBlocker before gov's so the vetoed proposal's votes are
deleted before the quorum check runs. Add a guard test for the ordering and
document the requirement on the EndBlocker.
The previous implementation collected the ids first because the cleanup was
assumed to be unsafe while walking the queue. That premise is wrong: the SDK
collections walk tolerates removing the current key mid-iteration, exactly as
x/gov's own EndBlocker does for its queues. Remove the proposal inline and drop
the collect-then-delete indirection.
Returning an error from EndBlock halts the chain. The deferred veto cleanup is
best-effort, so run each proposal's cleanup in a cached context: commit on
success, and on failure log and leave the entry queued to be retried on the next
block instead of aborting the block.
@giunatale
giunatale force-pushed the fix/coredaos-veto-gas-exhaustion branch from 89c5f93 to 50c6e14 Compare August 26, 2026 15:35

@julienrbrt julienrbrt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants