SPP Plugin Compatibility
In the StagedProposalProcessor (SPP), each “body” within a stage can be configured as either automatic or manual. Automatic bodies simplify the user experience by having the SPP create sub-proposals on their behalf, while manual bodies require external intervention. Understanding how to set up and operate both types of bodies ensures smooth integration with the SPP.
Automatic vs. Manual Bodies
-
Automatic Bodies: If
isManualis set tofalsein the stage configuration, the SPP will automatically create sub-proposals on these bodies whenever a proposal enters their stage. This approach reduces the operational overhead, making governance processes more seamless. To qualify as an automatic body:-
The plugin must meet the compatibility requirements detailed below.
-
The SPP must have the necessary permission to call
createProposalon the body.
-
-
Manual Bodies: If
isManualis set totrue, you must create and manage sub-proposals externally. In this case, the body is responsible for callingreportProposalResulton the SPP to register approvals or vetoes. While this offers flexibility—useful if the body’s contract does not support the required interfaces—it can be more labor-intensive.
Requirements for Automatic Bodies
A plugin that fully integrates with the SPP as an automatic body must implement the IProposal interface and support ERC165. You can simplify this by inheriting from the Proposal or ProposalUpgradeable abstract contracts provided by Aragon, which handle ERC165 requirements automatically.
Key Functions:
createProposal
Automatic bodies must implement createProposal to accept parameters from the SPP:
-
_startDate/_endDate: The time window for the sub-proposal. For a voting plugin, this defines the voting period. -
_data: Custom parameters for scenarios where default inputs are insufficient. To support these, implementcustomProposalParamsABIto declare the expected parameters, for example:
function customProposalParamsABI() external pure override returns (string memory) {
return "(uint256 allowFailureMap, uint8 voteOption, bool tryEarlyExecution)";
}
|
Do not add custom conditional logic in |
hasSucceeded
The SPP calls hasSucceeded to determine if a sub-proposal has met its success criteria without triggering execution.
This should return true if the sub-proposal passed at any point. Avoid time-based logic here — once true, it should
remain true, reflecting that the sub-proposal succeeded during its designated window, regardless of when SPP checks it.
|
If |
Manual Body Best Practices
For manual bodies, the SPP does not create sub-proposals automatically. Instead, you must manually call reportProposalResult on the SPP to inform it of approval or veto outcomes. This might involve creating external transactions or leveraging another governance process to signal results.
Example Using a Safe:
-
Add the Safe’s address as a body with
isManual = true. -
After creating a proposal in the SPP, note its
proposalIdand initiate a transaction on the Safe, where:-
to: SPP’s address
-
data:
abi.encodeCall(StagedProposalProcessor.reportProposalResult, (proposalId, stageId, resultType, tryAdvance))-
resultTypecan beApprovalorVeto. -
stageIdmust correspond to the stage where this body is registered. We require bodies to pass this explicitly as there could be the same body added in multiple stages. IfstageIdis passed in which this body has not been added, the resultType will not be used in SPP’s decision making process to advance(i.e it will have no effect other than for you, spending gas in vain). -
tryAdvanceif you know the result is enough to advance the proposal and body also hasADVANCE_PERMISSION_ID, this can betruewhich will automatically advance the proposal to the next stage.
-
-
-
Once the transaction is executed, the SPP records the result. Ensure this transaction occurs before the
maxAdvancetime of the relevant stage.
|
If you are creating a new contract to act as a body, consider implementing |