Riding the EVM with Aragon Agent and EVM scripts

January 24, 2020

Originally published on Aragon One Official Blog

Intro

Inspired by these tweets , I wrote this post to demonstrate and explain some more of the magical capabilities of Aragon Agent.

Every @AragonProject Network Vote has a story behind it. Some bigger, more dramatic, or thrilling than others, but nonetheless always something worth telling.

The story of how ANV#4 started is by far my favourite.

👇Timeline below, for how we got this whole thing kicked off twitter.com/AragonProject/…

— Brett Sun (@sohkai) November 8, 2019

Tweets that inspired this post

Initial situation

  • We deployed the ANJ token, which is a regular MiniMeToken that jurors stake to be eligible to adjudicate disputes for Aragon Court.
  • We deployed the Aragon Network DAO as the MiniMe controller of ANJ, allowing it to mint or burn tokens. The AN DAO is also governor of Aragon Court, which allows it to change parameters and perform upgrades.

Objective

What we wanted to do next:

  • Deploy a Fundraising pseudo-DAO controlled by the AN DAO. I call it “pseudo” because it’s entirely dependent on the AN DAO and doesn’t even have a Voting app. You can see the details in this chart generated with this excellent tool built by Consensys Diligence.

Diagram from AraGraph by CD

Problem

The main problem we had is that the Token Manager in that pseudo-DAO needs to control the ANJ token. The transfer of the control rights is done by the template here, so it needs to have them transferred to it in advance. So before we deploy a new instance, we need to run that transfer from the AN DAO to the template.

But, although the ANJ token is still empty and useless, we don’t want anybody to steal control of it, so we want to have the transfer and the instance deployment performed in one single transaction. That means two things:

  • The AN DAO must deploy the instance as the current ANJ controller, and therefore the only one that can do the transfer.
  • We need a way to call two different functions in two different contracts in a single transaction.

Solution

Aragon Agent + EVM scripts FTW!

As you probably know, the main purpose of the Agent is to allow DAOs to interact with the external ecosystem.

Besides, aragonOS CallsScript allows you to bundle more than one call in one single script.

So we just need to write an EVM script with those two calls and give it to the Agent… and we’re done!

Not so fast. The AN DAO’s EXECUTE ROLE is held by the Voting app, as it should be in any decent DAO. Ok, so we just create a vote to forward the script to the Agent.

Not yet. Only token holders in that DAO can create votes. We must wrap the vote in a script that we send to the Token Manager, which forwards it to the Voting app, which in turn receives the inner content and makes two calls to the Agent.

Let’s summarize the process in this diagram:

Process Summary Diagram

Some last details:

  • We don’t have a way to send EVM scripts to the Token Manager from Aragon client, so we’ll do it in the command line, using this tool we built for Aragon Network deployments.
  • An EVM script is a bunch of hexadecimal commands and params, and the one we want seems quite complex. Here is where we get the inspiration from Brett’s remarkable ANV deployment.

In particular, the structure of our script is the following:

Script Structure Nesting Diagram

  • A call to MiniMeToken contract function changeController, that is passed as a parameter to an Agent call to execute as a data parameter.
  • A call to EOPBCTemplate contract function newInstance, that is passed as a parameter to an Agent call to execute as a data parameter. (This is the template that deploys the Fundraising pseudo-DAO)
  • Those two agent calls bundled in a single CallsScript.
  • That CallsScript piece of code is passed as a first parameter to the newVote function of the Voting contract.
  • We build a new CallsScript instance containing the previous newVote call. This is the final result sent to the function forward of  TokenManager.

Here you have an example of the output produced by our deployment tool for Rinkeby:

Snippet of the raw bytecode

Here’s the full version of the output with comments!

Commented bytecode output

What about gas? This sounds like quite a large transaction. Indeed it is, but we are still within the current block gas limit. As you can see here, the creation of the vote with the scripts is not (around 700K gas). Execution of that vote is much more substantial as it creates the new instance, but still under the limit, as you can see here, around 7.6M gas.

As a final note, I would like to point out another way of playing with the Agent app to execute EVM scripts. With the awesome new CLI v7 release all the inner logic has been decoupled into a separate package called @aragon/toolkit that you can import and use inside your project to do all sorts of fancy stuff, like in these examples.


Thanks to Ale and Jack for reviewing this post.