Bringing Offchain Voting Onchain: SafeSnap

ETHCC 4 · July 2021 · 42:34

Auryn Macmillan introduces SafeSnap, which combines Safe asset management with Snapshot governance. He explains the module’s technical design and demonstrates how Snapshot votes can be brought onchain.

Speakers

Topics

From ETHCC 4, hosted by Ethereum France.

Transcript

uh okay just let me know when we are live or if we are then all right beautiful cool hi ron i'm oren uh hope you're all having a blast in paris uh sorry i couldn't be there in person today but i'm really excited to share some of the things that we've been working on at gnosis uh in particular bringing off chain voting on shane um so daos are not monoliths they're not the monoliths of the old world they are constellations they're multi-organizational networks of people communities organizations mediated by smart contracts and native to the internet gnosis has been building multi-sig wallets since 2017 uh and the nostal safe which was

launched in 2019 has become a core piece of ethereum's infrastructure it currently secures about 35 billion in assets for individuals families teams businesses d5 protocols and dowels but the nurse's safe is much more than a multi-sig then a safe interface that you have more than likely interacted with hides the fact that under the hood the gnosis safe is a programmable flexible and modular contract account standard so one advantage that contract accounts offer is transaction batching projects like omen and circles have been using the uh gnosis safe contract proxy kit under the hood of their applications to create friendly user experience

so essentially batching transactions together so that you only click once where multiple things kind of happen under the hood this is really great for uh things like the uh erc20 approve and then transact flow the contract proxy kit can kind of abstract that away from users in some cases another major advantage is modularity so the nurse's safe allows you to decouple the account the thing that holds funds interacts with systems and generally represents you or your organization on chain decouple that from the logic that controls it so in practice what this means is that you can frictionlessly change from one control mechanism to another

without the coordination costs that would typically be involved with migrating assets and references to your organization's address what i mean by this is let's say you launch an organization on chain using aragon and after six months the organization decides that it would prefer to use colony-style governance you now need to coordinate around migrating any assets and tokens that the aragon dow controls along with updating the permissions or any other contracts or systems that the aragon dow controls or interacts with and updating any external references to the aragondale's address on chain what that affect what this effectively creates is a massive coordination cost uh and then uh the by-product of that is

essentially silos platform lock-in where the switching costs are high enough to deter most users from actually migrating even if they see another setup that they would prefer to use now let's imagine the same organization with a little more foresight so it deploys the gnosis safe to hold its assets control its systems and to be the organization's avatar on chain the organization then launches its aragon dell and uses it to control its noses safe six months later the organization decides it would like to uh prefer to use colony-style governance so they deploy a new colony get it all set up and then execute a proposal to enable it as a module and

then also safe now the two dow frameworks exist in parallel and are both controlling the nurses safe but once they're comfortable that the colony is working as expected they execute a proposal in the colony to remove the aragon dow as a module so at no point did assets need to be moved permissions and external systems need to be changed or references to the organization's address need to be updated the migration is seamless and secure i know this is meant to be a talk on bringing off change governance on chain and we'll get there i promise but if you take nothing else home from this talk this is the point i want you to remember as a best practice the dow space must start to decouple accounts from control logic

this is a really key piece to enabling the kind of permissionless composability that fuel defies explosive growth over the last few years essentially in d5's case the ability to take the output of one system and use it as input for another system and then chain together those systems to create really kind of complex products uh in in the case of daos the same is kind of true there where the ability to permissionlessly couple together disparate systems that weren't explicitly built to uh to operate with one another but that have been built in such a way that they are actually composable will allow a much more kind of interesting and much larger design space for people

uh trying to create dow like structures um so speaking of d fire around this time last year gas prices surged from single digits to consistently over 100 gray and spiking to over a thousand grey in times of really extreme congestion this broke one of the fundamental assumptions that almost every dow framework could base their designs on the gas prices will be low enough for governance to cost effectively happen on chain snapshot emerged as a really well timed reaction to this it quickly saw adoption and arguably contributed to the explosive growth of

d5 in the spring of last year many new and established organizations seeking to progressively decentralize chose to use snapshots free off-chain signaling to empower their community with a voice for anyone that hasn't used snapshot essentially you anyone can create a proposal and then you vote on proposals by signing a message that is not actually published on chain but is published to ipfs where anyone can transparently audit all of the messages and it's time stamped by hubspot by snapshots hub server so uh yeah a whole bunch of organizations kind of adopted this as uh the easy way to give their community a voice uh in most cases the community's

will was and still is carried out unchained by a group of trusted community members who are signers on an also safe now this is a really practical and functional first step on the progressive decentralization journey but in an ideal world adele should not have to rely on and trust a small group of people that with everything it owns indeed it was while weighing up the pros and cons of the dow frameworks the existing dial frameworks and the lead up to launching the notice dow that we realized nothing that existed at the time solved for both permissionless control and gas free voting so leaning into the safe snapshot pattern that had already become the de facto standard

we set out to build a module to the nurse's safe that would allow daos to permissionlessly turn their off-chain decisions into on-chain execution the result was the gnosis safe dell module and the safe snap plug-in for snapshot now rather than having a snapshot instance plus a nurse's safe multi-sig organizations can directly control their noses safe via a proposal on snapshot uh so this provides a clear pathway to progressive decentralization taking the guesswork and worry out of an exit to community and allowing projects to start with a multi-sig and take incremental steps to hand over control of their ecosystem

so in this example we envision a four-step pathway starting with the nosa-safe multi-sig on the left adding in a governance mechanism snapshot to measure the community opinion then adding in uh safe snap to give the community a more direct control over their safe while the multi-stig also retains full control in parallel and then finally removing the multiseed sinus altogether and we actually have an upcoming uh feature here as well that will insert uh another step between those last two uh where you'll essentially be able to empower the multi-sig signers uh with the ability to veto snapshots or safe snap transactions that are

coming through but not do anything else so you essentially drastically limit the scope of what the multisig signers are allowed to do so they can they can kind of take on that veto role that backstaff or safeguard role but they can't run away with all the money or they can't kind of mess with any other systems or anything like that um but that's uh that's not yet released so kind of not factored into this uh this is progressive decentralization pathway all right so how does it work and what are the trust assumptions um we start with a nurse's safe and an instance of snapshot then we deploy an instance of our dell module contract and enable it as a module on our notice safe using the safesnap plugin anyone can

create a proposal on snapshot that includes some on-chain transaction that should be executed by the nurses safe if the proposal passes when a proposal passes anyone can call the ad proposal function on the notes on the dow module contract which queries an oracle reality.eth for the outcome of the snapshot proposal the oracle reports the outcome back to the dow module and after a cool down period anyone can call the execute proposal function on the dow module to trigger uh on-chain execution of the proposed transaction from the gnosis safe so essentially here we're relying on uh this oracle to uh report the off chain events uh truthfully on

chain so the oracle is the the key to this system working it's what allows us to uh allows anyone to permissionlessly bring results of the off chain proposal on chain to validate whether or not a given transaction should be allowed to be executed by the nurses say reality is an uh escalation game based oracle so in other words it's secured by game theory anyone can post a question to which anyone else can post an answer however to post an answer you must provide a bond that is at least double the bond uh or double any previously provided

bond for an answer to that question so each time a new bond is posted a timeout is reset at that time that's 24 hours by default uh if at any time the timeout ends without anyone doubling the bond the answer is considered final at this point assuming the question is properly formatted the bond is equals or greater than the minimum bond set in the dow module anyone can use that answer to trigger the associated transaction in the nurses safe you can optionally include an arbitration option like claros which can be used or can be called instead of continuing to play the escalation game and just a side note here that setup reality dot eth plus cleros is the

kind of oracle set up for the omen prediction market as well so one really cool thing about this architecture is that it's agnostic to the decision making mechanism so while snapshot was the obvious first choice for integrations we could easily import decisions from just about anywhere that could be discourse forum discussion twitter polls or discord polls for example and the friendly robots over at collab land have already started working on an integration with our dow module that will allow discord communities to own and control the nurses safe if you're in paris right now you should definitely touch base with james and the rest of the collab land crew to check out a demo of this setup all right so let's switch gears for a little bit i'm going

to try for the reliable live demo here so we'll be going through the process of creating and executing a notice of safe transaction using the safe snap plugin for snapshot uh there are a couple of cool down periods and uh since we'll be doing this live on ring be some delays while we wait for transactions to confirm so this is also a good time to shoot through questions on chat and i'll try to answer them as we go bear with me while i just switch screens here so here we've got our uh snapshot proposal our snapshot space this one is uh the wiener space for anyone who hasn't played with it before weenus is a token created by uh bucky poohba and it's essentially anyone can mint

basically as much of it as they want so it's a great token for testing with so what we're going to do here is just jump in and create a new proposal um and i'm just going to send myself some tokens we'll spend 13 tokens to me that's a little bit shorter um i've been to outcomes uh it's it's important that you always have a and no outcome essentially something

that is the equivalent of do nothing uh as of right now the module only supports binary outcomes so yes or no in future we may look at doing things like uh multiple choice outcomes uh in which case there would be you would still always have to have a kind of negative outcome this snapshot space is controlling the nurses safe at this address so if we follow this link here we can check out this notice safe uh you can see it holds a balance of this weenus token um and uh it has one owner that is an invalid address this is kind of a quirk of the current way that the nurse's safe multisig works and that you can't remove all of the signers so we

hacked that a little bit and just put in a uh an obviously invalid address and then uh it is now controlled exclusively by this dell module which if we load it up on ether scan here we can see the verified source code so if you want to go and check that out you most certainly can so we'll jump back into snapshot here i'm going to hit add transaction batch and just to explain this quickly first what you're doing here is actually creating batches of transactions so i mentioned earlier that one of the cool features of kind of an account a contract account is that you can bash

transactions together so here what we're doing is actually defining an array of batches of transactions uh so each batch in this array is executed separately on chain so these are separate transactions but every transaction that you build within a batch gets executed in one transaction all of the transactions within a batch get executed in the order that you define them and then each of the batches of transactions can only be executed in the order that you define them here so you have really precise control on uh on how you batch them in what order each of the transactions go and uh and whether or not they are executed within one transaction or in multiple transactions so in this case i'm just going to set up a

a nice easy transfer and it was to send me 13 wieners right so just so that we can use multiple uh transactions here i'm gonna switch accounts uh just so that we can use multiple transactions here i'm going to do one for six wieners and then i'm gonna do the same thing and one for seven wieners so now we have our two transactions confirmed in one batch i'm going to delete this batch here and that is our proposal to find the next thing we need to do is

just to pick our start date and time so for this one i'm going to pick today's date which is what the 21st and uh for me it is just after 10 so i'm just going to leave it at 10 a.m and then i'm going to pick 10 13 we'll say that as the end date or maybe 10 14 just to give me time to vote uh 13 should be fine i can be quick i will let's make that thing so i'll hit publish here i need to sign a message i don't know if you guys can see my men marks pop up but you if you could you would notice that it uh

it includes the uh a whole description of this proposal including the uh details for each of these transactions i can open that up on ipfs here in a minute so here's our proposal i'm going to hit vote i'll vote yes on this because i want this to happen um great so now i've got my vote in and we can quickly take a look at this ipfs document it's a little bit hard to read here uh because it's not uh it's not formatted very friendly for a human to read but you should be able to see here that uh

let's have a look we've got a couple of transactions defined um so we can see here our transfer funds to uh an address and then the amount of six and then transfer funds to an address and the amount was seven where did it go here we go and that was seven so that's uh essentially what our proposal will look like and uh yeah we can now as soon as this

proposal closes we are waiting for oh it should have already closed so i'm just gonna refresh this cool so the votes closed and now i can go and request execution from our oracle reality.eth so again i'm just going to hit request execution anyone can do this it's a permissionless function or a public function you hit confirm and what this is going to do is call the add proposal function on our dell module contract which basically then reaches out to reality and creates a question on reality asking if this proposal should be finalized uh or should be uh should after asking if this proposal here resolved to yes essentially um we

can go and open up this question independently on the reality interface but we've actually and built in all of the functionality that you need here within the uh the plugin so from here now we can go and change the outcome the current outcome is set to no by default to change the outcome we need to put down a bond there's a minimum bond of 0.1 eth on that was defined in the dial module attached to this snapshot space so we can hit yes to set the outcome with a 0.1 eth bond and then it's going to have a three minute timeout on this uh outcome

so long as no one comes and changes it which anyone could because again it's permissionless but so long as no one comes and changes it in the meantime then uh our outcome should finalize uh in the meantime we can go and take a look at the reality interface to make sure that it's showing up there as well i'm just waiting on rinkeby to do its thing but let's let's jump over to reality dot heath i don't know if i can actually do that from okay great okay so our outcome has been set uh finalized in two minutes so we just

need to wait for that cooldown um was hoping to be able to jump over to a new window but i'm not sure that i have an easy pathway to do it while i'm in full screen mode so here we go uh although we want the ring free version only oh evidently their app is down the ever reliable live demo strikes again so well um i guess this is probably the uh the teeth don't link to me being down oh so we'll hold off on that then and we'll hang out here for a minute

while we wait for this bond or this uh this question to finalize in the meantime i'm going to check back and just make sure that we don't have any questions that have come through i don't see anything in the uh the youtube chat so i think we're all good okay perfect yeah i can hear you just fine yeah so we don't have kind of a browser

extension type system right now the way that you can do it i guess there's two different ways one is you can drop in an api um so oh that's not the api let's drop that into the two address um go grab the api for this contract so i don't know it's filled it out by itself great so here we drop in an address that has verified source code into this contract interaction uh transaction type and then we can basically just interact with the api um so this is a a reasonably accessible way of doing it but obviously it requires some knowledge of how the contract works and what parameters should uh what the parameters go into this api should look like and what the results are going to be so it's not

it's not a uh a super user-friendly way of doing it the other way that we have is you can just drop in literally raw transaction data um and there's so just a a string of bytes here that that correspond to the function calls that you want to do so if you want to go and craft your transaction somewhere else and then just drop in the data you can do it here what we are hoping to build is um and we have kind of a simple proof of concept for at the moment is a way to basically impersonate the safe uh on a mainnet fork and then uh go and interact with a bunch of daps and queue up a whole bunch of transactions that you then just import over into uh into the plugin but that's still kind of very early stages so for

the time being they're probably the most user-friendly way to do things that aren't just uh fun transfers and nft transfers is uh with the contract interaction here by just dropping in the address and or the api to the contract that you want to interact with no worries so we can jump back over now to our um oh i don't know if that might have i'll just leave it like this um so we'll jump back over here now uh our proposal should have um yep so our timeouts finished so now i can hit the clean bond to clean back my bond

for setting the outcome because it was not challenged that it ultimately resolved to the uh the answer that i set um and then once i've claimed back this bond uh only i see this window by the way anyone else uh would just see the the next step but once this transaction is confirmed then uh i the the plugin here is gonna update and uh show me one more time out here this is um basically a cool down so the the idea here being that uh you you have a cool down from when the question uh finally resolves on reality to when it can

actually be executed in the nose safe and this is it to allow time for uh another control mechanism this might be your multi-c signers if they still exist on the safe or might be some other dell mechanism that you've permissioned through a uh through a module just allow time for these other mechanisms uh to act as a backstop if the proposal that's come through is malicious so this is your opportunity to basically jump into your dell module and call the mark proposal as invalid function here and basically that will do is block this transaction from being executed and so if you were to do that your proposal id is this the the ipfs

hash of this proposal and then the transaction um the uh tx hashes parameter is uh the the the hash of the concatenation of uh each of these transactions so uh that one's a bit uh more painful to to produce but we'll have some tools to make that a bit easier at some point as well um so we should be able to execute now perfect so now we have this button here execute transaction one of one in our case it's just one batch of uh transactions for two um two transfers so i'm gonna hit execute transaction here and uh once that goes through and the

nurse's safe um transaction service kind of catches up we should see it show up here in the transaction history so the last one was july 8th this one's been a little bit inactive but we should see that show up here momentarily and that when it does show up is essentially the the whole flow for creating uh resolving and then executing a transaction um there we go module transaction with two actions so the safe interface is actually really nice and that it decodes these uh transactions um so transfer one and transfer two and so that's it

we've we've essentially created a proposal uh defined transactions within the proposal uh had that proposal resolve uh queried the reality.eth oracle to get the the outcome of this proposal and then use that to trigger this transaction in the nurse's safe i should say this batch of transactions and in the nurse's safe now if we have created uh multiple batches of transactions here then these would have been executed uh as two separate transactions here in the safe and here where it said one of one it would have said one of two and then two of two and i would have had to actually make two separate ethereum transactions and so that can be really useful for situations where you for whatever

reason cannot put the transactions into the same block so you know maybe you have a transaction that's using up enough gas that uh or that like a combination of transactions that would use up more than the gas limit or more than you would reasonably be able to fit into a block uh or maybe you have something that's got a reentrancy guard or something like that that's going to block you from doing it in one transaction so in that case you would kind of put it into batches of transactions but otherwise wherever possible it makes sense to try to batch them all together just to save on the kind of coordination cost and save on the uh the actual gas costs of making individual transactions uh so yeah that's uh that's essentially uh the whole process again i'm happy to uh to kind of take

questions um for everyone that made it this far check out uh notice guild on twitter this is where we'll drop updates on all the awesome kind of new dow tooling that we're working on this is a relatively recent uh shift in in direction for kind of one of the internal teams at gnosis um so we're going to be kind of releasing a whole bunch of dow tooling too to really help to kick start this idea of much more modular and composable dow tooling if you want to learn more about safesnap you can jump into our discord server at chat.nurses.io or our forum at forum.nurses.io and this is absolutely an open invite to come and build a more composable future for the dao ecosystem if you're working on your own

project please get in touch with us and let us know with how we can help uh we'd love to collaborate about uh around kind of helping to make your project more composable help it to kind of plug into this ecosystem and and um and kind of leverage the tooling that we're building as well as allowing existing dowels to to leverage the tools that you're building and if you're looking to get involved with the dao space we're hiring for multiple technical and non-technical roles so please reach out thanks for tuning in to the talk everyone i'm oren and you can find me on twitter at lauren underscore macmillan um and if we still have time i haven't kept track of it very well then i'm totally open to doing some uh taking some more questions and kind of diving back through anything if there's

anything that was not clear right yes i mean the only limit really

is the uh the block limit like the block gas limit um so if you can fit it within a block uh and then you can get that transaction mined then there's there's no real limit to it obviously like the the closer to the block limit uh the the block gas limit you push your your transaction aside the harder it's going to be to get it mined because it kind of necessarily means the transaction that the miner probably losing out on some mev for other transactions so you know unless if you have a giant transaction like that then you probably need to pay a really really high uh gas price to actually get in mind um so that that's the kind of i guess practical

limit there is just the uh the gas limit and what you could how big you can make a transaction to get it uh kind of mined in a reasonable amount of time but outside of that this can be as arbitrarily complex as you want you can create um as many different transactions in each of these batches as you want they can have any combination of of different features they can be contract interactions you can drop in raw data you can transfer any amount of funds anything like that and then you can make as many batches as you want so this can get really really uh really deep and really complex quite quickly so again just to reiterate here everything within this batch happens in one transaction and gets executed in order and then each

of these batches are separate ethereum transactions and they must be executed in order as well one caveat to think about there as well is that if say you create this this kind of array of four transactions in a batch and for whatever reason batch two will always fail then batch three and four can never be executed you have to this one has to successfully execute in order to be able to execute the following transactions um so uh i guess maybe if we're kind of waiting on other questions maybe i'll talk a little bit and just kind of uh tease some of the other things that we're working on um

it talks about kind of making this more composable uh dow ecosystem and one part of that i think is is uh really realizing this this vision of dao's being these kind of constellations of of people and tools um as opposed to kind of these i guess like thinking of dials as essentially like a silo thinking of it as a as a contractor as kind of one particular system they can be much more complex and and the kind of design space can be much more wide open um and so one way that we've been thinking about this is this idea of obviously like decoupling the account standard from the mechanisms

that are controlling it and from the other mechanisms that the account is controlling uh making these kind of composable pieces and the really cool thing or one really cool thing i think that enables is then the idea of uh essentially like one control structure controlling multiple different accounts and so in that case like right now we have one notice safe that's being controlled by this snapshot but there's no reason that this snapshot instance couldn't control a suite of nurses saves um and then there's no reason that those nurses safes couldn't then control uh more nurses safes or more or kind of other systems couldn't be the the owner of a d5 protocol for example and set the variables in an e5 and then i think that the really neat uh thing that we've

we've actually already built and haven't uh haven't kind of announced yet so don't tell anyone um but we we built a um a way of controlling a nurse's safe on one side of an arbitrary message bridge from an address on the other side and so like in a practical sense what that means is things like being able to have say a colony deployed on x die that can control a nurse's safe on main net and so effectively what we're doing is allowing uh a an organization to kind of choose a home chain uh one where they're happy with the trust assumptions and happy with the the cost of execution but then extend their reach out to two other chains and so we kind of imagine an environment now

where uh you know you have say an organization chooses exercise at time chain but is able to still have a representation an avatar an account on mainnet and on polygon and on uh optimism and arbitrary and anywhere else that's kind of evm compatible and there's a suitable message bridge between the two networks and so we have this safebridge uh module that we've built already that enables it between xdi and mainnet and anywhere else that there is a compatible arbitrary message bridge um and this is one of the things that we're really excited about is these kind of like uh interdimensional dows interdimensional organizations that you know can live on one chain but still have a presence and uh and tangibly control a anosa safe on another chain

yes yeah so like the reason for doing something like this uh would typically be well i guess there's probably multiple reasons one is wanting to have one place that's the kind of canonical place where decisions are made so if you think about the the issue of trying to kind of keep decision making mechanisms in sync in multiple execution environments it gets really really sticky you know say you've got even with just a multi-seek so you've got a multi-sig on main net but then you also want to have a presence on x-tie um and your multi-sig starts out as a three or five um and then uh so you deploy an instance of that on x die as well and it's three of five uh and then later on you decide to add

some more people to the multisig on mainnet and maybe switch out some of the signers you then have to go and kind of duplicate that action over on xdi add some people switch out some sinus and get everything back in sync the more networks that you deploy this kind of instance of this multiseek to the more this like sinking problem becomes an issue um kind of keeping them all in sync uh becomes an issue and so like with a multi-seek that's a pain in the butt with dow where you're talking about token balances uh that's you know if it's you know adele with like liquid token balances then trying to keep like the vote weights in sync across each of these chains is uh is a near impossible task and so having uh being able to kind of point to one

instance of this down and say this is where all of the decisions are going to be made and then rather than kind of trying to mirror that dow elsewhere trying to keep it in sync we are just going to make all of the decisions here and then bridge our decisions to other chains uh and have this this nurses safe be the thing that actually represents the dow on these other chains and is kind of controlled directly by our uh our chain our dow structure on the chain that we uh that we live on you avoid all of that kind of sinking cost all of that effort to try to keep uh keep all of these disparate instances of your organization in sync and instead just have everything happen in one place

and then from a from a gas point of view it means you know like say say you have um an aragon dao this has been a big problem for a lot of aragon dallas that launched you know a year or two ago on mainnet um have now uh have reached a point where on-chain governance is just not cost effective for them they they struggle to get uh voter participation because it costs so much to actually cast a vote um there's been a pretty uh pretty substantial migration from uh from aragon deployed on mainnet to uh instances of aragon deployed on x-dire to accommodate this for folks have basically just packed up on left

mainnet and deployed onto uh onto extire the same is true for for molecule with the uh the um dow house folks or the the rate yield folks uh kind of deploying all of that infrastructure to extire and there's been a whole bunch of projects including regular themselves that basically migrated all of their operations over to extire and so what this uh what this allows you to do is still have this kind of cheap execution on extire but maintain a presence on uh on main net and so it's like the point where you would choose to do this is where the the execution costs or the additional uh kind of gas costs of crossing the bridge with your transaction is less than the kind of aggregate cost of participating in voting on

mainnet alrighty yeah i know where it is thanks for having me really enjoyed the uh chat again sorry i couldn't be there to do it in person uh next year fingers crossed cool all right thanks everyone bye you