Coder Social home page Coder Social logo

gnosisguild / zodiac-module-reality Goto Github PK

View Code? Open in Web Editor NEW
101.0 10.0 52.0 1.36 MB

A Zodiac module that uses Reality.eth as an oracle for triggering execution on a Safe.

License: GNU Lesser General Public License v3.0

Solidity 17.20% TypeScript 82.04% Shell 0.22% JavaScript 0.53%

zodiac-module-reality's Introduction

Zodiac Reality Module

Build Status Coverage Status Contributor Covenant

The Reality Module belongs to the Zodiac collection of tools, which can be accessed through the Zodiac App available on Gnosis Safe, as well as in this repository.

If you have any questions about Zodiac, join the Gnosis Guild Discord. Follow @GnosisGuild on Twitter for updates.

About the Reality Module

This module allows on-chain execution based on the outcome of events reported by Reality.eth. While built initially to execute Gnosis Safe transactions according to Snapshot proposals, this module is framework agnostic. It can enable proposal execution from just about anywhere. For example, it can bring Discord polls on-chain.

This module allows for execution of transactions that have been approved through a Reality.eth question for execution. The question asked on Reality.eth consists of a proposal ID (e.g. an IPFS hash), which can be used to provide more information for the transaction to be executed, as well as an array of EIP-712-based transaction hashes that represent the transactions that should be executed.

These two components (proposalId and txHashes) uniquely identify a question on the module. While it is possible to ask the same question with different Reality.eth question parameters, it is only possible to execute transactions related to a specific question once.

Once the question on Reality.eth has resolved to "yes", meaning that the transactions should be executed, they are submitted to the immutable executor defined in the module. Transactions defined in questions that resolve to "no" or "invalid" cannot be executed by the module.

This module is intended to be used with Gnosis Safe, but it is ultimately framework agnostic.

Setup Guides

This module can be setup either using the Zodiac App's UI or by using command line tools; both methods allow for connecting to Snapshot.

View docs for using the Zodiac App

View docs for using the command line

Features

  • Submit proposals uniquely identified by a proposalId and an array of txHashes, to create a Reality.eth question that validates the execution of the connected transactions.
  • Proposals can be marked invalid by the executor using markProposalInvalid, thereby preventing the execution of the transactions related to that proposal.
  • The Reality.eth question parameters (templateId, timeout, arbitrator) can be set on the module by the executor.
  • A minimum bond can be set, which is the amount required to be staked on a Reality.eth answer before the transactions can be executed.
  • A cooldown can be specified representing the minimum amount of time required to pass after the Reality.eth question has been answered before the transactions can be executed.

Flow

  • Create question on Reality.eth via the addProposal method of this module.
  • The question needs to be answered on Reality.eth with yes (1) to approve it for execution.
  • Once the question has a result and the cooldown period has passed, the transaction(s) can be executed via executeProposal.

Definitions

Transaction nonce or index

The nonce of a transaction makes it possible to have two transactions with the same to, value and data but still generate a different transaction hash. This is important as all hashes in the txHashes array should be unique. To make sure that this is the case, the module will always use the index of the transaction hash inside the txHashes array as a nonce. So the first transaction to be executed has the nonce with the value 0, the second with the value 1, and so on.

Therefore we can simplify it to the following statement: The nonce of a Reality Module transaction is equal to the index of that transaction's hash in the txHashes array.

Proposal nonce

There is a chance that a question is marked invalid on the oracle (e.g. if it is asked too early). In this case it should be possible to ask the question again, and we need to be able to generate a new question ID. For this it is possible to provide the next higher nonce compared to the last invalidated proposal. So in case the first proposal (with the default nonce of 0) was marked invalid on the oracle, a new proposal can be submitted with the nonce of 1.

Oracle / Reality.eth

The Reality Module depends on an oracle to determine if a proposal was expected and deemed valid. The following assumptions are being made:

  • The oracle MUST implement the Reality.eth contract interface.
  • It MUST not be possible to ask the same question with the same parameters again.
  • Once a result is known and finalized for a question, it MUST not change.
  • The oracle MUST use the same question ID generation algorithm as this module.

The reference oracle implementations are the Reality.eth contracts. These can be found on:

Failed transactions

The Reality Modules requires proposal transactions are successful (e.g. transactions should not internally revert for any reason). If any of the transactions of a proposal fail, it will not be possible to continue with the execution of the following transactions. This is to prevent subsequent transactions being executed in a scenario in which earlier transactions failed due to the gas limit being too low or due to other errors.

Transactions that failed will not be marked as executed, and therefore, they can be executed at any later point in time. This is a potential risk, and therefore it is recommended to either set an answer expiration time or invalidate the proposal (e.g. via another proposal).

Answer expiration

The Reality Module can be configured so that positive answers will expire after a certain time. This can be done by calling setAnswerExpiration with a duration in seconds. If the transactions related to the proposal are not executed before the answer expires, it will not be possible to execute them. This is useful in the case of transactions that revert and therefore cannot be executed in order to prevent them from being unexpectedly executed in the future. Negative answers (no or invalid) cannot expire.

Note: If the expiration time is set to 0, answers will never expire. This also means answers that expired before will become available again. To prevent this, it is recommended to call markProposalWithExpiredAnswerAsInvalid immediately after any proposal expires (or on all outstanding expired answers prior to setting the expiration date to 0). This will mark a proposal with an expired answer as invalid. This method can be called by anyone.

EIP-712 details

EIP-712 is used to generate the hashes for the transactions to be executed. The following EIP-712 domain and types are used.

Domain

{
  EIP712Domain: [
    { type: "uint256", name: "chainId" },
    { type: "address", name: "verifyingContract" }
  ]
}

TransactionType

{
  Transaction: [
    { type: "address", name: "to" },
    { type: "uint256", name: "value" },
    { type: "bytes", name: "data" },
    { type: "uint8", name: "operation" },
    { type: "uint256", name: "nonce" }
  ]
}

Solidity Compiler

The contracts have been developed with Solidity 0.8.0 in mind. This version of Solidity made all arithmetic checked by default, therefore eliminating the need for explicit overflow or underflow (or other arithmetic) checks.

Audits

An audit has been performed by the G0 group.

No issues have been discovered.

The audit results are available as a pdf in this repo or on the g0-group repo.

Security and Liability

All contracts are WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

zodiac-module-reality's People

Contributors

alirun avatar asgeir-s avatar auryn-macmillan avatar bonustrack avatar carlosfebres avatar cbrzn avatar edmundedgar avatar fedgiac avatar fnanni-0 avatar github-actions[bot] avatar jfschwarz avatar juliopavila avatar keikreutler avatar metrox-eth avatar rmeissner avatar samepant avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zodiac-module-reality's Issues

Fix plugin configuration in setup guide

Apparently the way to configure the SafeSnap plugin in SnapShot has changed, so that the in setup guide is outdated. As a consequence this exemplary configuration file is not up-to-date.

In this section "daoModule" needs to be replaced with "safeSnap":

  "plugins": {
    "daoModule": {
      "address": "0x6c57cEa2dE7D386d349Ff6c4E8631bD567DFd0fC"
    }
  }

This should be:

  "plugins": {
    "safeSnap": {
      "address": "0x6c57cEa2dE7D386d349Ff6c4E8631bD567DFd0fC"
    }
  }

Emit events in setter functions

Add Gnosis Safe Fallback Handler for minimal arbitration support

Currently the DAO module uses the connected DAO (normally a Safe) as the arbitrator. The Realitio interface expects the arbitrator to expose some information via on-chain function calls. A fallback handler should be provided that can be set on the DAO safe to return this required information.

Required methods:

Reality.eth Template Builder UI link is broken.

Describe the bug
Reality.eth Template Builder UI link points to a page that 404s, and looks like it was from github pages.

To Reproduce
Steps to reproduce the behavior:

  1. Go to The zodiac-module-reality github page
  2. Scroll down to the line in the readme.md doc that reads:

You can also create your template using the Reality.eth Template Builder UI. For more info on using it, use this guide.

  1. Click on the link that reads "use this guide"
  2. See a 404 page at https://gnosis.github.io/zodiac/docs/tutorial-module-reality/add-template#template-builder

Expected behavior
Should lead to a page with information on how to use the template builder

Screenshots / logs
image

Handle a file for --template, or validate the input

We've had a couple of people showing up in the reality.eth discord saying their templates didn't work, it turned out they'd put the name of a file containing the template, when in fact they need the contents of the template.

I feel like the principle of least astonishment here would say to do what those people have expected, use the name of a file and automatically read the file in.

Failing that it might be good to at least put in some validation that the string we're using as a template looks like JSON. This is complicated by the fact that the templates only need to make valid json once the parameters are substituted in so attempting to parse it and erroring out if it fails might error our when it shouldn't. It might be best just to do a crude check for that it begins with "{" and ends with "}", that should catch most of the mistakes.

`executeProposal` failure for multi-tx proposal

Here's the pull you requested @rmeissner, let me know what else is needed. In the meantime I'll try another proposal that does a single tx vs a multi.

Failing to execute proposal:

$ cat bridge_proposal_3.json
{
    "id": "irFNzGV0BPfAdAA4lH68mLuZXHgJ4_wJADsMPTw2PtM",
    "txs": [
        {
            "to": "0x9AD2Bc9435D41Cc6f55a681552071C2EabDB2b31",
            "value": "1",
            "data": "0x",
            "operation": 0
        },
        {
            "to": "0x140E42Ff76591Bf20675952Cc1B15774F75707c0",
            "value": "2",
            "data": "0x",
            "operation": 0
        }
    ]
}

Etherescan says the tx succeeded but my account balances are unchanged and the CLI says it failed.

$ /Users/wjm/repos/dao-module/node_modules/.bin/hardhat --network rinkeby executeProposal --module 0xD0A9A4cd312E046642341b70221358095C9c0cCE --proposal-file bridge_proposal_3.json
Transaction: 0xed4742f4e3074ba0243af1b240f2e352bc294cb54cc69a0aa4eb388db37232e3
An unexpected error occurred:

Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"name":"ProviderError","code":3,"data":"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002550726576696f7573207472616e73616374696f6e206e6f7420657865637574656420796574000000000000000000000000000000000000000000000000000000"}, method="estimateGas", transaction={"from":"0x140E42Ff76591Bf20675952Cc1B15774F75707c0","to":"0xD0A9A4cd312E046642341b70221358095C9c0cCE","data":"0x14604b8c00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000140e42ff76591bf20675952cc1b15774f75707c0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002b6972464e7a47563042506641644141346c4836386d4c755a5848674a345f774a4144734d5054773250744d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026e1ce05a50d11be25515bc4b7e62d4ad5022af39bda9f325bcae16c15200c857f0a7086b4ffaf456a6af8e948c704399b2e291609c3cd4830038d00d829cfd380000000000000000000000000000000000000000000000000000000000000000"}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.0.23)

If SAFE/DAO/etc addresses are needed:

$ cat details.rinkeby
SAFE_ADDRESS='0x842f93D83095f1cF09e8C8dd87a69A8DB3d47cdF'
DAO_ADDRESS='0x842f93D83095f1cF09e8C8dd87a69A8DB3d47cdF'
TEMPLATE_ID='0x000000000000000000000000000000000000000000000000000000000000003a'
ORACLE_ADDRESS='0x3D00D77ee771405628a4bA4913175EcC095538da'
MODULE_ADDRESS='0xD0A9A4cd312E046642341b70221358095C9c0cCE'

addProposal() should return questionId

In order to make testing and integrating with other contracts easier, addProposal() and addProposalWithNonce() should return the questionId of the question Reality.eth question.

Strict proposal enforcements

Motivation

Certain proposals require all function calls are executed within one transaction to achieve atomicity. This is currently achievable by using a wrapper contract, but it is not currently enforced on a proposal at the module level.

Another desired enforcement is that of call vs. delegateCall. The effect of a proposal can differ with different operations. Once a proposal passes, there is nothing dictating which of the two can be used to execute a proposal.

Solution

  • Add a way of tracking whether atomic execution is enforced on a given proposal
  • Add a function to call all transactions within a proposal (will require using ABIEncoderV2)
  • Add a variable to set whether call or delegateCall should be used to execute a proposal.

I have been playing with this on my fork and am happy to do the changes properly, but I was informed that the main repo is not yet configured for external contributions, so I won't push forward with PR-ready changes just yet.

Emit an event when a proposal has completed its lifecycle

Is your feature request related to a problem? Please describe.
It's hard to know when a proposal has completed its lifecycle.

Describe the solution you'd like
Emit an event when a proposal is marked as invalid.
Emit an event when a proposal is executed.

Additional context
Both from a UI and monitoring perspective it's good to know when a proposal is no longer relevant.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.