--- tags: rage-report, boost --- # Rage Report: Minion Safe WalletConnect **Background:** Currently creating proposals though the Safe Minion that interact with other dapps require some advanced knowledge of the smart contracts that the dapp uses. We have come a long way with making these interactions easier through: - transaction builder: adds ability to make batched transactions to interact with smart contract. (still fairly advanced for the user, requiring interaction with contract interaction directly) - 'forged' tasks such as transfer, airdrops (disperse) and NFT management actions. This is much more simple for the user but fairly restrictive to specific actions and requires custom development for every task. Adding WalletConnect would leverage a common pattern used in the space to allow uses to interact with a dapp as the minion. Any transactions would be forwarded to a proposal that can be executed by the DAO. **deliverables:** - An interface in every Minion Safe vault to connect to a dapp using Wallet connect. - Paste walletconnect string from a third party dapp into the MInion Safe interface to make the connection - Interactions made in the third party app are intercepted and forwarded onto dao proposals to be executed. **known issues** - Many dapp interactions are time sensitive. The full timelock of voting and grace may not be acceptable. (this can be addressed using early execution and sand boxed assets with the Safe Minion) - see this forum post for other potential issues and solutions to arbitrary on chain execution. https://forum.daohaus.club/t/trade-offs-in-supporting-ace-eg-minion-transactions/10865 - Many dapps do not have WalletConnect support - A dapp will show the current state of the Minion address meaning it is hard to batch some interaction like approve and then swap. The transaction builder is still a good option for these more complex batches but early execution minions can help with these flows. - One of the prime usecases is for one dao to connect to another dao for sub/sibling dao interactions, this could have issues if session is storing too different connections across tabs. **Potential Resources** - See Gnosis Safe implementation for a common pattern https://github.com/gnosis/safe-react-apps/tree/development/apps/wallet-connect/src - WalletConnect https://walletconnect.com/ - https://github.com/HausDAO/MinionSummonerV2 **Experiment 1** Spike on a POC around adding interface to Minion Vault pages https://youtu.be/2ALFUZN5Pyk updated with proposal flow https://youtu.be/DiHHcTwZK1c **Experiment 2** Interact with a AMM on Gnosis chain like swapr. this will require at least 2 transactions. (approve and swap) - PoC wrapping some ETH using Cowswap https://youtu.be/DiHHcTwZK1c - Found an issues when trying to test WalletConnect connection using Uniswap on Rinkeby. Need to reload the page in order to pair, but might be an issue with a testnet only - Swapr doesn't work on Rinkeby even if it is listed in the UI. Pairing was successful on GnosisChain - It's not possible to batch Txs (i.e. approve + swap) so it will need separate minion proposals - Would be nice to find other dApps (with WalletConnect support) DAOs could potentially interact with - Need to test other scenarios like signing with a contract wallet (Snapshot?, NFT dApps or cowswap potentially) **Experiment 3** Interaction between two differet DAOs This works. Experiment followed the steps below: 1. Go to Minion Safe on DAO A 2. Open WalletConnect proposal and wait for WCLink 3. Connect to DAO B with WConnect 4. Paste WConnect link on proposal form in DAO A 5. Go back to DAO B and create a funding proposal that send funds to a minion 6. Submit proposal & get. msg that Tx was forward to an external minion 7. Back to DAO A & Submit proposal 8. Go trough proposal voting period & execution 9. Check DAO B & a new funding proposal appears Considerations: - In 3) there is an issue with how awallet "session" is handled by web3Modal that is not possible to use two different wallet connection providers in different tabs, so I had to open DAO B in another browser - In 6) the tx forwarding message is displayed as an "error" message - Seems that BlockNative web3Onboard library manages different wallet connections within their own state https://docs.blocknative.com/onboard/core#state but need to do some tests to make sure **Experiment 4:** Voting on snapshot similar to what is allowed for gnosis safe. Snapshot has support for EIP 1271 so should be possible https://docs.snapshot.org/gnosis-safe Gnosis Safe support connecting to the snapshot app to make votes. The question is if they have something special for safes or if they are handling it with walletconnect. Considerations: - According to the page, only works on Mainnet ATM - Tested on Rinkeby and got the following error in the console ``` POST https://snapshot-relayer.herokuapp.com/api/message 500 (Internal Server Error) { "error": "unauthorized", "error_description": { "reason": "invalid address", "code": "INVALID_ARGUMENT", "argument": "address", "value": "0x0" } } Payload { "address": "0x032e835F6ad43f7a72e82e7202d8f2Cd75505cb8", "msg": "{\"version\":\"0.1.3\",\"timestamp\":\"1650581567\",\"space\":\"santteegt.eth\",\"type\":\"vote\",\"payload\":{\"proposal\":\"0xa415542a17799f4a354913daa4b2f96ccbdab36829608a750cf685b9013644a6\",\"choice\":1,\"metadata\":{}}}", "sig": "0x" } ``` another potential solution using snapshot delegation https://docs.snapshot.org/guides/delegation Results: - A minion will open the WConnect modal and connect to https://snapshot.org/#/delegate in order to send a proposal to set a delegate (e.g. dao member) - Once a delegete is set, this invididual will be able to vote on proposal with the proper delegate strategy enabled **Experiment 5** Trade on CowSwap Results: - It's possible to trade using Minion WConnect & Cowswap UI - Requires a separate Tx proposal per action (e.g. approve + Trade) - CowSwap UI internally manages Txs from a Gnosis Safe using a `presign` signature scheme, instead of off-chain signatures that are usually triggered when using EOA accounts. - The steps are the following 1. Queries the Safe Tx Service to get Safe details 2. Once trade params are set, POST a quote POST https://api.cow.fi/rinkeby/api/v1/quote ``` Payload { "kind": "sell", "sellAmountBeforeFee": "1000000000000000000000", "sellToken": "0x5592EC0cfb4dbc12D3aB100b257153436a1f0FEa", "buyToken": "0x4DBCdF9B62e891a7cec5A2568C3F4FAF9E8Abe2b", "from": "0x0000000000000000000000000000000000000000", "receiver": "0x0000000000000000000000000000000000000000", "appData": "0x487B02C558D729ABAF3ECF17881A4181E5BC2446429A0995142297E897B6EB37", "validTo": 1650585170, "partiallyFillable": false } Response { "quote": { "sellToken": "0x5592ec0cfb4dbc12d3ab100b257153436a1f0fea", "buyToken": "0x4dbcdf9b62e891a7cec5a2568c3f4faf9e8abe2b", "receiver": "0x0000000000000000000000000000000000000000", "sellAmount": "624584995196991438848", "buyAmount": "8898013741", "validTo": 1650585170, "appData": "0x487b02c558d729abaf3ecf17881a4181e5bc2446429a0995142297e897b6eb37", "feeAmount": "375415004803008561152", "kind": "sell", "partiallyFillable": false, "sellTokenBalance": "erc20", "buyTokenBalance": "erc20" }, "from": "0x0000000000000000000000000000000000000000", "expiration": "2022-04-21T23:24:42.197523740Z" } ``` 3. Once click on Trade, it executes the folliwing Tx - To: 0x9008d19f58aabd9ed0d60971565aa8510560ab41 - Method: setPreSignature - Params: - orderId - signed (true) ![](https://i.imgur.com/7bj6x5A.jpg) 4. Use the Safe Tx API to monitor Tx status GET https://safe-transaction.rinkeby.gnosis.io/api/v1/multisig-transactions/0x4f13a9d37494477dd82551574c7dce2b5f6c9354400f17dc4ca52052fc2a244a/ ``` { "safe": "0x032e835F6ad43f7a72e82e7202d8f2Cd75505cb8", "to": "0x9008D19f58AAbD9eD0D60971565AA8510560ab41", "value": "0", "data": "0xec6cb13f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000038a661970eedca1350ad9bfa8bf362b87b33a70d40fca9c97f3a38784172e9a729032e835f6ad43f7a72e82e7202d8f2cd75505cb86261ee520000000000000000", "operation": 0, "gasToken": "0x0000000000000000000000000000000000000000", "safeTxGas": 0, "baseGas": 0, "gasPrice": "0", "refundReceiver": "0x0000000000000000000000000000000000000000", "nonce": 10, "executionDate": null, "submissionDate": "2022-04-21T23:23:29.985681Z", "modified": "2022-04-21T23:23:29.985681Z", "blockNumber": null, "transactionHash": null, "safeTxHash": "0x4f13a9d37494477dd82551574c7dce2b5f6c9354400f17dc4ca52052fc2a244a", "executor": null, "isExecuted": false, "isSuccessful": null, "ethGasPrice": null, "maxFeePerGas": null, "maxPriorityFeePerGas": null, "gasUsed": null, "fee": null, "origin": "{\"url\":\"http://localhost:3001\",\"name\":\"WalletConnect\"}", "dataDecoded": { "method": "setPreSignature", "parameters": [ { "name": "orderUid", "type": "bytes", "value": "0xa661970eedca1350ad9bfa8bf362b87b33a70d40fca9c97f3a38784172e9a729032e835f6ad43f7a72e82e7202d8f2cd75505cb86261ee52" }, { "name": "signed", "type": "bool", "value": "True" } ] }, "confirmationsRequired": null, "confirmations": [], "trusted": false, "signatures": null } ``` 6. Queries their own API to get the order status. Status sequence is `presign` -> `open` -> `fulfilled` GET https://api.cow.fi/rinkeby/api/v1/orders/0xa661970eedca1350ad9bfa8bf362b87b33a70d40fca9c97f3a38784172e9a729032e835f6ad43f7a72e82e7202d8f2cd75505cb86261ee52 ``` { "creationDate": "2022-04-21T23:22:51.460568Z", "owner": "0x032e835f6ad43f7a72e82e7202d8f2cd75505cb8", "uid": "0xa661970eedca1350ad9bfa8bf362b87b33a70d40fca9c97f3a38784172e9a729032e835f6ad43f7a72e82e7202d8f2cd75505cb86261ee52", "availableBalance": null, "executedBuyAmount": "0", "executedSellAmount": "0", "executedSellAmountBeforeFees": "0", "executedFeeAmount": "0", "invalidated": false, "status": "presignaturePending", "settlementContract": "0x9008d19f58aabd9ed0d60971565aa8510560ab41", "fullFeeAmount": "375415003238781026304", "sellToken": "0x5592ec0cfb4dbc12d3ab100b257153436a1f0fea", "buyToken": "0x4dbcdf9b62e891a7cec5a2568c3f4faf9e8abe2b", "receiver": "0x032e835f6ad43f7a72e82e7202d8f2cd75505cb8", "sellAmount": "623372224362349264896", "buyAmount": "8836553498", "validTo": 1650585170, "appData": "0x487b02c558d729abaf3ecf17881a4181e5bc2446429a0995142297e897b6eb37", "feeAmount": "376627775637650735104", "kind": "sell", "partiallyFillable": false, "signingScheme": "presign", "signature": "0x032e835f6ad43f7a72e82e7202d8f2cd75505cb8", "sellTokenBalance": "erc20", "buyTokenBalance": "erc20" } ``` 7. Once the order is fulfilled ``` { "creationDate": "2022-04-21T23:22:51.460568Z", "owner": "0x032e835f6ad43f7a72e82e7202d8f2cd75505cb8", "uid": "0xa661970eedca1350ad9bfa8bf362b87b33a70d40fca9c97f3a38784172e9a729032e835f6ad43f7a72e82e7202d8f2cd75505cb86261ee52", "availableBalance": "830000000000000000000", "executedBuyAmount": "9059749151", "executedSellAmount": "1000000000000000000000", "executedSellAmountBeforeFees": "623372224362349264896", "executedFeeAmount": "376627775637650735104", "invalidated": false, "status": "fulfilled", "settlementContract": "0x9008d19f58aabd9ed0d60971565aa8510560ab41", "fullFeeAmount": "375415003238781026304", "sellToken": "0x5592ec0cfb4dbc12d3ab100b257153436a1f0fea", "buyToken": "0x4dbcdf9b62e891a7cec5a2568c3f4faf9e8abe2b", "receiver": "0x032e835f6ad43f7a72e82e7202d8f2cd75505cb8", "sellAmount": "623372224362349264896", "buyAmount": "8836553498", "validTo": 1650585170, "appData": "0x487b02c558d729abaf3ecf17881a4181e5bc2446429a0995142297e897b6eb37", "feeAmount": "376627775637650735104", "kind": "sell", "partiallyFillable": false, "signingScheme": "presign", "signature": "0x032e835f6ad43f7a72e82e7202d8f2cd75505cb8", "sellTokenBalance": "erc20", "buyTokenBalance": "erc20" } ``` ### Expectations: Having another way for DAO members to interact with apps will allow daos to take advantage of the ecosystem easier. Can better open up the defi landscape to DAO treasuries, making things like swaps, staking and lending easy to less advanced DAO members. THis will work best with Minions that have a min quorum for early execution. allowing Dao members to accelerate the voting and grace periods ### team Santiago Dekan ### Results/Findings: #### Demos - [Safe Minion + WalletConnect: Trading on CowSwap](https://youtu.be/KFjuf5Sz7Sk) - [Safe Minion + WalletConnect: Using Snapshot](https://youtu.be/RpKR1KqXrF8) - [Safe Minion + WalletConnect: DAO2DAO Interactions](https://youtu.be/mbHOD9A4RAc) #### Pull Request https://github.com/HausDAO/daohaus-app/pull/1788 ### Proposed Next Steps: ### other ideas to explore