History – Typed vs arbitrary proposal execution
Back1 block modified
- Modified – Text at Block 7
The enumeration is an ABI, so …sting installations” (https://web.archive.org/web/20260713024235/https://docs.aragon.org/osx-contracts/…coding space it does not need.
4 blocks modified
- Modified – Text at Block 1 → Block 1
Topic Whether a passed proposa…ameworks/daohaus) multi-send
—– a proposal carries raw callda…ailure Tornado Cash, May 2023—– a proposal whose code changed…curity-and-governance-attacks) - Modified – Text at Block 3
What arbitrary execution actua…it is work almost nobody does
—– decoding calldata against an …n means changing the contract. - Modified – Text at Block 4
The failure mode: a proposal t…s. When the proposal executed
—– via delegatecall, so in governance's own storage context—– it minted the attacker 1.2 mi…aid and what its calldata did—– the gap that arbitrary execut…no voting parameter can close. - Modified – Text at Block 6
Why typed designs are rarer th…ction vocabulary genuinely is
—– and, if it is narrow, whether…t assumptions can ever become.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …_1cq6jcm9… after 15 September.The 7 September redeploy retun… the method surface unchanged.The only methods to go were tw… naming the long-retired VOTE.Closing the gap took what a ty…an a title they have to trust.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …make. Read on-chain again on
2530 September 2026: the CaperMain… to today ( component_tdx_2_1cr40xf3qma5fh… (https://dashboard.radixscan…o/component/component_tdx_2_1cr40xf3hk3wauqz7pjnvvm067a5hu9ss52wwawdzuz8uxqlj0szvu9) , published bqma5fhxglr6z6s6ym9y73zm4r9lnuzq474ent08xtsplmdufn8npm) , the logic upgrade of 30 September 2026 on the registry the full redeploy of 25 September 2026 published) exposes twenty-one methods a…an a title they have to trust.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …per and the trade fee on sells; the 21 September redeploy added exit_open ( component_tdx_2_1czmc8h0… (https://dashboard.radixscan.io/component/component_tdx_2_1czmc8h097upkzdpptzjz7k00fh8msjtq7m634zd74g7qxyhuxrck0u) ), which records a member's vote-token balance so that exit can only burn tokens that account gave up; and the 25 September redeploy replaced the trade fee with the treasury's share of the skim, with the method surface unchanged. The only methods to go were …grade – and none of the twenty-one is a generic call entry point…an a title they have to trust.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …make. Read on-chain again on
1925 September 2026: the CaperMain…rRegistry ( component_tdx_2_1crf8dl07pndqmgr… (https://dashboard.radixscan…o/component/component_tdx_2_1crf8dl07k744cd0ekefyxf450r93jjwe9ewl6shl4zqr8vngjmnnxgpndqmgr5n6fsf6kausxlyllm4rpuc2zwhn94adws7zegkenqsad8z) ) resolves to today ( component_tdx_2_1czqsy8nr40xf3… (https://dashboard.radixscan…o/component/component_tdx_2_1czqsy8ncz6mcfp43mmnus39kk2l73f8x7wrxjwnzmth93aruhv43pmr40xf3hk3wauqz7pjnvvm067a5hu9ss52wwawdzuz8uxqlj0szvu9) , published by thesecond logic upgradefull redeploy of1925 September 2026) exposes twenty-one methods and one instantiation function; exit_open, added on 21 September, is the twenty-first. From 5 September to the rede…an a title they have to trust.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A … to today ( component_tdx_2_1c
qadjtvzqsy8n… (https://dashboard.radixscan…o/component/component_tdx_2_1cqadjtv57kjsswhzftulwh6cek2yvwsdgddgvv87230z8qmq0wav20zqsy8ncz6mcfp43mmnus39kk2l73f8x7wrxjwnzmth93aruhv43pm) , published by the second logic upgrade of 19 September …an a title they have to trust.
1 block modified
- Modified – Text at Block 5
Narrowing the surface without …lamorous positioning suggests. Agora (/wiki/dao-governance/tooling/voting/agora) 's version shows why the setup matters. Since April 2025 it runs a proposal inside its full governor and timelock context, following ScopeLift's Seatbelt (https://github.com/Uniswap/governance-seatbelt) , because calldata simulated on its own can report success for a call that would fail ( Agora (https://www.agora.xyz/blogs/7-context-failures) ). Its Pretty view, added in March 2026, describes each action in plain language, such as which contract's owner a call sets, but only for function selectors and contract addresses on a curated list; anything else is shown as decoded or raw calldata ( Agora (https://www.agora.xyz/blogs/10-pretty-view-proposal-actions) ). - Procedural checks. DAOhaus…hat the answer is not obvious.
1 block modified
- Modified – Text at Block 5
Narrowing the surface without …pted is enumerated in advance. Aragon (/wiki/dao-governance/tooling/frameworks/aragon) added the same control to its app in August 2025: each governance process can be granted permission to call only chosen functions, each named by a contract address and a function selector, the four bytes at the start of a call that identify which function it invokes, with no change to the target contracts ( Aragon (https://blog.aragon.org/new-in-the-aragon-app-permissions-based-access-control/) ). - A typed fast path. Geo (/wiki/dao-governance/tooling/frameworks/geo) 's second-generation space contracts, specified in October 2025, split the difference by speed. Editors can pass a single action from a short list (adding or removing a member, publishing an edit, flagging or unflagging content) as soon as enough of them vote yes, while anything else, including a change to who the editors are, goes through a slower majority vote that can carry several actions ( Geo (https://github.com/geobrowser/geo-contracts-foundry/blob/dev/docs/2026_03-internal-review/rfcs/2025_10_22-geo-singleton-architecture.md) ). The fast path is typed; the slow path stays general. - Simulation. Front-ends inc…hat the answer is not obvious.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …ake. Read on-chain again on 1
89 September 2026: the CaperMain…Registry ( component_tdx_2_1cr65qc2f8dl07… (https://dashboard.radixscan…/component/component_tdx_2_1cr65qc2r33ky36j49lp3mdee7x45pzewr8dp0q6z2ya57mkajmtch9f8dl07k744cd0ekefyxf450r93jjwe9ewl6shl4zqr8vngjmnnxg) ) resolves to today ( component_tdx_2_1cr3qm57qadjtv… (https://dashboard.radixscan…o/component/component_tdx_2_1cr3qm57h5fld30uq8ufefx60ycfuucyu5m7v4zkl9pwkca6d6g7zggqadjtv57kjsswhzftulwh6cek2yvwsdgddgvv87230z8qmq0wav20) , published by the logic upgrade of 189 September 2026) exposes twenty-twomethods and one instantiation function– the same count as component_tdx_2_1cq6jcm9… after the redeploy of 1. From 5 September to the redeploy of 18 September every component carried twenty-two: component_tdx_2_1czm6lcn… on 5 September, component_tdx_2_1cq64v5twr8psn5… afterthe redeploy of 117 September, component_tdx_2_1cr8psn5q64v5tw… after711 September and component_tdx_2_1czm6lcn… on 5 September. None of those redeploys moved a methodq6jcm9… after 15 September. The 7 Septemberoneredeploy retuned the governance window…nder's skim; the 18 Septemberupgrade changed only the shape of that skim. None added or removredeploy removed the $XRD caper and the trade fee on sells. The only methods to go were two address reads, dao and treasury, dropped by the logic upgrade on the afternoon of 18 September; that upgrade and the one of 19 September 2026 otherwise changed only how the skim is priced and its shape. None added a method. Six of the method…grade – and none of the twenty-twois a generic call entry point…an a title they have to trust.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …ake. Read on-chain again on 1
78 September 2026: the CaperMain… to today ( component_tdx_2_1cq6jcm9r3qm57… (https://dashboard.radixscan…o/component/component_tdx_2_1cq6jcm9hd6uakguta74dvv63qa2p4seap47htt0px8rftecq2wd3nar3qm57h5fld30uq8ufefx60ycfuucyu5m7v4zkl9pwkca6d6g7zgg) , published by theredeploylogic upgrade of 158 September 2026) exposes twent…n function – the same count as component_tdx_2_1cq6jcm9… after the redeploy of 15 September, component_tdx_2_1cq64v5tw… af…e trade fee and the founder's skim; the 18 September upgrade changed only the shape of that skim. None added or removed a …an a title they have to trust.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …ake. Read on-chain again on 1
37 September 2026: the CaperMain the live CaperRegistry (component_tdx_2_1cr7l4u0c…65qc2… (https://dashboard.radixscan.io/component/component_tdx_2_1cr65qc2r33ky36j49lp3mdee7x45pzewr8dp0q6z2ya57mkajmtch9) ) resolves to today (component_tdx_2_1cq64v5tw…jcm9… (https://dashboard.radixscan.io/component/component_tdx_2_1cq6jcm9hd6uakguta74dvv63qa2p4seap47htt0px8rftecq2wd3na) , published by thegenesisredeploy of 115 September 2026) exposes twent…me count as component_tdx_2_1cr8psn5q64v5tw… after the redeploy of 11 September, component_tdx_2_1cr8psn5… after 7 September and component_tdx_2_1czm6lcn… on 5 September. Neitherone of those redeploys moved a method: the first. The 7 September one retuned the governance windows and the price measurement, and the sec; the 11 September onde changed what existing methods…es amounts rather than buckets– without adding or removing one; the 15 September one changed how buys, sells and exits charge the trade fee and the founder's skim. None added or removed a method. Six of the methods are execu…an a title they have to trust.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …make. Read on-chain again on
713 September 2026, after that morning’s redeploy: the CaperMain the registry resolves to today (component_tdx_2_1cr8psn5…, resolved from the CaperRegistry at component_tdx_2_1cqtsx3p… that the site’s own client bundle names) exposes twenty-two methods and one instantiation function, exactly as its predecessor: the CaperMain the live CaperRegistry (component_tdx_2_1cr7l4u0c…) resolves to today (component_tdx_2_1cq64v5tw…, published by the genesis redeploy of 11 September 2026) exposes twenty-two methods and one instantiation function – the same count as component_tdx_2_1cr8psn5… after the redeploy of 7 September and component_tdx_2_1czm6lcn…didon 5 September–. Neither redeploy moved a method: the first retuned the governance windows…nd the price measurement, andmoved no methodthe second changed what existing methods do – exit, for one, now takes amounts rather than buckets – without adding or removing one. Six of the methods are execu…move when the enumeration did: DEBATE, the kind addedthat morningon 5 September 2026, executes nothing, so it neede…an a title they have to trust.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …w how to make. Read on-chain again on
57 September 2026: the live CaperMain component, after that morning’s redeploy: the CaperMain the registry resolves to today (component_tdx_2_1czm6lcnr8psn5…, resolved from the CaperRegi…and one instantiation function, exactly as its predecessor component_tdx_2_1czm6lcn… did on 5 September – the redeploy retuned the governance windows and the price measurement, and moved no method. Six of the methods are execu…an a title they have to trust.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …earing that ballot only opens
a 48-hourthe optimistic market window; the winning action exe…olds at or above the trailingseven-dayaverage lockedwhenat thewindow openedtrigger ( optimistic governance (/wik…an a title they have to trust.
1 block modified
- Modified – Text at Block 8
How Caper approaches this A …he time of writing recognises
exactly fivsix, five of which execute: pay an address from the tre…hat every caper runs (UPGRADE) – plus a sixth that executes nothing at all, DEBATE, a ranked position in an argument that is terminal at the tally. There is no calldata field. …ow to make. Read on-chain on30 August5 September 2026: the live CaperMain component (component_tdx_2_1cpz5lthzm6lcn…, resolved from the CaperRegi…_tdx_2_1cqtsx3p… that the site'’s own client bundle names) exp…thods are executors – one per executable kind, plus the second leg of t…call entry point of any shape. That count is worth stating because it did not move when the enumeration did: the kind added that morning executes nothing, so it needed no executor, and a diff of the method surface would not have shown the change at all. The consequences run both wa…on rule. Its enumeration hasalready narrowed oncenow moved in both directions, which is where the versionin… 1 INVEST, 3 UPGRADE, 4 DIVESTand, 5 METADATA and 6 DEBATE: the gap at 2 was VOTE, an ac…et one caper cast its treasury'’s ballot inside another, and i…d the creation-time whitelistaccepts only– 0 | 1 | 3 | 4 | 5wh| 6 – stilel naminges VOTE in its abort message–, so a proposal built against t…anently unusable discriminant. The widening is the more instructive half, because it puts a price on the ceiling described above. DEBATE was written into the contract source on 30 August 2026 and could not be used for six days. The app half shipped first, so the create-proposal form, the published OpenAPI document (https://caper.network/.well-known/openapi.json) and the MCP tool manifest all advertised a kind the deployed component refused, and a proposer who picked it got an abort naming the long-retired VOTE. Closing the gap took what a typed design always requires and an arbitrary-execution design never does: a newly published logic package and a governed swap of the registry’s current_main, both completed on the morning of 5 September 2026. A Governor (/wiki/dao-governance/tooling/voting/openzeppelin-governor) DAO wanting the same thing – a proposal that is voted on and deliberately executes nothing – expresses it with an empty targets array and deploys nothing. That is the trade in one worked example: legibility bought at the price of a contract release, and a six-day window in which the interface and the ledger disagreed about what a proposal was allowed to say. One thing this page's axis d… a “Do nothing”, at least oneexecutablean answer other than it – and clearing that ballot on…an a title they have to trust.
1 block modified
- Modified – Text at Block 7
The enumeration is an ABI, so …-develop-plugin/upgrade-plugin/) , and updates across release…coding space it does not need.
1 block added, 1 block modified, 1 block reordered
- Moved – Text at Block 8
- Modified – Text at Block 8
How Caper approaches this A …to the same resolution rule. Its enumeration has already narrowed once, which is where the versioning question above stops being hypothetical. The discriminants run 0 PAYOUT, 1 INVEST, 3 UPGRADE, 4 DIVEST and 5 METADATA: the gap at 2 was VOTE, an action that let one caper cast its treasury's ballot inside another, and it died with the escrow voting system it belonged to. The number was retired rather than recycled, and the creation-time whitelist accepts only 0 | 1 | 3 | 4 | 5 while naming VOTE in its abort message – so a proposal built against the old interface fails at creation with a message that says why, instead of decoding into some later kind. That is the loud-and-early handling, chosen at the cost of a permanently unusable discriminant. One thing this page's axis doe…an a title they have to trust.
- Added – Text at Block 7
The enumeration is an ABI, so it has a version The generality trade-off above is the one this axis is usually argued on. There is a second, quieter one that only typed designs face: a fixed set of action kinds is an interface, and interfaces change. Arbitrary calldata has no version to break – a Governor proposal is bytes, and bytes mean whatever the target contract makes of them. A typed proposal is a discriminator plus typed fields, so retiring or renumbering a kind is a breaking change to every client that builds proposals, every indexer that reads them, and every archived proposal that already carries the old number. The dangerous handling is silent reinterpretation. If a removed discriminant is recycled for a new action, a proposal encoded by an old client still decodes cleanly – into the wrong action. Nothing aborts, nothing looks malformed, and the mismatch surfaces only at execution, which is precisely the gap between stated intent and performed action that typing was adopted to close. The safe handling is the opposite: make the stale encoding fail loudly and early, at creation rather than at execution. Frameworks solve this a layer up, at the plugin rather than the action. Aragon OSx (/wiki/dao-governance/tooling/frameworks/aragon) versions each plugin as a release and a build, and its documentation draws the line in exactly these terms: “Releases contain breaking changes, which are incompatible with preexisting installations” (https://docs.aragon.org/osx-contracts/1.x/guide-develop-plugin/upgrade-plugin) , and updates across releases are not possible at all – a DAO must uninstall the old plugin and install the new one, while builds are reserved for compatible upgrades. That is the same instinct expressed as deployment policy: an incompatible interface change is made impossible to apply by accident. The practical question for anyone evaluating a typed DAO is therefore not only how wide its action vocabulary is, but what its enumeration does when it narrows. A design that reuses freed discriminants is trading a legibility guarantee it advertised for a byte of encoding space it does not need.
1 block modified
- Modified – Text at Block 7
How Caper approaches this A …a kind discriminator, and the
contractlogic package live at the time of writing recognises exactly five: pay …r runs (UPGRADE). There is nosixth slot and nocalldata field. A proposal can…ow to make. Read on-chain on2830 August 2026: the live CaperMa… component (component_tdx_2_1cqtt9nzpz5lth…, resolved from the CaperRegistry at component_tdx_2_1cqtsx3p… that the site's own client bundle names) exposeseighteen methods, six of themtwenty-two methods and one instantiation function. Six of the methods are executors – one per kind, plu…nd leg of the upgrade – and none of the twenty-two is a generic call entry point of a… ceiling: adding a kind needsthe state-holding contract's cooperationa new logic package, not merely a passed proposal…e's axis does not anticipate:Ca caperretired ballots in August 2026, so a's proposalihasntolongerbe legible twice, to voters–and thern to the mare none. It resolves on price instead, passing only if the caper's spot price at the close of a 48-hourket. It is a ranked ballot over two to five options – at least one a “Do nothing”, at least one executable – and clearing that ballot only opens a 48-hour optimistic window; the winning action executes if the token's time-weighted price across the windowiholds at or abovea seven-day time-weightedthe trailing seven-day average locked when theproposal was raiswindow opened ( optimistic governance (/w…amily). Typing therefore doesmoreits workhere than in a Governor DAO, not less: with no tally standing between a proposal's title and its payload, the enumeration is the only thing that doeson both readers: a voter ranks options whose payloads the enumeration has already constrained, and a holder who wants to veto one is selling against an action they can read rather than a title they have to trust.
1 block modified
- Modified – Text at Block 7
How Caper approaches this A … component (component_tdx_2_1c
rmlq2fqtt9nz…, resolved from the CaperRegi…n is the only thing that does.
1 block modified
- Modified – Text at Block 7
How Caper approaches this A …(/wiki/governance/proposals)
optioncarries a kind discriminator, …y an address from the treasury (PAYOUT), buy another caper's token (INVEST), sell one back down its curve, cast a vote inside ano(DIVEST), rewrite the mutable metadata of thercaper's own token (METADATA), or—– on the platform's own caper only—– swap the shared logic tier that every caper runs (UPGRADE). There is no sixth slot and n…ot already know how to make. Read on-chain on 28 August 2026: the live CaperMain component (component_tdx_2_1crmlq2f…, resolved from the CaperRegistry that the site's own client bundle names) exposes eighteen methods, six of them executors – one per kind, plus the second leg of the upgrade – and no generic call entry point of any shape. The consequences run both ways…and both are worth stating. Avotreader canreadtell what an optionproposal does from its kind and its ty…, so the Tornado failure mode—– a description that does not match the payload—– has no room to occur. But the…really is a ceiling: adding anewkindrequireneeds the state-holding contract's…peration, not merely a passedvoteproposal. Caper's answer to that is thefifth kind, an upgrade of the sharedUPGRADE kind, which swaps the logic tier, whichand is itself a proposal subject to the samevoting rules. The action vocabulary is fixed, but the process for widening it is inside governance rather than outside it. See executionresolution rule. One thing this page's axis does not anticipate: Caper retired ballots in August 2026, so a proposal is no longer legible to voters – there are none. It resolves on price instead, passing only if the caper's spot price at the close of a 48-hour window is at or above a seven-day time-weighted average locked when the proposal was raised ( optimistic governance (/wiki/dao-governance/execution) for how a winning option is settledconcepts/voting/optimistic-governance) is the wider family). Typing therefore does more work here than in a Governor DAO, not less: with no tally standing between a proposal's title and its payload, the enumeration is the only thing that does.
7 blocks added
- Added – Text at Block 1 → Block 1
Topic Whether a passed proposal may run any call, or only one of a fixed set of actions The arbitrary end OpenZeppelin Governor (/wiki/dao-governance/tooling/voting/openzeppelin-governor) · Compound Governor Bravo · Baal (/wiki/dao-governance/tooling/frameworks/daohaus) multi-send — a proposal carries raw calldata The typed end Enumerated action kinds the contract itself understands; anything outside the enum is not expressible Core trade-off Generality (any future action, no upgrade needed) against legibility (a voter can tell what the proposal does) Mitigations in practice Timelocks (/wiki/dao-governance/concepts/voting/governance-timelocks) · Zodiac Roles (/wiki/dao-governance/tooling/frameworks/zodiac) scoping · simulation before the vote Worked failure Tornado Cash, May 2023 — a proposal whose code changed after it passed Related The proposal lifecycle (/wiki/dao-governance/concepts/voting/proposal-lifecycle) · Governance attacks (/wiki/dao-governance/concepts/analysis/dao-security-and-governance-attacks)
- Added – Text at Block 2
Every DAO framework has to answer one question about its proposals: what is a passed vote allowed to do? There are two families of answer. In an arbitrary-execution design, a proposal carries raw transaction data and the governance contract will execute whatever that data says. In a typed design, a proposal selects from a fixed list of action kinds that the contract itself understands, and nothing outside that list can be expressed at all. This axis is rarely stated explicitly, but it decides more about a DAO's real risk profile than quorum or threshold settings do. It determines whether a voter can know what they are voting for by reading the ballot, and it is the axis on which the most expensive governance failures (/wiki/dao-governance/concepts/analysis/dao-security-and-governance-attacks) turn.
- Added – Text at Block 3
What arbitrary execution actually looks like The dominant Ethereum pattern is arbitrary. OpenZeppelin's Governor (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/governance/Governor.sol) declares its entry point as propose(address[] targets, uint256[] values, bytes[] calldatas, string description). The first three arrays are the proposal; the fourth argument, the human-readable description, is the only part a voter reads and the only part the contract does not enforce. Compound's Governor Bravo (https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/GovernorBravoDelegate.sol) takes the same shape with an extra signatures array and caps a proposal at ten actions (proposalMaxOperations = 10). Nothing in either contract relates the description to the calldata. A proposal titled “Fund the grants program for Q3” and a proposal that drains the treasury are, to the governance contract, the same kind of object: a list of addresses, values and byte strings. Verifying that the two agree is off-chain social work, and it is work almost nobody does — decoding calldata against an unverified target contract is a skill most delegates do not have and most voters do not attempt. The upside is real and is why the pattern won. An arbitrary-execution DAO can do things its designers never anticipated: call a protocol that did not exist when the governance contract shipped, adopt a new standard, or wind itself down. A typed DAO can only ever do what its enumeration allows, and widening the enumeration means changing the contract.
- Added – Text at Block 4
The failure mode: a proposal that changed after it passed In May 2023 Tornado Cash lost governance control of itself to a proposal that looked like an earlier, legitimate one. Per Halborn's analysis (https://www.halborn.com/blog/post/explained-the-tornado-cash-hack-may-2023) , the attacker submitted a proposal that claimed to implement the same logic as a previously approved proposal, but whose deployed contract carried extra self-destruct logic. Voters, comparing it to the version they already trusted, passed it. The attacker then destroyed the proposal contract and redeployed different code at the same address. When the proposal executed — via delegatecall, so in governance's own storage context — it minted the attacker 1.2 million votes against roughly 70,000 legitimate ones, and about 483,000 TORN (~$2.17 million) was drained. The instructive part is not the self-destruct trick. It is that every governance rule worked correctly. Quorum was met, the vote was honest, the timelock elapsed, and the contract executed exactly the bytes it was given. The failure was entirely in the gap between what the proposal said and what its calldata did — the gap that arbitrary execution creates by design and that no voting parameter can close.
- Added – Text at Block 5
Narrowing the surface without giving up generality Most of the tooling built around Governor over the past few years is, read charitably, an attempt to recover legibility that arbitrary execution gave away. - Timelocks (/wiki/dao-governance/concepts/voting/governance-timelocks) do not make a proposal legible; they buy time for someone else to notice. They convert an execution problem into a monitoring problem, which is an improvement only if somebody is monitoring. - Scoped permissions. Zodiac's Roles Modifier (/wiki/dao-governance/tooling/frameworks/zodiac) sits between a module and a Safe (/wiki/dao-governance/tooling/treasury/safe) and, in its own description (https://github.com/gnosisguild/zodiac-modifier-roles) , lets holders of a role “unilaterally make calls to any approved addresses, approved functions, and using approved parameters.” That is typing applied at the permission layer rather than the proposal layer: the calldata stays arbitrary, but the set of calls that will be accepted is enumerated in advance. - Simulation. Front-ends increasingly simulate a proposal's calls against forked state and show the resulting balance changes. This is the closest thing to making calldata readable, and it is why proposal tooling and governance data (/wiki/dao-governance/tooling/analytics/boardroom) services matter more than their unglamorous positioning suggests. - Procedural checks. DAOhaus's published vote-decision flow (https://github.com/HausDAO/moloch-skills/blob/main/VOTE_DECISION_FLOW.md) for autonomous agent members is the clearest written statement of the problem: it classifies every proposal into one of six buckets, of which the last is plainly “arbitrary execution”, and requires the agent to ask “does action data match proposal text?” before voting. When a procedure has to name that question explicitly, the design has already conceded that the answer is not obvious.
- Added – Text at Block 6
Why typed designs are rarer than they should be Typing a proposal system has an obvious cost: the enumeration is a ceiling. Adding a genuinely new action means changing the contract that holds the state, which is exactly the kind of change a DAO is slowest at making and most reluctant to authorise. Frameworks that expect to serve arbitrary future protocols therefore default to arbitrary calldata, and the burden of understanding a proposal shifts to the voter. The counter-argument is that most DAOs do not need generality. A treasury that in practice only pays contributors, buys assets, sells assets and votes in other organizations has a small action vocabulary, and paying for unlimited expressiveness it never uses buys nothing but attack surface. The right question is not “which design is safer” but how wide the DAO's action vocabulary genuinely is — and, if it is narrow, whether the framework will let it say so on-chain. Most will not. This is one of the places where framework choice, made once and early, quietly sets a ceiling on how minimal (/wiki/dao-governance/concepts/fundamentals/governance-minimization) a DAO's trust assumptions can ever become.
- Added – Text at Block 7
How Caper approaches this A caper (/wiki/foundations/what-is-a-caper) sits at the typed end, and deliberately. An executive proposal (/wiki/governance/proposals) option carries a kind discriminator, and the contract recognises exactly five: pay an address from the treasury, buy another caper's token, sell one back down its curve, cast a vote inside another caper, or — on the platform's own caper only — swap the shared logic every caper runs. There is no sixth slot and no calldata field. A proposal cannot encode a call the contract does not already know how to make. The consequences run both ways, and both are worth stating. A voter can read what an option does from its kind and its typed fields, so the Tornado failure mode — a description that does not match the payload — has no room to occur. But the enumeration really is a ceiling: adding a new kind requires the state-holding contract's cooperation, not merely a passed vote. Caper's answer to that is the fifth kind, an upgrade of the shared logic tier, which is itself a proposal subject to the same voting rules. The action vocabulary is fixed, but the process for widening it is inside governance rather than outside it. See execution (/wiki/governance/execution) for how a winning option is settled.