There are two different approaches:

Each has it pros and cons.

DecisionEngine as a multisig owner. This means that we can use a vanilla multsig, with no customizations. This is good for security (no custom code) and also for UX (one can continue to use concepts such as approval and execution familiar to multisig users, and also use gnosis safe UI). The drawback here is lack of flexibility: this gives us just one, limited, security model.

Decision Engine interfaces with Safe via a Gnosis Safe Module. This is the most flexible approach. For example, to implement the "fast-track plus veto" pattern, or a timelock, we should be using this.

Execution Flow

Typical flow for DAOs decisions a propose-vote-queue-execute pattern (where the "queue" step is sometimes skipped).

This maps as follows between the Compound API to the Gnosis Safe API

If the decision Engine is a multsig owner

Gnosis Safe support different styles of transaction approval, both on-chain and off-chain.

  1. After a Proposal has Succeeded in the decision engine, it is ready to be approved.

  2. Approval is done by calling the queue(proposalId) on the Decision Engine contract. This function does the following:

    a. The decision engine encodes the cascade of transactions associated with the proposal, and calculated the transactionHash of the proposal using GnosisSafe.calculateTransactionhash()

    b. The decision engine calls approveHash(transactionHash) f

    DecisionEngine01.sol has an implementation (still needs work!)

  3. After the proposal is approved by the enough other multisig signers, the transaction can be executed. With the approval of enough signers, anyone can call the execute method on the Safe. Transaction approvals can be either signed on-chain (using approveHash, as in the step abouve), or be signed off-chain and submitted as an argument to the execute method.

Special case is when the decision engine is the only owner of the safe. In that case, the queue/approveHash step can be skipped and the transaction can be executed directly.

Question: what type of execution should be supported by the Decision engine here? What is a natural UX flow for adding off-chain transactions?

If the decision engine is a module

TODO: work out some specific patterns here